Merge pull request #13205 from davezarzycki/nfc_typebase_layout_optimization

[AST] NFC: Shrink TypeKind size and optimize TypeBase layout
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 0c04168..d837a3d 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -57,6 +57,7 @@
     single-source/DictionaryGroup
     single-source/DictionaryLiteral
     single-source/DictionaryRemove
+    single-source/DictionarySubscriptDefault
     single-source/DictionarySwap
     single-source/DropFirst
     single-source/DropLast
@@ -118,6 +119,7 @@
     single-source/StrComplexWalk
     single-source/StrToInt
     single-source/StringBuilder
+    single-source/StringComparison
     single-source/StringEdits
     single-source/StringEnum
     single-source/StringInterpolation
diff --git a/benchmark/single-source/DeadArray.swift b/benchmark/single-source/DeadArray.swift
index b8ebcc3..4111e13 100644
--- a/benchmark/single-source/DeadArray.swift
+++ b/benchmark/single-source/DeadArray.swift
@@ -16,7 +16,7 @@
 public let DeadArray = BenchmarkInfo(
   name: "DeadArray",
   runFunction: run_DeadArray,
-  tags: [.regression])
+  tags: [.regression, .unstable])
 
 @inline(__always)
 func debug(_ m:String) {}
diff --git a/benchmark/single-source/DictionarySubscriptDefault.swift b/benchmark/single-source/DictionarySubscriptDefault.swift
new file mode 100644
index 0000000..2c90d01
--- /dev/null
+++ b/benchmark/single-source/DictionarySubscriptDefault.swift
@@ -0,0 +1,124 @@
+//===--- DictionarySubscriptDefault.swift ---------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+import TestsUtils
+
+public let DictionarySubscriptDefault = [
+  BenchmarkInfo(name: "DictionarySubscriptDefaultMutation",
+                runFunction: run_DictionarySubscriptDefaultMutation,
+                tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionarySubscriptDefaultMutationArray",
+                runFunction: run_DictionarySubscriptDefaultMutationArray,
+                tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionarySubscriptDefaultMutationOfObjects",
+                runFunction: run_DictionarySubscriptDefaultMutationOfObjects,
+                tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionarySubscriptDefaultMutationArrayOfObjects",
+                runFunction:
+                  run_DictionarySubscriptDefaultMutationArrayOfObjects,
+                tags: [.validation, .api, .Dictionary]),
+]
+
+let count = 10_000
+let result = count / 100
+
+@inline(never)
+public func run_DictionarySubscriptDefaultMutation(_ N: Int) {
+  for _ in 1...N {
+
+    var dict = [Int: Int]()
+
+    for i in 0..<count {
+      dict[i % 100, default: 0] += 1
+    }
+
+    CheckResults(dict.count == 100)
+    CheckResults(dict[0]! == result)
+  }
+}
+
+@inline(never)
+public func run_DictionarySubscriptDefaultMutationArray(_ N: Int) {
+  for _ in 1...N {
+
+    var dict = [Int: [Int]]()
+
+    for i in 0..<count {
+      dict[i % 100, default: []].append(i)
+    }
+
+    CheckResults(dict.count == 100)
+    CheckResults(dict[0]!.count == result)
+  }
+}
+
+// Hack to workaround the fact that if we attempt to increment the Box's value
+// from the subscript, the compiler will just call the subscript's getter (and
+// therefore not insert the instance) as it's dealing with a reference type.
+// By using a mutating method in a protocol extension, the compiler is forced to
+// treat this an actual mutation, so cannot call the getter.
+protocol P {
+  associatedtype T
+  var value: T { get set }
+}
+
+extension P {
+  mutating func mutateValue(_ mutations: (inout T) -> Void) {
+    mutations(&value)
+  }
+}
+
+class Box<T : Hashable> : Hashable, P {
+  var value: T
+
+  init(_ v: T) {
+    value = v
+  }
+
+  var hashValue: Int {
+    return value.hashValue
+  }
+
+  static func ==(lhs: Box, rhs: Box) -> Bool {
+    return lhs.value == rhs.value
+  }
+}
+
+@inline(never)
+public func run_DictionarySubscriptDefaultMutationOfObjects(_ N: Int) {
+  for _ in 1...N {
+
+    var dict = [Box<Int>: Box<Int>]()
+
+    for i in 0..<count {
+      dict[Box(i % 100), default: Box(0)].mutateValue { $0 += 1 }
+    }
+
+    CheckResults(dict.count == 100)
+    CheckResults(dict[Box(0)]!.value == result)
+  }
+}
+
+@inline(never)
+public func run_DictionarySubscriptDefaultMutationArrayOfObjects(_ N: Int) {
+  for _ in 1...N {
+
+    var dict = [Box<Int>: [Box<Int>]]()
+
+    for i in 0..<count {
+      dict[Box(i % 100), default: []].append(Box(i))
+    }
+
+    CheckResults(dict.count == 100)
+    CheckResults(dict[Box(0)]!.count == result)
+  }
+}
diff --git a/benchmark/single-source/DropLast.swift b/benchmark/single-source/DropLast.swift
index 83f2a3b..49750be 100644
--- a/benchmark/single-source/DropLast.swift
+++ b/benchmark/single-source/DropLast.swift
@@ -51,7 +51,7 @@
   BenchmarkInfo(
     name: "DropLastArray",
     runFunction: run_DropLastArray,
-    tags: [.validation, .api, .Array]),
+    tags: [.validation, .api, .Array, .unstable]),
   BenchmarkInfo(
     name: "DropLastCountableRangeLazy",
     runFunction: run_DropLastCountableRangeLazy,
diff --git a/benchmark/single-source/DropLast.swift.gyb b/benchmark/single-source/DropLast.swift.gyb
index f91dc5f..102599b 100644
--- a/benchmark/single-source/DropLast.swift.gyb
+++ b/benchmark/single-source/DropLast.swift.gyb
@@ -47,7 +47,7 @@
   BenchmarkInfo(
     name: "DropLast${Name}",
     runFunction: run_DropLast${Name},
-    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+    tags: [.validation, .api${', .Array, .unstable' if Name == 'Array' else ''}]),
 % end
 ]
 
diff --git a/benchmark/single-source/DropWhile.swift b/benchmark/single-source/DropWhile.swift
index d3aa4ae..27013ad 100644
--- a/benchmark/single-source/DropWhile.swift
+++ b/benchmark/single-source/DropWhile.swift
@@ -51,7 +51,7 @@
   BenchmarkInfo(
     name: "DropWhileArray",
     runFunction: run_DropWhileArray,
-    tags: [.validation, .api, .Array]),
+    tags: [.validation, .api, .Array, .unstable]),
   BenchmarkInfo(
     name: "DropWhileCountableRangeLazy",
     runFunction: run_DropWhileCountableRangeLazy,
diff --git a/benchmark/single-source/DropWhile.swift.gyb b/benchmark/single-source/DropWhile.swift.gyb
index 295a651..d87b89b 100644
--- a/benchmark/single-source/DropWhile.swift.gyb
+++ b/benchmark/single-source/DropWhile.swift.gyb
@@ -47,7 +47,7 @@
   BenchmarkInfo(
     name: "DropWhile${Name}",
     runFunction: run_DropWhile${Name},
-    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+    tags: [.validation, .api${', .Array, .unstable' if Name == 'Array' else ''}]),
 % end
 ]
 
diff --git a/benchmark/single-source/ObjectiveCBridging.swift b/benchmark/single-source/ObjectiveCBridging.swift
index 281d802..0da767f 100644
--- a/benchmark/single-source/ObjectiveCBridging.swift
+++ b/benchmark/single-source/ObjectiveCBridging.swift
@@ -23,15 +23,15 @@
   BenchmarkInfo(name: "ObjectiveCBridgeFromNSArrayAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSArrayAnyObjectToString, tags: [.validation, .bridging, .String]),
   BenchmarkInfo(name: "ObjectiveCBridgeFromNSArrayAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSArrayAnyObjectToStringForced, tags: [.validation, .bridging, .String]),
   BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObject", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObject, tags: [.validation, .bridging]),
-  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectForced", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectForced, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectForced", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectForced, tags: [.validation, .bridging, .unstable]),
   BenchmarkInfo(name: "ObjectiveCBridgeToNSDictionary", runFunction: run_ObjectiveCBridgeToNSDictionary, tags: [.validation, .bridging]),
-  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectToString, tags: [.validation, .bridging, .String]),
-  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectToString, tags: [.validation, .bridging, .String, .unstable]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced, tags: [.validation, .bridging, .String, .unstable]),
   BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObject", runFunction: run_ObjectiveCBridgeFromNSSetAnyObject, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectForced", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectForced, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeToNSSet", runFunction: run_ObjectiveCBridgeToNSSet, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectToString, tags: [.validation, .bridging, .String]),
-  BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectToStringForced, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectToStringForced, tags: [.validation, .bridging, .String, .unstable]),
 ]
 
 #if _runtime(_ObjC)
diff --git a/benchmark/single-source/ObjectiveCBridgingStubs.swift b/benchmark/single-source/ObjectiveCBridgingStubs.swift
index f5d1c4c..7c0cf3f 100644
--- a/benchmark/single-source/ObjectiveCBridgingStubs.swift
+++ b/benchmark/single-source/ObjectiveCBridgingStubs.swift
@@ -18,7 +18,7 @@
 
 public let ObjectiveCBridgingStubs = [
   BenchmarkInfo(name: "ObjectiveCBridgeStubDataAppend", runFunction: run_ObjectiveCBridgeStubDataAppend, tags: [.validation, .bridging]),
-  BenchmarkInfo(name: "ObjectiveCBridgeStubDateAccess", runFunction: run_ObjectiveCBridgeStubDateAccess, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubDateAccess", runFunction: run_ObjectiveCBridgeStubDateAccess, tags: [.validation, .bridging, .unstable]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubDateMutation", runFunction: run_ObjectiveCBridgeStubDateMutation, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubFromArrayOfNSString", runFunction: run_ObjectiveCBridgeStubFromArrayOfNSString, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSDate", runFunction: run_ObjectiveCBridgeStubFromNSDate, tags: [.validation, .bridging]),
diff --git a/benchmark/single-source/ObjectiveCNoBridgingStubs.swift b/benchmark/single-source/ObjectiveCNoBridgingStubs.swift
index 46b8cd6..dd7c64f 100644
--- a/benchmark/single-source/ObjectiveCNoBridgingStubs.swift
+++ b/benchmark/single-source/ObjectiveCNoBridgingStubs.swift
@@ -24,11 +24,11 @@
 public let ObjectiveCNoBridgingStubs = [
   BenchmarkInfo(name: "ObjectiveCBridgeStubToNSStringRef", runFunction: run_ObjectiveCBridgeStubToNSStringRef, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubToNSDateRef", runFunction: run_ObjectiveCBridgeStubToNSDateRef, tags: [.validation, .bridging]),
-  BenchmarkInfo(name: "ObjectiveCBridgeStubNSDateRefAccess", runFunction: run_ObjectiveCBridgeStubNSDateRefAccess, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubNSDateRefAccess", runFunction: run_ObjectiveCBridgeStubNSDateRefAccess, tags: [.validation, .bridging, .unstable]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubNSDateMutationRef", runFunction: run_ObjectiveCBridgeStubNSDateMutationRef, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubNSDataAppend", runFunction: run_ObjectiveCBridgeStubNSDataAppend, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSStringRef", runFunction: run_ObjectiveCBridgeStubFromNSStringRef, tags: [.validation, .bridging]),
-  BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSDateRef", runFunction: run_ObjectiveCBridgeStubFromNSDateRef, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSDateRef", runFunction: run_ObjectiveCBridgeStubFromNSDateRef, tags: [.validation, .bridging, .unstable]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubURLAppendPathRef", runFunction: run_ObjectiveCBridgeStubURLAppendPathRef, tags: [.validation, .bridging]),
 ]
 
diff --git a/benchmark/single-source/ProtocolDispatch.swift b/benchmark/single-source/ProtocolDispatch.swift
index 515c875..68398b1 100644
--- a/benchmark/single-source/ProtocolDispatch.swift
+++ b/benchmark/single-source/ProtocolDispatch.swift
@@ -15,7 +15,7 @@
 public let ProtocolDispatch = BenchmarkInfo(
   name: "ProtocolDispatch",
   runFunction: run_ProtocolDispatch,
-  tags: [.validation, .abstraction])
+  tags: [.validation, .abstraction, .unstable])
 
 @inline(never)
 public func run_ProtocolDispatch(_ N: Int) {
diff --git a/benchmark/single-source/ProtocolDispatch2.swift b/benchmark/single-source/ProtocolDispatch2.swift
index 8fda9c7..8e5e5f9 100644
--- a/benchmark/single-source/ProtocolDispatch2.swift
+++ b/benchmark/single-source/ProtocolDispatch2.swift
@@ -20,7 +20,7 @@
 public let ProtocolDispatch2 = BenchmarkInfo(
   name: "ProtocolDispatch2",
   runFunction: run_ProtocolDispatch2,
-  tags: [.validation, .abstraction])
+  tags: [.validation, .abstraction, .unstable])
 
 protocol Pingable { func ping() -> Int;  func pong() -> Int}
 
diff --git a/benchmark/single-source/StringComparison.swift b/benchmark/single-source/StringComparison.swift
new file mode 100644
index 0000000..0422bfd
--- /dev/null
+++ b/benchmark/single-source/StringComparison.swift
@@ -0,0 +1,392 @@
+//===--- StringComparison.swift -------------------------------------*- swift -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+////////////////////////////////////////////////////////////////////////////////
+// WARNING: This file is manually generated from .gyb template and should not
+// be directly modified. Instead, make changes to StringComparison.swift.gyb and run
+// scripts/generate_harness/generate_harness.py to regenerate this file.
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Test String iteration performance over a variety of workloads, languages,
+// and symbols.
+//
+
+import TestsUtils
+
+extension String {
+  func lines() -> [String] {
+    return self.split(separator: "\n").map { String($0) }
+  }
+}
+
+
+public let StringComparison = [
+  BenchmarkInfo(
+    name: "StringComparison_ascii",
+    runFunction: run_StringComparison_ascii,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_latin1",
+    runFunction: run_StringComparison_latin1,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_fastPrenormal",
+    runFunction: run_StringComparison_fastPrenormal,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_slowerPrenormal",
+    runFunction: run_StringComparison_slowerPrenormal,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_nonBMPSlowestPrenormal",
+    runFunction: run_StringComparison_nonBMPSlowestPrenormal,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_emoji",
+    runFunction: run_StringComparison_emoji,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_abnormal",
+    runFunction: run_StringComparison_abnormal,
+    tags: [.validation, .api, .String]),    
+  BenchmarkInfo(
+    name: "StringComparison_zalgo",
+    runFunction: run_StringComparison_zalgo,
+    tags: [.validation, .api, .String]),    
+]
+    
+  @inline(never)
+  public func run_StringComparison_ascii(_ N: Int) {
+    var count = 0
+    let workload = Workload.ascii
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_latin1(_ N: Int) {
+    var count = 0
+    let workload = Workload.latin1
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_fastPrenormal(_ N: Int) {
+    var count = 0
+    let workload = Workload.fastPrenormal
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_slowerPrenormal(_ N: Int) {
+    var count = 0
+    let workload = Workload.slowerPrenormal
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_nonBMPSlowestPrenormal(_ N: Int) {
+    var count = 0
+    let workload = Workload.nonBMPSlowestPrenormal
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_emoji(_ N: Int) {
+    var count = 0
+    let workload = Workload.emoji
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_abnormal(_ N: Int) {
+    var count = 0
+    let workload = Workload.abnormal
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+  @inline(never)
+  public func run_StringComparison_zalgo(_ N: Int) {
+    var count = 0
+    let workload = Workload.zalgo
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+
+struct Workload {
+  static let N = 100
+
+  let name: String
+  let payload: [String]
+  var scaleMultiplier: Double
+
+  init(name: String, payload: [String], scaleMultiplier: Double = 1.0) {
+    self.name = name
+    self.payload = payload
+    self.scaleMultiplier = scaleMultiplier
+  }
+
+  var tripCount: Int {
+    return Int(Double(Workload.N) * scaleMultiplier)
+  }
+
+  static let ascii = Workload(
+    name: "ASCII",
+    payload: """
+      woodshed
+      lakism
+      gastroperiodynia
+      afetal
+      Casearia
+      ramsch
+      Nickieben
+      undutifulness
+      decorticate
+      neognathic
+      mentionable
+      tetraphenol
+      pseudonymal
+      dislegitimate
+      Discoidea
+      criminative
+      disintegratory
+      executer
+      Cylindrosporium
+      complimentation
+      Ixiama
+      Araceae
+      silaginoid
+      derencephalus
+      Lamiidae
+      marrowlike
+      ninepin
+      trihemimer
+      semibarbarous
+      heresy
+      existence
+      fretless
+      Amiranha
+      handgravure
+      orthotropic
+      Susumu
+      teleutospore
+      sleazy
+      shapeliness
+      hepatotomy
+      exclusivism
+      stifler
+      cunning
+      isocyanuric
+      pseudepigraphy
+      carpetbagger
+      unglory
+      """.lines(),
+      scaleMultiplier: 0.25
+  )
+
+  static let latin1 = Workload(
+    name: "Latin1",
+    payload: """
+      café
+      résumé
+      caférésumé
+      ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º
+      1+1=3
+      ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹
+      ¡¢£¤¥¦§¨©ª«¬­®
+      »¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍ
+      ÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãä
+      åæçèéêëìíîïðñò
+      ÎÏÐÑÒÓÔÕÖëìíîïðñò
+      óôõö÷øùúûüýþÿ
+      123.456£=>¥
+      123.456
+      """.lines()
+  )
+  static let fastPrenormal = Workload(
+    name: "FastPrenormal",
+    payload: """
+      ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥ
+      ĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸ
+      ĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲ
+      ųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆ
+      ƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀ
+      Ƈ
+      ǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖ
+      ǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑ
+      ȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬ
+      ȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑ
+      ȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰ
+      ɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄ
+      ɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃ
+      ʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰ
+      ʱʲʳʴʵʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊˋˌˍˎˏːˑ˒˓˔˕˖˗˘˙˚˛˜˝˞˟ˠˡˢˣˤ˥˦
+      ˧˨˩˪˫ˬ˭ˮ˯˰˱˲˳˴˵˶˷˸˹˺˻˼˽˾
+      """.lines()
+  )
+  static let slowerPrenormal = Workload(
+    name: "SlowerPrenormal",
+    payload: """
+      Swiftに大幅な改良が施され、
+      安定していてしかも
+      直感的に使うことができる
+      向けプログラミング言語になりました。
+      이번 업데이트에서는 강력하면서도
+      \u{201c}Hello\u{2010}world\u{2026}\u{201d}
+      平台的编程语言
+      功能强大且直观易用
+      而本次更新对其进行了全面优化
+      в чащах юга жил-был цитрус
+      \u{300c}\u{300e}今日は\u{3001}世界\u{3002}\u{300f}\u{300d}
+      но фальшивый экземпляр
+      """.lines()
+  )
+  // static let slowestPrenormal = """
+  //   """.lines()
+  static let nonBMPSlowestPrenormal = Workload(
+    name: "NonBMPSlowestPrenormal",
+    payload: """
+      𓀀𓀤𓁓𓁲𓃔𓃗
+      𓀀𓀁𓀂𓀃𓀄𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀞𓀟𓀠𓀡𓀢𓀣
+      𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭
+      𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸
+      𓁹𓁺𓁓𓁔𓁕𓁻𓁼𓁽𓁾𓁿
+      𓀀𓀁𓀂𓀃𓀄𓃒𓃓𓃔𓃕𓃻𓃼𓃽𓃾𓃿𓄀𓄁𓄂𓄃𓄄𓄅𓄆𓄇𓄈𓄉𓄊𓄋𓄌𓄍𓄎
+      𓂿𓃀𓃁𓃂𓃃𓃄𓃅
+      𓃘𓃙𓃚𓃛𓃠𓃡𓃢𓃣𓃦𓃧𓃨𓃩𓃬𓃭𓃮𓃯𓃰𓃲𓃳𓃴𓃵𓃶𓃷𓃸
+      𓃘𓃙𓃚𓃛𓃠𓃡𓃢𓃣𓃦𓃧𓃨𓃩𓃬𓃭𓃮𓃯𓃰𓃲𓃳𓃴𓃵𓃶𓃷
+      𓀀𓀁𓀂𓀃𓀄𓆇𓆈𓆉𓆊𓆋𓆌𓆍𓆎𓆏𓆐𓆑𓆒𓆓𓆔𓆗𓆘𓆙𓆚𓆛𓆝𓆞𓆟𓆠𓆡𓆢𓆣𓆤
+      𓆥𓆦𓆧𓆨𓆩𓆪𓆫𓆬𓆭𓆮𓆯𓆰𓆱𓆲𓆳𓆴𓆵𓆶𓆷𓆸𓆹𓆺𓆻
+      """.lines()
+  )
+  static let emoji = Workload(
+    name: "Emoji",
+    payload: """
+      👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏻👍🏼👍🏽👍🏾👍🏿
+      👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏿👍🏻👍🏼👍🏽👍🏾
+      😀🧀😀😃😄😁🤣😂😅😆
+      😺🎃🤖👾😸😹😻😼😾😿🙀😽🙌🙏🤝👍✌🏽
+      ☺️😊😇🙂😍😌😉🙃😘😗😙😚😛😝😜
+      😋🤑🤗🤓😎😒😏🤠🤡😞😔😟😕😖😣☹️🙁😫😩😤😠😑😐😶😡😯
+      😦😧😮😱😳😵😲😨😰😢😥
+      😪😓😭🤤😴🙄🤔🤥🤧🤢🤐😬😷🤒🤕😈💩👺👹👿👻💀☠️👽
+      """.lines()
+  )
+
+  static let abnormal = Workload(
+    name: "Abnormal",
+    payload: """
+    ae\u{301}ae\u{301}ae\u{302}ae\u{303}ae\u{304}ae\u{305}ae\u{306}ae\u{307}
+    ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{300}
+    \u{f900}\u{f901}\u{f902}\u{f903}\u{f904}\u{f905}\u{f906}\u{f907}\u{f908}\u{f909}\u{f90a}
+    \u{f90b}\u{f90c}\u{f90d}\u{f90e}\u{f90f}\u{f910}\u{f911}\u{f912}\u{f913}\u{f914}\u{f915}\u{f916}\u{f917}\u{f918}\u{f919}
+    \u{f900}\u{f91a}\u{f91b}\u{f91c}\u{f91d}\u{f91e}\u{f91f}\u{f920}\u{f921}\u{f922}
+    """.lines()
+  )
+  // static let pathological = """
+  //   """.lines()
+  static let zalgo = Workload(
+    name: "Zalgo",
+    payload: """
+    ṭ̴̵̶̷̸̢̧̨̡̛̤̥̦̩̪̫̬̭̮̯̰̖̗̘̙̜̝̞̟̠̱̲̳̹̺̻̼͇͈͉͍͎̀́̂̃̄̅̆̇̈̉ͣͤ̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚͜͟͢͝͞͠͡ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    h̀́̂̃
+    è͇͈͉͍͎́̂̃̄̅̆̇̈̉͊͋͌͏̡̢̧̨̛͓͔͕͖͙͚̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭͇͈͉͍͎͐͑͒͗͛̊̋̌̍̎̏̐̑̒̓̔̀́͂̓̈́͆͊͋͌͘̕̚͜͟͝͞͠ͅ͏͓͔͕͖͐͑͒
+    q̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼͇̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆̕̚ͅ
+    ư̴̵̶̷̸̗̘̙̜̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    ì̡̢̧̨̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̹̺̻̼͇͈͉͍͎́̂̃̄̉̊̋̌̍̎̏̐̑̒̓̽̾̿̀́͂̓̈́͆͊͋͌ͅ͏͓͔͕͖͙͐͑͒͗ͬͭͮ͘
+    c̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼̀́̂̃̄̔̽̾̿̀́͂̓̈́͆ͣͤͥͦͧͨͩͪͫͬͭͮ̕̚͢͡ͅ
+    k̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼͇͈͉͍͎̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    b̴̵̶̷̸̡̢̛̗̘̙̜̝̞̟̠̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    ŗ̴̵̶̷̸̨̛̩̪̫̯̰̱̲̳̹̺̻̼̬̭̮͇̗̘̙̜̝̞̟̤̥̦͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏̡̢͓͔͕͖͙͚̠̣͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    o
+    w̗̘͇͈͉͍͎̓̈́͆͊͋͌ͅ͏̛͓͔͕͖͙͚̙̜̹̺̻̼͐͑͒͗͛ͣͤͥͦ̽̾̿̀́͂ͧͨͩͪͫͬͭͮ͘̚͜͟͢͝͞͠͡
+    n͇͈͉͍͎͊͋͌ͧͨͩͪͫͬͭͮ͏̛͓͔͕͖͙͚̗̘̙̜̹̺̻̼͐͑͒͗͛ͣͤͥͦ̽̾̿̀́͂̓̈́͆ͧͨͩͪͫͬͭͮ͘̚͜͟͢͝͞͠͡ͅ
+    f̛̗̘̙̜̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦ͘͜͟͢͝͞͠͡
+    ơ̗̘̙̜̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͥͦͧͨͩͪͫͬͭͮ͘
+    xͣͤͥͦͧͨͩͪͫͬͭͮ
+    """.lines(),
+    scaleMultiplier: 0.25
+  )
+  
+}
\ No newline at end of file
diff --git a/benchmark/single-source/StringComparison.swift.gyb b/benchmark/single-source/StringComparison.swift.gyb
new file mode 100644
index 0000000..27112f3
--- /dev/null
+++ b/benchmark/single-source/StringComparison.swift.gyb
@@ -0,0 +1,258 @@
+//===--- StringComparison.swift -------------------------------------*- swift -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+% # Ignore the following warning. This _is_ the correct file to edit.
+////////////////////////////////////////////////////////////////////////////////
+// WARNING: This file is manually generated from .gyb template and should not
+// be directly modified. Instead, make changes to StringComparison.swift.gyb and run
+// scripts/generate_harness/generate_harness.py to regenerate this file.
+////////////////////////////////////////////////////////////////////////////////
+
+//
+// Test String iteration performance over a variety of workloads, languages,
+// and symbols.
+//
+
+import TestsUtils
+
+extension String {
+  func lines() -> [String] {
+    return self.split(separator: "\n").map { String($0) }
+  }
+}
+
+% Names = ["ascii", "latin1", "fastPrenormal", "slowerPrenormal", "nonBMPSlowestPrenormal", "emoji", "abnormal", "zalgo"]
+
+public let StringComparison = [
+% for Name in Names:
+  BenchmarkInfo(
+    name: "StringComparison_${Name}",
+    runFunction: run_StringComparison_${Name},
+    tags: [.validation, .api, .String]),    
+% end # Names
+]
+    
+% for Name in Names:
+  @inline(never)
+  public func run_StringComparison_${Name}(_ N: Int) {
+    var count = 0
+    let workload = Workload.${Name}
+    let tripCount = workload.tripCount
+    let payload = workload.payload
+    for _ in 1...tripCount*N {
+      for s1 in payload {
+        for s2 in payload {
+          let cmp = s1 < s2
+          count += cmp ? 1 : 0
+        }
+      }
+    }
+  }
+    
+% end # Names
+
+struct Workload {
+  static let N = 100
+
+  let name: String
+  let payload: [String]
+  var scaleMultiplier: Double
+
+  init(name: String, payload: [String], scaleMultiplier: Double = 1.0) {
+    self.name = name
+    self.payload = payload
+    self.scaleMultiplier = scaleMultiplier
+  }
+
+  var tripCount: Int {
+    return Int(Double(Workload.N) * scaleMultiplier)
+  }
+
+  static let ascii = Workload(
+    name: "ASCII",
+    payload: """
+      woodshed
+      lakism
+      gastroperiodynia
+      afetal
+      Casearia
+      ramsch
+      Nickieben
+      undutifulness
+      decorticate
+      neognathic
+      mentionable
+      tetraphenol
+      pseudonymal
+      dislegitimate
+      Discoidea
+      criminative
+      disintegratory
+      executer
+      Cylindrosporium
+      complimentation
+      Ixiama
+      Araceae
+      silaginoid
+      derencephalus
+      Lamiidae
+      marrowlike
+      ninepin
+      trihemimer
+      semibarbarous
+      heresy
+      existence
+      fretless
+      Amiranha
+      handgravure
+      orthotropic
+      Susumu
+      teleutospore
+      sleazy
+      shapeliness
+      hepatotomy
+      exclusivism
+      stifler
+      cunning
+      isocyanuric
+      pseudepigraphy
+      carpetbagger
+      unglory
+      """.lines(),
+      scaleMultiplier: 0.25
+  )
+
+  static let latin1 = Workload(
+    name: "Latin1",
+    payload: """
+      café
+      résumé
+      caférésumé
+      ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º
+      1+1=3
+      ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹
+      ¡¢£¤¥¦§¨©ª«¬­®
+      »¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍ
+      ÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãä
+      åæçèéêëìíîïðñò
+      ÎÏÐÑÒÓÔÕÖëìíîïðñò
+      óôõö÷øùúûüýþÿ
+      123.456£=>¥
+      123.456
+      """.lines()
+  )
+  static let fastPrenormal = Workload(
+    name: "FastPrenormal",
+    payload: """
+      ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥ
+      ĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸ
+      ĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲ
+      ųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆ
+      ƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀ
+      Ƈ
+      ǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖ
+      ǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑ
+      ȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬ
+      ȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬDzdzǴǵǶǷǸǹǺǻǼǽǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑ
+      ȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰ
+      ɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄ
+      ɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃ
+      ʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰ
+      ʱʲʳʴʵʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊˋˌˍˎˏːˑ˒˓˔˕˖˗˘˙˚˛˜˝˞˟ˠˡˢˣˤ˥˦
+      ˧˨˩˪˫ˬ˭ˮ˯˰˱˲˳˴˵˶˷˸˹˺˻˼˽˾
+      """.lines()
+  )
+  static let slowerPrenormal = Workload(
+    name: "SlowerPrenormal",
+    payload: """
+      Swiftに大幅な改良が施され、
+      安定していてしかも
+      直感的に使うことができる
+      向けプログラミング言語になりました。
+      이번 업데이트에서는 강력하면서도
+      \u{201c}Hello\u{2010}world\u{2026}\u{201d}
+      平台的编程语言
+      功能强大且直观易用
+      而本次更新对其进行了全面优化
+      в чащах юга жил-был цитрус
+      \u{300c}\u{300e}今日は\u{3001}世界\u{3002}\u{300f}\u{300d}
+      но фальшивый экземпляр
+      """.lines()
+  )
+  // static let slowestPrenormal = """
+  //   """.lines()
+  static let nonBMPSlowestPrenormal = Workload(
+    name: "NonBMPSlowestPrenormal",
+    payload: """
+      𓀀𓀤𓁓𓁲𓃔𓃗
+      𓀀𓀁𓀂𓀃𓀄𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀞𓀟𓀠𓀡𓀢𓀣
+      𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭
+      𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸
+      𓁹𓁺𓁓𓁔𓁕𓁻𓁼𓁽𓁾𓁿
+      𓀀𓀁𓀂𓀃𓀄𓃒𓃓𓃔𓃕𓃻𓃼𓃽𓃾𓃿𓄀𓄁𓄂𓄃𓄄𓄅𓄆𓄇𓄈𓄉𓄊𓄋𓄌𓄍𓄎
+      𓂿𓃀𓃁𓃂𓃃𓃄𓃅
+      𓃘𓃙𓃚𓃛𓃠𓃡𓃢𓃣𓃦𓃧𓃨𓃩𓃬𓃭𓃮𓃯𓃰𓃲𓃳𓃴𓃵𓃶𓃷𓃸
+      𓃘𓃙𓃚𓃛𓃠𓃡𓃢𓃣𓃦𓃧𓃨𓃩𓃬𓃭𓃮𓃯𓃰𓃲𓃳𓃴𓃵𓃶𓃷
+      𓀀𓀁𓀂𓀃𓀄𓆇𓆈𓆉𓆊𓆋𓆌𓆍𓆎𓆏𓆐𓆑𓆒𓆓𓆔𓆗𓆘𓆙𓆚𓆛𓆝𓆞𓆟𓆠𓆡𓆢𓆣𓆤
+      𓆥𓆦𓆧𓆨𓆩𓆪𓆫𓆬𓆭𓆮𓆯𓆰𓆱𓆲𓆳𓆴𓆵𓆶𓆷𓆸𓆹𓆺𓆻
+      """.lines()
+  )
+  static let emoji = Workload(
+    name: "Emoji",
+    payload: """
+      👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏻👍🏼👍🏽👍🏾👍🏿
+      👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏿👍🏻👍🏼👍🏽👍🏾
+      😀🧀😀😃😄😁🤣😂😅😆
+      😺🎃🤖👾😸😹😻😼😾😿🙀😽🙌🙏🤝👍✌🏽
+      ☺️😊😇🙂😍😌😉🙃😘😗😙😚😛😝😜
+      😋🤑🤗🤓😎😒😏🤠🤡😞😔😟😕😖😣☹️🙁😫😩😤😠😑😐😶😡😯
+      😦😧😮😱😳😵😲😨😰😢😥
+      😪😓😭🤤😴🙄🤔🤥🤧🤢🤐😬😷🤒🤕😈💩👺👹👿👻💀☠️👽
+      """.lines()
+  )
+
+  static let abnormal = Workload(
+    name: "Abnormal",
+    payload: """
+    ae\u{301}ae\u{301}ae\u{302}ae\u{303}ae\u{304}ae\u{305}ae\u{306}ae\u{307}
+    ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{301}ae\u{300}
+    \u{f900}\u{f901}\u{f902}\u{f903}\u{f904}\u{f905}\u{f906}\u{f907}\u{f908}\u{f909}\u{f90a}
+    \u{f90b}\u{f90c}\u{f90d}\u{f90e}\u{f90f}\u{f910}\u{f911}\u{f912}\u{f913}\u{f914}\u{f915}\u{f916}\u{f917}\u{f918}\u{f919}
+    \u{f900}\u{f91a}\u{f91b}\u{f91c}\u{f91d}\u{f91e}\u{f91f}\u{f920}\u{f921}\u{f922}
+    """.lines()
+  )
+  // static let pathological = """
+  //   """.lines()
+  static let zalgo = Workload(
+    name: "Zalgo",
+    payload: """
+    ṭ̴̵̶̷̸̢̧̨̡̛̤̥̦̩̪̫̬̭̮̯̰̖̗̘̙̜̝̞̟̠̱̲̳̹̺̻̼͇͈͉͍͎̀́̂̃̄̅̆̇̈̉ͣͤ̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚͜͟͢͝͞͠͡ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    h̀́̂̃
+    è͇͈͉͍͎́̂̃̄̅̆̇̈̉͊͋͌͏̡̢̧̨̛͓͔͕͖͙͚̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭͇͈͉͍͎͐͑͒͗͛̊̋̌̍̎̏̐̑̒̓̔̀́͂̓̈́͆͊͋͌͘̕̚͜͟͝͞͠ͅ͏͓͔͕͖͐͑͒
+    q̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼͇̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆̕̚ͅ
+    ư̴̵̶̷̸̗̘̙̜̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    ì̡̢̧̨̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̹̺̻̼͇͈͉͍͎́̂̃̄̉̊̋̌̍̎̏̐̑̒̓̽̾̿̀́͂̓̈́͆͊͋͌ͅ͏͓͔͕͖͙͐͑͒͗ͬͭͮ͘
+    c̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼̀́̂̃̄̔̽̾̿̀́͂̓̈́͆ͣͤͥͦͧͨͩͪͫͬͭͮ̕̚͢͡ͅ
+    k̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̰̱̲̳̹̺̻̼͇͈͉͍͎̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    b̴̵̶̷̸̡̢̛̗̘̙̜̝̞̟̠̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    ŗ̴̵̶̷̸̨̛̩̪̫̯̰̱̲̳̹̺̻̼̬̭̮͇̗̘̙̜̝̞̟̤̥̦͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏̡̢͓͔͕͖͙͚̠̣͐͑͒͗͛ͣͤͥͦͧͨͩͪͫͬͭͮ͘͜͟͢͝͞͠͡
+    o
+    w̗̘͇͈͉͍͎̓̈́͆͊͋͌ͅ͏̛͓͔͕͖͙͚̙̜̹̺̻̼͐͑͒͗͛ͣͤͥͦ̽̾̿̀́͂ͧͨͩͪͫͬͭͮ͘̚͜͟͢͝͞͠͡
+    n͇͈͉͍͎͊͋͌ͧͨͩͪͫͬͭͮ͏̛͓͔͕͖͙͚̗̘̙̜̹̺̻̼͐͑͒͗͛ͣͤͥͦ̽̾̿̀́͂̓̈́͆ͧͨͩͪͫͬͭͮ͘̚͜͟͢͝͞͠͡ͅ
+    f̛̗̘̙̜̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͣͤͥͦ͘͜͟͢͝͞͠͡
+    ơ̗̘̙̜̹̺̻̼͇͈͉͍͎̽̾̿̀́͂̓̈́͆͊͋͌̚ͅ͏͓͔͕͖͙͚͐͑͒͗͛ͥͦͧͨͩͪͫͬͭͮ͘
+    xͣͤͥͦͧͨͩͪͫͬͭͮ
+    """.lines(),
+    scaleMultiplier: 0.25
+  )
+  
+}
\ No newline at end of file
diff --git a/benchmark/utils/DriverUtils.swift b/benchmark/utils/DriverUtils.swift
index 37bbb37..91f234e 100644
--- a/benchmark/utils/DriverUtils.swift
+++ b/benchmark/utils/DriverUtils.swift
@@ -86,11 +86,6 @@
   }
 }
 
-// Legacy test dictionaries.
-public var precommitTests: [BenchmarkInfo] = []
-public var otherTests: [BenchmarkInfo] = []
-public var stringTests: [BenchmarkInfo] = []
-
 // We should migrate to a collection of BenchmarkInfo.
 public var registeredBenchmarks: [BenchmarkInfo] = []
 
@@ -231,22 +226,12 @@
   }
 
   mutating func findTestsToRun() {
-    // Begin by creating a set of our non-legacy registeredBenchmarks
-    var allTests = Set(registeredBenchmarks)
-
-    // Merge legacy benchmark info into allTests. If we already have a
-    // registered benchmark info, formUnion leaves this alone. This allows for
-    // us to perform incremental work.
-    for testList in [precommitTests, otherTests, stringTests] {
-      allTests.formUnion(testList)
-    }
-
     let benchmarkNameFilter = Set(filters)
 
     // t is needed so we don't capture an ivar of a mutable inout self.
     let t = tags
     let st = skipTags
-    let filteredTests = Array(allTests.filter { benchInfo in
+    let filteredTests = Array(registeredBenchmarks.filter { benchInfo in
       if !t.isSubset(of: benchInfo.tags) {
         return false
       }
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index b8524f3..13a6708 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -44,6 +44,7 @@
 import DictionaryGroup
 import DictionaryLiteral
 import DictionaryRemove
+import DictionarySubscriptDefault
 import DictionarySwap
 import DropFirst
 import DropLast
@@ -106,6 +107,7 @@
 import StrComplexWalk
 import StrToInt
 import StringBuilder
+import StringComparison
 import StringEdits
 import StringEnum
 import StringInterpolation
@@ -163,6 +165,7 @@
 registerBenchmark(DictionaryGroup)
 registerBenchmark(DictionaryLiteral)
 registerBenchmark(DictionaryRemove)
+registerBenchmark(DictionarySubscriptDefault)
 registerBenchmark(DictionarySwap)
 registerBenchmark(DropFirst)
 registerBenchmark(DropLast)
@@ -225,6 +228,7 @@
 registerBenchmark(StrComplexWalk)
 registerBenchmark(StrToInt)
 registerBenchmark(StringBuilder)
+registerBenchmark(StringComparison)
 registerBenchmark(StringEdits)
 registerBenchmark(StringEnum)
 registerBenchmark(StringInterpolation)
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index 5c2db0f..a832224 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -81,9 +81,7 @@
   # HACK: this ugly tweaking is to prevent the propagation of the flag from LLVM
   # into swift.  The use of this flag pollutes all targets, and we are not able
   # to remove it on a per-target basis which breaks cross-compilation.
-  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
-    string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
-  endif()
+  string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
 
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
   string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" PACKAGE_VERSION_MAJOR
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 76b376a..9fd1b87 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -189,13 +189,11 @@
   entity-spec ::= 'Te' bridge-spec           // outlined objective c method call
 
   entity-spec ::= decl-name function-signature generic-signature? 'F'    // function
-  entity-spec ::= storage-spec
+  entity-spec ::= type file-discriminator? 'i' ACCESSOR                  // subscript
+  entity-spec ::= decl-name type 'v' ACCESSOR                            // variable
   entity-spec ::= decl-name type 'fp'                // generic type parameter
   entity-spec ::= decl-name type 'fo'                // enum element (currently not used)
 
-  storage-spec ::= type file-discriminator? 'i' ACCESSOR
-  storage-spec ::= decl-name type 'v' ACCESSOR
-
   ACCESSOR ::= 'm'                           // materializeForSet
   ACCESSOR ::= 's'                           // setter
   ACCESSOR ::= 'g'                           // getter
diff --git a/docs/ABI/TypeMetadata.rst b/docs/ABI/TypeMetadata.rst
index e765d8d..c44aa71 100644
--- a/docs/ABI/TypeMetadata.rst
+++ b/docs/ABI/TypeMetadata.rst
@@ -407,3 +407,29 @@
   * **Bit 31** is set by the Objective-C runtime when it has done its
     initialization of the protocol record. It is unused by the Swift runtime.
 
+
+Protocol Conformance Records
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A *protocol conformance record* states that a given type conforms to a
+particular protocol. Protocol conformance records are emitted into their own
+section, which is scanned by the Swift runtime when needed (e.g., in response to
+a `swift_conformsToProtocol()` query). Each protocol conformance record
+contains:
+
+- The `protocol descriptor`_ describing the protocol of the conformance.
+- A reference to the metadata for the **conforming type**, whose form is
+  determined by the **protocol conformance flags** described below.
+- The **witness table field** that provides access to the witness table
+  describing the conformance itself; the form of this field is determined by the
+  **protocol conformance flags** described below.
+- The **protocol conformance flags** is a 32-bit field comprised of:
+  * **Bits 0-3** contain the type metadata record kind, which indicates how
+    the **conforming type** field is encoded.
+  * **Bits 4-5** contain the kind of witness table. The value can be one of:
+    0) The **witness table field** is a reference to a witness table.
+    1) The **witness table field** is a reference to a **witness table
+       accessor** function for an unconditional conformance.
+    2) The **witness table field** is a reference to a **witness table
+       accessor** function for a conditional conformance.
+
diff --git a/docs/StandardLibraryProgrammersManual.md b/docs/StandardLibraryProgrammersManual.md
index 675a998..e9d0dd1 100644
--- a/docs/StandardLibraryProgrammersManual.md
+++ b/docs/StandardLibraryProgrammersManual.md
@@ -137,16 +137,17 @@
 Rather than hard-code Swift mangling into C code, `@_silgen_name` is used to provide a stable and known symbol name for linking. Note that C code still must understand and use the Swift calling convention (available in swift-clang) for such Swift functions (if they use Swift's CC). Example:
 
 ```swift
-@_silgen_name("_swift_stdlib_destroyTLS")
+@_silgen_name("_destroyTLS")
 internal func _destroyTLS(_ ptr: UnsafeMutableRawPointer?) {
   // ... implementation ...
 }
 ```
 
 ```C++
-__attribute__((__swiftcall__)) extern "C" void _swift_stdlib_destroyTLS(void *);
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+void _destroyTLS(void *);
 
-// ... C code can now call _swift_stdlib_destroyTLS on a void * ...
+// ... C code can now call _destroyTLS on a void * ...
 ```
 
 ##### Using `@_silgen_name` to call C from Swift
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index 69027e2..fdd3a02 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -212,6 +212,10 @@
   /// A function pointer that can be called to access the protocol witness
   /// table.
   WitnessTableAccessor,
+  /// A function pointer that can be called to access the protocol witness
+  /// table whose conformance is conditional on additional requirements that
+  /// must first be evaluated and then provided to the accessor function.
+  ConditionalWitnessTableAccessor,
 };
 
 // Type metadata record discriminant
@@ -245,7 +249,7 @@
 struct ProtocolConformanceFlags : public TypeMetadataRecordFlags {
 private:
   enum : int_type {
-    ConformanceKindMask = 0x00000010U,
+    ConformanceKindMask = 0x00000030U,
     ConformanceKindShift = 4,
   };
 
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index ede6e16..3740f2f 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -610,10 +610,15 @@
   mutable llvm::PointerIntPair<Decl *, 2, IterableDeclContextKind> 
     LastDeclAndKind;
 
-  // The DeclID this IDC was deserialized from, if any. Used for named lazy
-  // member loading, as a key when doing lookup in this IDC.
+  /// The DeclID this IDC was deserialized from, if any. Used for named lazy
+  /// member loading, as a key when doing lookup in this IDC.
   serialization::DeclID SerialID;
 
+  /// Lazy member loading has a variety of feedback loops that need to
+  /// switch to pseudo-empty-member behaviour to avoid infinite recursion;
+  /// we use this flag to control them.
+  bool lazyMemberLoadingInProgress = false;
+
   template<class A, class B, class C>
   friend struct ::llvm::cast_convert_val;
 
@@ -634,6 +639,11 @@
   /// Retrieve the set of members in this context.
   DeclRange getMembers() const;
 
+  /// Retrieve the set of members in this context without loading any from the
+  /// associated lazy loader; this should only be used as part of implementing
+  /// abstractions on top of member loading, such as a name lookup table.
+  DeclRange getCurrentMembersWithoutLoading() const;
+
   /// Add a member to this context. If the hint decl is specified, the new decl
   /// is inserted immediately after the hint.
   void addMember(Decl *member, Decl *hint = nullptr);
@@ -643,6 +653,14 @@
     return FirstDeclAndLazyMembers.getInt();
   }
 
+  bool isLoadingLazyMembers() {
+    return lazyMemberLoadingInProgress;
+  }
+
+  void setLoadingLazyMembers(bool inProgress) {
+    lazyMemberLoadingInProgress = inProgress;
+  }
+
   /// Setup the loader for lazily-loaded members.
   void setMemberLoader(LazyMemberLoader *loader, uint64_t contextData);
 
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index d41ccf7..35d411f 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3117,11 +3117,11 @@
 WARNING(implicitly_unwrapped_optional_spelling_deprecated_with_fixit,none,
         "the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name", ())
 
-WARNING(implicitly_unwrapped_optional_spelling_decay_to_optional,none,
-        "'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead", ())
+WARNING(implicitly_unwrapped_optional_spelling_suggest_optional,none,
+        "using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead", ())
 
-WARNING(implicitly_unwrapped_optional_in_illegal_position_decay_to_optional,none,
-        "'!' is not allowed here; interpreting this as '?' instead", ())
+WARNING(implicitly_unwrapped_optional_in_illegal_position_suggest_optional,none,
+        "using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead", ())
 
 ERROR(implicitly_unwrapped_optional_spelling_error,none,
         "the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use an explicit type followed by '!'", ())
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index ed2eb31..55a8d79 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -159,7 +159,7 @@
     bool IterativeTypeChecker = false;
 
     /// \brief Enable named lazy member loading.
-    bool NamedLazyMemberLoading = false;
+    bool NamedLazyMemberLoading = true;
 
     /// Debug the generic signatures computed by the generic signature builder.
     bool DebugGenericSignatures = false;
diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h
index cec53cd..44e2a1d 100644
--- a/include/swift/Frontend/Frontend.h
+++ b/include/swift/Frontend/Frontend.h
@@ -306,7 +306,7 @@
   /// sil-opt, sil-func-extractor, sil-llvm-gen, and sil-nm.
   /// Return value includes the buffer so caller can keep it alive.
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-  setUpInputForSILTool(StringRef InputFilename, StringRef ModuleNameArg,
+  setUpInputForSILTool(StringRef inputFilename, StringRef moduleNameArg,
                        bool alwaysSetModuleToMain,
                        serialization::ExtendedValidationInfo &extendedInfo);
   bool hasSerializedAST() {
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index 626e170..7681da8 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -21,10 +21,6 @@
 
 namespace llvm {
   class MemoryBuffer;
-  namespace opt {
-  class ArgList;
-  class Arg;
-  } // namespace opt
 }
 
 namespace swift {
@@ -88,17 +84,17 @@
 
   // Input filename readers
   ArrayRef<std::string> getInputFilenames() const { return InputFilenames; }
-  bool haveInputFilenames() const { return !getInputFilenames().empty(); }
+  bool hasInputFilenames() const { return !getInputFilenames().empty(); }
   unsigned inputFilenameCount() const { return getInputFilenames().size(); }
 
-  bool haveUniqueInputFilename() const { return inputFilenameCount() == 1; }
+  bool hasUniqueInputFilename() const { return inputFilenameCount() == 1; }
   const std::string &getFilenameOfFirstInput() const {
-    assert(haveInputFilenames());
+    assert(hasInputFilenames());
     return getInputFilenames()[0];
   }
 
   bool isReadingFromStdin() const {
-    return haveUniqueInputFilename() && getFilenameOfFirstInput() == "-";
+    return hasUniqueInputFilename() && getFilenameOfFirstInput() == "-";
   }
 
   // If we have exactly one input filename, and its extension is "bc" or "ll",
@@ -127,32 +123,32 @@
 
   // Primary count readers:
 
-  bool haveUniquePrimaryInput() const { return primaryInputCount() == 1; }
+  bool hasUniquePrimaryInput() const { return primaryInputCount() == 1; }
 
-  bool havePrimaryInputs() const { return primaryInputCount() > 0; }
+  bool hasPrimaryInputs() const { return primaryInputCount() > 0; }
 
-  bool isWholeModule() const { return !havePrimaryInputs(); }
+  bool isWholeModule() const { return !hasPrimaryInputs(); }
 
   // Count-dependend readers:
 
   Optional<SelectedInput> getOptionalPrimaryInput() const {
-    return havePrimaryInputs() ? Optional<SelectedInput>(getPrimaryInputs()[0])
-                               : Optional<SelectedInput>();
+    return hasPrimaryInputs() ? Optional<SelectedInput>(getPrimaryInputs()[0])
+                              : Optional<SelectedInput>();
   }
 
   SelectedInput getRequiredUniquePrimaryInput() const {
-    assert(haveUniquePrimaryInput());
+    assert(hasUniquePrimaryInput());
     return getPrimaryInputs()[0];
   }
 
   Optional<SelectedInput> getOptionalUniquePrimaryInput() const {
-    return haveUniquePrimaryInput()
+    return hasUniquePrimaryInput()
                ? Optional<SelectedInput>(getPrimaryInputs()[0])
                : Optional<SelectedInput>();
   }
 
-  bool haveAPrimaryInputFile() const {
-    return havePrimaryInputs() && getOptionalPrimaryInput()->isFilename();
+  bool hasAPrimaryInputFile() const {
+    return hasPrimaryInputs() && getOptionalPrimaryInput()->isFilename();
   }
 
   Optional<StringRef> getOptionalUniquePrimaryInputFilename() const {
@@ -162,7 +158,7 @@
                : Optional<StringRef>();
   }
 
-  bool isPrimaryInputAFileAt(unsigned i) const {
+  bool isInputPrimary(unsigned i) const {
     assertMustNotBeMoreThanOnePrimaryInput();
     if (Optional<SelectedInput> primaryInput = getOptionalPrimaryInput())
       return primaryInput->isFilename() && primaryInput->Index == i;
@@ -170,7 +166,7 @@
   }
 
   Optional<unsigned> primaryInputFileIndex() const {
-    return haveAPrimaryInputFile()
+    return hasAPrimaryInputFile()
                ? Optional<unsigned>(getOptionalPrimaryInput()->Index)
                : None;
   }
@@ -184,13 +180,10 @@
 
 public:
   // Multi-facet readers
-  StringRef baseNameOfOutput(const llvm::opt::ArgList &Args,
-                             StringRef ModuleName) const;
-
   bool shouldTreatAsSIL() const;
 
   /// Return true for error
-  bool verifyInputs(DiagnosticEngine &Diags, bool TreatAsSIL,
+  bool verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
                     bool isREPLRequested, bool isNoneRequested) const;
 
   // Input filename writers
@@ -250,6 +243,8 @@
 
 /// Options for controlling the behavior of the frontend.
 class FrontendOptions {
+  friend class FrontendArgsToOptionsConverter;
+
 public:
   FrontendInputs Inputs;
 
@@ -279,12 +274,9 @@
     return getSingleOutputFilename() == "-";
   }
   bool isOutputFileDirectory() const;
-  bool isOutputFilePlainFile() const;
-  bool haveNamedOutputFile() const {
+  bool hasNamedOutputFile() const {
     return !OutputFilenames.empty() && !isOutputFilenameStdout();
   }
-  void setOutputFileList(DiagnosticEngine &Diags,
-                         const llvm::opt::ArgList &Args);
 
   /// A list of arbitrary modules to import and make implicitly visible.
   std::vector<std::string> ImplicitImportModuleNames;
@@ -522,11 +514,8 @@
   /// -dump-scope-maps.
   SmallVector<std::pair<unsigned, unsigned>, 2> DumpScopeMapLocations;
 
-  /// Indicates whether the RequestedAction has output.
-  bool actionHasOutput() const;
-
-  /// Indicates whether the RequestedAction will immediately run code.
-  bool actionIsImmediate() const;
+  /// Indicates whether the action will immediately run code.
+  static bool isActionImmediate(ActionType);
 
   /// Return a hash code of any components from these options that should
   /// contribute to a Swift Bridging PCH hash.
@@ -540,10 +529,26 @@
 
   bool isCompilingExactlyOneSwiftFile() const {
     return InputKind == InputFileKind::IFK_Swift &&
-           Inputs.haveUniqueInputFilename();
+           Inputs.hasUniqueInputFilename();
   }
 
-  void setModuleName(DiagnosticEngine &Diags, const llvm::opt::ArgList &Args);
+private:
+  static const char *suffixForPrincipalOutputFileForAction(ActionType);
+
+  bool hasUnusedDependenciesFilePath() const;
+  static bool canActionEmitDependencies(ActionType);
+  bool hasUnusedObjCHeaderOutputPath() const;
+  static bool canActionEmitHeader(ActionType);
+  bool hasUnusedLoadedModuleTracePath() const;
+  static bool canActionEmitLoadedModuleTrace(ActionType);
+  bool hasUnusedModuleOutputPath() const;
+  static bool canActionEmitModule(ActionType);
+  bool hasUnusedModuleDocOutputPath() const;
+  static bool canActionEmitModuleDoc(ActionType);
+
+  static bool doesActionProduceOutput(ActionType);
+  static bool doesActionProduceTextualOutput(ActionType);
+  static bool needsProperModuleName(ActionType);
 };
 
 }
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 4b59e5e..4aa8317 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -155,8 +155,8 @@
 def iterative_type_checker : Flag<["-"], "iterative-type-checker">,
   HelpText<"Enable the iterative type checker">;
 
-def enable_named_lazy_member_loading : Flag<["-"], "enable-named-lazy-member-loading">,
-  HelpText<"Enable per-name lazy member loading">;
+def disable_named_lazy_member_loading : Flag<["-"], "disable-named-lazy-member-loading">,
+  HelpText<"Disable per-name lazy member loading">;
 
 def debug_generic_signatures : Flag<["-"], "debug-generic-signatures">,
   HelpText<"Debug generic signatures">;
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index 1800744..1268d46 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -140,18 +140,12 @@
 
     State advance(unsigned Offset) const {
       assert(isValid());
-      return State(Loc.getAdvancedLoc(Offset), LeadingTrivia, TrailingTrivia);
+      return State(Loc.getAdvancedLoc(Offset));
     }
 
   private:
-    explicit State(SourceLoc Loc,
-                   syntax::TriviaList LeadingTrivia,
-                   syntax::TriviaList TrailingTrivia)
-      : Loc(Loc), LeadingTrivia(LeadingTrivia),
-        TrailingTrivia(TrailingTrivia) {}
+    explicit State(SourceLoc Loc) : Loc(Loc) {}
     SourceLoc Loc;
-    syntax::TriviaList LeadingTrivia;
-    syntax::TriviaList TrailingTrivia;
     friend class Lexer;
   };
 
@@ -210,10 +204,8 @@
     assert(Offset <= EndOffset && "invalid range");
     initSubLexer(
         *this,
-        State(getLocForStartOfBuffer().getAdvancedLoc(Offset),
-              LeadingTrivia, TrailingTrivia),
-        State(getLocForStartOfBuffer().getAdvancedLoc(EndOffset),
-              LeadingTrivia, TrailingTrivia));
+        State(getLocForStartOfBuffer().getAdvancedLoc(Offset)),
+        State(getLocForStartOfBuffer().getAdvancedLoc(EndOffset)));
   }
 
   /// \brief Create a sub-lexer that lexes from the same buffer, but scans
@@ -271,7 +263,13 @@
   /// \brief Returns the lexer state for the beginning of the given token.
   /// After restoring the state, lexer will return this token and continue from
   /// there.
-  State getStateForBeginningOfToken(const Token &Tok) const {
+  State getStateForBeginningOfToken(const Token &Tok,
+                                    const syntax::Trivia &LeadingTrivia = {}) const {
+    // If trivia parsing mode, start position of trivia is the position we want
+    // to restore.
+    if (TriviaRetention == TriviaRetentionMode::WithTrivia)
+      return State(Tok.getLoc().getAdvancedLoc(-LeadingTrivia.getTextLength()));
+
     // If the token has a comment attached to it, rewind to before the comment,
     // not just the start of the token.  This ensures that we will re-lex and
     // reattach the comment to the token if rewound to this state.
@@ -282,8 +280,7 @@
   }
 
   State getStateForEndOfTokenLoc(SourceLoc Loc) const {
-    return State(getLocForEndOfToken(SourceMgr, Loc), LeadingTrivia,
-                 TrailingTrivia);
+    return State(getLocForEndOfToken(SourceMgr, Loc));
   }
 
   /// \brief Restore the lexer state to a given one, that can be located either
@@ -291,8 +288,8 @@
   void restoreState(State S, bool enableDiagnostics = false) {
     assert(S.isValid());
     CurPtr = getBufferPtrForSourceLoc(S.Loc);
-    LeadingTrivia = S.LeadingTrivia;
-    TrailingTrivia = S.TrailingTrivia;
+    LeadingTrivia.clear();
+    TrailingTrivia.clear();
     // Don't reemit diagnostics while readvancing the lexer.
     llvm::SaveAndRestore<DiagnosticEngine*>
       D(Diags, enableDiagnostics ? Diags : nullptr);
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index c627bbd..7a8d51a 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -377,7 +377,7 @@
   };
 
   ParserPosition getParserPosition() {
-    return ParserPosition(L->getStateForBeginningOfToken(Tok),
+    return ParserPosition(L->getStateForBeginningOfToken(Tok, LeadingTrivia),
                           PreviousLoc);
   }
 
@@ -386,9 +386,6 @@
                           Pos.PrevLoc);
   }
 
-  /// \brief Return parser position after the first character of token T
-  ParserPosition getParserPositionAfterFirstCharacter(Token T);
-
   void restoreParserPosition(ParserPosition PP, bool enableDiagnostics = false) {
     L->restoreState(PP.LS, enableDiagnostics);
 
@@ -594,7 +591,8 @@
   /// \brief Consume the starting character of the current token, and split the
   /// remainder of the token into a new token (or tokens).
   SourceLoc
-  consumeStartingCharacterOfCurrentToken(tok Kind = tok::oper_binary_unspaced);
+  consumeStartingCharacterOfCurrentToken(tok Kind = tok::oper_binary_unspaced,
+                                         size_t Len = 1);
 
   swift::ScopeInfo &getScopeInfo() { return State->getScopeInfo(); }
 
diff --git a/include/swift/Runtime/HeapObject.h b/include/swift/Runtime/HeapObject.h
index d3498ff..501b845 100644
--- a/include/swift/Runtime/HeapObject.h
+++ b/include/swift/Runtime/HeapObject.h
@@ -1243,7 +1243,9 @@
 #endif /* SWIFT_OBJC_INTEROP */
 
 /// Return the name of a Swift type represented by a metadata object.
-SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
+/// func _getTypeName(_ type: Any.Type, qualified: Bool)
+///   -> (UnsafePointer<UInt8>, Int)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
 TwoWordPair<const char *, uintptr_t>::Return
 swift_getTypeName(const Metadata *type, bool qualified);  
 
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index eb786f2..22b647b 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -2454,8 +2454,7 @@
     RelativeDirectPointer<const WitnessTable> WitnessTable;
     
     /// A function that produces the witness table given an instance of the
-    /// type. The function may return null if a specific instance does not
-    /// conform to the protocol.
+    /// type.
     RelativeDirectPointer<WitnessTableAccessorFn> WitnessTableAccessor;
   };
   
@@ -2560,6 +2559,7 @@
       break;
         
     case ProtocolConformanceReferenceKind::WitnessTableAccessor:
+    case ProtocolConformanceReferenceKind::ConditionalWitnessTableAccessor:
       assert(false && "not witness table");
     }
     return WitnessTable;
@@ -2568,6 +2568,7 @@
   WitnessTableAccessorFn *getWitnessTableAccessor() const {
     switch (Flags.getConformanceKind()) {
     case ProtocolConformanceReferenceKind::WitnessTableAccessor:
+    case ProtocolConformanceReferenceKind::ConditionalWitnessTableAccessor:
       break;
         
     case ProtocolConformanceReferenceKind::WitnessTable:
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index fb2766f..f50dc95 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -540,7 +540,7 @@
   LoadInst *createTrivialLoadOr(SILLocation Loc, SILValue LV,
                                 LoadOwnershipQualifier Qualifier,
                                 bool SupportUnqualifiedSIL = false) {
-    if (SupportUnqualifiedSIL && getFunction().hasUnqualifiedOwnership()) {
+    if (SupportUnqualifiedSIL && !getFunction().hasQualifiedOwnership()) {
       assert(
           Qualifier != LoadOwnershipQualifier::Copy &&
           "In unqualified SIL, a copy must be done separately form the load");
@@ -556,7 +556,7 @@
   LoadInst *createLoad(SILLocation Loc, SILValue LV,
                        LoadOwnershipQualifier Qualifier) {
     assert((Qualifier != LoadOwnershipQualifier::Unqualified) ||
-           getFunction().hasUnqualifiedOwnership() &&
+           !getFunction().hasQualifiedOwnership() &&
                "Unqualified inst in qualified function");
     assert((Qualifier == LoadOwnershipQualifier::Unqualified) ||
            getFunction().hasQualifiedOwnership() &&
@@ -610,7 +610,7 @@
                                   SILValue DestAddr,
                                   StoreOwnershipQualifier Qualifier,
                                   bool SupportUnqualifiedSIL = false) {
-    if (SupportUnqualifiedSIL && getFunction().hasUnqualifiedOwnership()) {
+    if (SupportUnqualifiedSIL && !getFunction().hasQualifiedOwnership()) {
       assert(
           Qualifier != StoreOwnershipQualifier::Assign &&
           "In unqualified SIL, assigns must be represented via 2 instructions");
@@ -626,7 +626,7 @@
   StoreInst *createStore(SILLocation Loc, SILValue Src, SILValue DestAddr,
                          StoreOwnershipQualifier Qualifier) {
     assert((Qualifier != StoreOwnershipQualifier::Unqualified) ||
-           getFunction().hasUnqualifiedOwnership() &&
+           !getFunction().hasQualifiedOwnership() &&
                "Unqualified inst in qualified function");
     assert((Qualifier == StoreOwnershipQualifier::Unqualified) ||
            getFunction().hasQualifiedOwnership() &&
@@ -959,21 +959,21 @@
 
   RetainValueInst *createRetainValue(SILLocation Loc, SILValue operand,
                                      Atomicity atomicity) {
-    assert(isParsing || getFunction().hasUnqualifiedOwnership());
+    assert(isParsing || !getFunction().hasQualifiedOwnership());
     return insert(new (getModule()) RetainValueInst(getSILDebugLocation(Loc),
                                                       operand, atomicity));
   }
 
   RetainValueAddrInst *createRetainValueAddr(SILLocation Loc, SILValue operand,
                                              Atomicity atomicity) {
-    assert(isParsing || getFunction().hasUnqualifiedOwnership());
+    assert(isParsing || !getFunction().hasQualifiedOwnership());
     return insert(new (getModule()) RetainValueAddrInst(
         getSILDebugLocation(Loc), operand, atomicity));
   }
 
   ReleaseValueInst *createReleaseValue(SILLocation Loc, SILValue operand,
                                        Atomicity atomicity) {
-    assert(isParsing || getFunction().hasUnqualifiedOwnership());
+    assert(isParsing || !getFunction().hasQualifiedOwnership());
     return insert(new (getModule()) ReleaseValueInst(getSILDebugLocation(Loc),
                                                        operand, atomicity));
   }
@@ -981,7 +981,7 @@
   ReleaseValueAddrInst *createReleaseValueAddr(SILLocation Loc,
                                                SILValue operand,
                                                Atomicity atomicity) {
-    assert(isParsing || getFunction().hasUnqualifiedOwnership());
+    assert(isParsing || !getFunction().hasQualifiedOwnership());
     return insert(new (getModule()) ReleaseValueAddrInst(
         getSILDebugLocation(Loc), operand, atomicity));
   }
@@ -1449,13 +1449,13 @@
   }
   StrongRetainInst *createStrongRetain(SILLocation Loc, SILValue Operand,
                                        Atomicity atomicity) {
-    assert(isParsing || getFunction().hasUnqualifiedOwnership());
+    assert(isParsing || !getFunction().hasQualifiedOwnership());
     return insert(new (getModule()) StrongRetainInst(getSILDebugLocation(Loc),
                                                        Operand, atomicity));
   }
   StrongReleaseInst *createStrongRelease(SILLocation Loc, SILValue Operand,
                                          Atomicity atomicity) {
-    assert(isParsing || getFunction().hasUnqualifiedOwnership());
+    assert(isParsing || !getFunction().hasQualifiedOwnership());
     return insert(new (getModule()) StrongReleaseInst(
         getSILDebugLocation(Loc), Operand, atomicity));
   }
@@ -1919,7 +1919,7 @@
     assert(!Value->getType().isAddress());
     // If ownership is not enabled in the function, just return our original
     // value.
-    if (getFunction().hasUnqualifiedOwnership())
+    if (!getFunction().hasQualifiedOwnership())
       return Value;
 
     // If we have a trivial value, just return the value. Trivial values have
@@ -1943,7 +1943,7 @@
                               SILValue Original) {
     assert(!Borrowed->getType().isAddress());
     // If ownership is not enabled, just return.
-    if (getFunction().hasUnqualifiedOwnership())
+    if (!getFunction().hasQualifiedOwnership())
       return;
 
     // If we have a trivial value, just return. Trivial values have lifetimes
diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h
index 8058d1b..3bd4ba5 100644
--- a/include/swift/SIL/SILFunction.h
+++ b/include/swift/SIL/SILFunction.h
@@ -318,10 +318,6 @@
   /// Returns true if this function has qualified ownership instructions in it.
   bool hasQualifiedOwnership() const { return HasQualifiedOwnership; }
 
-  /// Returns true if this function has unqualified ownership instructions in
-  /// it.
-  bool hasUnqualifiedOwnership() const { return !HasQualifiedOwnership; }
-
   /// Sets the HasQualifiedOwnership flag to false. This signals to SIL that no
   /// ownership instructions should be in this function any more.
   void setUnqualifiedOwnership() {
diff --git a/include/swift/Syntax/SyntaxParsingContext.h b/include/swift/Syntax/SyntaxParsingContext.h
index c1256d7..7373d00 100644
--- a/include/swift/Syntax/SyntaxParsingContext.h
+++ b/include/swift/Syntax/SyntaxParsingContext.h
@@ -33,6 +33,7 @@
   Expr,
   Type,
   Pattern,
+  Syntax,
 };
 
 /// Indicates what action should be performed on the destruction of
diff --git a/include/swift/Syntax/Trivia.h b/include/swift/Syntax/Trivia.h
index 6e072c5..83ac416 100644
--- a/include/swift/Syntax/Trivia.h
+++ b/include/swift/Syntax/Trivia.h
@@ -184,6 +184,23 @@
     return TriviaPiece {TriviaKind::Backtick, 1, OwnedString{}};
   }
 
+  size_t getTextLength() const {
+    switch (Kind) {
+      case TriviaKind::LineComment:
+      case TriviaKind::BlockComment:
+      case TriviaKind::DocBlockComment:
+      case TriviaKind::DocLineComment:
+        return Text.size();
+      case TriviaKind::Newline:
+      case TriviaKind::Space:
+      case TriviaKind::Backtick:
+      case TriviaKind::Tab:
+      case TriviaKind::VerticalTab:
+      case TriviaKind::Formfeed:
+        return Count;
+    }
+  }
+
   void accumulateAbsolutePosition(AbsolutePosition &Pos) const;
 
   /// Print a debug representation of this trivia piece to the provided output
@@ -270,6 +287,13 @@
     return Pieces.size();
   }
 
+  size_t getTextLength() const {
+    size_t Len = 0;
+    for (auto &P : Pieces)
+      Len += P.getTextLength();
+    return Len;
+  }
+
   /// Dump a debug representation of this Trivia collection to standard error.
   void dump() const;
 
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 5c9f0d5..75f2e93 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -3058,7 +3058,8 @@
 
     void visitArchetypeType(ArchetypeType *T, StringRef label) {
       printCommon(label, "archetype_type");
-      if (T->getOpenedExistentialType())
+      auto openedExistential = T->getOpenedExistentialType();
+      if (openedExistential)
         printField("opened_existential_id", T->getOpenedExistentialID());
       else
         printField("name", T->getFullName());
@@ -3068,9 +3069,10 @@
         printField("conforms_to", proto->printRef());
       if (auto parent = T->getParent())
         printField("parent", static_cast<void *>(parent));
-      if (auto assocType = T->getAssocType())
-        printField("assoc_type", assocType->printRef());
-
+      if (!openedExistential) {
+        if (auto assocType = T->getAssocType())
+          printField("assoc_type", assocType->printRef());
+      }
       // FIXME: This is ugly.
       OS << "\n";
       if (auto genericEnv = T->getGenericEnvironment()) {
@@ -3081,7 +3083,7 @@
 
       if (auto superclass = T->getSuperclass())
         printRec("superclass", superclass);
-      if (auto openedExistential = T->getOpenedExistentialType())
+      if (openedExistential)
         printRec("opened_existential", openedExistential);
 
       Indent += 2;
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 86c2404..6865794 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -612,48 +612,23 @@
     // FIXME: Pattern initializers at top-level scope end up here.
     return true;
 
-  case DeclContextKind::AbstractFunctionDecl: {
+  case DeclContextKind::AbstractFunctionDecl:
     if (functionsAreNonCascading)
       return false;
-    auto *AFD = cast<AbstractFunctionDecl>(this);
-    if (AFD->hasAccess())
-      return AFD->getFormalAccess() > AccessLevel::FilePrivate;
     break;
-  }
 
-  case DeclContextKind::SubscriptDecl: {
-    auto *SD = cast<SubscriptDecl>(this);
-    if (SD->hasAccess())
-      return SD->getFormalAccess() > AccessLevel::FilePrivate;
+  case DeclContextKind::SubscriptDecl:
     break;
-  }
-      
+
   case DeclContextKind::Module:
   case DeclContextKind::FileUnit:
     return true;
 
-  case DeclContextKind::GenericTypeDecl: {
-    auto *nominal = cast<GenericTypeDecl>(this);
-    if (nominal->hasAccess())
-      return nominal->getFormalAccess() > AccessLevel::FilePrivate;
+  case DeclContextKind::GenericTypeDecl:
     break;
-  }
 
-  case DeclContextKind::ExtensionDecl: {
-    auto *extension = cast<ExtensionDecl>(this);
-    if (extension->hasDefaultAccessLevel())
-      return extension->getDefaultAccessLevel() > AccessLevel::FilePrivate;
-    // FIXME: duplicated from computeDefaultAccessLevel in TypeCheckDecl.cpp.
-    if (auto *AA = extension->getAttrs().getAttribute<AccessControlAttr>())
-      return AA->getAccess() > AccessLevel::FilePrivate;
-    if (Type extendedTy = extension->getExtendedType()) {
-
-      // Need to check if extendedTy is ErrorType
-      if (extendedTy->getAnyNominal())
-        return extendedTy->getAnyNominal()->isCascadingContextForLookup(true);
-    }
-    break;
-  }
+  case DeclContextKind::ExtensionDecl:
+    return true;
   }
 
   return getParent()->isCascadingContextForLookup(true);
@@ -897,10 +872,14 @@
   return getDecl()->getASTContext();
 }
 
+DeclRange IterableDeclContext::getCurrentMembersWithoutLoading() const {
+  return DeclRange(FirstDeclAndLazyMembers.getPointer(), nullptr);
+}
+
 DeclRange IterableDeclContext::getMembers() const {
   loadAllMembers();
 
-  return DeclRange(FirstDeclAndLazyMembers.getPointer(), nullptr);
+  return getCurrentMembersWithoutLoading();
 }
 
 /// Add a member to this context.
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index f374f09..9e8fba4 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -1024,15 +1024,6 @@
     return Lookup.find(name);
   }
 
-  /// \brief Add an empty entry to the lookup map for a given name if it does
-  /// not yet have one.
-  void addEmptyEntry(DeclName name) {
-    (void)Lookup[name];
-    if (!name.isSimpleName()) {
-      (void)Lookup[name.getBaseName()];
-    }
-  }
-
   // \brief Mark all Decls in this table as not-resident in a table, drop
   // references to them. Should only be called when this was not fully-populated
   // from an IterableDeclContext.
@@ -1247,6 +1238,69 @@
 // In all lookup routines, the 'ignoreNewExtensions' flag means that
 // lookup should only use the set of extensions already observed.
 
+static bool
+populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
+                                          MemberLookupTable &LookupTable,
+                                          DeclName name,
+                                          IterableDeclContext *IDC) {
+  if (IDC->isLoadingLazyMembers()) {
+    return false;
+  }
+  IDC->setLoadingLazyMembers(true);
+  auto ci = ctx.getOrCreateLazyIterableContextData(IDC,
+                                                   /*lazyLoader=*/nullptr);
+  if (auto res = ci->loader->loadNamedMembers(IDC, name, ci->memberData)) {
+    IDC->setLoadingLazyMembers(false);
+    if (auto s = ctx.Stats) {
+      ++s->getFrontendCounters().NamedLazyMemberLoadSuccessCount;
+    }
+    for (auto d : *res) {
+      LookupTable.addMember(d);
+    }
+    return false;
+  } else {
+    IDC->setLoadingLazyMembers(false);
+    if (auto s = ctx.Stats) {
+      ++s->getFrontendCounters().NamedLazyMemberLoadFailureCount;
+    }
+    return true;
+  }
+}
+
+static void populateLookupTableEntryFromCurrentMembersWithoutLoading(
+    ASTContext &ctx, MemberLookupTable &LookupTable, DeclName name,
+    IterableDeclContext *IDC) {
+  for (auto m : IDC->getCurrentMembersWithoutLoading()) {
+    if (auto v = dyn_cast<ValueDecl>(m)) {
+      if (v->getFullName().matchesRef(name)) {
+        LookupTable.addMember(m);
+      }
+    }
+  }
+}
+
+static bool
+populateLookupTableEntryFromExtensions(ASTContext &ctx,
+                                       MemberLookupTable &table,
+                                       NominalTypeDecl *nominal,
+                                       DeclName name,
+                                       bool ignoreNewExtensions) {
+  if (!ignoreNewExtensions) {
+    for (auto e : nominal->getExtensions()) {
+      if (e->wasDeserialized() || e->hasClangNode()) {
+        if (populateLookupTableEntryFromLazyIDCLoader(ctx, table,
+                                                      name, e)) {
+          return true;
+        }
+      } else {
+        populateLookupTableEntryFromCurrentMembersWithoutLoading(ctx, table,
+                                                                 name, e);
+      }
+    }
+  }
+  return false;
+}
+
 void NominalTypeDecl::prepareLookupTable(bool ignoreNewExtensions) {
   // If we haven't allocated the lookup table yet, do so now.
   if (!LookupTable.getPointer()) {
@@ -1254,24 +1308,34 @@
     LookupTable.setPointer(new (ctx) MemberLookupTable(ctx));
   }
 
-  // If we're an IDC that has not yet loaded its full member set, we're doing
-  // NamedLazyMemberLoading, and we should not force getMembers().
-  if (hasLazyMembers())
-    return;
+  if (hasLazyMembers()) {
+    // Lazy members: if the table needs population, populate the table _only
+    // from those members already in the IDC member list_ such as implicits or
+    // globals-as-members, then update table entries from the extensions that
+    // have the same names as any such initial-population members.
+    if (!LookupTable.getInt()) {
+      LookupTable.setInt(true);
+      LookupTable.getPointer()->addMembers(getCurrentMembersWithoutLoading());
+      for (auto *m : getCurrentMembersWithoutLoading()) {
+        if (auto v = dyn_cast<ValueDecl>(m)) {
+          populateLookupTableEntryFromExtensions(getASTContext(),
+                                                 *LookupTable.getPointer(),
+                                                 this, v->getBaseName(),
+                                                 ignoreNewExtensions);
+        }
+      }
+    }
 
-  // If we haven't walked the member list yet to update the lookup
-  // table, do so now.
-  if (!LookupTable.getInt()) {
-    // Note that we'll have walked the members now.
-    LookupTable.setInt(true);
-
-    // Add the members of the nominal declaration to the table.
-    LookupTable.getPointer()->addMembers(getMembers());
-  }
-
-  if (!ignoreNewExtensions) {
-    // Update the lookup table to introduce members from extensions.
-    LookupTable.getPointer()->updateLookupTable(this);
+  } else {
+    // No lazy members: if the table needs population, populate the table
+    // en-masse; and in either case update the extensions.
+    if (!LookupTable.getInt()) {
+      LookupTable.setInt(true);
+      LookupTable.getPointer()->addMembers(getMembers());
+    }
+    if (!ignoreNewExtensions) {
+      LookupTable.getPointer()->updateLookupTable(this);
+    }
   }
 }
 
@@ -1284,47 +1348,6 @@
   LookupTable.getPointer()->addMember(member);
 }
 
-static bool
-populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
-                                          MemberLookupTable &LookupTable,
-                                          DeclName name,
-                                          IterableDeclContext *IDC) {
-  auto ci = ctx.getOrCreateLazyIterableContextData(IDC,
-                                                   /*lazyLoader=*/nullptr);
-  // Populate LookupTable with an empty vector before we call into our loader,
-  // so that any reentry of this routine will find the set-so-far, and not
-  // fall into infinite recursion.
-  LookupTable.addEmptyEntry(name);
-  if (auto res = ci->loader->loadNamedMembers(IDC, name, ci->memberData)) {
-    if (auto s = ctx.Stats) {
-      ++s->getFrontendCounters().NamedLazyMemberLoadSuccessCount;
-    }
-    for (auto d : *res) {
-      LookupTable.addMember(d);
-    }
-    return false;
-  } else {
-    if (auto s = ctx.Stats) {
-      ++s->getFrontendCounters().NamedLazyMemberLoadFailureCount;
-    }
-    return true;
-  }
-}
-
-static void
-populateLookupTableEntryFromMembers(ASTContext &ctx,
-                                    MemberLookupTable &LookupTable,
-                                    DeclName name,
-                                    IterableDeclContext *IDC) {
-  for (auto m : IDC->getMembers()) {
-    if (auto v = dyn_cast<ValueDecl>(m)) {
-      if (v->getFullName().matchesRef(name)) {
-        LookupTable.addMember(m);
-      }
-    }
-  }
-}
-
 TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
                                                   DeclName name,
                                                   bool ignoreNewExtensions) {
@@ -1336,16 +1359,24 @@
                 .NominalTypeDecl__lookupDirect.getGuard();
   }
 
-  DEBUG(llvm::dbgs() << getNameStr() << ".lookupDirect(" << name << ")"
-        << ", lookupTable.getInt()=" << LookupTable.getInt()
-        << ", hasLazyMembers()=" << hasLazyMembers()
-        << "\n");
-
   // We only use NamedLazyMemberLoading when a user opts-in and we have
   // not yet loaded all the members into the IDC list in the first place.
   bool useNamedLazyMemberLoading = (ctx.LangOpts.NamedLazyMemberLoading &&
                                     hasLazyMembers());
 
+  // FIXME: At present, lazy member loading conflicts with a bunch of other code
+  // that appears to special-case initializers (clang-imported initializer
+  // sorting, implicit initializer synthesis), so for the time being we have to
+  // turn it off for them entirely.
+  if (name.getBaseName() == ctx.Id_init)
+    useNamedLazyMemberLoading = false;
+
+  DEBUG(llvm::dbgs() << getNameStr() << ".lookupDirect(" << name << ")"
+        << ", lookupTable.getInt()=" << LookupTable.getInt()
+        << ", hasLazyMembers()=" << hasLazyMembers()
+        << ", useNamedLazyMemberLoading=" << useNamedLazyMemberLoading
+        << "\n");
+
   // We check the LookupTable at most twice, possibly treating a miss in the
   // first try as a cache-miss that we then do a cache-fill on, and retry.
   for (int i = 0; i < 2; ++i) {
@@ -1354,12 +1385,22 @@
     // populated the IDC and brought it up to date with any extensions. This
     // will flip the hasLazyMembers() flag to false as well.
     if (!useNamedLazyMemberLoading) {
-      // If we're about to load members here, purge the MemberLookupTable;
-      // it will be rebuilt in prepareLookup, below.
-      if (hasLazyMembers() && LookupTable.getPointer()) {
-        // We should not have scanned the IDC list yet. Double check.
-        assert(!LookupTable.getInt());
+      // It's possible that the lookup table exists but has information in it
+      // that is either currently out of date or soon to be out of date.
+      // This can happen two ways:
+      //
+      //   - We've not yet indexed the members we have (LookupTable.getInt()
+      //     is zero).
+      //
+      //   - We've still got more lazy members left to load; this can happen
+      //     even if we _did_ index some members.
+      //
+      // In either of these cases, we want to reset the table to empty and
+      // mark it as needing reconstruction.
+      if (LookupTable.getPointer() &&
+          (hasLazyMembers() || !LookupTable.getInt())) {
         LookupTable.getPointer()->clear();
+        LookupTable.setInt(false);
       }
 
       (void)getMembers();
@@ -1373,8 +1414,7 @@
     }
 
     // Next, in all cases, prepare the lookup table for use, possibly
-    // repopulating it from the IDC if just did our initial IDC population
-    // above.
+    // repopulating it from the IDC if the IDC member list has just grown.
     prepareLookupTable(ignoreNewExtensions);
 
     // Look for a declaration with this name.
@@ -1395,23 +1435,10 @@
     // false, and we fall back to loading all members during the retry.
     auto &Table = *LookupTable.getPointer();
     if (populateLookupTableEntryFromLazyIDCLoader(ctx, Table,
-                                                  name, this)) {
+                                                  name, this) ||
+        populateLookupTableEntryFromExtensions(ctx, Table, this, name,
+                                               ignoreNewExtensions)) {
       useNamedLazyMemberLoading = false;
-    } else {
-      if (!ignoreNewExtensions) {
-        for (auto E : getExtensions()) {
-          if (E->wasDeserialized()) {
-            if (populateLookupTableEntryFromLazyIDCLoader(ctx, Table,
-                                                          name, E)) {
-              useNamedLazyMemberLoading = false;
-              break;
-            }
-          } else {
-            populateLookupTableEntryFromMembers(ctx, Table,
-                                                name, E);
-          }
-        }
-      }
     }
   }
 
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index fc85b1f..0349d52 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -747,13 +747,13 @@
     // terms of the specialized types, not the conformance-declaring decl's
     // types.
     auto nominal = GenericConformance->getType()->getAnyNominal();
-    auto subMap =
-      getType()->getContextSubstitutionMap(nominal->getModuleContext(),
-                                           nominal);
+    auto module = nominal->getModuleContext();
+    auto subMap = getType()->getContextSubstitutionMap(module, nominal);
 
     SmallVector<Requirement, 4> newReqs;
     for (auto oldReq : GenericConformance->getConditionalRequirements()) {
-      if (auto newReq = oldReq.subst(subMap))
+      if (auto newReq = oldReq.subst(QuerySubstitutionMap{subMap},
+                                     LookUpConformanceInModule(module)))
         newReqs.push_back(*newReq);
     }
     auto &ctxt = getProtocol()->getASTContext();
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0ed0100..f48268c 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2687,12 +2687,14 @@
 }
 
 AssociatedTypeDecl *ArchetypeType::getAssocType() const {
+  assert(!getOpenedExistentialType());
   if (auto *depMemTy = InterfaceType->getAs<DependentMemberType>())
     return depMemTy->getAssocType();
   return nullptr;
 }
 
 Identifier ArchetypeType::getName() const {
+  assert(!getOpenedExistentialType());
   if (auto assocType = getAssocType())
     return assocType->getName();
 
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 4a973b2..241f9ce 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -3278,8 +3278,34 @@
   auto *D = IDC->getDecl();
   auto *DC = cast<DeclContext>(D);
   auto *CD = D->getClangDecl();
+  auto *CDC = cast<clang::DeclContext>(CD);
   assert(CD && "loadNamedMembers on a Decl without a clangDecl");
 
+  auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
+  auto effectiveClangContext = getEffectiveClangContext(nominal);
+
+  // FIXME: The legacy of mirroring protocol members rears its ugly head,
+  // and as a result we have to bail on any @interface or @category that
+  // has a declared protocol conformance.
+  if (auto *ID = dyn_cast<clang::ObjCInterfaceDecl>(CD)) {
+    if (ID->protocol_begin() != ID->protocol_end())
+      return None;
+  }
+  if (auto *CCD = dyn_cast<clang::ObjCCategoryDecl>(CD)) {
+    if (CCD->protocol_begin() != CCD->protocol_end())
+      return None;
+  }
+
+  // Also bail out if there are any global-as-member mappings for this type; we
+  // can support some of them lazily but the full set of idioms seems
+  // prohibitively complex (also they're not stored in by-name lookup, for
+  // reasons unclear).
+  if (forEachLookupTable([&](SwiftLookupTable &table) -> bool {
+        return (table.lookupGlobalsAsMembers(
+                  effectiveClangContext).size() > 0);
+      }))
+    return None;
+
   // There are 3 cases:
   //
   //  - The decl is from a bridging header, CMO is Some(nullptr)
@@ -3303,29 +3329,30 @@
 
   clang::ASTContext &clangCtx = getClangASTContext();
 
+  assert(isa<clang::ObjCContainerDecl>(CD));
+
   TinyPtrVector<ValueDecl *> Members;
-  if (auto *CCD = dyn_cast<clang::ObjCContainerDecl>(CD)) {
-    for (auto entry : table->lookup(SerializedSwiftName(N.getBaseName()), CCD)) {
-      if (!entry.is<clang::NamedDecl *>()) continue;
-      auto member = entry.get<clang::NamedDecl *>();
-      if (!isVisibleClangEntry(clangCtx, member)) continue;
-      SmallVector<Decl*, 4> tmp;
-      insertMembersAndAlternates(member, tmp);
-      for (auto *TD : tmp) {
-        if (auto *V = dyn_cast<ValueDecl>(TD)) {
-          // Skip ValueDecls if they import into different DeclContexts
-          // or under different names than the one we asked about.
-          if (V->getDeclContext() == DC &&
-              V->getFullName().matchesRef(N)) {
-            Members.push_back(V);
-          }
+  for (auto entry : table->lookup(SerializedSwiftName(N.getBaseName()),
+                                  effectiveClangContext)) {
+    if (!entry.is<clang::NamedDecl *>()) continue;
+    auto member = entry.get<clang::NamedDecl *>();
+    if (!isVisibleClangEntry(clangCtx, member)) continue;
+
+    // Skip Decls from different clang::DeclContexts
+    if (member->getDeclContext() != CDC) continue;
+
+    SmallVector<Decl*, 4> tmp;
+    insertMembersAndAlternates(member, tmp);
+    for (auto *TD : tmp) {
+      if (auto *V = dyn_cast<ValueDecl>(TD)) {
+        // Skip ValueDecls if they import under different names.
+        if (V->getFullName().matchesRef(N)) {
+          Members.push_back(V);
         }
       }
     }
-    return Members;
   }
-
-  return None;
+  return Members;
 }
 
 
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index aebb3c6..f1e4c18 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -4970,6 +4970,7 @@
     }
   }
 
+  theClass->addImplicitDestructor();
   return theClass;
 }
 
diff --git a/lib/ClangImporter/ImportMacro.cpp b/lib/ClangImporter/ImportMacro.cpp
index 518aa99..38a768d 100644
--- a/lib/ClangImporter/ImportMacro.cpp
+++ b/lib/ClangImporter/ImportMacro.cpp
@@ -27,6 +27,7 @@
 #include "swift/AST/Expr.h"
 #include "swift/AST/Stmt.h"
 #include "swift/AST/Types.h"
+#include "swift/Basic/PrettyStackTrace.h"
 #include "swift/ClangImporter/ClangModule.h"
 
 using namespace swift;
@@ -635,9 +636,14 @@
   if (!macro)
     return nullptr;
 
+  PrettyStackTraceStringAction stackRAII{"importing macro", name.str()};
+
   // Look for macros imported with the same name.
   auto known = ImportedMacros.find(name);
-  if (known != ImportedMacros.end()) {
+  if (known == ImportedMacros.end()) {
+    // Push in a placeholder to break circularity.
+    ImportedMacros[name].push_back({macro, nullptr});
+  } else {
     // Check whether this macro has already been imported.
     for (const auto &entry : known->second) {
       if (entry.first == macro) return entry.second;
@@ -655,6 +661,9 @@
         return result;
       }
     }
+
+    // If not, push in a placeholder to break circularity.
+    known->second.push_back({macro, nullptr});
   }
 
   ImportingEntityRAII ImportingEntity(*this);
@@ -672,6 +681,20 @@
 
   auto valueDecl = ::importMacro(*this, DC, name, macro, macroNode,
                                  /*castType*/{});
-  ImportedMacros[name].push_back({macro, valueDecl});
+
+  // Update the entry for the value we just imported.
+  // It's /probably/ the last entry in ImportedMacros[name], but there's an
+  // outside chance more macros with the same name have been imported
+  // re-entrantly since this method started.
+  if (valueDecl) {
+    auto entryIter = llvm::find_if(llvm::reverse(ImportedMacros[name]),
+        [macro](std::pair<const clang::MacroInfo *, ValueDecl *> entry) {
+      return entry.first == macro;
+    });
+    assert(entryIter != llvm::reverse(ImportedMacros[name]).end() &&
+           "placeholder not found");
+    entryIter->second = valueDecl;
+  }
+
   return valueDecl;
 }
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index a51dc25..7772da4 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -79,6 +79,18 @@
   llvm_unreachable("Unhandled InputFileKind in switch.");
 }
 
+// This is a separate function so that it shows up in stack traces.
+LLVM_ATTRIBUTE_NOINLINE
+static void debugFailWithAssertion() {
+  // This assertion should always fail, per the user's request, and should
+  // not be converted to llvm_unreachable.
+  assert(0 && "This is an assertion!");
+}
+
+// This is a separate function so that it shows up in stack traces.
+LLVM_ATTRIBUTE_NOINLINE
+static void debugFailWithCrash() { LLVM_BUILTIN_TRAP; }
+
 namespace swift {
 
 /// Implement argument semantics in a way that will make it easier to have
@@ -218,25 +230,164 @@
     return false;
   }
 };
+class FrontendArgsToOptionsConverter {
+private:
+  DiagnosticEngine &Diags;
+  const llvm::opt::ArgList &Args;
+  FrontendOptions &Opts;
+
+  Optional<const std::vector<std::string>>
+      cachedOutputFilenamesFromCommandLineOrFilelist;
+
+  void handleDebugCrashGroupArguments();
+
+  void computeDebugTimeOptions();
+  bool computeFallbackModuleName();
+  bool computeModuleName();
+  bool computeOutputFilenames();
+  void computeDumpScopeMapLocations();
+  void computeHelpOptions();
+  void computeImplicitImportModuleNames();
+  void computeImportObjCHeaderOptions();
+  void computeLLVMArgs();
+  void computePlaygroundOptions();
+  void computePrintStatsOptions();
+  void computeTBDOptions();
+
+  void setUnsignedIntegerArgument(options::ID optionID, unsigned max,
+                                  unsigned &valueToSet);
+
+  FrontendOptions::ActionType determineRequestedAction() const;
+
+  bool setUpForSILOrLLVM();
+
+  /// Determine the correct output filename when none was specified.
+  ///
+  /// Such an absence should only occur when invoking the frontend
+  /// without the driver,
+  /// because the driver will always pass -o with an appropriate filename
+  /// if output is required for the requested action.
+  bool deriveOutputFilenameFromInputFile();
+
+  /// Determine the correct output filename when a directory was specified.
+  ///
+  /// Such a specification should only occur when invoking the frontend
+  /// directly, because the driver will always pass -o with an appropriate
+  /// filename if output is required for the requested action.
+  bool deriveOutputFilenameForDirectory(StringRef outputDir);
+
+  std::string determineBaseNameOfOutput() const;
+
+  void determineSupplementaryOutputFilenames();
+
+  /// Returns the output filenames on the command line or in the output
+  /// filelist. If there
+  /// were neither -o's nor an output filelist, returns an empty vector.
+  ArrayRef<std::string> getOutputFilenamesFromCommandLineOrFilelist();
+
+  bool checkForUnusedOutputPaths() const;
+
+  std::vector<std::string> readOutputFileList(StringRef filelistPath) const;
+
+public:
+  FrontendArgsToOptionsConverter(DiagnosticEngine &Diags,
+                                 const llvm::opt::ArgList &Args,
+                                 FrontendOptions &Opts)
+      : Diags(Diags), Args(Args), Opts(Opts) {}
+
+  bool convert();
+};
 } // namespace swift
 
-// This is a separate function so that it shows up in stack traces.
-LLVM_ATTRIBUTE_NOINLINE
-static void debugFailWithAssertion() {
-  // This assertion should always fail, per the user's request, and should
-  // not be converted to llvm_unreachable.
-  assert(0 && "This is an assertion!");
+bool FrontendArgsToOptionsConverter::convert() {
+  using namespace options;
+
+  handleDebugCrashGroupArguments();
+
+  if (const Arg *A = Args.getLastArg(OPT_dump_api_path)) {
+    Opts.DumpAPIPath = A->getValue();
+  }
+  if (const Arg *A = Args.getLastArg(OPT_group_info_path)) {
+    Opts.GroupInfoPath = A->getValue();
+  }
+  if (const Arg *A = Args.getLastArg(OPT_index_store_path)) {
+    Opts.IndexStorePath = A->getValue();
+  }
+  Opts.IndexSystemModules |= Args.hasArg(OPT_index_system_modules);
+
+  Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
+  Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
+
+  Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
+  Opts.EnableResilience |= Args.hasArg(OPT_enable_resilience);
+
+  computePrintStatsOptions();
+  computeDebugTimeOptions();
+  computeTBDOptions();
+
+  setUnsignedIntegerArgument(OPT_warn_long_function_bodies, 10,
+                             Opts.WarnLongFunctionBodies);
+  setUnsignedIntegerArgument(OPT_warn_long_expression_type_checking, 10,
+                             Opts.WarnLongExpressionTypeChecking);
+  setUnsignedIntegerArgument(OPT_solver_expression_time_threshold_EQ, 10,
+                             Opts.SolverExpressionTimeThreshold);
+
+  computePlaygroundOptions();
+
+  // This can be enabled independently of the playground transform.
+  Opts.PCMacro |= Args.hasArg(OPT_pc_macro);
+
+  computeHelpOptions();
+  if (ArgsToFrontendInputsConverter(Diags, Args, Opts.Inputs).convert())
+    return true;
+
+  Opts.ParseStdlib |= Args.hasArg(OPT_parse_stdlib);
+
+  if (const Arg *A = Args.getLastArg(OPT_verify_generic_signatures)) {
+    Opts.VerifyGenericSignaturesInModule = A->getValue();
+  }
+
+  computeDumpScopeMapLocations();
+  Opts.RequestedAction = determineRequestedAction();
+
+  if (Opts.RequestedAction == FrontendOptions::ActionType::Immediate &&
+      Opts.Inputs.hasPrimaryInputs()) {
+    Diags.diagnose(SourceLoc(), diag::error_immediate_mode_primary_file);
+    return true;
+  }
+
+  if (setUpForSILOrLLVM())
+    return true;
+
+  if (computeModuleName())
+    return true;
+
+  if (computeOutputFilenames())
+    return true;
+  determineSupplementaryOutputFilenames();
+
+  if (checkForUnusedOutputPaths())
+    return true;
+
+  if (const Arg *A = Args.getLastArg(OPT_module_link_name)) {
+    Opts.ModuleLinkName = A->getValue();
+  }
+
+  Opts.AlwaysSerializeDebuggingOptions |=
+      Args.hasArg(OPT_serialize_debugging_options);
+  Opts.EnableSourceImport |= Args.hasArg(OPT_enable_source_import);
+  Opts.ImportUnderlyingModule |= Args.hasArg(OPT_import_underlying_module);
+  Opts.EnableSerializationNestedTypeLookupTable &=
+      !Args.hasArg(OPT_disable_serialization_nested_type_lookup_table);
+
+  computeImportObjCHeaderOptions();
+  computeImplicitImportModuleNames();
+  computeLLVMArgs();
+
+  return false;
 }
 
-// This is a separate function so that it shows up in stack traces.
-LLVM_ATTRIBUTE_NOINLINE
-static void debugFailWithCrash() {
-  LLVM_BUILTIN_TRAP;
-}
-
-
-static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
-                              DiagnosticEngine &Diags) {
+void FrontendArgsToOptionsConverter::handleDebugCrashGroupArguments() {
   using namespace options;
 
   if (const Arg *A = Args.getLastArg(OPT_debug_crash_Group)) {
@@ -255,36 +406,23 @@
       llvm_unreachable("Unknown debug_crash_Group option!");
     }
   }
+}
 
-  if (const Arg *A = Args.getLastArg(OPT_dump_api_path)) {
-    Opts.DumpAPIPath = A->getValue();
-  }
-
-  if (const Arg *A = Args.getLastArg(OPT_group_info_path)) {
-    Opts.GroupInfoPath = A->getValue();
-  }
-
-  if (const Arg *A = Args.getLastArg(OPT_index_store_path)) {
-    Opts.IndexStorePath = A->getValue();
-  }
-  Opts.IndexSystemModules |= Args.hasArg(OPT_index_system_modules);
-
-  Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
-  Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
-
-  Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
-  Opts.EnableResilience |= Args.hasArg(OPT_enable_resilience);
-
+void FrontendArgsToOptionsConverter::computePrintStatsOptions() {
+  using namespace options;
   Opts.PrintStats |= Args.hasArg(OPT_print_stats);
   Opts.PrintClangStats |= Args.hasArg(OPT_print_clang_stats);
 #if defined(NDEBUG) && !defined(LLVM_ENABLE_STATS)
   if (Opts.PrintStats || Opts.PrintClangStats)
     Diags.diagnose(SourceLoc(), diag::stats_disabled);
 #endif
+}
 
+void FrontendArgsToOptionsConverter::computeDebugTimeOptions() {
+  using namespace options;
   Opts.DebugTimeFunctionBodies |= Args.hasArg(OPT_debug_time_function_bodies);
   Opts.DebugTimeExpressionTypeChecking |=
-    Args.hasArg(OPT_debug_time_expression_type_checking);
+      Args.hasArg(OPT_debug_time_expression_type_checking);
   Opts.DebugTimeCompilation |= Args.hasArg(OPT_debug_time_compilation);
   if (const Arg *A = Args.getLastArg(OPT_stats_output_dir)) {
     Opts.StatsOutputDir = A->getValue();
@@ -292,7 +430,10 @@
       Opts.TraceStats = true;
     }
   }
+}
 
+void FrontendArgsToOptionsConverter::computeTBDOptions() {
+  using namespace options;
   if (const Arg *A = Args.getLastArg(OPT_validate_tbd_against_ir_EQ)) {
     using Mode = FrontendOptions::TBDValidationMode;
     StringRef value = A->getValue();
@@ -307,50 +448,35 @@
                      A->getOption().getPrefixedName(), value);
     }
   }
-
   if (const Arg *A = Args.getLastArg(OPT_tbd_install_name)) {
     Opts.TBDInstallName = A->getValue();
   }
+}
 
-  if (const Arg *A = Args.getLastArg(OPT_warn_long_function_bodies)) {
+void FrontendArgsToOptionsConverter::setUnsignedIntegerArgument(
+    options::ID optionID, unsigned max, unsigned &valueToSet) {
+  if (const Arg *A = Args.getLastArg(optionID)) {
     unsigned attempt;
-    if (StringRef(A->getValue()).getAsInteger(10, attempt)) {
+    if (StringRef(A->getValue()).getAsInteger(max, attempt)) {
       Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
                      A->getAsString(Args), A->getValue());
     } else {
-      Opts.WarnLongFunctionBodies = attempt;
+      valueToSet = attempt;
     }
   }
+}
 
-  if (const Arg *A = Args.getLastArg(OPT_warn_long_expression_type_checking)) {
-    unsigned attempt;
-    if (StringRef(A->getValue()).getAsInteger(10, attempt)) {
-      Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
-                     A->getAsString(Args), A->getValue());
-    } else {
-      Opts.WarnLongExpressionTypeChecking = attempt;
-    }
-  }
-
-  if (const Arg *A = Args.getLastArg(OPT_solver_expression_time_threshold_EQ)) {
-    unsigned attempt;
-    if (StringRef(A->getValue()).getAsInteger(10, attempt)) {
-      Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
-                     A->getAsString(Args), A->getValue());
-    } else {
-      Opts.SolverExpressionTimeThreshold = attempt;
-    }
-  }
-
+void FrontendArgsToOptionsConverter::computePlaygroundOptions() {
+  using namespace options;
   Opts.PlaygroundTransform |= Args.hasArg(OPT_playground);
   if (Args.hasArg(OPT_disable_playground_transform))
     Opts.PlaygroundTransform = false;
   Opts.PlaygroundHighPerformance |=
-    Args.hasArg(OPT_playground_high_performance);
+      Args.hasArg(OPT_playground_high_performance);
+}
 
-  // This can be enabled independently of the playground transform.
-  Opts.PCMacro |= Args.hasArg(OPT_pc_macro);
-
+void FrontendArgsToOptionsConverter::computeHelpOptions() {
+  using namespace options;
   if (const Arg *A = Args.getLastArg(OPT_help, OPT_help_hidden)) {
     if (A->getOption().matches(OPT_help)) {
       Opts.PrintHelp = true;
@@ -360,124 +486,117 @@
       llvm_unreachable("Unknown help option parsed");
     }
   }
+}
 
-  if (ArgsToFrontendInputsConverter(Diags, Args, Opts.Inputs).convert())
-    return true;
+void FrontendArgsToOptionsConverter::computeDumpScopeMapLocations() {
+  using namespace options;
+  const Arg *A = Args.getLastArg(OPT_modes_Group);
+  if (!A || !A->getOption().matches(OPT_dump_scope_maps))
+    return;
+  StringRef value = A->getValue();
+  if (value == "expanded") {
+    // Note: fully expanded the scope map.
+    return;
+  }
+  // Parse a comma-separated list of line:column for lookups to
+  // perform (and dump the result of).
+  SmallVector<StringRef, 4> locations;
+  value.split(locations, ',');
 
-  Opts.ParseStdlib |= Args.hasArg(OPT_parse_stdlib);
-
-  if (const Arg *A = Args.getLastArg(OPT_verify_generic_signatures)) {
-    Opts.VerifyGenericSignaturesInModule = A->getValue();
+  bool invalid = false;
+  for (auto location : locations) {
+    auto lineColumnStr = location.split(':');
+    unsigned line, column;
+    if (lineColumnStr.first.getAsInteger(10, line) ||
+        lineColumnStr.second.getAsInteger(10, column)) {
+      Diags.diagnose(SourceLoc(), diag::error_invalid_source_location_str,
+                     location);
+      invalid = true;
+      continue;
+    }
+    Opts.DumpScopeMapLocations.push_back({line, column});
   }
 
-  // Determine what the user has asked the frontend to do.
-  FrontendOptions::ActionType &Action = Opts.RequestedAction;
-  if (const Arg *A = Args.getLastArg(OPT_modes_Group)) {
-    Option Opt = A->getOption();
-    if (Opt.matches(OPT_emit_object)) {
-      Action = FrontendOptions::ActionType::EmitObject;
-    } else if (Opt.matches(OPT_emit_assembly)) {
-      Action = FrontendOptions::ActionType::EmitAssembly;
-    } else if (Opt.matches(OPT_emit_ir)) {
-      Action = FrontendOptions::ActionType::EmitIR;
-    } else if (Opt.matches(OPT_emit_bc)) {
-      Action = FrontendOptions::ActionType::EmitBC;
-    } else if (Opt.matches(OPT_emit_sil)) {
-      Action = FrontendOptions::ActionType::EmitSIL;
-    } else if (Opt.matches(OPT_emit_silgen)) {
-      Action = FrontendOptions::ActionType::EmitSILGen;
-    } else if (Opt.matches(OPT_emit_sib)) {
-      Action = FrontendOptions::ActionType::EmitSIB;
-    } else if (Opt.matches(OPT_emit_sibgen)) {
-      Action = FrontendOptions::ActionType::EmitSIBGen;
-    } else if (Opt.matches(OPT_emit_pch)) {
-      Action = FrontendOptions::ActionType::EmitPCH;
-    } else if (Opt.matches(OPT_emit_imported_modules)) {
-      Action = FrontendOptions::ActionType::EmitImportedModules;
-    } else if (Opt.matches(OPT_parse)) {
-      Action = FrontendOptions::ActionType::Parse;
-    } else if (Opt.matches(OPT_typecheck)) {
-      Action = FrontendOptions::ActionType::Typecheck;
-    } else if (Opt.matches(OPT_dump_parse)) {
-      Action = FrontendOptions::ActionType::DumpParse;
-    } else if (Opt.matches(OPT_dump_ast)) {
-      Action = FrontendOptions::ActionType::DumpAST;
-    } else if (Opt.matches(OPT_emit_syntax)) {
-      Action = FrontendOptions::ActionType::EmitSyntax;
-    } else if (Opt.matches(OPT_merge_modules)) {
-      Action = FrontendOptions::ActionType::MergeModules;
-    } else if (Opt.matches(OPT_dump_scope_maps)) {
-      Action = FrontendOptions::ActionType::DumpScopeMaps;
+  if (!invalid && Opts.DumpScopeMapLocations.empty())
+    Diags.diagnose(SourceLoc(), diag::error_no_source_location_scope_map);
+}
 
-      StringRef value = A->getValue();
-      if (value == "expanded") {
-        // Note: fully expanded the scope map.
-      } else {
-        // Parse a comma-separated list of line:column for lookups to
-        // perform (and dump the result of).
-        SmallVector<StringRef, 4> locations;
-        value.split(locations, ',');
-
-        bool invalid = false;
-        for (auto location : locations) {
-          auto lineColumnStr = location.split(':');
-          unsigned line, column;
-          if (lineColumnStr.first.getAsInteger(10, line) ||
-              lineColumnStr.second.getAsInteger(10, column)) {
-            Diags.diagnose(SourceLoc(), diag::error_invalid_source_location_str,
-                           location);
-            invalid = true;
-            continue;
-          }
-
-          Opts.DumpScopeMapLocations.push_back({line, column});
-        }
-
-        if (!invalid && Opts.DumpScopeMapLocations.empty())
-          Diags.diagnose(SourceLoc(), diag::error_no_source_location_scope_map);
-      }
-    } else if (Opt.matches(OPT_dump_type_refinement_contexts)) {
-      Action = FrontendOptions::ActionType::DumpTypeRefinementContexts;
-    } else if (Opt.matches(OPT_dump_interface_hash)) {
-      Action = FrontendOptions::ActionType::DumpInterfaceHash;
-    } else if (Opt.matches(OPT_print_ast)) {
-      Action = FrontendOptions::ActionType::PrintAST;
-    } else if (Opt.matches(OPT_repl) ||
-               Opt.matches(OPT_deprecated_integrated_repl)) {
-      Action = FrontendOptions::ActionType::REPL;
-    } else if (Opt.matches(OPT_interpret)) {
-      Action = FrontendOptions::ActionType::Immediate;
-    } else {
-      llvm_unreachable("Unhandled mode option");
-    }
-  } else {
+FrontendOptions::ActionType
+FrontendArgsToOptionsConverter::determineRequestedAction() const {
+  using namespace options;
+  const Arg *A = Args.getLastArg(OPT_modes_Group);
+  if (!A) {
     // We don't have a mode, so determine a default.
     if (Args.hasArg(OPT_emit_module, OPT_emit_module_path)) {
       // We've been told to emit a module, but have no other mode indicators.
       // As a result, put the frontend into EmitModuleOnly mode.
       // (Setting up module output will be handled below.)
-      Action = FrontendOptions::ActionType::EmitModuleOnly;
+      return FrontendOptions::ActionType::EmitModuleOnly;
     }
+    return FrontendOptions::ActionType::NoneAction;
   }
+  Option Opt = A->getOption();
+  if (Opt.matches(OPT_emit_object))
+    return FrontendOptions::ActionType::EmitObject;
+  if (Opt.matches(OPT_emit_assembly))
+    return FrontendOptions::ActionType::EmitAssembly;
+  if (Opt.matches(OPT_emit_ir))
+    return FrontendOptions::ActionType::EmitIR;
+  if (Opt.matches(OPT_emit_bc))
+    return FrontendOptions::ActionType::EmitBC;
+  if (Opt.matches(OPT_emit_sil))
+    return FrontendOptions::ActionType::EmitSIL;
+  if (Opt.matches(OPT_emit_silgen))
+    return FrontendOptions::ActionType::EmitSILGen;
+  if (Opt.matches(OPT_emit_sib))
+    return FrontendOptions::ActionType::EmitSIB;
+  if (Opt.matches(OPT_emit_sibgen))
+    return FrontendOptions::ActionType::EmitSIBGen;
+  if (Opt.matches(OPT_emit_pch))
+    return FrontendOptions::ActionType::EmitPCH;
+  if (Opt.matches(OPT_emit_imported_modules))
+    return FrontendOptions::ActionType::EmitImportedModules;
+  if (Opt.matches(OPT_parse))
+    return FrontendOptions::ActionType::Parse;
+  if (Opt.matches(OPT_typecheck))
+    return FrontendOptions::ActionType::Typecheck;
+  if (Opt.matches(OPT_dump_parse))
+    return FrontendOptions::ActionType::DumpParse;
+  if (Opt.matches(OPT_dump_ast))
+    return FrontendOptions::ActionType::DumpAST;
+  if (Opt.matches(OPT_emit_syntax))
+    return FrontendOptions::ActionType::EmitSyntax;
+  if (Opt.matches(OPT_merge_modules))
+    return FrontendOptions::ActionType::MergeModules;
+  if (Opt.matches(OPT_dump_scope_maps))
+    return FrontendOptions::ActionType::DumpScopeMaps;
+  if (Opt.matches(OPT_dump_type_refinement_contexts))
+    return FrontendOptions::ActionType::DumpTypeRefinementContexts;
+  if (Opt.matches(OPT_dump_interface_hash))
+    return FrontendOptions::ActionType::DumpInterfaceHash;
+  if (Opt.matches(OPT_print_ast))
+    return FrontendOptions::ActionType::PrintAST;
 
-  if (Opts.RequestedAction == FrontendOptions::ActionType::Immediate &&
-      Opts.Inputs.havePrimaryInputs()) {
-    Diags.diagnose(SourceLoc(), diag::error_immediate_mode_primary_file);
-    return true;
-  }
+  if (Opt.matches(OPT_repl) || Opt.matches(OPT_deprecated_integrated_repl))
+    return FrontendOptions::ActionType::REPL;
+  if (Opt.matches(OPT_interpret))
+    return FrontendOptions::ActionType::Immediate;
 
-  bool TreatAsSIL =
+  llvm_unreachable("Unhandled mode option");
+}
+
+bool FrontendArgsToOptionsConverter::setUpForSILOrLLVM() {
+  using namespace options;
+  bool treatAsSIL =
       Args.hasArg(OPT_parse_sil) || Opts.Inputs.shouldTreatAsSIL();
-
-  bool TreatAsLLVM = Opts.Inputs.shouldTreatAsLLVM();
+  bool treatAsLLVM = Opts.Inputs.shouldTreatAsLLVM();
 
   if (Opts.Inputs.verifyInputs(
-          Diags, TreatAsSIL,
+          Diags, treatAsSIL,
           Opts.RequestedAction == FrontendOptions::ActionType::REPL,
           Opts.RequestedAction == FrontendOptions::ActionType::NoneAction)) {
     return true;
   }
-
   if (Opts.RequestedAction == FrontendOptions::ActionType::Immediate) {
     Opts.ImmediateArgv.push_back(
         Opts.Inputs.getFilenameOfFirstInput()); // argv[0]
@@ -488,190 +607,244 @@
     }
   }
 
-  if (TreatAsSIL)
+  if (treatAsSIL)
     Opts.InputKind = InputFileKind::IFK_SIL;
-  else if (TreatAsLLVM)
+  else if (treatAsLLVM)
     Opts.InputKind = InputFileKind::IFK_LLVM_IR;
   else if (Args.hasArg(OPT_parse_as_library))
     Opts.InputKind = InputFileKind::IFK_Swift_Library;
-  else if (Action == FrontendOptions::ActionType::REPL)
+  else if (Opts.RequestedAction == FrontendOptions::ActionType::REPL)
     Opts.InputKind = InputFileKind::IFK_Swift_REPL;
   else
     Opts.InputKind = InputFileKind::IFK_Swift;
 
-  Opts.setOutputFileList(Diags, Args);
+  return false;
+}
 
-  Opts.setModuleName(Diags, Args);
+bool FrontendArgsToOptionsConverter::computeModuleName() {
+  const Arg *A = Args.getLastArg(options::OPT_module_name);
+  if (A) {
+    Opts.ModuleName = A->getValue();
+  } else if (Opts.ModuleName.empty()) {
+    // The user did not specify a module name, so determine a default fallback
+    // based on other options.
 
-  if (Opts.OutputFilenames.empty() ||
-      llvm::sys::fs::is_directory(Opts.getSingleOutputFilename())) {
-    // No output filename was specified, or an output directory was specified.
-    // Determine the correct output filename.
-
-    // Note: this should typically only be used when invoking the frontend
-    // directly, as the driver will always pass -o with an appropriate filename
-    // if output is required for the requested action.
-
-    StringRef Suffix;
-    switch (Opts.RequestedAction) {
-    case FrontendOptions::ActionType::NoneAction:
-      break;
-
-    case FrontendOptions::ActionType::Parse:
-    case FrontendOptions::ActionType::Typecheck:
-    case FrontendOptions::ActionType::DumpParse:
-    case FrontendOptions::ActionType::DumpInterfaceHash:
-    case FrontendOptions::ActionType::DumpAST:
-    case FrontendOptions::ActionType::EmitSyntax:
-    case FrontendOptions::ActionType::PrintAST:
-    case FrontendOptions::ActionType::DumpScopeMaps:
-    case FrontendOptions::ActionType::DumpTypeRefinementContexts:
-      // Textual modes.
-      Opts.setOutputFilenameToStdout();
-      break;
-
-    case FrontendOptions::ActionType::EmitPCH:
-      Suffix = PCH_EXTENSION;
-      break;
-
-    case FrontendOptions::ActionType::EmitSILGen:
-    case FrontendOptions::ActionType::EmitSIL: {
-      if (Opts.OutputFilenames.empty())
-        Opts.setOutputFilenameToStdout();
-      else
-        Suffix = SIL_EXTENSION;
-      break;
-    }
-
-    case FrontendOptions::ActionType::EmitSIBGen:
-    case FrontendOptions::ActionType::EmitSIB:
-      Suffix = SIB_EXTENSION;
-      break;
-
-    case FrontendOptions::ActionType::MergeModules:
-    case FrontendOptions::ActionType::EmitModuleOnly:
-      Suffix = SERIALIZED_MODULE_EXTENSION;
-      break;
-
-    case FrontendOptions::ActionType::Immediate:
-    case FrontendOptions::ActionType::REPL:
-      // These modes have no frontend-generated output.
-      Opts.OutputFilenames.clear();
-      break;
-
-    case FrontendOptions::ActionType::EmitAssembly: {
-      if (Opts.OutputFilenames.empty())
-        Opts.setOutputFilenameToStdout();
-      else
-        Suffix = "s";
-      break;
-    }
-
-    case FrontendOptions::ActionType::EmitIR: {
-      if (Opts.OutputFilenames.empty())
-        Opts.setOutputFilenameToStdout();
-      else
-        Suffix = "ll";
-      break;
-    }
-
-    case FrontendOptions::ActionType::EmitBC: {
-      Suffix = "bc";
-      break;
-    }
-
-    case FrontendOptions::ActionType::EmitObject:
-      Suffix = "o";
-      break;
-
-    case FrontendOptions::ActionType::EmitImportedModules:
-      if (Opts.OutputFilenames.empty())
-        Opts.setOutputFilenameToStdout();
-      else
-        Suffix = "importedmodules";
-      break;
-    }
-
-    if (!Suffix.empty()) {
-      // We need to deduce a file name.
-
-      // First, if we're reading from stdin and we don't have a directory,
-      // output to stdout.
-      if (Opts.Inputs.isReadingFromStdin() && Opts.OutputFilenames.empty())
-        Opts.setOutputFilenameToStdout();
-      else {
-        // We have a suffix, so determine an appropriate name.
-        StringRef BaseName =
-            Opts.Inputs.baseNameOfOutput(Args, Opts.ModuleName);
-        llvm::SmallString<128> Path(Opts.getSingleOutputFilename());
-        llvm::sys::path::append(Path, BaseName);
-        llvm::sys::path::replace_extension(Path, Suffix);
-
-        Opts.setSingleOutputFilename(Path.str());
-      }
-    }
-
-    if (Opts.OutputFilenames.empty()) {
-      if (Opts.RequestedAction != FrontendOptions::ActionType::REPL &&
-          Opts.RequestedAction != FrontendOptions::ActionType::Immediate &&
-          Opts.RequestedAction != FrontendOptions::ActionType::NoneAction) {
-        Diags.diagnose(SourceLoc(), diag::error_no_output_filename_specified);
-        return true;
-      }
-    } else if (Opts.isOutputFileDirectory()) {
-      Diags.diagnose(SourceLoc(), diag::error_implicit_output_file_is_directory,
-                     Opts.getSingleOutputFilename());
+    // Note: this code path will only be taken when running the frontend
+    // directly; the driver should always pass -module-name when invoking the
+    // frontend.
+    if (computeFallbackModuleName())
       return true;
-    }
   }
 
-  auto determineOutputFilename = [&](std::string &output,
-                                     OptSpecifier optWithoutPath,
-                                     OptSpecifier optWithPath,
-                                     const char *extension,
-                                     bool useMainOutput) {
-    if (const Arg *A = Args.getLastArg(optWithPath)) {
-      Args.ClaimAllArgs(optWithoutPath);
-      output = A->getValue();
-      return;
+  if (Lexer::isIdentifier(Opts.ModuleName) &&
+      (Opts.ModuleName != STDLIB_NAME || Opts.ParseStdlib)) {
+    return false;
+  }
+  if (!FrontendOptions::needsProperModuleName(Opts.RequestedAction) ||
+      Opts.isCompilingExactlyOneSwiftFile()) {
+    Opts.ModuleName = "main";
+    return false;
+  }
+  auto DID = (Opts.ModuleName == STDLIB_NAME) ? diag::error_stdlib_module_name
+                                              : diag::error_bad_module_name;
+  Diags.diagnose(SourceLoc(), DID, Opts.ModuleName, A == nullptr);
+  Opts.ModuleName = "__bad__";
+  return false; // FIXME: Must continue to run to pass the tests, but should not
+                // have to.
+}
+
+bool FrontendArgsToOptionsConverter::computeFallbackModuleName() {
+  if (Opts.RequestedAction == FrontendOptions::ActionType::REPL) {
+    // Default to a module named "REPL" if we're in REPL mode.
+    Opts.ModuleName = "REPL";
+    return false;
+  }
+  if (!Opts.Inputs.hasInputFilenames()) {
+    Opts.ModuleName = StringRef();
+    // FIXME: This is a bug that should not happen, but does in tests.
+    // The current behavior is needed to pass the tests.
+    // The compiler should bail out earlier, where "no frontend action was
+    // selected".
+    return false;
+  }
+  ArrayRef<std::string> outputFilenames =
+      getOutputFilenamesFromCommandLineOrFilelist();
+
+  bool isOutputAUniqueOrdinaryFile =
+      outputFilenames.size() == 1 && outputFilenames[0] != "-" &&
+      !llvm::sys::fs::is_directory(outputFilenames[0]);
+  std::string nameToStem = isOutputAUniqueOrdinaryFile
+                               ? outputFilenames[0]
+                               : Opts.Inputs.getFilenameOfFirstInput();
+  Opts.ModuleName = llvm::sys::path::stem(nameToStem);
+  return false;
+}
+
+bool FrontendArgsToOptionsConverter::computeOutputFilenames() {
+  assert(Opts.OutputFilenames.empty() &&
+         "Output filename should not be set at this point");
+  if (!FrontendOptions::doesActionProduceOutput(Opts.RequestedAction)) {
+    return false;
+  }
+  ArrayRef<std::string> outputFilenamesFromCommandLineOrFilelist =
+      getOutputFilenamesFromCommandLineOrFilelist();
+
+  if (outputFilenamesFromCommandLineOrFilelist.size() > 1) {
+    // WMO, threaded with N files (also someday batch mode).
+    Opts.OutputFilenames = outputFilenamesFromCommandLineOrFilelist;
+    return false;
+  }
+
+  if (outputFilenamesFromCommandLineOrFilelist.empty()) {
+    // When the Frontend is invoked without going through the driver
+    // (e.g. for testing), it is convenient to derive output filenames from
+    // input.
+    return deriveOutputFilenameFromInputFile();
+  }
+
+  StringRef outputFilename = outputFilenamesFromCommandLineOrFilelist[0];
+  if (!llvm::sys::fs::is_directory(outputFilename)) {
+    // Could be -primary-file (1), or -wmo (non-threaded w/ N (input) files)
+    Opts.OutputFilenames = outputFilenamesFromCommandLineOrFilelist;
+    return false;
+  }
+  // Only used for testing & when invoking frontend directly.
+  return deriveOutputFilenameForDirectory(outputFilename);
+}
+
+bool FrontendArgsToOptionsConverter::deriveOutputFilenameFromInputFile() {
+  if (Opts.Inputs.isReadingFromStdin() ||
+      FrontendOptions::doesActionProduceTextualOutput(Opts.RequestedAction)) {
+    Opts.setOutputFilenameToStdout();
+    return false;
+  }
+  std::string baseName = determineBaseNameOfOutput();
+  if (baseName.empty()) {
+    if (Opts.RequestedAction != FrontendOptions::ActionType::REPL &&
+        Opts.RequestedAction != FrontendOptions::ActionType::Immediate &&
+        Opts.RequestedAction != FrontendOptions::ActionType::NoneAction) {
+      Diags.diagnose(SourceLoc(), diag::error_no_output_filename_specified);
+      return true;
     }
+    return false;
+  }
+  llvm::SmallString<128> path(baseName);
+  StringRef suffix = FrontendOptions::suffixForPrincipalOutputFileForAction(
+      Opts.RequestedAction);
+  llvm::sys::path::replace_extension(path, suffix);
+  Opts.OutputFilenames.push_back(path.str());
+  return false;
+}
 
-    if (!Args.hasArg(optWithoutPath))
-      return;
+bool FrontendArgsToOptionsConverter::deriveOutputFilenameForDirectory(
+    StringRef outputDir) {
 
-    if (useMainOutput && !Opts.OutputFilenames.empty()) {
-      output = Opts.getSingleOutputFilename();
-      return;
-    }
+  std::string baseName = determineBaseNameOfOutput();
+  if (baseName.empty()) {
+    Diags.diagnose(SourceLoc(), diag::error_implicit_output_file_is_directory,
+                   outputDir);
+    return true;
+  }
+  llvm::SmallString<128> path(outputDir);
+  llvm::sys::path::append(path, baseName);
+  StringRef suffix = FrontendOptions::suffixForPrincipalOutputFileForAction(
+      Opts.RequestedAction);
+  llvm::sys::path::replace_extension(path, suffix);
+  Opts.OutputFilenames.push_back(path.str());
+  return false;
+}
 
-    if (!output.empty())
-      return;
+std::string FrontendArgsToOptionsConverter::determineBaseNameOfOutput() const {
+  std::string nameToStem;
+  if (Opts.Inputs.hasAPrimaryInputFile()) {
+    assert(Opts.Inputs.hasUniquePrimaryInput() &&
+           "Cannot handle multiple primaries yet");
+    nameToStem = Opts.Inputs.primaryInputFilenameIfAny();
+  } else if (auto UserSpecifiedModuleName =
+                 Args.getLastArg(options::OPT_module_name)) {
+    nameToStem = UserSpecifiedModuleName->getValue();
+  } else if (Opts.Inputs.inputFilenameCount() == 1) {
+    nameToStem = Opts.Inputs.getFilenameOfFirstInput();
+  } else
+    nameToStem = "";
 
-    llvm::SmallString<128> Path(Opts.originalPath());
-    llvm::sys::path::replace_extension(Path, extension);
-    output = Path.str();
-  };
+  return llvm::sys::path::stem(nameToStem).str();
+}
 
-  determineOutputFilename(Opts.DependenciesFilePath,
-                          OPT_emit_dependencies,
-                          OPT_emit_dependencies_path,
-                          "d", false);
-  determineOutputFilename(Opts.ReferenceDependenciesFilePath,
-                          OPT_emit_reference_dependencies,
-                          OPT_emit_reference_dependencies_path,
-                          "swiftdeps", false);
+ArrayRef<std::string>
+FrontendArgsToOptionsConverter::getOutputFilenamesFromCommandLineOrFilelist() {
+  if (cachedOutputFilenamesFromCommandLineOrFilelist) {
+    return *cachedOutputFilenamesFromCommandLineOrFilelist;
+  }
+
+  if (const Arg *A = Args.getLastArg(options::OPT_output_filelist)) {
+    assert(!Args.hasArg(options::OPT_o) &&
+           "don't use -o with -output-filelist");
+    cachedOutputFilenamesFromCommandLineOrFilelist.emplace(
+        readOutputFileList(A->getValue()));
+  } else {
+    cachedOutputFilenamesFromCommandLineOrFilelist.emplace(
+        Args.getAllArgValues(options::OPT_o));
+  }
+  return *cachedOutputFilenamesFromCommandLineOrFilelist;
+}
+
+/// Try to read an output file list file.
+std::vector<std::string> FrontendArgsToOptionsConverter::readOutputFileList(
+    const StringRef filelistPath) const {
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
+      llvm::MemoryBuffer::getFile(filelistPath);
+  if (!buffer) {
+    Diags.diagnose(SourceLoc(), diag::cannot_open_file, filelistPath,
+                   buffer.getError().message());
+  }
+  std::vector<std::string> outputFiles;
+  for (StringRef line : make_range(llvm::line_iterator(*buffer.get()), {})) {
+    outputFiles.push_back(line.str());
+  }
+  return outputFiles;
+}
+
+void FrontendArgsToOptionsConverter::determineSupplementaryOutputFilenames() {
+  using namespace options;
+  auto determineOutputFilename =
+      [&](std::string &output, OptSpecifier optWithoutPath,
+          OptSpecifier optWithPath, const char *extension, bool useMainOutput) {
+        if (const Arg *A = Args.getLastArg(optWithPath)) {
+          Args.ClaimAllArgs(optWithoutPath);
+          output = A->getValue();
+          return;
+        }
+
+        if (!Args.hasArg(optWithoutPath))
+          return;
+
+        if (useMainOutput && !Opts.OutputFilenames.empty()) {
+          output = Opts.getSingleOutputFilename();
+          return;
+        }
+
+        if (!output.empty())
+          return;
+
+        llvm::SmallString<128> path(Opts.originalPath());
+        llvm::sys::path::replace_extension(path, extension);
+        output = path.str();
+      };
+
+  determineOutputFilename(Opts.DependenciesFilePath, OPT_emit_dependencies,
+                          OPT_emit_dependencies_path, "d", false);
+  determineOutputFilename(
+      Opts.ReferenceDependenciesFilePath, OPT_emit_reference_dependencies,
+      OPT_emit_reference_dependencies_path, "swiftdeps", false);
   determineOutputFilename(Opts.SerializedDiagnosticsPath,
                           OPT_serialize_diagnostics,
-                          OPT_serialize_diagnostics_path,
-                          "dia", false);
-  determineOutputFilename(Opts.ObjCHeaderOutputPath,
-                          OPT_emit_objc_header,
-                          OPT_emit_objc_header_path,
-                          "h", false);
-  determineOutputFilename(Opts.LoadedModuleTracePath,
-                          OPT_emit_loaded_module_trace,
-                          OPT_emit_loaded_module_trace_path,
-                          "trace.json", false);
+                          OPT_serialize_diagnostics_path, "dia", false);
+  determineOutputFilename(Opts.ObjCHeaderOutputPath, OPT_emit_objc_header,
+                          OPT_emit_objc_header_path, "h", false);
+  determineOutputFilename(
+      Opts.LoadedModuleTracePath, OPT_emit_loaded_module_trace,
+      OPT_emit_loaded_module_trace_path, "trace.json", false);
 
   determineOutputFilename(Opts.TBDPath, OPT_emit_tbd, OPT_emit_tbd_path, "tbd",
                           false);
@@ -680,187 +853,74 @@
     Opts.FixitsOutputPath = A->getValue();
   }
 
-  bool IsSIB = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB ||
+  bool isSIB = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB ||
                Opts.RequestedAction == FrontendOptions::ActionType::EmitSIBGen;
   bool canUseMainOutputForModule =
       Opts.RequestedAction == FrontendOptions::ActionType::MergeModules ||
       Opts.RequestedAction == FrontendOptions::ActionType::EmitModuleOnly ||
-      IsSIB;
-  auto ext = IsSIB ? SIB_EXTENSION : SERIALIZED_MODULE_EXTENSION;
+      isSIB;
+  auto ext = isSIB ? SIB_EXTENSION : SERIALIZED_MODULE_EXTENSION;
   auto sibOpt = Opts.RequestedAction == FrontendOptions::ActionType::EmitSIB
                     ? OPT_emit_sib
                     : OPT_emit_sibgen;
   determineOutputFilename(Opts.ModuleOutputPath,
-                          IsSIB ? sibOpt : OPT_emit_module,
-                          OPT_emit_module_path,
-                          ext,
-                          canUseMainOutputForModule);
+                          isSIB ? sibOpt : OPT_emit_module,
+                          OPT_emit_module_path, ext, canUseMainOutputForModule);
 
-  determineOutputFilename(Opts.ModuleDocOutputPath,
-                          OPT_emit_module_doc,
+  determineOutputFilename(Opts.ModuleDocOutputPath, OPT_emit_module_doc,
                           OPT_emit_module_doc_path,
-                          SERIALIZED_MODULE_DOC_EXTENSION,
-                          false);
+                          SERIALIZED_MODULE_DOC_EXTENSION, false);
+}
 
-  if (!Opts.DependenciesFilePath.empty()) {
-    switch (Opts.RequestedAction) {
-    case FrontendOptions::ActionType::NoneAction:
-    case FrontendOptions::ActionType::DumpParse:
-    case FrontendOptions::ActionType::DumpInterfaceHash:
-    case FrontendOptions::ActionType::DumpAST:
-    case FrontendOptions::ActionType::EmitSyntax:
-    case FrontendOptions::ActionType::PrintAST:
-    case FrontendOptions::ActionType::DumpScopeMaps:
-    case FrontendOptions::ActionType::DumpTypeRefinementContexts:
-    case FrontendOptions::ActionType::Immediate:
-    case FrontendOptions::ActionType::REPL:
-      Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_dependencies);
-      return true;
-    case FrontendOptions::ActionType::Parse:
-    case FrontendOptions::ActionType::Typecheck:
-    case FrontendOptions::ActionType::MergeModules:
-    case FrontendOptions::ActionType::EmitModuleOnly:
-    case FrontendOptions::ActionType::EmitPCH:
-    case FrontendOptions::ActionType::EmitSILGen:
-    case FrontendOptions::ActionType::EmitSIL:
-    case FrontendOptions::ActionType::EmitSIBGen:
-    case FrontendOptions::ActionType::EmitSIB:
-    case FrontendOptions::ActionType::EmitIR:
-    case FrontendOptions::ActionType::EmitBC:
-    case FrontendOptions::ActionType::EmitAssembly:
-    case FrontendOptions::ActionType::EmitObject:
-    case FrontendOptions::ActionType::EmitImportedModules:
-      break;
-    }
+bool FrontendArgsToOptionsConverter::checkForUnusedOutputPaths() const {
+  if (Opts.hasUnusedDependenciesFilePath()) {
+    Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_dependencies);
+    return true;
   }
-
-  if (!Opts.ObjCHeaderOutputPath.empty()) {
-    switch (Opts.RequestedAction) {
-    case FrontendOptions::ActionType::NoneAction:
-    case FrontendOptions::ActionType::DumpParse:
-    case FrontendOptions::ActionType::DumpInterfaceHash:
-    case FrontendOptions::ActionType::DumpAST:
-    case FrontendOptions::ActionType::EmitSyntax:
-    case FrontendOptions::ActionType::PrintAST:
-    case FrontendOptions::ActionType::EmitPCH:
-    case FrontendOptions::ActionType::DumpScopeMaps:
-    case FrontendOptions::ActionType::DumpTypeRefinementContexts:
-    case FrontendOptions::ActionType::Immediate:
-    case FrontendOptions::ActionType::REPL:
-      Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_header);
-      return true;
-    case FrontendOptions::ActionType::Parse:
-    case FrontendOptions::ActionType::Typecheck:
-    case FrontendOptions::ActionType::MergeModules:
-    case FrontendOptions::ActionType::EmitModuleOnly:
-    case FrontendOptions::ActionType::EmitSILGen:
-    case FrontendOptions::ActionType::EmitSIL:
-    case FrontendOptions::ActionType::EmitSIBGen:
-    case FrontendOptions::ActionType::EmitSIB:
-    case FrontendOptions::ActionType::EmitIR:
-    case FrontendOptions::ActionType::EmitBC:
-    case FrontendOptions::ActionType::EmitAssembly:
-    case FrontendOptions::ActionType::EmitObject:
-    case FrontendOptions::ActionType::EmitImportedModules:
-      break;
-    }
+  if (Opts.hasUnusedObjCHeaderOutputPath()) {
+    Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_header);
+    return true;
   }
-
-  if (!Opts.LoadedModuleTracePath.empty()) {
-    switch (Opts.RequestedAction) {
-    case FrontendOptions::ActionType::NoneAction:
-    case FrontendOptions::ActionType::Parse:
-    case FrontendOptions::ActionType::DumpParse:
-    case FrontendOptions::ActionType::DumpInterfaceHash:
-    case FrontendOptions::ActionType::DumpAST:
-    case FrontendOptions::ActionType::EmitSyntax:
-    case FrontendOptions::ActionType::PrintAST:
-    case FrontendOptions::ActionType::DumpScopeMaps:
-    case FrontendOptions::ActionType::DumpTypeRefinementContexts:
-    case FrontendOptions::ActionType::Immediate:
-    case FrontendOptions::ActionType::REPL:
-      Diags.diagnose(SourceLoc(),
-                     diag::error_mode_cannot_emit_loaded_module_trace);
-      return true;
-    case FrontendOptions::ActionType::Typecheck:
-    case FrontendOptions::ActionType::MergeModules:
-    case FrontendOptions::ActionType::EmitModuleOnly:
-    case FrontendOptions::ActionType::EmitPCH:
-    case FrontendOptions::ActionType::EmitSILGen:
-    case FrontendOptions::ActionType::EmitSIL:
-    case FrontendOptions::ActionType::EmitSIBGen:
-    case FrontendOptions::ActionType::EmitSIB:
-    case FrontendOptions::ActionType::EmitIR:
-    case FrontendOptions::ActionType::EmitBC:
-    case FrontendOptions::ActionType::EmitAssembly:
-    case FrontendOptions::ActionType::EmitObject:
-    case FrontendOptions::ActionType::EmitImportedModules:
-      break;
-    }
+  if (Opts.hasUnusedLoadedModuleTracePath()) {
+    Diags.diagnose(SourceLoc(),
+                   diag::error_mode_cannot_emit_loaded_module_trace);
+    return true;
   }
-
-  if (!Opts.ModuleOutputPath.empty() ||
-      !Opts.ModuleDocOutputPath.empty()) {
-    switch (Opts.RequestedAction) {
-    case FrontendOptions::ActionType::NoneAction:
-    case FrontendOptions::ActionType::Parse:
-    case FrontendOptions::ActionType::Typecheck:
-    case FrontendOptions::ActionType::DumpParse:
-    case FrontendOptions::ActionType::DumpInterfaceHash:
-    case FrontendOptions::ActionType::DumpAST:
-    case FrontendOptions::ActionType::EmitSyntax:
-    case FrontendOptions::ActionType::PrintAST:
-    case FrontendOptions::ActionType::EmitPCH:
-    case FrontendOptions::ActionType::DumpScopeMaps:
-    case FrontendOptions::ActionType::DumpTypeRefinementContexts:
-    case FrontendOptions::ActionType::EmitSILGen:
-    case FrontendOptions::ActionType::Immediate:
-    case FrontendOptions::ActionType::REPL:
-      if (!Opts.ModuleOutputPath.empty())
-        Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module);
-      else
-        Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_doc);
-      return true;
-    case FrontendOptions::ActionType::MergeModules:
-    case FrontendOptions::ActionType::EmitModuleOnly:
-    case FrontendOptions::ActionType::EmitSIL:
-    case FrontendOptions::ActionType::EmitSIBGen:
-    case FrontendOptions::ActionType::EmitSIB:
-    case FrontendOptions::ActionType::EmitIR:
-    case FrontendOptions::ActionType::EmitBC:
-    case FrontendOptions::ActionType::EmitAssembly:
-    case FrontendOptions::ActionType::EmitObject:
-    case FrontendOptions::ActionType::EmitImportedModules:
-      break;
-    }
+  if (Opts.hasUnusedModuleOutputPath()) {
+    Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module);
+    return true;
   }
-
-  if (const Arg *A = Args.getLastArg(OPT_module_link_name)) {
-    Opts.ModuleLinkName = A->getValue();
+  if (Opts.hasUnusedModuleDocOutputPath()) {
+    Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_doc);
+    return true;
   }
+  return false;
+}
 
-  Opts.AlwaysSerializeDebuggingOptions |=
-      Args.hasArg(OPT_serialize_debugging_options);
-  Opts.EnableSourceImport |= Args.hasArg(OPT_enable_source_import);
-  Opts.ImportUnderlyingModule |= Args.hasArg(OPT_import_underlying_module);
-  Opts.EnableSerializationNestedTypeLookupTable &=
-      !Args.hasArg(OPT_disable_serialization_nested_type_lookup_table);
-
+void FrontendArgsToOptionsConverter::computeImportObjCHeaderOptions() {
+  using namespace options;
   if (const Arg *A = Args.getLastArgNoClaim(OPT_import_objc_header)) {
     Opts.ImplicitObjCHeaderPath = A->getValue();
     Opts.SerializeBridgingHeader |=
-        !Opts.Inputs.havePrimaryInputs() && !Opts.ModuleOutputPath.empty();
+        !Opts.Inputs.hasPrimaryInputs() && !Opts.ModuleOutputPath.empty();
   }
-
+}
+void FrontendArgsToOptionsConverter::computeImplicitImportModuleNames() {
+  using namespace options;
   for (const Arg *A : Args.filtered(OPT_import_module)) {
     Opts.ImplicitImportModuleNames.push_back(A->getValue());
   }
-
+}
+void FrontendArgsToOptionsConverter::computeLLVMArgs() {
+  using namespace options;
   for (const Arg *A : Args.filtered(OPT_Xllvm)) {
     Opts.LLVMArgs.push_back(A->getValue());
   }
+}
 
-  return false;
+static bool ParseFrontendArgs(FrontendOptions &opts, ArgList &args,
+                              DiagnosticEngine &diags) {
+  return FrontendArgsToOptionsConverter(diags, args, opts).convert();
 }
 
 static void diagnoseSwiftVersion(Optional<version::Version> &vers, Arg *verArg,
@@ -989,7 +1049,7 @@
   Opts.DebugConstraintSolver |= Args.hasArg(OPT_debug_constraints);
   Opts.EnableConstraintPropagation |= Args.hasArg(OPT_propagate_constraints);
   Opts.IterativeTypeChecker |= Args.hasArg(OPT_iterative_type_checker);
-  Opts.NamedLazyMemberLoading |= Args.hasArg(OPT_enable_named_lazy_member_loading);
+  Opts.NamedLazyMemberLoading &= !Args.hasArg(OPT_disable_named_lazy_member_loading);
   Opts.DebugGenericSignatures |= Args.hasArg(OPT_debug_generic_signatures);
 
   Opts.DebuggerSupport |= Args.hasArg(OPT_debugger_support);
@@ -1592,7 +1652,7 @@
   } else if (const Optional<StringRef> filename =
                  FrontendOpts.Inputs.getOptionalUniquePrimaryInputFilename()) {
     Opts.MainInputFilename = filename.getValue();
-  } else if (FrontendOpts.Inputs.haveUniqueInputFilename()) {
+  } else if (FrontendOpts.Inputs.hasUniqueInputFilename()) {
     Opts.MainInputFilename = FrontendOpts.Inputs.getFilenameOfFirstInput();
   }
   Opts.OutputFilenames = FrontendOpts.OutputFilenames;
@@ -1824,36 +1884,36 @@
 
 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
 CompilerInvocation::setUpInputForSILTool(
-    StringRef InputFilename, StringRef ModuleNameArg,
+    StringRef inputFilename, StringRef moduleNameArg,
     bool alwaysSetModuleToMain,
     serialization::ExtendedValidationInfo &extendedInfo) {
   // Load the input file.
-  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
-      llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
-  if (!FileBufOrErr) {
-    return FileBufOrErr;
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
+      llvm::MemoryBuffer::getFileOrSTDIN(inputFilename);
+  if (!fileBufOrErr) {
+    return fileBufOrErr;
   }
 
   // If it looks like we have an AST, set the source file kind to SIL and the
   // name of the module to the file's name.
-  addInputBuffer(FileBufOrErr.get().get());
+  addInputBuffer(fileBufOrErr.get().get());
 
   auto result = serialization::validateSerializedAST(
-      FileBufOrErr.get()->getBuffer(), &extendedInfo);
-  bool HasSerializedAST = result.status == serialization::Status::Valid;
+      fileBufOrErr.get()->getBuffer(), &extendedInfo);
+  bool hasSerializedAST = result.status == serialization::Status::Valid;
 
-  if (HasSerializedAST) {
-    const StringRef Stem = !ModuleNameArg.empty()
-                               ? ModuleNameArg
-                               : llvm::sys::path::stem(InputFilename);
-    setModuleName(Stem);
+  if (hasSerializedAST) {
+    const StringRef stem = !moduleNameArg.empty()
+                               ? moduleNameArg
+                               : llvm::sys::path::stem(inputFilename);
+    setModuleName(stem);
     setInputKind(InputFileKind::IFK_Swift_Library);
   } else {
-    const StringRef Name = (alwaysSetModuleToMain || ModuleNameArg.empty())
+    const StringRef name = (alwaysSetModuleToMain || moduleNameArg.empty())
                                ? "main"
-                               : ModuleNameArg;
-    setModuleName(Name);
+                               : moduleNameArg;
+    setModuleName(name);
     setInputKind(InputFileKind::IFK_SIL);
   }
-  return FileBufOrErr;
+  return fileBufOrErr;
 }
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index ac75c2a..ff0228a 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -111,31 +111,33 @@
                                SourceMgr, Diagnostics));
 
   if (Invocation.getFrontendOptions().EnableSourceImport) {
-    bool immediate = Invocation.getFrontendOptions().actionIsImmediate();
+    bool immediate = FrontendOptions::isActionImmediate(
+        Invocation.getFrontendOptions().RequestedAction);
     bool enableResilience = Invocation.getFrontendOptions().EnableResilience;
     Context->addModuleLoader(SourceLoader::create(*Context,
                                                   !immediate,
                                                   enableResilience,
                                                   DepTracker));
   }
-  
-  auto SML = SerializedModuleLoader::create(*Context, DepTracker);
-  this->SML = SML.get();
-  Context->addModuleLoader(std::move(SML));
-
-  // Wire up the Clang importer. If the user has specified an SDK, use it.
-  // Otherwise, we just keep it around as our interface to Clang's ABI
-  // knowledge.
-  auto clangImporter =
-    ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
-                          Invocation.getPCHHash(),
-                          DepTracker);
-  if (!clangImporter) {
-    Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
-    return true;
+  {
+    auto SML = SerializedModuleLoader::create(*Context, DepTracker);
+    this->SML = SML.get();
+    Context->addModuleLoader(std::move(SML));
   }
+  {
+    // Wire up the Clang importer. If the user has specified an SDK, use it.
+    // Otherwise, we just keep it around as our interface to Clang's ABI
+    // knowledge.
+    auto clangImporter =
+        ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
+                              Invocation.getPCHHash(), DepTracker);
+    if (!clangImporter) {
+      Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
+      return true;
+    }
 
-  Context->addModuleLoader(std::move(clangImporter), /*isClang*/true);
+    Context->addModuleLoader(std::move(clangImporter), /*isClang*/ true);
+  }
 
   assert(Lexer::isIdentifier(Invocation.getModuleName()));
 
@@ -272,6 +274,7 @@
   Context->LoadedModules[MainModule->getName()] = getMainModule();
 
   if (Invocation.getInputKind() == InputFileKind::IFK_SIL) {
+    assert(!InputSourceCodeBufferIDs.empty());
     assert(InputSourceCodeBufferIDs.size() == 1);
     assert(MainBufferID != NO_SUCH_BUFFER);
     createSILModule();
@@ -389,11 +392,11 @@
 
 void CompilerInstance::createREPLFile(
     const ImplicitImports &implicitImports) const {
-  auto *SingleInputFile = new (*Context) SourceFile(
+  auto *singleInputFile = new (*Context) SourceFile(
       *MainModule, Invocation.getSourceFileKind(), None, implicitImports.kind,
       Invocation.getLangOptions().KeepSyntaxInfoInSourceFile);
-  MainModule->addFile(*SingleInputFile);
-  addAdditionalInitialImportsTo(SingleInputFile, implicitImports);
+  MainModule->addFile(*singleInputFile);
+  addAdditionalInitialImportsTo(singleInputFile, implicitImports);
 }
 
 std::unique_ptr<DelayedParsingCallbacks>
@@ -533,7 +536,7 @@
   if (options.DebugTimeFunctionBodies) {
     TypeCheckOptions |= TypeCheckingFlags::DebugTimeFunctionBodies;
   }
-  if (options.actionIsImmediate()) {
+  if (FrontendOptions::isActionImmediate(options.RequestedAction)) {
     TypeCheckOptions |= TypeCheckingFlags::ForImmediateMode;
   }
   if (options.DebugTimeExpressionTypeChecking) {
@@ -626,8 +629,8 @@
 static void
 forEachSourceFileIn(ModuleDecl *module,
                     llvm::function_ref<void(SourceFile &)> fn) {
-  for (auto File : module->getFiles()) {
-    if (auto SF = dyn_cast<SourceFile>(File))
+  for (auto file : module->getFiles()) {
+    if (auto SF = dyn_cast<SourceFile>(file))
       fn(*SF);
   }
 }
@@ -740,7 +743,7 @@
     if (SILMode || (MainMode && filename(File) == "main.swift"))
       MainBufferID = ExistingBufferID.getValue();
 
-    if (Invocation.getFrontendOptions().Inputs.isPrimaryInputAFileAt(i))
+    if (Invocation.getFrontendOptions().Inputs.isInputPrimary(i))
       PrimaryBufferID = ExistingBufferID.getValue();
 
     return false; // replaced by a memory buffer.
@@ -782,7 +785,7 @@
   if (SILMode || (MainMode && filename(File) == "main.swift"))
     MainBufferID = BufferID;
 
-  if (Invocation.getFrontendOptions().Inputs.isPrimaryInputAFileAt(i))
+  if (Invocation.getFrontendOptions().Inputs.isInputPrimary(i))
     PrimaryBufferID = BufferID;
 
   return false;
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index 8ef2d3d..24ffd12 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -28,7 +28,7 @@
 using namespace llvm::opt;
 
 bool FrontendInputs::shouldTreatAsLLVM() const {
-  if (haveUniqueInputFilename()) {
+  if (hasUniqueInputFilename()) {
     StringRef Input(getFilenameOfFirstInput());
     return llvm::sys::path::extension(Input).endswith(LLVM_BC_EXTENSION) ||
            llvm::sys::path::extension(Input).endswith(LLVM_IR_EXTENSION);
@@ -36,21 +36,8 @@
   return false;
 }
 
-StringRef FrontendInputs::baseNameOfOutput(const llvm::opt::ArgList &Args,
-                                           StringRef ModuleName) const {
-  StringRef pifn = primaryInputFilenameIfAny();
-  if (!pifn.empty()) {
-    return llvm::sys::path::stem(pifn);
-  }
-  bool UserSpecifiedModuleName = Args.getLastArg(options::OPT_module_name);
-  if (!UserSpecifiedModuleName && haveUniqueInputFilename()) {
-    return llvm::sys::path::stem(getFilenameOfFirstInput());
-  }
-  return ModuleName;
-}
-
 bool FrontendInputs::shouldTreatAsSIL() const {
-  if (haveUniqueInputFilename()) {
+  if (hasUniqueInputFilename()) {
     // If we have exactly one input filename, and its extension is "sil",
     // treat the input as SIL.
     StringRef Input(getFilenameOfFirstInput());
@@ -66,36 +53,36 @@
   return false;
 }
 
-bool FrontendInputs::verifyInputs(DiagnosticEngine &Diags, bool TreatAsSIL,
+bool FrontendInputs::verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
                                   bool isREPLRequested,
                                   bool isNoneRequested) const {
   if (isREPLRequested) {
-    if (haveInputFilenames()) {
-      Diags.diagnose(SourceLoc(), diag::error_repl_requires_no_input_files);
+    if (hasInputFilenames()) {
+      diags.diagnose(SourceLoc(), diag::error_repl_requires_no_input_files);
       return true;
     }
-  } else if (TreatAsSIL && havePrimaryInputs()) {
+  } else if (treatAsSIL && hasPrimaryInputs()) {
     // If we have the SIL as our primary input, we can waive the one file
     // requirement as long as all the other inputs are SIBs.
     for (unsigned i = 0, e = inputFilenameCount(); i != e; ++i) {
       if (i == getOptionalUniquePrimaryInput()->Index)
         continue;
 
-      StringRef File(getInputFilenames()[i]);
-      if (!llvm::sys::path::extension(File).endswith(SIB_EXTENSION)) {
-        Diags.diagnose(SourceLoc(),
+      StringRef file(getInputFilenames()[i]);
+      if (!llvm::sys::path::extension(file).endswith(SIB_EXTENSION)) {
+        diags.diagnose(SourceLoc(),
                        diag::error_mode_requires_one_sil_multi_sib);
         return true;
       }
     }
-  } else if (TreatAsSIL) {
-    if (!haveUniqueInputFilename()) {
-      Diags.diagnose(SourceLoc(), diag::error_mode_requires_one_input_file);
+  } else if (treatAsSIL) {
+    if (!hasUniqueInputFilename()) {
+      diags.diagnose(SourceLoc(), diag::error_mode_requires_one_input_file);
       return true;
     }
   } else if (!isNoneRequested) {
-    if (!haveInputFilenames()) {
-      Diags.diagnose(SourceLoc(), diag::error_mode_requires_an_input_file);
+    if (!hasInputFilenames()) {
+      diags.diagnose(SourceLoc(), diag::error_mode_requires_an_input_file);
       return true;
     }
   }
@@ -109,8 +96,8 @@
   }
 }
 
-bool FrontendOptions::actionHasOutput() const {
-  switch (RequestedAction) {
+bool FrontendOptions::needsProperModuleName(ActionType action) {
+  switch (action) {
   case ActionType::NoneAction:
   case ActionType::Parse:
   case ActionType::Typecheck:
@@ -143,8 +130,8 @@
   llvm_unreachable("Unknown ActionType");
 }
 
-bool FrontendOptions::actionIsImmediate() const {
-  switch (RequestedAction) {
+bool FrontendOptions::isActionImmediate(ActionType action) {
+  switch (action) {
   case ActionType::NoneAction:
   case ActionType::Parse:
   case ActionType::Typecheck:
@@ -195,37 +182,9 @@
   }
 }
 
-void FrontendOptions::setModuleName(DiagnosticEngine &Diags,
-                                    const llvm::opt::ArgList &Args) {
-  const Arg *A = Args.getLastArg(options::OPT_module_name);
-  if (A) {
-    ModuleName = A->getValue();
-  } else if (ModuleName.empty()) {
-    // The user did not specify a module name, so determine a default fallback
-    // based on other options.
-
-    // Note: this code path will only be taken when running the frontend
-    // directly; the driver should always pass -module-name when invoking the
-    // frontend.
-    ModuleName = determineFallbackModuleName();
-  }
-
-  if (Lexer::isIdentifier(ModuleName) &&
-      (ModuleName != STDLIB_NAME || ParseStdlib)) {
-    return;
-  }
-  if (!actionHasOutput() || isCompilingExactlyOneSwiftFile()) {
-    ModuleName = "main";
-    return;
-  }
-  auto DID = (ModuleName == STDLIB_NAME) ? diag::error_stdlib_module_name
-                                         : diag::error_bad_module_name;
-  Diags.diagnose(SourceLoc(), DID, ModuleName, A == nullptr);
-  ModuleName = "__bad__";
-}
 
 StringRef FrontendOptions::originalPath() const {
-  if (haveNamedOutputFile())
+  if (hasNamedOutputFile())
     // Put the serialized diagnostics file next to the output file.
     return getSingleOutputFilename();
 
@@ -236,57 +195,276 @@
   return !fn.empty() ? llvm::sys::path::filename(fn) : StringRef(ModuleName);
 }
 
-StringRef FrontendOptions::determineFallbackModuleName() const {
-  // Note: this code path will only be taken when running the frontend
-  // directly; the driver should always pass -module-name when invoking the
-  // frontend.
-  if (RequestedAction == FrontendOptions::ActionType::REPL) {
-    // Default to a module named "REPL" if we're in REPL mode.
-    return "REPL";
-  }
-  // In order to pass Driver/options.swift test must leave ModuleName empty
-  if (!Inputs.haveInputFilenames()) {
-    return StringRef();
-  }
-  StringRef OutputFilename = getSingleOutputFilename();
-  bool useOutputFilename = isOutputFilePlainFile();
-  return llvm::sys::path::stem(
-      useOutputFilename ? OutputFilename
-                        : StringRef(Inputs.getFilenameOfFirstInput()));
-}
-
-/// Try to read an output file list file.
-static void readOutputFileList(DiagnosticEngine &diags,
-                               std::vector<std::string> &outputFiles,
-                               const llvm::opt::Arg *filelistPath) {
-  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
-      llvm::MemoryBuffer::getFile(filelistPath->getValue());
-  if (!buffer) {
-    diags.diagnose(SourceLoc(), diag::cannot_open_file,
-                   filelistPath->getValue(), buffer.getError().message());
-  }
-  for (StringRef line : make_range(llvm::line_iterator(*buffer.get()), {})) {
-    outputFiles.push_back(line);
-  }
-}
-
-void FrontendOptions::setOutputFileList(swift::DiagnosticEngine &Diags,
-                                        const llvm::opt::ArgList &Args) {
-  if (const Arg *A = Args.getLastArg(options::OPT_output_filelist)) {
-    readOutputFileList(Diags, OutputFilenames, A);
-    assert(!Args.hasArg(options::OPT_o) &&
-           "don't use -o with -output-filelist");
-  } else {
-    OutputFilenames = Args.getAllArgValues(options::OPT_o);
-  }
-}
-
 bool FrontendOptions::isOutputFileDirectory() const {
-  return haveNamedOutputFile() &&
+  return hasNamedOutputFile() &&
          llvm::sys::fs::is_directory(getSingleOutputFilename());
 }
 
-bool FrontendOptions::isOutputFilePlainFile() const {
-  return haveNamedOutputFile() &&
-         !llvm::sys::fs::is_directory(getSingleOutputFilename());
+const char *
+FrontendOptions::suffixForPrincipalOutputFileForAction(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+    return nullptr;
+
+  case ActionType::Parse:
+  case ActionType::Typecheck:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+    return nullptr;
+
+  case ActionType::EmitPCH:
+    return PCH_EXTENSION;
+
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIL:
+    return SIL_EXTENSION;
+
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+    return SIB_EXTENSION;
+
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+    return SERIALIZED_MODULE_EXTENSION;
+
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    // These modes have no frontend-generated output.
+    return nullptr;
+
+  case ActionType::EmitAssembly:
+    return "s";
+
+  case ActionType::EmitIR:
+    return "ll";
+
+  case ActionType::EmitBC:
+    return "bc";
+
+  case ActionType::EmitObject:
+    return "o";
+
+  case ActionType::EmitImportedModules:
+    return "importedmodules";
+  }
+}
+
+bool FrontendOptions::hasUnusedDependenciesFilePath() const {
+  return !DependenciesFilePath.empty() &&
+         !canActionEmitDependencies(RequestedAction);
+}
+
+bool FrontendOptions::canActionEmitDependencies(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    return false;
+  case ActionType::Parse:
+  case ActionType::Typecheck:
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+  case ActionType::EmitPCH:
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIL:
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+  case ActionType::EmitIR:
+  case ActionType::EmitBC:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitObject:
+  case ActionType::EmitImportedModules:
+    return true;
+  }
+}
+
+bool FrontendOptions::hasUnusedObjCHeaderOutputPath() const {
+  return !ObjCHeaderOutputPath.empty() && !canActionEmitHeader(RequestedAction);
+}
+
+bool FrontendOptions::canActionEmitHeader(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::EmitPCH:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    return false;
+  case ActionType::Parse:
+  case ActionType::Typecheck:
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIL:
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+  case ActionType::EmitIR:
+  case ActionType::EmitBC:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitObject:
+  case ActionType::EmitImportedModules:
+    return true;
+  }
+}
+
+bool FrontendOptions::hasUnusedLoadedModuleTracePath() const {
+  return !LoadedModuleTracePath.empty() &&
+         !canActionEmitLoadedModuleTrace(RequestedAction);
+}
+
+bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+  case ActionType::Parse:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    return false;
+  case ActionType::Typecheck:
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+  case ActionType::EmitPCH:
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIL:
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+  case ActionType::EmitIR:
+  case ActionType::EmitBC:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitObject:
+  case ActionType::EmitImportedModules:
+    return true;
+  }
+}
+
+bool FrontendOptions::hasUnusedModuleOutputPath() const {
+  return !ModuleOutputPath.empty() && !canActionEmitModule(RequestedAction);
+}
+
+bool FrontendOptions::hasUnusedModuleDocOutputPath() const {
+  return !ModuleDocOutputPath.empty() && !canActionEmitModule(RequestedAction);
+}
+
+bool FrontendOptions::canActionEmitModule(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+  case ActionType::Parse:
+  case ActionType::Typecheck:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::EmitPCH:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::EmitSILGen:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    return false;
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+  case ActionType::EmitSIL:
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+  case ActionType::EmitIR:
+  case ActionType::EmitBC:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitObject:
+  case ActionType::EmitImportedModules:
+    return true;
+  }
+}
+
+bool FrontendOptions::canActionEmitModuleDoc(ActionType action) {
+  return canActionEmitModule(action);
+}
+
+bool FrontendOptions::doesActionProduceOutput(ActionType action) {
+  switch (action) {
+  case ActionType::Parse:
+  case ActionType::Typecheck:
+  case ActionType::DumpParse:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::PrintAST:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::EmitPCH:
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIL:
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+  case ActionType::EmitModuleOnly:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitIR:
+  case ActionType::EmitBC:
+  case ActionType::EmitObject:
+  case ActionType::EmitImportedModules:
+  case ActionType::MergeModules:
+    return true;
+
+  case ActionType::NoneAction:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    return false;
+  }
+  llvm_unreachable("Unknown ActionType");
+}
+
+bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+  case ActionType::EmitPCH:
+  case ActionType::EmitSIBGen:
+  case ActionType::EmitSIB:
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+  case ActionType::EmitBC:
+  case ActionType::EmitObject:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+    return false;
+
+  case ActionType::Parse:
+  case ActionType::Typecheck:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::EmitImportedModules:
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIL:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitIR:
+    return true;
+  }
 }
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index 105179d..aa034a2 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -541,7 +541,7 @@
     auto &LLVMContext = getGlobalLLVMContext();
 
     // Load in bitcode file.
-    assert(Invocation.getFrontendOptions().Inputs.haveUniqueInputFilename() &&
+    assert(Invocation.getFrontendOptions().Inputs.hasUniqueInputFilename() &&
            "We expect a single input for bitcode input!");
     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
         llvm::MemoryBuffer::getFileOrSTDIN(
@@ -776,7 +776,7 @@
       auto SASTF = dyn_cast<SerializedASTFile>(File);
       return SASTF && SASTF->isSIB();
     };
-    if (opts.Inputs.haveAPrimaryInputFile()) {
+    if (opts.Inputs.hasAPrimaryInputFile()) {
       FileUnit *PrimaryFile = PrimarySourceFile;
       if (!PrimaryFile) {
         auto Index = opts.Inputs.getRequiredUniquePrimaryInput().Index;
diff --git a/lib/IDE/CommentConversion.cpp b/lib/IDE/CommentConversion.cpp
index 25074e0..44cb237 100644
--- a/lib/IDE/CommentConversion.cpp
+++ b/lib/IDE/CommentConversion.cpp
@@ -408,14 +408,15 @@
   std::string S;
   llvm::raw_string_ostream SS(S);
   D->print(SS, Options);
-  std::string Signature = SS.str();
   auto OI = Doc.find(Open);
   auto CI = Doc.find(Close);
-  if (StringRef::npos != OI && StringRef::npos != CI && CI > OI)
-    OS << Doc.substr(0, OI) << Open << Signature << Close <<
-      Doc.substr(CI + Close.size());
-  else
+  if (StringRef::npos != OI && StringRef::npos != CI && CI > OI) {
+    OS << Doc.substr(0, OI) << Open;
+    appendWithXMLEscaping(OS, SS.str());
+    OS << Close << Doc.substr(CI + Close.size());
+  } else {
     OS << Doc;
+  }
 }
 
 static LineList getLineListFromComment(SourceManager &SourceMgr,
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index 3c75375..1ba8af9 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -435,11 +435,23 @@
         } while (!shouldSkip(E));
         break;
       case ExprKind::Subscript: {
-        auto Labels = getCallArgLabelRanges(getSourceMgr(),
-                                            cast<SubscriptExpr>(E)->getIndex(),
+        auto SubExpr = cast<SubscriptExpr>(E);
+        // visit and check in source order
+        if (!SubExpr->getBase()->walk(*this))
+          return {false, nullptr};
+
+        auto Labels = getCallArgLabelRanges(getSourceMgr(), SubExpr->getIndex(),
                                             LabelRangeEndAt::BeforeElemStart);
         tryResolve(ASTWalker::ParentTy(E), E->getLoc(), LabelRangeType::CallArg, Labels);
-        break;
+        if (isDone())
+            break;
+        if (!SubExpr->getIndex()->walk(*this))
+          return {false, nullptr};
+
+        // We already visited the children.
+        if (!walkToExprPost(E))
+          return {false, nullptr};
+        return {false, E};
       }
       case ExprKind::Tuple: {
         TupleExpr *T = cast<TupleExpr>(E);
diff --git a/lib/IRGen/AllocStackHoisting.cpp b/lib/IRGen/AllocStackHoisting.cpp
index 5c47e78..acb15f7 100644
--- a/lib/IRGen/AllocStackHoisting.cpp
+++ b/lib/IRGen/AllocStackHoisting.cpp
@@ -103,7 +103,7 @@
                           AllocStackInst *AllocStack) {
   // Insert dealloc_stack in the exit blocks.
   for (auto *Exit : FunctionExits) {
-    SILBuilder Builder(Exit);
+    SILBuilderWithScope Builder(Exit);
     Builder.createDeallocStack(AllocStack->getLoc(), AllocStack);
   }
 }
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index ce5891f..2496ed5 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -2108,10 +2108,14 @@
                                      IGM.getPointerAlignment(),
                                      /*constant*/ true,
                                      llvm::GlobalVariable::PrivateLinkage);
+
       switch (IGM.TargetInfo.OutputObjectFormat) {
       case llvm::Triple::MachO:
         var->setSection("__DATA, __objc_const");
         break;
+      case llvm::Triple::COFF:
+        var->setSection(".data");
+        break;
       case llvm::Triple::ELF:
         var->setSection(".data");
         break;
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 618ecd6..5ce97a6 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -770,31 +770,82 @@
   }
 }
 
+std::string IRGenModule::GetObjCSectionName(StringRef Section,
+                                            StringRef MachOAttributes) {
+  assert(Section.substr(0, 2) == "__" && "expected the name to begin with __");
+
+  switch (TargetInfo.OutputObjectFormat) {
+  case llvm::Triple::UnknownObjectFormat:
+    llvm_unreachable("must know the object file format");
+  case llvm::Triple::MachO:
+    return MachOAttributes.empty()
+               ? ("__DATA," + Section).str()
+               : ("__DATA," + Section + "," + MachOAttributes).str();
+  case llvm::Triple::ELF:
+    return Section.substr(2).str();
+  case llvm::Triple::COFF:
+    return ("." + Section.substr(2) + "$B").str();
+  case llvm::Triple::Wasm:
+    error(SourceLoc(), "wasm is not a supported object file format");
+  }
+
+  llvm_unreachable("unexpected object file format");
+}
+
+void IRGenModule::SetCStringLiteralSection(llvm::GlobalVariable *GV,
+                                           ObjCLabelType Type) {
+  switch (TargetInfo.OutputObjectFormat) {
+  case llvm::Triple::UnknownObjectFormat:
+    llvm_unreachable("must know the object file format");
+  case llvm::Triple::MachO:
+    switch (Type) {
+    case ObjCLabelType::ClassName:
+      GV->setSection("__TEXT,__objc_classname,cstring_literals");
+      return;
+    case ObjCLabelType::MethodVarName:
+      GV->setSection("__TEXT,__objc_methname,cstring_literals");
+      return;
+    case ObjCLabelType::MethodVarType:
+      GV->setSection("__TEXT,__objc_methtype,cstring_literals");
+      return;
+    case ObjCLabelType::PropertyName:
+      GV->setSection("__TEXT,__cstring,cstring_literals");
+      return;
+    }
+  case llvm::Triple::ELF:
+    return;
+  case llvm::Triple::COFF:
+    return;
+  case llvm::Triple::Wasm:
+    error(SourceLoc(), "wasm is not a supported object file format");
+    return;
+  }
+
+  llvm_unreachable("unexpected object file format");
+}
+
 void IRGenModule::emitGlobalLists() {
   if (ObjCInterop) {
-    assert(TargetInfo.OutputObjectFormat == llvm::Triple::MachO);
     // Objective-C class references go in a variable with a meaningless
     // name but a magic section.
     emitGlobalList(*this, ObjCClasses, "objc_classes",
-                   "__DATA, __objc_classlist, regular, no_dead_strip",
-                   llvm::GlobalValue::InternalLinkage,
-                   Int8PtrTy,
-                   false);
+                   GetObjCSectionName("__objc_classlist",
+                                      "regular,no_dead_strip"),
+                   llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
+
     // So do categories.
     emitGlobalList(*this, ObjCCategories, "objc_categories",
-                   "__DATA, __objc_catlist, regular, no_dead_strip",
-                   llvm::GlobalValue::InternalLinkage,
-                   Int8PtrTy,
-                   false);
+                   GetObjCSectionName("__objc_catlist",
+                                      "regular,no_dead_strip"),
+                   llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
 
     // Emit nonlazily realized class references in a second magic section to make
     // sure they are realized by the Objective-C runtime before any instances
     // are allocated.
     emitGlobalList(*this, ObjCNonLazyClasses, "objc_non_lazy_classes",
-                   "__DATA, __objc_nlclslist, regular, no_dead_strip",
-                   llvm::GlobalValue::InternalLinkage,
-                   Int8PtrTy,
-                   false);
+                   GetObjCSectionName("__objc_nlclslist",
+                                      "regular,no_dead_strip"),
+                   llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
   }
 
   // @llvm.used
@@ -2288,7 +2339,8 @@
     auto flags = typeEntity.flags;
     llvm::Constant *witnessTableVar;
     if (!isResilient(conformance->getProtocol(),
-                     ResilienceExpansion::Maximal)) {
+                     ResilienceExpansion::Maximal) &&
+        conformance->getConditionalRequirements().empty()) {
       flags = flags.withConformanceKind(
           ProtocolConformanceReferenceKind::WitnessTable);
 
@@ -2297,8 +2349,13 @@
       // it.
       witnessTableVar = getAddrOfWitnessTable(conformance);
     } else {
-      flags = flags.withConformanceKind(
-          ProtocolConformanceReferenceKind::WitnessTableAccessor);
+      if (conformance->getConditionalRequirements().empty()) {
+        flags = flags.withConformanceKind(
+            ProtocolConformanceReferenceKind::WitnessTableAccessor);
+      } else {
+        flags = flags.withConformanceKind(
+            ProtocolConformanceReferenceKind::ConditionalWitnessTableAccessor);
+      }
 
       witnessTableVar = getAddrOfWitnessTableAccessFunction(
           conformance, ForDefinition);
@@ -2422,7 +2479,8 @@
   // Define it lazily.
   if (auto global = dyn_cast<llvm::GlobalVariable>(addr)) {
     if (global->isDeclaration()) {
-      global->setSection("__DATA,__objc_classrefs,regular,no_dead_strip");
+      global->setSection(GetObjCSectionName("__objc_classrefs",
+                                            "regular,no_dead_strip"));
       global->setLinkage(llvm::GlobalVariable::PrivateLinkage);
       global->setExternallyInitialized(true);
       global->setInitializer(getAddrOfObjCClass(theClass, NotForDefinition));
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index 3285596..7776b2d 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -945,7 +945,7 @@
         llvm::MapVector<CanType, llvm::Value *> &typeToMetadataVec,
         SILType T) const override {
       auto canType = T.getSwiftRValueType();
-      assert(!canType->hasArchetype() &&
+      assert(!canType->is<ArchetypeType>() &&
              "collectArchetypeMetadata: no archetype expected here");
     }
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 30a36da..d2c5485 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -3939,7 +3939,8 @@
   bool isIndirect = false;
 
   StringRef section{};
-  if (classDecl->isObjC())
+  if (classDecl->isObjC() &&
+      IGM.TargetInfo.OutputObjectFormat == llvm::Triple::MachO)
     section = "__DATA,__objc_data, regular";
 
   auto var = IGM.defineTypeMetadata(declaredType, isIndirect, isPattern,
diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp
index a62f3e1..e5d75d1 100644
--- a/lib/IRGen/GenObjC.cpp
+++ b/lib/IRGen/GenObjC.cpp
@@ -329,7 +329,7 @@
                                          llvm::GlobalValue::PrivateLinkage,
                                          init,
                           llvm::Twine("\01L_selector_data(") + selector + ")");
-  global->setSection("__TEXT,__objc_methname,cstring_literals");
+  SetCStringLiteralSection(global, ObjCLabelType::MethodVarName);
   global->setAlignment(1);
   addCompilerUsedGlobal(global);
 
@@ -364,7 +364,8 @@
   global->setAlignment(getPointerAlignment().getValue());
 
   // This section name is magical for the Darwin static and dynamic linkers.
-  global->setSection("__DATA,__objc_selrefs,literal_pointers,no_dead_strip");
+  global->setSection(GetObjCSectionName("__objc_selrefs",
+                                        "literal_pointers,no_dead_strip"));
 
   // Make sure that this reference does not get optimized away.
   addCompilerUsedGlobal(global);
@@ -426,19 +427,19 @@
                                  + protocolName);
   protocolLabel->setAlignment(getPointerAlignment().getValue());
   protocolLabel->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  protocolLabel->setSection("__DATA,__objc_protolist,coalesced,no_dead_strip");
-  
+  protocolLabel->setSection(GetObjCSectionName("__objc_protolist",
+                                               "coalesced,no_dead_strip"));
+
   // Introduce a variable to reference the protocol.
-  auto *protocolRef
-    = new llvm::GlobalVariable(Module, Int8PtrTy,
-                               /*constant*/ false,
+  auto *protocolRef =
+      new llvm::GlobalVariable(Module, Int8PtrTy, /*constant*/ false,
                                llvm::GlobalValue::WeakAnyLinkage,
                                protocolRecord,
-                               llvm::Twine("\01l_OBJC_PROTOCOL_REFERENCE_$_")
-                                 + protocolName);
+                               llvm::Twine("\01l_OBJC_PROTOCOL_REFERENCE_$_") + protocolName);
   protocolRef->setAlignment(getPointerAlignment().getValue());
   protocolRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  protocolRef->setSection("__DATA,__objc_protorefs,coalesced,no_dead_strip");
+  protocolRef->setSection(GetObjCSectionName("__objc_protorefs",
+                                             "coalesced,no_dead_strip"));
 
   ObjCProtocolPair pair{protocolRecord, protocolRef};
   ObjCProtocols.insert({proto, pair});
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index 22c1df0..84247a4 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -1397,6 +1397,5 @@
     llvm::MapVector<CanType, llvm::Value *> &typeToMetadataVec,
     SILType T) const {
   auto canType = T.getSwiftRValueType();
-  assert(!canType->getWithoutSpecifierType()->is<ArchetypeType>() &&
-         "Did not expect an ArchetypeType");
+  assert(!canType->is<ArchetypeType>() && "Did not expect an ArchetypeType");
 }
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 430fb0a..71f52c5 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -587,6 +587,16 @@
   Size getAtomicBoolSize() const { return AtomicBoolSize; }
   Alignment getAtomicBoolAlignment() const { return AtomicBoolAlign; }
 
+  enum class ObjCLabelType {
+    ClassName,
+    MethodVarName,
+    MethodVarType,
+    PropertyName,
+  };
+
+  std::string GetObjCSectionName(StringRef Section, StringRef MachOAttributes);
+  void SetCStringLiteralSection(llvm::GlobalVariable *GV, ObjCLabelType Type);
+
 private:
   Size PtrSize;
   Size AtomicBoolSize;
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index c14f367..8103061 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -3488,11 +3488,12 @@
     return;
 
   bool IsAnonymous = false;
+  bool IsLoadablyByAddress = isa<AllocStackInst>(SILVal);
   StringRef Name = getVarName(i, IsAnonymous);
   auto Addr = getLoweredAddress(SILVal).getAddress();
   SILType SILTy = SILVal->getType();
   auto RealType = SILTy.getSwiftRValueType();
-  if (SILTy.isAddress())
+  if (SILTy.isAddress() && !IsLoadablyByAddress)
     RealType = CanInOutType::get(RealType);
   // Unwrap implicitly indirect types and types that are passed by
   // reference only at the SIL level and below.
@@ -3512,7 +3513,8 @@
   emitDebugVariableDeclaration(
       emitShadowCopy(Addr, i->getDebugScope(), Name, ArgNo, IsAnonymous), DbgTy,
       SILType(), i->getDebugScope(), Decl, Name, ArgNo,
-      DbgTy.isImplicitlyIndirect() ? DirectValue : IndirectValue);
+      (IsLoadablyByAddress || DbgTy.isImplicitlyIndirect()) ? DirectValue
+                                                            : IndirectValue);
 }
 
 void IRGenSILFunction::visitLoadWeakInst(swift::LoadWeakInst *i) {
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index a2fd72f..411589e 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -867,16 +867,16 @@
     LoadInst *optimizableLoad) {
   SILValue value = optimizableLoad->getOperand();
 
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   AllocStackInst *allocInstr =
       allocBuilder.createAllocStack(value.getLoc(), value->getType());
 
-  SILBuilder outlinedBuilder(optimizableLoad);
+  SILBuilderWithScope outlinedBuilder(optimizableLoad);
   createOutlinedCopyCall(outlinedBuilder, value, allocInstr, pass);
 
   // Insert stack deallocations.
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 
@@ -994,16 +994,16 @@
   }
   SILValue value = unoptimizableLoad->getOperand();
 
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   AllocStackInst *allocInstr =
       allocBuilder.createAllocStack(value.getLoc(), value->getType());
 
-  SILBuilder outlinedBuilder(unoptimizableLoad);
+  SILBuilderWithScope outlinedBuilder(unoptimizableLoad);
   createOutlinedCopyCall(outlinedBuilder, value, allocInstr, pass);
 
   // Insert stack deallocations.
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 
@@ -1175,7 +1175,7 @@
 
 void LoadableStorageAllocation::convertIndirectFunctionArgs() {
   SILBasicBlock *entry = pass.F->getEntryBlock();
-  SILBuilder argBuilder(entry->begin());
+  SILBuilderWithScope argBuilder(entry->begin());
 
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
   auto loweredTy = pass.F->getLoweredFunctionType();
@@ -1268,7 +1268,7 @@
       } else {
         auto tryApplyIns = cast<TryApplyInst>(currIns);
         auto *normalBB = tryApplyIns->getNormalBB();
-        SILBuilder argBuilder(normalBB->begin());
+        SILBuilderWithScope argBuilder(normalBB->begin());
         assert(normalBB->getNumArguments() == 1 &&
                "Expected only one arg for try_apply normal BB");
         auto arg = normalBB->getArgument(0);
@@ -1284,7 +1284,7 @@
 void LoadableStorageAllocation::
     convertIndirectFunctionPointerArgsForUnmodifiable() {
   SILBasicBlock *entry = pass.F->getEntryBlock();
-  SILBuilder argBuilder(entry->begin());
+  SILBuilderWithScope argBuilder(entry->begin());
 
   for (SILArgument *arg : entry->getArguments()) {
     SILType storageType = arg->getType();
@@ -1317,7 +1317,7 @@
       // Already took care of function args
       continue;
     }
-    SILBuilder argBuilder(BB.begin());
+    SILBuilderWithScope argBuilder(BB.begin());
     for (SILArgument *arg : BB.getArguments()) {
       if (!shouldConvertBBArg(arg, pass.Mod)) {
         continue;
@@ -1343,7 +1343,7 @@
     auto *applyInst = pass.allocToApplyRetMap[allocInstr];
     assert(applyInst && "Value is not an apply");
     auto II = applyInst->getIterator();
-    SILBuilder loadBuilder(II);
+    SILBuilderWithScope loadBuilder(II);
     if (auto *tryApply = dyn_cast<TryApplyInst>(applyInst)) {
       auto *tgtBB = tryApply->getNormalBB();
       assert(tgtBB && "Could not find try apply's target BB");
@@ -1352,7 +1352,7 @@
       ++II;
       loadBuilder.setInsertionPoint(II);
     }
-    if (pass.F->hasUnqualifiedOwnership()) {
+    if (!pass.F->hasQualifiedOwnership()) {
       load = loadBuilder.createLoad(applyInst->getLoc(), value,
                                     LoadOwnershipQualifier::Unqualified);
     } else {
@@ -1365,7 +1365,7 @@
 
   assert(!ApplySite::isa(value) && "Unexpected instruction");
 
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   AllocStackInst *allocInstr =
       allocBuilder.createAllocStack(value.getLoc(), value->getType());
 
@@ -1373,7 +1373,7 @@
   auto *applyOutlinedCopy =
       createOutlinedCopyCall(allocBuilder, value, allocInstr, pass);
 
-  if (pass.F->hasUnqualifiedOwnership()) {
+  if (!pass.F->hasQualifiedOwnership()) {
     loadCopy = allocBuilder.createLoad(applyOutlinedCopy->getLoc(), allocInstr,
                                        LoadOwnershipQualifier::Unqualified);
   } else {
@@ -1384,7 +1384,7 @@
 
   // Insert stack deallocations.
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 }
@@ -1392,7 +1392,7 @@
 AllocStackInst *
 LoadableStorageAllocation::allocateForApply(SILInstruction *apply,
                                             SILType type) {
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   auto *allocInstr = allocBuilder.createAllocStack(apply->getLoc(), type);
 
   pass.largeLoadableArgs.push_back(allocInstr);
@@ -1400,7 +1400,7 @@
   pass.applyRetToAllocMap[apply] = allocInstr;
 
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 
@@ -1461,10 +1461,15 @@
       assert(std::find(pass.storeInstsToMod.begin(), pass.storeInstsToMod.end(),
                        storeUser) == pass.storeInstsToMod.end() &&
              "Did not expect this instr in storeInstsToMod");
-      SILBuilder copyBuilder(storeUser);
+      SILBuilderWithScope copyBuilder(storeUser);
       SILValue tgt = storeUser->getDest();
       createOutlinedCopyCall(copyBuilder, allocInstr, tgt, 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);
+      dbgInst->eraseFromParent();
     }
   }
 }
@@ -1472,13 +1477,13 @@
 static void allocateAndSetForInstrOperand(StructLoweringState &pass,
                                           SingleValueInstruction *instrOperand){
   assert(instrOperand->getType().isObject());
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   AllocStackInst *allocInstr = allocBuilder.createAllocStack(
       instrOperand->getLoc(), instrOperand->getType());
 
   auto II = instrOperand->getIterator();
   ++II;
-  SILBuilder storeBuilder(II);
+  SILBuilderWithScope storeBuilder(II);
   StoreInst *store = nullptr;
   if (pass.F->hasQualifiedOwnership()) {
     store = storeBuilder.createStore(instrOperand->getLoc(), instrOperand,
@@ -1491,7 +1496,7 @@
 
   // Insert stack deallocations.
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 
@@ -1506,7 +1511,7 @@
   auto *arg = dyn_cast<SILArgument>(value);
   assert(arg && "non-instr operand must be an argument");
 
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   AllocStackInst *allocInstr =
       allocBuilder.createAllocStack(applyInst->getLoc(), value->getType());
 
@@ -1515,20 +1520,22 @@
     // Store should happen *after* allocInstr
     ++storeIt;
   }
-  SILBuilder storeBuilder(storeIt);
+  SILBuilderWithScope storeBuilder(storeIt);
+  SILLocation Loc = applyInst->getLoc();
+  Loc.markAutoGenerated();
 
   StoreInst *store = nullptr;
   if (pass.F->hasQualifiedOwnership()) {
-    store = storeBuilder.createStore(applyInst->getLoc(), value, allocInstr,
+    store = storeBuilder.createStore(Loc, value, allocInstr,
                                      StoreOwnershipQualifier::Init);
   } else {
-    store = storeBuilder.createStore(applyInst->getLoc(), value, allocInstr,
+    store = storeBuilder.createStore(Loc, value, allocInstr,
                                      StoreOwnershipQualifier::Unqualified);
   }
 
   // Insert stack deallocations.
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 
@@ -1598,7 +1605,7 @@
 
   auto II = instr->getIterator();
   ++II;
-  SILBuilder castBuilder(II);
+  SILBuilderWithScope castBuilder(II);
   SingleValueInstruction *castInstr = nullptr;
   switch (instr->getKind()) {
   // Add cast to the new sil function type:
@@ -1624,10 +1631,10 @@
   auto value = orig->getOperand();
   auto type = value->getType();
   if (type.isObject()) {
-    SILBuilder allocBuilder(pass.F->begin()->begin());
+    SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
     // support for non-address operands / enums
     auto *allocInstr = allocBuilder.createAllocStack(orig->getLoc(), type);
-    SILBuilder storeBuilder(orig);
+    SILBuilderWithScope storeBuilder(orig);
     StoreInst *store = nullptr;
     if (pass.F->hasQualifiedOwnership()) {
       store = storeBuilder.createStore(orig->getLoc(), value, allocInstr,
@@ -1638,19 +1645,19 @@
     }
     // Insert stack deallocations.
     for (TermInst *termInst : pass.returnInsts) {
-      SILBuilder deallocBuilder(termInst);
+      SILBuilderWithScope deallocBuilder(termInst);
       deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
     }
     value = allocInstr;
   }
-  SILBuilder allocBuilder(pass.F->begin()->begin());
+  SILBuilderWithScope allocBuilder(pass.F->begin()->begin());
   auto *allocInstr = allocBuilder.createAllocStack(value.getLoc(), type);
 
-  SILBuilder copyBuilder(orig);
+  SILBuilderWithScope copyBuilder(orig);
   createOutlinedCopyCall(copyBuilder, value, allocInstr, pass);
 
   for (TermInst *termInst : pass.returnInsts) {
-    SILBuilder deallocBuilder(termInst);
+    SILBuilderWithScope deallocBuilder(termInst);
     deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
   }
 
@@ -1673,13 +1680,13 @@
       /* unchecked_take_enum_data_addr can be destructive.
        * work on a copy instead of the original enum */
       auto copiedValue = createCopyOfEnum(pass, instr);
-      SILBuilder enumBuilder(instr);
+      SILBuilderWithScope enumBuilder(instr);
       unsigned numOfCases = instr->getNumCases();
       SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 16> caseBBs;
       for (unsigned i = 0; i < numOfCases; ++i) {
         auto currCase = instr->getCase(i);
         auto *currBB = currCase.second;
-        SILBuilder argBuilder(currBB->begin());
+        SILBuilderWithScope argBuilder(currBB->begin());
         assert(currBB->getNumArguments() <= 1 && "Unhandled BB Type");
         EnumElementDecl *decl = currCase.first;
         for (SILArgument *arg : currBB->getArguments()) {
@@ -1696,7 +1703,7 @@
 
           // Load the enum addr then see if we can get rid of the load:
           LoadInst *loadArg = nullptr;
-          if (pass.F->hasUnqualifiedOwnership()) {
+          if (!pass.F->hasQualifiedOwnership()) {
             loadArg = argBuilder.createLoad(
                 newArg->getLoc(), newArg, LoadOwnershipQualifier::Unqualified);
           } else {
@@ -1734,13 +1741,13 @@
       if (updateResultTy) {
         pass.resultTyInstsToMod.remove(instr);
       }
-      SILBuilder structBuilder(instr);
+      SILBuilderWithScope structBuilder(instr);
       auto *newInstr = structBuilder.createStructElementAddr(
           instr->getLoc(), instr->getOperand(), instr->getField(),
           instr->getType().getAddressType());
       // Load the struct element then see if we can get rid of the load:
       LoadInst *loadArg = nullptr;
-      if (pass.F->hasUnqualifiedOwnership()) {
+      if (!pass.F->hasQualifiedOwnership()) {
         loadArg = structBuilder.createLoad(newInstr->getLoc(), newInstr,
                                            LoadOwnershipQualifier::Unqualified);
       } else {
@@ -1828,7 +1835,7 @@
 
   while (!pass.allocStackInstsToMod.empty()) {
     auto *instr = pass.allocStackInstsToMod.pop_back_val();
-    SILBuilder allocBuilder(instr);
+    SILBuilderWithScope allocBuilder(instr);
     SILType currSILType = instr->getType();
     SILType newSILType = getNewSILType(genEnv, currSILType, pass.Mod);
     auto *newInstr = allocBuilder.createAllocStack(instr->getLoc(), newSILType);
@@ -1838,7 +1845,7 @@
 
   while (!pass.pointerToAddrkInstsToMod.empty()) {
     auto *instr = pass.pointerToAddrkInstsToMod.pop_back_val();
-    SILBuilder pointerBuilder(instr);
+    SILBuilderWithScope pointerBuilder(instr);
     SILType currSILType = instr->getType();
     SILType newSILType = getNewSILType(genEnv, currSILType, pass.Mod);
     auto *newInstr = pointerBuilder.createPointerToAddress(
@@ -1862,7 +1869,7 @@
       } else {
         assert(currOperand->getType().isAddress() &&
                "Expected an address type");
-        SILBuilder debugBuilder(instr);
+        SILBuilderWithScope debugBuilder(instr);
         debugBuilder.createDebugValueAddr(instr->getLoc(), currOperand);
         instr->getParent()->erase(instr);
       }
@@ -1875,7 +1882,7 @@
     for (Operand &operand : instr->getAllOperands()) {
       auto currOperand = operand.get();
       assert(currOperand->getType().isAddress() && "Expected an address type");
-      SILBuilder destroyBuilder(instr);
+      SILBuilderWithScope destroyBuilder(instr);
       destroyBuilder.createDestroyAddr(instr->getLoc(), currOperand);
       instr->getParent()->erase(instr);
     }
@@ -1890,20 +1897,20 @@
     assert(tgtType.isAddress() && "Expected an address-type target");
     assert(srcType == tgtType && "Source and target type do not match");
 
-    SILBuilder copyBuilder(instr);
+    SILBuilderWithScope copyBuilder(instr);
     createOutlinedCopyCall(copyBuilder, src, tgt, pass);
     instr->getParent()->erase(instr);
   }
 
   for (RetainValueInst *instr : pass.retainInstsToMod) {
-    SILBuilder retainBuilder(instr);
+    SILBuilderWithScope retainBuilder(instr);
     retainBuilder.createRetainValueAddr(
         instr->getLoc(), instr->getOperand(), instr->getAtomicity());
     instr->getParent()->erase(instr);
   }
 
   for (ReleaseValueInst *instr : pass.releaseInstsToMod) {
-    SILBuilder releaseBuilder(instr);
+    SILBuilderWithScope releaseBuilder(instr);
     releaseBuilder.createReleaseValueAddr(
         instr->getLoc(), instr->getOperand(), instr->getAtomicity());
     instr->getParent()->erase(instr);
@@ -1914,7 +1921,7 @@
     // Note: The operand was already updated!
     SILType currSILType = instr->getType().getObjectType();
     SILType newSILType = getNewSILType(genEnv, currSILType, pass.Mod);
-    SILBuilder resultTyBuilder(instr);
+    SILBuilderWithScope resultTyBuilder(instr);
     SILLocation Loc = instr->getLoc();
     SingleValueInstruction *newInstr = nullptr;
     switch (instr->getKind()) {
@@ -1979,7 +1986,7 @@
         getNewSILFunctionType(genEnvForMethod, currSILFunctionType, pass.Mod));
     auto member = instr->getMember();
     auto loc = instr->getLoc();
-    SILBuilder methodBuilder(instr);
+    SILBuilderWithScope methodBuilder(instr);
     MethodInst *newInstr = nullptr;
 
     switch (instr->getKind()) {
@@ -2014,7 +2021,7 @@
     auto *instr = pass.modReturnInsts.pop_back_val();
     auto loc = instr->getLoc(); // SILLocation::RegularKind
     auto regLoc = RegularLocation(loc.getSourceLoc());
-    SILBuilder retBuilder(instr);
+    SILBuilderWithScope retBuilder(instr);
     assert(modNonFuncTypeResultType(pass.F, pass.Mod) &&
            "Expected a regular type");
     // Before we return an empty tuple, init return arg:
@@ -2037,7 +2044,7 @@
       auto II = (IIR != instr->getParent()->rend())
                     ? IIR->getIterator()
                     : instr->getParent()->begin();
-      SILBuilder retCopyBuilder(II);
+      SILBuilderWithScope retCopyBuilder(II);
       createOutlinedCopyCall(retCopyBuilder, retOp, retArg, pass, &regLoc);
     } else {
       if (pass.F->hasQualifiedOwnership()) {
@@ -2229,7 +2236,7 @@
   SILFunctionConventions newSILFunctionConventions(newCanSILFuncType,
                                                    *getModule());
   SmallVector<SILValue, 8> callArgs;
-  SILBuilder applyBuilder(applyInst);
+  SILBuilderWithScope applyBuilder(applyInst);
   // If we turned a direct result into an indirect parameter
   // Find the new alloc we created earlier.
   // and pass it as first parameter:
@@ -2298,7 +2305,7 @@
 
 void LoadableByAddress::recreateLoadInstrs() {
   for (auto *loadInstr : loadInstrsOfFunc) {
-    SILBuilder loadBuilder(loadInstr);
+    SILBuilderWithScope loadBuilder(loadInstr);
     // If this is a load of a function for which we changed the return type:
     // add UncheckedBitCast before the load
     auto loadOp = loadInstr->getOperand();
@@ -2313,7 +2320,7 @@
 
 void LoadableByAddress::recreateUncheckedEnumDataInstrs() {
   for (auto *enumInstr : uncheckedEnumDataOfFunc) {
-    SILBuilder enumBuilder(enumInstr);
+    SILBuilderWithScope enumBuilder(enumInstr);
     SILFunction *F = enumInstr->getFunction();
     CanSILFunctionType funcType = F->getLoweredFunctionType();
     IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
@@ -2347,7 +2354,7 @@
 
 void LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst() {
   for (auto *enumInstr : uncheckedTakeEnumDataAddrOfFunc) {
-    SILBuilder enumBuilder(enumInstr);
+    SILBuilderWithScope enumBuilder(enumInstr);
     SILFunction *F = enumInstr->getFunction();
     CanSILFunctionType funcType = F->getLoweredFunctionType();
     IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
@@ -2388,7 +2395,7 @@
     SILType srcType = src->getType();
     if (destType.getObjectType() != srcType) {
       // Add cast to destType
-      SILBuilder castBuilder(instr);
+      SILBuilderWithScope castBuilder(instr);
       auto *castInstr = castBuilder.createUncheckedBitCast(
           instr->getLoc(), src, destType.getObjectType());
       instr->setOperand(StoreInst::Src, castInstr);
@@ -2417,7 +2424,7 @@
     CanSILFunctionType newFnType =
         getNewSILFunctionType(genEnv, currSILFunctionType, *currIRMod);
     SILType newType = SILType::getPrimitiveObjectType(newFnType);
-    SILBuilder convBuilder(convInstr);
+    SILBuilderWithScope convBuilder(convInstr);
     SingleValueInstruction *newInstr = nullptr;
     switch (convInstr->getKind()) {
     case SILInstructionKind::ThinToThickFunctionInst: {
@@ -2467,7 +2474,7 @@
       newArgs.push_back(oldArg);
     }
 
-    SILBuilder builtinBuilder(builtinInstr);
+    SILBuilderWithScope builtinBuilder(builtinInstr);
     auto *newInstr = builtinBuilder.createBuiltin(
         builtinInstr->getLoc(), builtinInstr->getName(), newResultTy, newSubs,
         newArgs);
@@ -2608,7 +2615,7 @@
   // The pointer does not change
   for (FunctionRefInst *instr : funcRefs) {
     SILFunction *F = instr->getReferencedFunction();
-    SILBuilder refBuilder(instr);
+    SILBuilderWithScope refBuilder(instr);
     FunctionRefInst *newInstr =
         refBuilder.createFunctionRef(instr->getLoc(), F);
     instr->replaceAllUsesWith(newInstr);
diff --git a/lib/Migrator/TupleSplatMigratorPass.cpp b/lib/Migrator/TupleSplatMigratorPass.cpp
index 717c120..15c9607 100644
--- a/lib/Migrator/TupleSplatMigratorPass.cpp
+++ b/lib/Migrator/TupleSplatMigratorPass.cpp
@@ -76,53 +76,94 @@
 
 struct TupleSplatMigratorPass : public ASTMigratorPass,
   public SourceEntityWalker {
-    
-  bool handleClosureShorthandMismatch(FunctionConversionExpr *FC) {
-    if (!SF->getASTContext().LangOpts.isSwiftVersion3() || !FC->isImplicit() ||
-        !isa<ClosureExpr>(FC->getSubExpr())) {
-      return false;
-    }
 
-    auto *Closure = cast<ClosureExpr>(FC->getSubExpr());
-    if (Closure->getInLoc().isValid())
+  llvm::DenseSet<FunctionConversionExpr*> CallArgFuncConversions;
+
+  void blacklistFuncConversionArgs(CallExpr *CE) {
+    if (CE->isImplicit() || !SF->getASTContext().LangOpts.isSwiftVersion3())
+      return;
+
+    Expr *Arg = CE->getArg();
+    if (auto *Shuffle = dyn_cast<TupleShuffleExpr>(Arg))
+      Arg = Shuffle->getSubExpr();
+
+    if (auto *Paren = dyn_cast<ParenExpr>(Arg)) {
+      if (auto FC = dyn_cast_or_null<FunctionConversionExpr>(Paren->getSubExpr()))
+        CallArgFuncConversions.insert(FC);
+    } else if (auto *Tuple = dyn_cast<TupleExpr>(Arg)){
+      for (auto Elem : Tuple->getElements()) {
+        if (auto *FC = dyn_cast_or_null<FunctionConversionExpr>(Elem))
+          CallArgFuncConversions.insert(FC);
+      }
+    }
+  }
+
+  ClosureExpr *getShorthandClosure(Expr *E) {
+    if (auto *Closure = dyn_cast_or_null<ClosureExpr>(E)) {
+      if (Closure->hasAnonymousClosureVars())
+        return Closure;
+    }
+    return nullptr;
+  }
+
+  bool handleClosureShorthandMismatch(const FunctionConversionExpr *FC) {
+    if (!SF->getASTContext().LangOpts.isSwiftVersion3() || !FC->isImplicit())
+      return false;
+
+    ClosureExpr *Closure = getShorthandClosure(FC->getSubExpr());
+    if (!Closure)
       return false;
 
     FunctionType *FuncTy = FC->getType()->getAs<FunctionType>();
 
     unsigned NativeArity = FuncTy->getParams().size();
     unsigned ClosureArity = Closure->getParameters()->size();
-    if (NativeArity <= ClosureArity)
+    if (NativeArity == ClosureArity)
       return false;
 
-    ShorthandFinder Finder(Closure);
-
     if (ClosureArity == 1 && NativeArity > 1) {
       // Remove $0. from existing references or if it's only $0, replace it
       // with a tuple of the native arity, e.g. ($0, $1, $2)
-      Finder.forEachReference([this, NativeArity](Expr *Ref, ParamDecl *Def) {
-        if (auto *TE = dyn_cast<TupleElementExpr>(Ref)) {
-          SourceLoc Start = TE->getStartLoc();
-          SourceLoc End = TE->getLoc();
-          Editor.replace(CharSourceRange(SM, Start, End), "$");
-        } else {
-          std::string TupleText;
-          {
-            llvm::raw_string_ostream OS(TupleText);
-            for (size_t i = 1; i < NativeArity; ++i) {
-              OS << ", $" << i;
+      ShorthandFinder(Closure)
+        .forEachReference([this, NativeArity](Expr *Ref, ParamDecl *Def) {
+          if (auto *TE = dyn_cast<TupleElementExpr>(Ref)) {
+            SourceLoc Start = TE->getStartLoc();
+            SourceLoc End = TE->getLoc();
+            Editor.replace(CharSourceRange(SM, Start, End), "$");
+          } else {
+            std::string TupleText;
+            {
+              llvm::raw_string_ostream OS(TupleText);
+              for (size_t i = 1; i < NativeArity; ++i) {
+                OS << ", $" << i;
+              }
+              OS << ")";
             }
-            OS << ")";
+            Editor.insert(Ref->getStartLoc(), "(");
+            Editor.insertAfterToken(Ref->getEndLoc(), TupleText);
           }
-          Editor.insert(Ref->getStartLoc(), "(");
-          Editor.insertAfterToken(Ref->getEndLoc(), TupleText);
-        }
-      });
+        });
+      return true;
+    }
+
+    // This direction is only needed if not passed as a call argument. e.g.
+    // someFunc({ $0 > $1 }) // doesn't need migration
+    // let x: ((Int, Int)) -> Bool = { $0 > $1 } // needs migration
+    if (NativeArity == 1 && ClosureArity > 1 && !CallArgFuncConversions.count(FC)) {
+      // Prepend $0. to existing references
+      ShorthandFinder(Closure)
+        .forEachReference([this](Expr *Ref, ParamDecl *Def) {
+          if (auto *TE = dyn_cast<TupleElementExpr>(Ref))
+            Ref = TE->getBase();
+          SourceLoc AfterDollar = Ref->getStartLoc().getAdvancedLoc(1);
+          Editor.insert(AfterDollar, "0.");
+        });
       return true;
     }
     return false;
   }
 
-      /// Migrates code that compiles fine in Swift 3 but breaks in Swift 4 due to
+  /// Migrates code that compiles fine in Swift 3 but breaks in Swift 4 due to
   /// changes in how the typechecker handles tuple arguments.
   void handleTupleArgumentMismatches(const CallExpr *E) {
     if (!SF->getASTContext().LangOpts.isSwiftVersion3())
@@ -169,6 +210,7 @@
     if (auto *FCE = dyn_cast<FunctionConversionExpr>(E)) {
       handleClosureShorthandMismatch(FCE);
     } else if (auto *CE = dyn_cast<CallExpr>(E)) {
+      blacklistFuncConversionArgs(CE);
       handleTupleArgumentMismatches(CE);
     }
     return true;
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 5ff63a4..2aa183b 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -242,7 +242,7 @@
 
   Lexer L(LangOpts, SourceMgr, BufferID, Diags, InSILMode,
           CommentRetentionMode::None, TriviaRetentionMode::WithoutTrivia);
-  L.restoreState(State(Loc, {}, {}));
+  L.restoreState(State(Loc));
   Token Result;
   L.lex(Result);
   return Result;
@@ -264,14 +264,9 @@
 
   StringRef TokenText { TokStart, static_cast<size_t>(CurPtr - TokStart) };
 
-  if (!MultilineString)
-    lexTrivia(TrailingTrivia, /* StopAtFirstNewline */ true);
+  lexTrivia(TrailingTrivia, /* StopAtFirstNewline */ true);
 
   NextToken.setToken(Kind, TokenText, CommentLength, MultilineString);
-  if (!MultilineString)
-    if (!TrailingTrivia.empty() &&
-        TrailingTrivia.front().Kind == syntax::TriviaKind::Backtick)
-      ++CurPtr;
 }
 
 Lexer::State Lexer::getStateForBeginningOfTokenLoc(SourceLoc Loc) const {
@@ -298,7 +293,7 @@
     }
     break;
   }
-  return State(SourceLoc(llvm::SMLoc::getFromPointer(Ptr)), {}, {});
+  return State(SourceLoc(llvm::SMLoc::getFromPointer(Ptr)));
 }
 
 //===----------------------------------------------------------------------===//
@@ -2309,7 +2304,7 @@
   // we need to lex just the comment token.
   Lexer L(FakeLangOpts, SM, BufferID, nullptr, /*InSILMode=*/ false,
           CommentRetentionMode::ReturnAsTokens);
-  L.restoreState(State(Loc, {}, {}));
+  L.restoreState(State(Loc));
   return L.peekNextToken();
 }
 
@@ -2348,23 +2343,11 @@
     case '\n':
     case '\r':
       NextToken.setAtStartOfLine(true);
-      return syntax::TriviaPiece {
-        syntax::TriviaKind::Newline,
-        Length,
-        OwnedString(Start, Length),
-      };
+      return syntax::TriviaPiece{syntax::TriviaKind::Newline, Length, {}};
     case ' ':
-      return syntax::TriviaPiece {
-        syntax::TriviaKind::Space,
-        Length,
-        OwnedString(Start, Length),
-      };
+      return syntax::TriviaPiece{syntax::TriviaKind::Space, Length, {}};
     case '\t':
-      return syntax::TriviaPiece {
-        syntax::TriviaKind::Tab,
-        Length,
-        OwnedString(Start, Length),
-      };
+      return syntax::TriviaPiece{syntax::TriviaKind::Tab, Length, {}};
     default:
       return None;
   }
@@ -2379,11 +2362,7 @@
   if (Length == 0)
     return None;
 
-  return Optional<syntax::TriviaPiece>({
-    Kind,
-    Length,
-    OwnedString(Start, Length)
-  });
+  return Optional<syntax::TriviaPiece>({Kind, 1, OwnedString(Start, Length)});
 }
 
 Optional<syntax::TriviaPiece>
@@ -2394,11 +2373,7 @@
   if (Length == 0)
     return None;
 
-  return Optional<syntax::TriviaPiece>({
-    Kind,
-    Length,
-    OwnedString(Start, Length)
-  });
+  return Optional<syntax::TriviaPiece>({Kind, 1, OwnedString(Start, Length)});
 }
 
 Optional<syntax::TriviaPiece> Lexer::lexComment() {
@@ -2608,7 +2583,7 @@
   // we need to lex just the comment token.
   Lexer L(FakeLangOpts, SM, BufferID, nullptr, /*InSILMode=*/ false,
           CommentRetentionMode::ReturnAsTokens);
-  L.restoreState(State(Loc, {}, {}));
+  L.restoreState(State(Loc));
   L.skipToEndOfLine();
   return getSourceLoc(L.CurPtr);
 }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 3549931..ef9805c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -512,6 +512,11 @@
   // Ok, it is a valid attribute, eat it, and then process it.
   StringRef AttrName = Tok.getText();
   SourceLoc Loc = consumeToken();
+
+  // We can only make this attribute a token list intead of an Attribute node
+  // because the attribute node may include '@'
+  SyntaxParsingContext TokListContext(SyntaxContext, SyntaxKind::TokenList);
+
   bool DiscardAttribute = false;
 
   // Diagnose duplicated attributes.
@@ -1853,17 +1858,21 @@
 bool Parser::parseDeclAttributeList(DeclAttributes &Attributes,
                                     bool &FoundCCToken) {
   FoundCCToken = false;
-  while (Tok.is(tok::at_sign)) {
+  if (Tok.isNot(tok::at_sign))
+    return false;
+  SyntaxParsingContext AttrListCtx(SyntaxContext, SyntaxKind::AttributeList);
+  do {
     if (peekToken().is(tok::code_complete)) {
       consumeToken(tok::at_sign);
       consumeToken(tok::code_complete);
       FoundCCToken = true;
       continue;
     }
+    SyntaxParsingContext AttrCtx(SyntaxContext, SyntaxKind::Attribute);
     SourceLoc AtLoc = consumeToken();
     if (parseDeclAttribute(Attributes, AtLoc))
       return true;
-  }
+  } while (Tok.is(tok::at_sign));
   return false;
 }
 
@@ -2263,7 +2272,7 @@
 
     switch (Tok.getKind()) {
     // Modifiers
-    case tok::kw_static:
+    case tok::kw_static: {
       if (StaticLoc.isValid()) {
         diagnose(Tok, diag::decl_already_static,
                  StaticSpellingKind::KeywordStatic)
@@ -2273,16 +2282,27 @@
         StaticLoc = Tok.getLoc();
         StaticSpelling = StaticSpellingKind::KeywordStatic;
       }
+      SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
       consumeToken(tok::kw_static);
+      // Static modifier doesn't have more details.
+      SyntaxParsingContext DetailContext(SyntaxContext, SyntaxKind::TokenList);
       continue;
-
+    }
     // 'class' is a modifier on func, but is also a top-level decl.
     case tok::kw_class: {
-      SourceLoc ClassLoc = consumeToken(tok::kw_class);
-
+      SourceLoc ClassLoc;
+      bool AsModifier;
+      {
+        BacktrackingScope Scope(*this);
+        ClassLoc = consumeToken(tok::kw_class);
+        AsModifier = isStartOfDecl();
+      }
       // If 'class' is a modifier on another decl kind, like var or func,
       // then treat it as a modifier.
-      if (isStartOfDecl()) {
+      if (AsModifier) {
+        SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
+        consumeToken(tok::kw_class);
+        SyntaxParsingContext DetailContext(SyntaxContext, SyntaxKind::TokenList);
         if (StaticLoc.isValid()) {
           diagnose(Tok, diag::decl_already_static,
                    StaticSpellingKind::KeywordClass)
@@ -2294,6 +2314,7 @@
         continue;
       }
 
+      consumeToken(tok::kw_class);
       // Otherwise this is the start of a class declaration.
       DeclResult = parseDeclClass(ClassLoc, Flags, Attributes);
       break;
@@ -2302,84 +2323,60 @@
     case tok::kw_private:
     case tok::kw_fileprivate:
     case tok::kw_internal:
-    case tok::kw_public:
+    case tok::kw_public: {
+      SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
       // We still model these specifiers as attributes.
       parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_AccessControl);
       continue;
-
+    }
     // Context sensitive keywords.
-    case tok::identifier:
+    case tok::identifier: {
+      Optional<DeclAttrKind> Kind;
       // FIXME: This is ridiculous, this all needs to be sucked into the
       // declparsing goop.
       if (Tok.isContextualKeyword("open")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_AccessControl);
-        continue;
+        Kind = DAK_AccessControl;
+      } else if (Tok.isContextualKeyword("weak") ||
+                 Tok.isContextualKeyword("unowned")) {
+        Kind = DAK_Ownership;
+      } else if (Tok.isContextualKeyword("optional")) {
+        Kind = DAK_Optional;
+      } else if (Tok.isContextualKeyword("required")) {
+        Kind = DAK_Required;
+      } else if (Tok.isContextualKeyword("lazy")) {
+        Kind = DAK_Lazy;
+      } else if (Tok.isContextualKeyword("final")) {
+        Kind = DAK_Final;
+      } else if (Tok.isContextualKeyword("dynamic")) {
+        Kind = DAK_Dynamic;
+      } else if (Tok.isContextualKeyword("prefix")) {
+        Kind = DAK_Prefix;
+      } else if (Tok.isContextualKeyword("postfix")) {
+        Kind = DAK_Postfix;
+      } else if (Tok.isContextualKeyword("indirect")) {
+        Kind = DAK_Indirect;
+      } else if (Tok.isContextualKeyword("infix")) {
+        Kind = DAK_Infix;
+      } else if (Tok.isContextualKeyword("override")) {
+        Kind = DAK_Override;
+      } else if (Tok.isContextualKeyword("mutating")) {
+        Kind = DAK_Mutating;
+      } else if (Tok.isContextualKeyword("nonmutating")) {
+        Kind = DAK_NonMutating;
+      } else if (Tok.isContextualKeyword("__consuming")) {
+        Kind = DAK_Consuming;
+      } else if (Tok.isContextualKeyword("convenience")) {
+        Kind = DAK_Convenience;
       }
-      if (Tok.isContextualKeyword("weak") ||
-          Tok.isContextualKeyword("unowned")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_Ownership);
-        continue;
-      }
-      if (Tok.isContextualKeyword("optional")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_Optional);
-        continue;
-      }
-      if (Tok.isContextualKeyword("required")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_Required);
-        continue;
-      }
-      if (Tok.isContextualKeyword("lazy")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_Lazy);
-        continue;
-      }
-      if (Tok.isContextualKeyword("final")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc=*/{}, DAK_Final);
-        continue;
-      }
-      if (Tok.isContextualKeyword("dynamic")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Dynamic);
-        continue;
-      }
-      if (Tok.isContextualKeyword("prefix")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Prefix);
-        continue;
-      }
-      if (Tok.isContextualKeyword("postfix")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Postfix);
-        continue;
-      }
-      if (Tok.isContextualKeyword("indirect")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Indirect);
-        continue;
-      }
-      if (Tok.isContextualKeyword("infix")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Infix);
-        continue;
-      }
-      if (Tok.isContextualKeyword("override")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Override);
-        continue;
-      }
-      if (Tok.isContextualKeyword("mutating")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Mutating);
-        continue;
-      }
-      if (Tok.isContextualKeyword("nonmutating")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_NonMutating);
-        continue;
-      }
-      if (Tok.isContextualKeyword("__consuming")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Consuming);
-        continue;
-      }
-      if (Tok.isContextualKeyword("convenience")) {
-        parseNewDeclAttribute(Attributes, /*AtLoc*/ {}, DAK_Convenience);
+      if (Kind) {
+        SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
+        parseNewDeclAttribute(Attributes, SourceLoc(), *Kind);
         continue;
       }
 
       // Otherwise this is not a context-sensitive keyword.
       LLVM_FALLTHROUGH;
-
+    }
     case tok::pound_if:
     case tok::pound_sourceLocation:
     case tok::pound_line:
@@ -4810,33 +4807,22 @@
 
   SourceLoc FuncLoc = consumeToken(tok::kw_func);
 
-  // Forgive the lexer
-  if (Tok.is(tok::amp_prefix)) {
-    Tok.setKind(tok::oper_prefix);
-  }
+  // Parse function name.
   Identifier SimpleName;
-  Token NameTok = Tok;
   SourceLoc NameLoc;
-
-  if (Tok.isAny(tok::identifier, tok::integer_literal, tok::floating_literal,
-                tok::unknown) ||
-      Tok.isKeyword()) {
-    // This non-operator path is quite accepting of what tokens might be a name,
-    // because we're aggressive about recovering/providing good diagnostics for
-    // beginners.
-    ParserStatus NameStatus =
-        parseIdentifierDeclName(*this, SimpleName, NameLoc, "function",
-                                tok::l_paren, tok::arrow, tok::l_brace,
-                                TokenProperty::StartsWithLess);
-    if (NameStatus.isError())
-      return nullptr;
-  } else {
-    // May be operator.
-    if (parseAnyIdentifier(SimpleName, NameLoc,
-                           diag::expected_identifier_in_decl, "function")) {
-      return nullptr;
+  if (Tok.isAnyOperator() || Tok.isAny(tok::exclaim_postfix, tok::amp_prefix)) {
+    // If the name is an operator token that ends in '<' and the following token
+    // is an identifier, split the '<' off as a separate token. This allows
+    // things like 'func ==<T>(x:T, y:T) {}' to parse as '==' with generic type
+    // variable '<T>' as expected.
+    auto NameStr = Tok.getText();
+    if (NameStr.size() > 1 && NameStr.back() == '<' &&
+        peekToken().is(tok::identifier)) {
+      NameStr = NameStr.slice(0, NameStr.size() - 1);
     }
-    assert(SimpleName.isOperator());
+    SimpleName = Context.getIdentifier(NameStr);
+    NameLoc = consumeStartingCharacterOfCurrentToken(tok::oper_binary_spaced,
+                                                     NameStr.size());
     // Within a protocol, recover from a missing 'static'.
     if (Flags & PD_InProtocol) {
       switch (StaticSpelling) {
@@ -4858,6 +4844,15 @@
         llvm_unreachable("should have been fixed above");
       }
     }
+  } else {
+    // This non-operator path is quite accepting of what tokens might be a name,
+    // because we're aggressive about recovering/providing good diagnostics for
+    // beginners.
+    auto NameStatus = parseIdentifierDeclName(
+        *this, SimpleName, NameLoc, "function", tok::l_paren, tok::arrow,
+        tok::l_brace, TokenProperty::StartsWithLess);
+    if (NameStatus.isError())
+      return nullptr;
   }
 
   DebuggerContextChange DCC(*this, SimpleName, DeclKind::Func);
@@ -4867,30 +4862,9 @@
   GenericsScope.emplace(this, ScopeKind::Generics);
   GenericParamList *GenericParams;
   bool SignatureHasCodeCompletion = false;
-  // If the name is an operator token that ends in '<' and the following token
-  // is an identifier, split the '<' off as a separate token. This allows things
-  // like 'func ==<T>(x:T, y:T) {}' to parse as '==' with generic type variable
-  // '<T>' as expected.
-  if (SimpleName.str().size() > 1 && SimpleName.str().back() == '<'
-      && Tok.is(tok::identifier)) {
-    SimpleName = Context.getIdentifier(SimpleName.str().
-                                       slice(0, SimpleName.str().size() - 1));
-    SourceLoc LAngleLoc = NameLoc.getAdvancedLoc(SimpleName.str().size());
-    auto Result = parseGenericParameters(LAngleLoc);
-    GenericParams = Result.getPtrOrNull();
-    SignatureHasCodeCompletion |= Result.hasCodeCompletion();
-
-    auto NameTokText = NameTok.getRawText();
-    markSplitToken(tok::identifier,
-                   NameTokText.substr(0, NameTokText.size() - 1));
-    markSplitToken(tok::oper_binary_unspaced,
-                   NameTokText.substr(NameTokText.size() - 1));
-
-  } else {
-    auto Result = maybeParseGenericParams();
-    GenericParams = Result.getPtrOrNull();
-    SignatureHasCodeCompletion |= Result.hasCodeCompletion();
-  }
+  auto GenericParamResult = maybeParseGenericParams();
+  GenericParams = GenericParamResult.getPtrOrNull();
+  SignatureHasCodeCompletion |= GenericParamResult.hasCodeCompletion();
   if (SignatureHasCodeCompletion && !CodeCompletion)
     return makeParserCodeCompletionStatus();
 
diff --git a/lib/Parse/ParseGeneric.cpp b/lib/Parse/ParseGeneric.cpp
index d5f83da..be5d54f 100644
--- a/lib/Parse/ParseGeneric.cpp
+++ b/lib/Parse/ParseGeneric.cpp
@@ -22,6 +22,7 @@
 #include "swift/Syntax/SyntaxNodes.h"
 #include "swift/Syntax/SyntaxParsingContext.h"
 using namespace swift;
+using namespace swift::syntax;
 
 /// parseGenericParameters - Parse a sequence of generic parameters, e.g.,
 /// < T : Comparable, U : Container> along with an optional requires clause.
@@ -245,11 +246,17 @@
                SmallVectorImpl<RequirementRepr> &Requirements,
                bool &FirstTypeInComplete,
                bool AllowLayoutConstraints) {
+  SyntaxParsingContext ClauseContext(SyntaxContext,
+                                     SyntaxKind::GenericWhereClause);
   ParserStatus Status;
   // Parse the 'where'.
   WhereLoc = consumeToken(tok::kw_where);
   FirstTypeInComplete = false;
+  SyntaxParsingContext ReqListContext(SyntaxContext,
+                                      SyntaxKind::GenericRequirementList);
+  bool HasNextReq;
   do {
+    SyntaxParsingContext ReqContext(SyntaxContext, SyntaxContextKind::Syntax);
     // Parse the leading type-identifier.
     auto FirstTypeResult = parseTypeIdentifier();
     if (FirstTypeResult.hasSyntax())
@@ -269,7 +276,7 @@
     if (Tok.is(tok::colon)) {
       // A conformance-requirement.
       SourceLoc ColonLoc = consumeToken();
-
+      ReqContext.setCreateSyntax(SyntaxKind::ConformanceRequirement);
       if (Tok.is(tok::identifier) &&
           getLayoutConstraint(Context.getIdentifier(Tok.getText()), Context)
               ->isKnownLayout()) {
@@ -309,6 +316,7 @@
       }
     } else if ((Tok.isAnyOperator() && Tok.getText() == "==") ||
                Tok.is(tok::equal)) {
+      ReqContext.setCreateSyntax(SyntaxKind::SameTypeRequirement);
       // A same-type-requirement
       if (Tok.is(tok::equal)) {
         diagnose(Tok, diag::requires_single_equal)
@@ -334,8 +342,9 @@
       Status.setIsParseError();
       break;
     }
+    HasNextReq = consumeIf(tok::comma);
     // If there's a comma, keep parsing the list.
-  } while (consumeIf(tok::comma));
+  } while (HasNextReq);
 
   if (Requirements.empty())
     WhereLoc = SourceLoc();
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index c704176..efbdb9a 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -506,28 +506,26 @@
   return Lexer::getLocForEndOfToken(SourceMgr, PreviousLoc);
 }
 
-Parser::ParserPosition Parser::getParserPositionAfterFirstCharacter(Token T) {
-  assert(T.getLength() > 1 && "Token must have more than one character");
-  auto Loc = T.getLoc();
-  auto NewState = L->getStateForBeginningOfTokenLoc(Loc.getAdvancedLoc(1));
-  return ParserPosition(NewState, Loc);
-}
-
-SourceLoc Parser::consumeStartingCharacterOfCurrentToken(tok Kind) {
-  // Consumes one-character token (like '?', '<', '>' or '!') and returns
-  // its location.
+SourceLoc Parser::consumeStartingCharacterOfCurrentToken(tok Kind, size_t Len) {
+  // Consumes prefix of token and returns its location.
+  // (like '?', '<', '>' or '!' immediately followed by '<') 
+  assert(Len >= 1);
 
   // Current token can be either one-character token we want to consume...
-  if (Tok.getLength() == 1) {
+  if (Tok.getLength() == Len) {
     Tok.setKind(Kind);
     return consumeToken();
   }
 
-  markSplitToken(Kind, Tok.getText().substr(0, 1));
+  auto Loc = Tok.getLoc();
 
-  // ... or a multi-character token with the first character being the one that
-  // we want to consume as a separate token.
-  restoreParserPosition(getParserPositionAfterFirstCharacter(Tok),
+  // ... or a multi-character token with the first N characters being the one
+  // that we want to consume as a separate token.
+  assert(Tok.getLength() > Len);
+  markSplitToken(Kind, Tok.getText().substr(0, Len));
+
+  auto NewState = L->getStateForBeginningOfTokenLoc(Loc.getAdvancedLoc(Len));
+  restoreParserPosition(ParserPosition(NewState, Loc),
                         /*enableDiagnostics=*/true);
   return PreviousLoc;
 }
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index 080fcc7..e200b03 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -2218,7 +2218,7 @@
 
   // If the given function has unqualified ownership or we have been asked by
   // the user not to verify this function, there is nothing to verify.
-  if (getFunction()->hasUnqualifiedOwnership() ||
+  if (!getFunction()->hasQualifiedOwnership() ||
       !getFunction()->shouldVerifyOwnership())
     return;
 
@@ -2266,7 +2266,7 @@
 
   // If the given function has unqualified ownership or we have been asked by
   // the user not to verify this function, there is nothing to verify.
-  if (F->hasUnqualifiedOwnership() || !F->shouldVerifyOwnership())
+  if (!F->hasQualifiedOwnership() || !F->shouldVerifyOwnership())
     return;
 
   ErrorBehaviorKind ErrorBehavior;
@@ -2304,7 +2304,7 @@
 
   // If the given function has unqualified ownership, there is nothing further
   // to verify.
-  if (F->hasUnqualifiedOwnership())
+  if (!F->hasQualifiedOwnership())
     return false;
 
   ErrorBehaviorKind ErrorBehavior(ErrorBehaviorKind::ReturnFalse);
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 9c3715b..3376344 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -1161,7 +1161,7 @@
     case LoadOwnershipQualifier::Unqualified:
       // We should not see loads with unqualified ownership when SILOwnership is
       // enabled.
-      require(F.hasUnqualifiedOwnership(),
+      require(!F.hasQualifiedOwnership(),
               "Load with unqualified ownership in a qualified function");
       break;
     case LoadOwnershipQualifier::Copy:
@@ -1278,7 +1278,7 @@
     case StoreOwnershipQualifier::Unqualified:
       // We should not see loads with unqualified ownership when SILOwnership is
       // enabled.
-      require(F.hasUnqualifiedOwnership(),
+      require(!F.hasQualifiedOwnership(),
               "Qualified store in function with unqualified ownership?!");
       break;
     case StoreOwnershipQualifier::Init:
@@ -1448,14 +1448,14 @@
   void checkRetainValueInst(RetainValueInst *I) {
     require(I->getOperand()->getType().isObject(),
             "Source value should be an object value");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "retain_value is only in functions with unqualified ownership");
   }
 
   void checkRetainValueAddrInst(RetainValueAddrInst *I) {
     require(I->getOperand()->getType().isAddress(),
             "Source value should be an address value");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "retain_value is only in functions with unqualified ownership");
   }
 
@@ -1488,14 +1488,14 @@
   void checkReleaseValueInst(ReleaseValueInst *I) {
     require(I->getOperand()->getType().isObject(),
             "Source value should be an object value");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "release_value is only in functions with unqualified ownership");
   }
 
   void checkReleaseValueAddrInst(ReleaseValueAddrInst *I) {
     require(I->getOperand()->getType().isAddress(),
             "Source value should be an address value");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "release_value is only in functions with unqualified ownership");
   }
 
@@ -1760,12 +1760,12 @@
 
   void checkStrongRetainInst(StrongRetainInst *RI) {
     requireReferenceValue(RI->getOperand(), "Operand of strong_retain");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "strong_retain is only in functions with unqualified ownership");
   }
   void checkStrongReleaseInst(StrongReleaseInst *RI) {
     requireReferenceValue(RI->getOperand(), "Operand of release");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "strong_release is only in functions with unqualified ownership");
   }
   void checkStrongRetainUnownedInst(StrongRetainUnownedInst *RI) {
@@ -1773,16 +1773,16 @@
                                          "Operand of strong_retain_unowned");
     require(unownedType->isLoadable(ResilienceExpansion::Maximal),
             "strong_retain_unowned requires unowned type to be loadable");
-    require(F.hasUnqualifiedOwnership(), "strong_retain_unowned is only in "
-                                         "functions with unqualified "
-                                         "ownership");
+    require(!F.hasQualifiedOwnership(), "strong_retain_unowned is only in "
+                                        "functions with unqualified "
+                                        "ownership");
   }
   void checkUnownedRetainInst(UnownedRetainInst *RI) {
     auto unownedType = requireObjectType(UnownedStorageType, RI->getOperand(),
                                           "Operand of unowned_retain");
     require(unownedType->isLoadable(ResilienceExpansion::Maximal),
             "unowned_retain requires unowned type to be loadable");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "unowned_retain is only in functions with unqualified ownership");
   }
   void checkUnownedReleaseInst(UnownedReleaseInst *RI) {
@@ -1790,7 +1790,7 @@
                                          "Operand of unowned_release");
     require(unownedType->isLoadable(ResilienceExpansion::Maximal),
             "unowned_release requires unowned type to be loadable");
-    require(F.hasUnqualifiedOwnership(),
+    require(!F.hasQualifiedOwnership(),
             "unowned_release is only in functions with unqualified ownership");
   }
   void checkDeallocStackInst(DeallocStackInst *DI) {
@@ -3465,7 +3465,7 @@
                     SOI->getOperand()->getType(),
                 "Switch enum default block should have one argument that is "
                 "the same as the input type");
-      } else if (F.hasUnqualifiedOwnership()) {
+      } else if (!F.hasQualifiedOwnership()) {
         require(SOI->getDefaultBB()->args_empty(),
                 "switch_enum default destination must take no arguments");
       }
diff --git a/lib/SILGen/SILGenEpilog.cpp b/lib/SILGen/SILGenEpilog.cpp
index 49e5e38..fc06a3e 100644
--- a/lib/SILGen/SILGenEpilog.cpp
+++ b/lib/SILGen/SILGenEpilog.cpp
@@ -67,36 +67,36 @@
   return SGF.B.createTuple(loc, resultType, directResults);
 }
 
-std::pair<Optional<SILValue>, SILLocation>
-SILGenFunction::emitEpilogBB(SILLocation TopLevel) {
-  assert(ReturnDest.getBlock() && "no epilog bb prepared?!");
-  SILBasicBlock *epilogBB = ReturnDest.getBlock();
-  SILLocation ImplicitReturnFromTopLevel =
-    ImplicitReturnLocation::getImplicitReturnLoc(TopLevel);
-  SmallVector<SILValue, 4> directResults;
-  Optional<SILLocation> returnLoc = None;
+static Optional<SILLocation>
+prepareForEpilogBlockEmission(SILGenFunction &SGF, SILLocation topLevel,
+                              SILBasicBlock *epilogBB,
+                              SmallVectorImpl<SILValue> &directResults) {
+  SILLocation implicitReturnFromTopLevel =
+      ImplicitReturnLocation::getImplicitReturnLoc(topLevel);
 
-  // If the current BB isn't terminated, and we require a return, then we
+  // If the current BB we are inserting into isn't terminated, and we require a
+  // return, then we
   // are not allowed to fall off the end of the function and can't reach here.
-  if (NeedsReturn && B.hasValidInsertionPoint())
-    B.createUnreachable(ImplicitReturnFromTopLevel);
+  if (SGF.NeedsReturn && SGF.B.hasValidInsertionPoint())
+    SGF.B.createUnreachable(implicitReturnFromTopLevel);
 
   if (epilogBB->pred_empty()) {
     // If the epilog was not branched to at all, kill the BB and
     // just emit the epilog into the current BB.
     while (!epilogBB->empty())
       epilogBB->back().eraseFromParent();
-    eraseBasicBlock(epilogBB);
+    SGF.eraseBasicBlock(epilogBB);
 
     // If the current bb is terminated then the epilog is just unreachable.
-    if (!B.hasValidInsertionPoint())
-      return { None, TopLevel };
+    if (!SGF.B.hasValidInsertionPoint())
+      return None;
 
     // We emit the epilog at the current insertion point.
-    returnLoc = ImplicitReturnFromTopLevel;
+    return implicitReturnFromTopLevel;
+  }
 
-  } else if (std::next(epilogBB->pred_begin()) == epilogBB->pred_end()
-             && !B.hasValidInsertionPoint()) {
+  if (std::next(epilogBB->pred_begin()) == epilogBB->pred_end() &&
+      !SGF.B.hasValidInsertionPoint()) {
     // If the epilog has a single predecessor and there's no current insertion
     // point to fall through from, then we can weld the epilog to that
     // predecessor BB.
@@ -113,14 +113,15 @@
       epilogBB->getArgument(index)->replaceAllUsesWith(result);
     }
 
+    Optional<SILLocation> returnLoc;
     // If we are optimizing, we should use the return location from the single,
     // previously processed, return statement if any.
     if (predBranch->getLoc().is<ReturnLocation>()) {
       returnLoc = predBranch->getLoc();
     } else {
-      returnLoc = ImplicitReturnFromTopLevel;
+      returnLoc = implicitReturnFromTopLevel;
     }
-    
+
     // Kill the branch to the now-dead epilog BB.
     pred->erase(predBranch);
 
@@ -128,37 +129,55 @@
     pred->spliceAtEnd(epilogBB);
 
     // Finally we can erase the epilog BB.
-    eraseBasicBlock(epilogBB);
+    SGF.eraseBasicBlock(epilogBB);
 
     // Emit the epilog into its former predecessor.
-    B.setInsertionPoint(pred);
-  } else {
-    // Move the epilog block to the end of the ordinary section.
-    auto endOfOrdinarySection = StartOfPostmatter;
-    B.moveBlockTo(epilogBB, endOfOrdinarySection);
-
-    // Emit the epilog into the epilog bb. Its arguments are the
-    // direct results.
-    directResults.append(epilogBB->args_begin(), epilogBB->args_end());
-
-    // If we are falling through from the current block, the return is implicit.
-    B.emitBlock(epilogBB, ImplicitReturnFromTopLevel);
+    SGF.B.setInsertionPoint(pred);
+    return returnLoc;
   }
-  
-  // Emit top-level cleanups into the epilog block.
-  assert(!Cleanups.hasAnyActiveCleanups(getCleanupsDepth(),
-                                        ReturnDest.getDepth()) &&
-         "emitting epilog in wrong scope");
 
-  auto cleanupLoc = CleanupLocation::get(TopLevel);
-  Cleanups.emitCleanupsForReturn(cleanupLoc);
+  // Move the epilog block to the end of the ordinary section.
+  auto endOfOrdinarySection = SGF.StartOfPostmatter;
+  SGF.B.moveBlockTo(epilogBB, endOfOrdinarySection);
+
+  // Emit the epilog into the epilog bb. Its arguments are the
+  // direct results.
+  directResults.append(epilogBB->args_begin(), epilogBB->args_end());
+
+  // If we are falling through from the current block, the return is implicit.
+  SGF.B.emitBlock(epilogBB, implicitReturnFromTopLevel);
 
   // If the return location is known to be that of an already
   // processed return, use it. (This will get triggered when the
   // epilog logic is simplified.)
   //
   // Otherwise make the ret instruction part of the cleanups.
-  if (!returnLoc) returnLoc = cleanupLoc;
+  auto cleanupLoc = CleanupLocation::get(topLevel);
+  return cleanupLoc;
+}
+
+std::pair<Optional<SILValue>, SILLocation>
+SILGenFunction::emitEpilogBB(SILLocation topLevel) {
+  assert(ReturnDest.getBlock() && "no epilog bb prepared?!");
+  SILBasicBlock *epilogBB = ReturnDest.getBlock();
+  SmallVector<SILValue, 8> directResults;
+
+  // Prepare the epilog block for emission. If we need to actually emit the
+  // block, we return a real SILLocation. Otherwise, the epilog block is
+  // actually unreachable and we can just return early.
+  auto returnLoc =
+      prepareForEpilogBlockEmission(*this, topLevel, epilogBB, directResults);
+  if (!returnLoc.hasValue()) {
+    return {None, topLevel};
+  }
+
+  // Emit top-level cleanups into the epilog block.
+  assert(!Cleanups.hasAnyActiveCleanups(getCleanupsDepth(),
+                                        ReturnDest.getDepth()) &&
+         "emitting epilog in wrong scope");
+
+  auto cleanupLoc = CleanupLocation::get(topLevel);
+  Cleanups.emitCleanupsForReturn(cleanupLoc);
 
   // Build the return value.  We don't do this if there are no direct
   // results; this can happen for void functions, but also happens when
@@ -167,10 +186,10 @@
   SILValue returnValue;
   if (!directResults.empty()) {
     assert(directResults.size() == F.getConventions().getNumDirectSILResults());
-    returnValue = buildReturnValue(*this, TopLevel, directResults);
+    returnValue = buildReturnValue(*this, topLevel, directResults);
   }
 
-  return { returnValue, *returnLoc };
+  return {returnValue, *returnLoc};
 }
 
 SILLocation SILGenFunction::
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index d503baa..97650fe 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -467,7 +467,7 @@
 
   // Subtype conversions:
 
-  //  - upcasts
+  //  - upcasts for classes
   if (outputSubstType->getClassOrBoundGenericClass() &&
       inputSubstType->getClassOrBoundGenericClass()) {
     auto class1 = inputSubstType->getClassOrBoundGenericClass();
@@ -490,6 +490,32 @@
     }
   }
 
+  // - upcasts for collections
+  if (outputSubstType->getStructOrBoundGenericStruct() &&
+      inputSubstType->getStructOrBoundGenericStruct()) {
+    auto *inputStruct = inputSubstType->getStructOrBoundGenericStruct();
+    auto *outputStruct = outputSubstType->getStructOrBoundGenericStruct();
+
+    // Attempt collection upcast only if input and output declarations match.
+    if (inputStruct == outputStruct) {
+      FuncDecl *fn = nullptr;
+      auto &ctx = SGF.getASTContext();
+      if (inputStruct == ctx.getArrayDecl()) {
+        fn = SGF.SGM.getArrayForceCast(Loc);
+      } else if (inputStruct == ctx.getDictionaryDecl()) {
+        fn = SGF.SGM.getDictionaryUpCast(Loc);
+      } else if (inputStruct == ctx.getSetDecl()) {
+        fn = SGF.SGM.getSetUpCast(Loc);
+      } else {
+        llvm_unreachable("unsupported collection upcast kind");
+      }
+
+      return SGF.emitCollectionConversion(Loc, fn, inputSubstType,
+                                          outputSubstType, v, ctxt)
+                .getScalarValue();
+    }
+  }
+
   //  - upcasts from an archetype
   if (outputSubstType->getClassOrBoundGenericClass()) {
     if (auto archetypeType = dyn_cast<ArchetypeType>(inputSubstType)) {
diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp
index ddaacb2..0875a1f 100644
--- a/lib/SILOptimizer/IPO/CapturePromotion.cpp
+++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp
@@ -435,7 +435,7 @@
       Orig->getDebugScope());
   for (auto &Attr : Orig->getSemanticsAttrs())
     Fn->addSemanticsAttr(Attr);
-  if (Orig->hasUnqualifiedOwnership()) {
+  if (!Orig->hasQualifiedOwnership()) {
     Fn->setUnqualifiedOwnership();
   }
   return Fn;
@@ -534,7 +534,7 @@
 void
 ClosureCloner::visitStrongReleaseInst(StrongReleaseInst *Inst) {
   assert(
-      Inst->getFunction()->hasUnqualifiedOwnership() &&
+      !Inst->getFunction()->hasQualifiedOwnership() &&
       "Should not see strong release in a function with qualified ownership");
   SILValue Operand = Inst->getOperand();
   if (auto *A = dyn_cast<SILArgument>(Operand)) {
@@ -680,7 +680,7 @@
     // Loads of a struct_element_addr of an argument get replaced with a
     // struct_extract of the new passed in value. The value should be borrowed
     // already, so we can just extract the value.
-    assert(getBuilder().getFunction().hasUnqualifiedOwnership() ||
+    assert(!getBuilder().getFunction().hasQualifiedOwnership() ||
            Val.getOwnershipKind().isTrivialOr(ValueOwnershipKind::Guaranteed));
     Val = getBuilder().emitStructExtract(LI->getLoc(), Val, SEAI->getField(),
                                          LI->getType());
diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp
index 37b2d14..70c507d 100644
--- a/lib/SILOptimizer/IPO/CapturePropagation.cpp
+++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp
@@ -262,7 +262,7 @@
       OrigF->getEntryCount(), OrigF->isThunk(), OrigF->getClassSubclassScope(),
       OrigF->getInlineStrategy(), OrigF->getEffectsKind(),
       /*InsertBefore*/ OrigF, OrigF->getDebugScope());
-  if (OrigF->hasUnqualifiedOwnership()) {
+  if (!OrigF->hasQualifiedOwnership()) {
     NewF->setUnqualifiedOwnership();
   }
   DEBUG(llvm::dbgs() << "  Specialize callee as ";
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index c21f9c9..fdee276 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -633,7 +633,7 @@
       ClosureUser->isThunk(), ClosureUser->getClassSubclassScope(),
       ClosureUser->getInlineStrategy(), ClosureUser->getEffectsKind(),
       ClosureUser, ClosureUser->getDebugScope());
-  if (ClosureUser->hasUnqualifiedOwnership()) {
+  if (!ClosureUser->hasQualifiedOwnership()) {
     Fn->setUnqualifiedOwnership();
   }
   for (auto &Attr : ClosureUser->getSemanticsAttrs())
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 4d3581c..bccb8c0 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -269,7 +269,7 @@
       IsBare_t::IsBare, IsTransparent_t::IsNotTransparent,
       IsSerialized_t::IsSerialized);
   GetterF->setDebugScope(Store->getFunction()->getDebugScope());
-  if (Store->getFunction()->hasUnqualifiedOwnership())
+  if (!Store->getFunction()->hasQualifiedOwnership())
     GetterF->setUnqualifiedOwnership();
   auto *EntryBB = GetterF->createBasicBlock();
   // Copy instructions into GetterF
@@ -523,7 +523,7 @@
       getterName, SILLinkage::Private, LoweredType,
       IsBare_t::IsBare, IsTransparent_t::IsNotTransparent,
       IsSerialized_t::IsSerialized);
-  if (InitF->hasUnqualifiedOwnership())
+  if (!InitF->hasQualifiedOwnership())
     GetterF->setUnqualifiedOwnership();
 
   auto *EntryBB = GetterF->createBasicBlock();
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 4197def..9e945dd 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -601,7 +601,7 @@
 }
 
 /// Returns the address of an object with which the stack location \p ASI is
-/// initialized. This is either a init_existential_addr or the source of a
+/// initialized. This is either a init_existential_addr or the destination of a
 /// copy_addr. Returns a null value if the address does not dominate the
 /// alloc_stack user \p ASIUser.
 /// If the value is copied from another stack location, \p isCopied is set to
@@ -808,21 +808,45 @@
   return NewAI.getInstruction();
 }
 
+namespace {
+/// Record conformance and concrete type info derived from init_existential.
+struct ConformanceAndConcreteType {
+  Optional<ProtocolConformanceRef> Conformance;
+  // Concrete type of self from the found init_existential.
+  CanType ConcreteType;
+  // For opened existentials, record the type definition.
+  SingleValueInstruction *ConcreteTypeDef = nullptr;
+  // The value of concrete type used to initialize the existential.
+  SILValue NewSelf;
+  // The value that owns the lifetime of NewSelf.
+  // init_existential_addr's source address.
+  // init_existential_ref's defined value.
+  SILValue NewSelfOwner;
+  ArrayRef<ProtocolConformanceRef> Conformances;
+
+  ConformanceAndConcreteType(ASTContext &Ctx, FullApplySite AI,
+                             SILInstruction *InitExistential,
+                             ProtocolDecl *Protocol);
+
+  bool isValid() const {
+    return Conformance.hasValue() && ConcreteType && NewSelf;
+  }
+
+  ProtocolConformanceRef getConformance() const {
+    return Conformance.getValue();
+  }
+};
+} // namespace
+
 /// Derive a concrete type of self and conformance from the init_existential
 /// instruction.
-static Optional<std::tuple<ProtocolConformanceRef, CanType,
-                           SingleValueInstruction*, SILValue>>
-getConformanceAndConcreteType(ASTContext &Ctx,
-                              FullApplySite AI,
-                              SILInstruction *InitExistential,
-                              ProtocolDecl *Protocol,
-                              ArrayRef<ProtocolConformanceRef> &Conformances) {
-  // Try to derive the concrete type of self from the found init_existential.
-  CanType ConcreteType;
+/// If successful, initializes a valid ConformanceAndConcreteType.
+ConformanceAndConcreteType::ConformanceAndConcreteType(
+    ASTContext &Ctx, FullApplySite AI, SILInstruction *InitExistential,
+    ProtocolDecl *Protocol) {
+
   // The existential type result of the found init_existential.
   CanType ExistentialType;
-  SingleValueInstruction *ConcreteTypeDef = nullptr;
-  SILValue NewSelf;
 
   // FIXME: Factor this out. All we really need here is the ExistentialSig
   // below, which should be stored directly in the SILInstruction.
@@ -846,7 +870,8 @@
       ConcreteType = cast<MetatypeType>(ConcreteType).getInstanceType();
     }
   } else {
-    return None;
+    assert(!isValid());
+    return;
   }
 
   // Construct a substitution map from the existential type's generic
@@ -860,9 +885,8 @@
   // If the requirement is in a base protocol that is refined by the
   // conforming protocol, fish out the exact conformance for the base
   // protocol using the substitution map.
-  auto ExactConformance = SubMap.lookupConformance(
-    CanType(ExistentialSig->getGenericParams()[0]),
-    Protocol);
+  Conformance = SubMap.lookupConformance(
+      CanType(ExistentialSig->getGenericParams()[0]), Protocol);
 
   // If the concrete type is another existential, we're "forwarding" an
   // opened existential type, so we must keep track of the original
@@ -878,127 +902,149 @@
           InitExistential->getTypeDependentOperands()[0].get());
     }
   }
-
-  return std::make_tuple(*ExactConformance, ConcreteType,
-                         ConcreteTypeDef, NewSelf);
+  assert(isValid());
 }
 
-static bool isUseAfterFree(SILValue val, SILInstruction *Apply,
-                           DominanceInfo *DT) {
-  for (auto Use : val->getUses()) {
-    auto *User = Use->getUser();
-    if (!isa<DeallocStackInst>(User) && !isa<DestroyAddrInst>(User) &&
-        !isa<DeinitExistentialAddrInst>(User)) {
-      continue;
-    }
-    if (!DT->properlyDominates(Apply, User)) {
-      // we have use-after-free - Conservative heuristic
-      // Non conservative solution would require data flow analysis
+// Return true if the given value is guaranteed to be initialized across the
+// given call site.
+//
+// It's possible for an address to be initialized/deinitialized/reinitialized.
+// Rather than keeping track of liveness, we very conservatively check that all
+// deinitialization occures after the call.
+//
+// FIXME: Rather than whitelisting, use a common AllocStackAnalyzer.
+static bool isAddressInitializedAtCall(SILValue addr, SILInstruction *AI,
+                                       DominanceInfo *DT) {
+  auto isDestroy = [](Operand *use) {
+    switch (use->getUser()->getKind()) {
+    default:
+      return false;
+    case SILInstructionKind::DestroyAddrInst:
+    case SILInstructionKind::DeinitExistentialAddrInst:
       return true;
+    case SILInstructionKind::CopyAddrInst: {
+      auto *copy = cast<CopyAddrInst>(use->getUser());
+      return copy->getSrc() == use->get() && copy->isTakeOfSrc();
+    }
+    }
+  };
+  for (auto use : addr->getUses()) {
+    SILInstruction *user = use->getUser();
+    if (isDestroy(use)) {
+      if (!DT->properlyDominates(AI, user))
+        return false;
+    } else {
+      assert(isa<CopyAddrInst>(user) || isa<InitExistentialAddrInst>(user)
+             || isa<OpenExistentialAddrInst>(user)
+             || isa<DeallocStackInst>(user)
+             || isDebugInst(user) && "Unexpected instruction");
     }
   }
-  return false;
+  return true;
 }
 
+/// Scoped registration of opened archetypes.
+class RAIIOpenedArchetypesTracker {
+  SILBuilder &B;
+  // The original tracker may be null.
+  SILOpenedArchetypesTracker *OldOpenedArchetypesTracker;
+  SILOpenedArchetypesTracker OpenedArchetypesTracker;
+
+public:
+  RAIIOpenedArchetypesTracker(SILBuilder &B)
+    : B(B), OldOpenedArchetypesTracker(B.getOpenedArchetypesTracker()),
+    OpenedArchetypesTracker(&B.getFunction()) {
+    B.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
+  }
+
+  SILOpenedArchetypesTracker &getTracker() {
+    return OpenedArchetypesTracker;
+  }
+
+  ~RAIIOpenedArchetypesTracker() {
+    B.setOpenedArchetypesTracker(OldOpenedArchetypesTracker);
+  }
+};
+
 /// Propagate information about a concrete type from init_existential_addr
 /// or init_existential_ref into witness_method conformances and into
 /// apply instructions.
 /// This helps the devirtualizer to replace witness_method by
 /// class_method instructions and then devirtualize.
-SILInstruction *
-SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
-    ProtocolDecl *Protocol,
-    llvm::function_ref<void(CanType , ProtocolConformanceRef)> Propagate) {
+SILInstruction *SILCombiner::propagateConcreteTypeOfInitExistential(
+    FullApplySite Apply, ProtocolDecl *Protocol,
+    llvm::function_ref<void(CanType, ProtocolConformanceRef)> Propagate) {
 
   ASTContext &Ctx = Builder.getASTContext();
 
   // Get the self argument.
-  SILValue Self;
-  if (auto *Apply = dyn_cast<ApplyInst>(AI)) {
-    if (Apply->hasSelfArgument())
-      Self = Apply->getSelfArgument();
-  } else if (auto *Apply = dyn_cast<TryApplyInst>(AI)) {
-    if (Apply->hasSelfArgument())
-      Self = Apply->getSelfArgument();
-  }
-
-  assert(Self && "Self argument should be present");
+  assert(Apply.hasSelfArgument() && "Self argument should be present");
+  SILValue Self = Apply.getSelfArgument();
 
   // Try to find the init_existential, which could be used to
   // determine a concrete type of the self.
   ArchetypeType *OpenedArchetype = nullptr;
   SILValue OpenedArchetypeDef;
   bool isCopied = false;
-  SILInstruction *InitExistential =
-    findInitExistential(AI, Self, OpenedArchetype, OpenedArchetypeDef,
-                        isCopied);
+  SILInstruction *InitExistential = findInitExistential(
+      Apply, Self, OpenedArchetype, OpenedArchetypeDef, isCopied);
   if (!InitExistential)
     return nullptr;
 
   // Try to derive the concrete type of self and a related conformance from
   // the found init_existential.
-  ArrayRef<ProtocolConformanceRef> Conformances;
-  auto ConformanceAndConcreteType =
-    getConformanceAndConcreteType(Ctx, AI, InitExistential,
-                                  Protocol, Conformances);
-  if (!ConformanceAndConcreteType)
+  ConformanceAndConcreteType CCT(Ctx, Apply, InitExistential, Protocol);
+  if (!CCT.isValid())
     return nullptr;
 
-  ProtocolConformanceRef Conformance = std::get<0>(*ConformanceAndConcreteType);
-  CanType ConcreteType = std::get<1>(*ConformanceAndConcreteType);
-  auto ConcreteTypeDef = std::get<2>(*ConformanceAndConcreteType);
-  SILValue NewSelf = std::get<3>(*ConformanceAndConcreteType);
-
-  SILOpenedArchetypesTracker *OldOpenedArchetypesTracker =
-      Builder.getOpenedArchetypesTracker();
-
-  SILOpenedArchetypesTracker OpenedArchetypesTracker(AI.getFunction());
-
-  if (ConcreteType->isOpenedExistential()) {
-    // Prepare a mini-mapping for opened archetypes.
-    // SILOpenedArchetypesTracker OpenedArchetypesTracker(*AI.getFunction());
-    OpenedArchetypesTracker.addOpenedArchetypeDef(
-        cast<ArchetypeType>(ConcreteType), ConcreteTypeDef);
-    Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
+  RAIIOpenedArchetypesTracker tempTracker(Builder);
+  if (CCT.ConcreteType->isOpenedExistential()) {
+    // Temporarily record this opened existential def. Don't permanently record
+    // in the Builder's tracker because this opened existential's original
+    // dominating def may not have been recorded yet.
+    // FIXME: Redesign the tracker. This is not robust.
+    tempTracker.getTracker().addOpenedArchetypeDef(
+        cast<ArchetypeType>(CCT.ConcreteType), CCT.ConcreteTypeDef);
   }
 
   // Propagate the concrete type into the callee-operand if required.
-  Propagate(ConcreteType, Conformance);
+  Propagate(CCT.ConcreteType, CCT.getConformance());
 
-  if (isCopied) {
+  auto canReplaceCopiedSelf = [&]() {
     // If the witness method is mutating self, we cannot replace self with
     // the source of a copy. Otherwise the call would modify another value than
     // the original self.
-    switch (AI.getArgumentConvention(AI.getNumArguments() - 1)) {
-      case SILArgumentConvention::ConventionType::Indirect_Inout:
-      case SILArgumentConvention::ConventionType::Indirect_InoutAliasable:
-        return nullptr;
-      default:
-        break;
-    }
-    // check if using the value in the apply would cause use-after-free
-    auto *DT = DA->get(AI.getFunction());
-    auto *apply = AI.getInstruction();
-    auto op = InitExistential->getOperand(0);
-    if (isUseAfterFree(op, apply, DT)) {
-      return nullptr;
-    }
-    if (isUseAfterFree(NewSelf, apply, DT)) {
-      return nullptr;
-    }
-  }
+    if (Apply.getOrigCalleeType()->getSelfParameter().isIndirectMutating())
+      return false;
+
+    auto *DT = DA->get(Apply.getFunction());
+    auto *AI = Apply.getInstruction();
+    // Only init_existential_addr may be copied.
+    SILValue existentialAddr =
+        cast<InitExistentialAddrInst>(InitExistential)->getOperand();
+    return isAddressInitializedAtCall(existentialAddr, AI, DT);
+  };
+  if (isCopied && !canReplaceCopiedSelf())
+    return nullptr;
+
   // Create a new apply instruction that uses the concrete type instead
   // of the existential type.
-  auto *NewAI = createApplyWithConcreteType(AI, NewSelf, Self, ConcreteType,
-                                            ConcreteTypeDef, Conformance,
-                                            OpenedArchetype);
-
-  if (ConcreteType->isOpenedExistential())
-    Builder.setOpenedArchetypesTracker(OldOpenedArchetypesTracker);
+  auto *NewAI = createApplyWithConcreteType(
+      Apply, CCT.NewSelf, Self, CCT.ConcreteType, CCT.ConcreteTypeDef,
+      CCT.getConformance(), OpenedArchetype);
 
   return NewAI;
 }
 
+/// Rewrite a witness method's lookup type from an archetype to a concrete type.
+/// Example:
+///   %existential = alloc_stack $Protocol
+///   %value = init_existential_addr %existential : $Concrete
+///   copy_addr ... to %value
+///   %witness = witness_method $@opened
+///   apply %witness<T : Protocol>(%existential)
+///
+/// ==> apply %witness<Concrete : Protocol>(%existential)
 SILInstruction *
 SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
                                                     WitnessMethodInst *WMI) {
@@ -1097,7 +1143,7 @@
       return nullptr;
   }
 
-  // Obtain the protocol whose which should be used by the conformance.
+  // Obtain the protocol which should be used by the conformance.
   auto *AFD = dyn_cast<AbstractFunctionDecl>(Callee->getDeclContext());
   if (!AFD)
     return nullptr;
diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
index 996215f..05caf52 100644
--- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
+++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
@@ -648,7 +648,7 @@
   for (auto &Attr : Orig->getSemanticsAttrs()) {
     Fn->addSemanticsAttr(Attr);
   }
-  if (Orig->hasUnqualifiedOwnership()) {
+  if (!Orig->hasQualifiedOwnership()) {
     Fn->setUnqualifiedOwnership();
   }
   return Fn;
diff --git a/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
index 0a42821..cf293f0 100644
--- a/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
+++ b/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
@@ -662,7 +662,7 @@
                           F->isSerialized(), F->getEntryCount(), F->isThunk(),
                           F->getClassSubclassScope(), F->getInlineStrategy(),
                           F->getEffectsKind(), nullptr, F->getDebugScope());
-  if (F->hasUnqualifiedOwnership()) {
+  if (!F->hasQualifiedOwnership()) {
     NewF->setUnqualifiedOwnership();
   }
 
diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp
index 6b2687c..49f8e41 100644
--- a/lib/SILOptimizer/Transforms/Outliner.cpp
+++ b/lib/SILOptimizer/Transforms/Outliner.cpp
@@ -361,7 +361,7 @@
     return std::make_pair(nullptr, std::prev(StartBB->end()));
   }
 
-  if (OutlinedEntryBB->getParent()->hasUnqualifiedOwnership())
+  if (!OutlinedEntryBB->getParent()->hasQualifiedOwnership())
     Fun->setUnqualifiedOwnership();
 
   Fun->setInlineStrategy(NoInline);
@@ -427,7 +427,8 @@
   SILValue Instance =
       FirstInst != ObjCMethod ? FirstInst : ObjCMethod->getOperand();
   if (!ObjCMethod || !ObjCMethod->hasOneUse() ||
-      ObjCMethod->getOperand() != Instance)
+      ObjCMethod->getOperand() != Instance ||
+      ObjCMethod->getFunction()->getLoweredFunctionType()->isPolymorphic())
     return false;
 
   // Don't outline in the outlined function.
@@ -568,7 +569,7 @@
   if (!Load) {
     // Try to match without the load/strong_retain prefix.
     auto *CMI = dyn_cast<ObjCMethodInst>(It);
-    if (!CMI)
+    if (!CMI || CMI->getFunction()->getLoweredFunctionType()->isPolymorphic())
       return false;
     FirstInst = CMI;
   } else
@@ -1044,7 +1045,7 @@
     return std::make_pair(Fun, I);
   }
 
-  if (ObjCMethod->getFunction()->hasUnqualifiedOwnership())
+  if (!ObjCMethod->getFunction()->hasQualifiedOwnership())
     Fun->setUnqualifiedOwnership();
 
   Fun->setInlineStrategy(NoInline);
@@ -1104,7 +1105,8 @@
   clearState();
 
   ObjCMethod = dyn_cast<ObjCMethodInst>(I);
-  if (!ObjCMethod)
+  if (!ObjCMethod ||
+      ObjCMethod->getFunction()->getLoweredFunctionType()->isPolymorphic())
     return false;
   auto *Use = ObjCMethod->getSingleUse();
   if (!Use)
diff --git a/lib/SILOptimizer/Utils/GenericCloner.cpp b/lib/SILOptimizer/Utils/GenericCloner.cpp
index 1b825bc..51f6646 100644
--- a/lib/SILOptimizer/Utils/GenericCloner.cpp
+++ b/lib/SILOptimizer/Utils/GenericCloner.cpp
@@ -48,7 +48,7 @@
   for (auto &Attr : Orig->getSemanticsAttrs()) {
     NewF->addSemanticsAttr(Attr);
   }
-  if (Orig->hasUnqualifiedOwnership()) {
+  if (!Orig->hasQualifiedOwnership()) {
     NewF->setUnqualifiedOwnership();
   }
   return NewF;
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index 494b080..e7bf2a8 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -1863,7 +1863,7 @@
           SpecializedF->getGenericEnvironment()) ||
          (!SpecializedF->getLoweredFunctionType()->isPolymorphic() &&
           !SpecializedF->getGenericEnvironment()));
-  assert(SpecializedF->hasUnqualifiedOwnership());
+  assert(!SpecializedF->hasQualifiedOwnership());
   // Check if this specialization should be linked for prespecialization.
   linkSpecialization(M, SpecializedF);
   // Store the meta-information about how this specialization was created.
@@ -2112,7 +2112,7 @@
   // inline qualified into unqualified functions /or/ have the
   // OwnershipModelEliminator run as part of the normal compilation pipeline
   // (which we are not doing yet).
-  if (SpecializedFunc->hasUnqualifiedOwnership()) {
+  if (!SpecializedFunc->hasQualifiedOwnership()) {
     Thunk->setUnqualifiedOwnership();
   }
 
@@ -2348,7 +2348,7 @@
                        << SpecializedF->getName() << "\n"
                        << "Specialized function type: "
                        << SpecializedF->getLoweredFunctionType() << "\n");
-    assert(SpecializedF->hasUnqualifiedOwnership());
+    assert(!SpecializedF->hasQualifiedOwnership());
     NewFunctions.push_back(SpecializedF);
   }
 
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 795b784..0625e61 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -161,8 +161,6 @@
     if (!conformance)
       return nullptr;
   }
-  assert(conformance->getConditionalRequirements().empty() &&
-         "unhandled conditional conformance");
 
   // For a type with dependent conformance, just return the requirement from
   // the protocol. There are no protocol conformance tables.
@@ -6608,8 +6606,6 @@
   auto conformance = tc.conformsToProtocol(type, protocol, cs.DC,
                                            ConformanceCheckFlags::InExpression);
   assert(conformance && "must conform to literal protocol");
-  assert(conformance->getConditionalRequirements().empty() &&
-         "unexpected conditional requirements");
 
   // Figure out the (non-builtin) argument type if there is one.
   Type argType;
@@ -6752,8 +6748,6 @@
   auto conformance = tc.conformsToProtocol(type, protocol, cs.DC,
                                            ConformanceCheckFlags::InExpression);
   assert(conformance && "must conform to literal protocol");
-  assert(conformance->getConditionalRequirements().empty() &&
-         "unexpected conditional requirements");
 
   // Dig out the literal type and perform a builtin literal conversion to it.
   if (!literalType.empty()) {
@@ -7514,9 +7508,6 @@
   }
     
   switch (fix.first.getKind()) {
-  case FixKind::None:
-    llvm_unreachable("no-fix marker should never make it into solution");
-
   case FixKind::ForceOptional: {
     const Expr *unwrapped = affected->getValueProvidingExpr();
     auto type = solution.simplifyType(getType(affected))
diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp
index 6af1819..8ad0c2d 100644
--- a/lib/Sema/CSBindings.cpp
+++ b/lib/Sema/CSBindings.cpp
@@ -278,6 +278,7 @@
 
         result.foundLiteralBinding(constraint->getProtocol());
         result.addPotentialBinding({defaultType, AllowedBindingKind::Subtypes,
+                                    constraint->getKind(),
                                     constraint->getProtocol()});
         continue;
       }
@@ -305,6 +306,7 @@
         result.foundLiteralBinding(constraint->getProtocol());
         exactTypes.insert(defaultType->getCanonicalType());
         result.addPotentialBinding({defaultType, AllowedBindingKind::Subtypes,
+                                    constraint->getKind(),
                                     constraint->getProtocol()});
       }
 
@@ -481,11 +483,11 @@
     }
 
     if (exactTypes.insert(type->getCanonicalType()).second)
-      result.addPotentialBinding({type, kind, None},
+      result.addPotentialBinding({type, kind, constraint->getKind()},
                                  /*allowJoinMeet=*/!adjustedIUO);
     if (alternateType &&
         exactTypes.insert(alternateType->getCanonicalType()).second)
-      result.addPotentialBinding({alternateType, kind, None},
+      result.addPotentialBinding({alternateType, kind, constraint->getKind()},
                                  /*allowJoinMeet=*/false);
   }
 
@@ -566,8 +568,9 @@
       continue;
 
     ++result.NumDefaultableBindings;
-    result.addPotentialBinding(
-        {type, AllowedBindingKind::Exact, None, constraint->getLocator()});
+    result.addPotentialBinding({type, AllowedBindingKind::Exact,
+                                constraint->getKind(), None,
+                                constraint->getLocator()});
   }
 
   // Determine if the bindings only constrain the type variable from above with
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 3ab4869..b63727a 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -2090,8 +2090,7 @@
     }
     
     // Special implicit nominal conversions.
-    if (!type1->is<LValueType>() &&
-        kind >= ConstraintKind::Conversion) {
+    if (!type1->is<LValueType>() && kind >= ConstraintKind::Subtype) {
       // Array -> Array.
       if (isArrayType(desugar1) && isArrayType(desugar2)) {
         assert(!type2->is<LValueType>() && "Unexpected lvalue type!");
@@ -2395,13 +2394,6 @@
         continue;
       }
 
-      // If the first thing we found is a fix, add a "don't fix" marker.
-      if (conversionsOrFixes.empty()) {
-        constraints.push_back(
-          Constraint::createFixed(*this, constraintKind, FixKind::None,
-                                  type1, type2, fixedLocator));
-      }
-
       auto fix = *potential.getFix();
       constraints.push_back(
         Constraint::createFixed(*this, constraintKind, fix, type1, type2,
@@ -4193,7 +4185,21 @@
   ConstraintLocatorBuilder outerLocator =
     getConstraintLocator(anchor, parts, locator.getSummaryFlags());
 
-retry:
+  unsigned unwrapCount = 0;
+  if (shouldAttemptFixes()) {
+    // If we have an optional type, try forcing it to see if that
+    // helps. Note that we only deal with function and metatype types
+    // below, so there is no reason not to attempt to strip these off
+    // immediately.
+    while (auto objectType2 = desugar2->getOptionalObjectType()) {
+      type2 = objectType2;
+      desugar2 = type2->getDesugaredType();
+
+      // Track how many times we do this so that we can record a fix for each.
+      ++unwrapCount;
+    }
+  }
+
   // For a function, bind the output and convert the argument to the input.
   auto func1 = type1->castTo<FunctionType>();
   if (auto func2 = dyn_cast<FunctionType>(desugar2)) {
@@ -4221,6 +4227,11 @@
           == SolutionKind::Error)
       return SolutionKind::Error;
 
+    // Record any fixes we attempted to get to the correct solution.
+    while (unwrapCount-- > 0)
+      if (recordFix(FixKind::ForceOptional, getConstraintLocator(locator)))
+        return SolutionKind::Error;
+
     return SolutionKind::Solved;
   }
 
@@ -4231,23 +4242,18 @@
       return formUnsolved();
 
     // Construct the instance from the input arguments.
-    return simplifyConstructionConstraint(instance2, func1, subflags,
+    auto simplified = simplifyConstructionConstraint(instance2, func1, subflags,
                                           /*FIXME?*/ DC,
                                           FunctionRefKind::SingleApply,
                                           getConstraintLocator(outerLocator));
-  }
 
-  if (!shouldAttemptFixes())
-    return SolutionKind::Error;
+    // Record any fixes we attempted to get to the correct solution.
+    if (simplified == SolutionKind::Solved)
+      while (unwrapCount-- > 0)
+        if (recordFix(FixKind::ForceOptional, getConstraintLocator(locator)))
+          return SolutionKind::Error;
 
-  // If we're coming from an optional type, unwrap the optional and try again.
-  if (auto objectType2 = desugar2->getOptionalObjectType()) {
-    if (recordFix(FixKind::ForceOptional, getConstraintLocator(locator)))
-      return SolutionKind::Error;
-
-    type2 = objectType2;
-    desugar2 = type2->getDesugaredType();
-    goto retry;
+    return simplified;
   }
 
   return SolutionKind::Error;
@@ -4729,15 +4735,15 @@
   }
 
   // Record the fix.
-  if (fix.getKind() != FixKind::None) {
-    // Increase the score. If this would make the current solution worse than
-    // the best solution we've seen already, stop now.
-    increaseScore(SK_Fix);
-    if (worseThanBestSolution())
-      return true;
 
-    Fixes.push_back({fix, getConstraintLocator(locator)});
-  }
+  // Increase the score. If this would make the current solution worse than
+  // the best solution we've seen already, stop now.
+  increaseScore(SK_Fix);
+  if (worseThanBestSolution())
+    return true;
+
+  Fixes.push_back({fix, getConstraintLocator(locator)});
+
   return false;
 }
 
@@ -4746,31 +4752,40 @@
                                         ConstraintKind matchKind,
                                         TypeMatchOptions flags,
                                         ConstraintLocatorBuilder locator) {
-  if (recordFix(fix, locator))
-    return SolutionKind::Error;
-
   // Try with the fix.
   TypeMatchOptions subflags =
     getDefaultDecompositionOptions(flags) | TMF_ApplyingFix;
   switch (fix.getKind()) {
-  case FixKind::None:
-    return matchTypes(type1, type2, matchKind, subflags, locator);
-
   case FixKind::ForceOptional:
-  case FixKind::OptionalChaining:
+  case FixKind::OptionalChaining: {
     // Assume that '!' was applied to the first type.
-    return matchTypes(type1->getRValueObjectType()->getOptionalObjectType(),
-                      type2, matchKind, subflags, locator);
+    auto result =
+        matchTypes(type1->getRValueObjectType()->getOptionalObjectType(), type2,
+                   matchKind, subflags, locator);
+    if (result == SolutionKind::Solved)
+      if (recordFix(fix, locator))
+        return SolutionKind::Error;
 
+    return result;
+  }
   case FixKind::ForceDowncast:
     // These work whenever they are suggested.
+    if (recordFix(fix, locator))
+      return SolutionKind::Error;
+
     return SolutionKind::Solved;
 
-  case FixKind::AddressOf:
+  case FixKind::AddressOf: {
     // Assume that '&' was applied to the first type, turning an lvalue into
     // an inout.
-    return matchTypes(InOutType::get(type1->getRValueType()), type2,
-                      matchKind, subflags, locator);
+    auto result = matchTypes(InOutType::get(type1->getRValueType()), type2,
+                             matchKind, subflags, locator);
+    if (result == SolutionKind::Solved)
+      if (recordFix(fix, locator))
+        return SolutionKind::Error;
+
+    return result;
+  }
 
   case FixKind::CoerceToCheckedCast:
     llvm_unreachable("handled elsewhere");
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 7433d6c..66ac650 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -650,6 +650,21 @@
         }
         type = openUnboundGenericType(type, typeVar->getImpl().getLocator());
         type = type->reconstituteSugar(/*recursive=*/false);
+      } else if ((binding.BindingSource == ConstraintKind::ArgumentConversion ||
+                  binding.BindingSource ==
+                      ConstraintKind::ArgumentTupleConversion) &&
+                 !type->hasTypeVariable() && isCollectionType(type)) {
+        // If the type binding comes from the argument conversion, let's
+        // instead of binding collection types directly let's try to
+        // bind using temporary type variables substituted for element
+        // types, that's going to ensure that subtype relationship is
+        // always preserved.
+        auto *BGT = type->castTo<BoundGenericType>();
+        auto UGT = UnboundGenericType::get(BGT->getDecl(), BGT->getParent(),
+                                           BGT->getASTContext());
+
+        type = openUnboundGenericType(UGT, typeVar->getImpl().getLocator());
+        type = type->reconstituteSugar(/*recursive=*/false);
       }
 
       // FIXME: We want the locator that indicates where the binding came
@@ -697,7 +712,8 @@
           = *((*binding.DefaultedProtocol)->getKnownProtocolKind());
         for (auto altType : getAlternativeLiteralTypes(knownKind)) {
           if (exploredTypes.insert(altType->getCanonicalType()).second)
-            newBindings.push_back({altType, AllowedBindingKind::Subtypes, 
+            newBindings.push_back({altType, AllowedBindingKind::Subtypes,
+                                   binding.BindingSource,
                                    binding.DefaultedProtocol});
         }
       }
@@ -710,7 +726,7 @@
         // Try lvalue qualification in addition to rvalue qualification.
         auto subtype = LValueType::get(type);
         if (exploredTypes.insert(subtype->getCanonicalType()).second)
-          newBindings.push_back({subtype, binding.Kind, None});
+          newBindings.push_back({subtype, binding.Kind, binding.BindingSource});
       }
 
       if (binding.Kind == AllowedBindingKind::Subtypes) {
@@ -719,7 +735,8 @@
           if (scalarIdx >= 0) {
             auto eltType = tupleTy->getElementType(scalarIdx);
             if (exploredTypes.insert(eltType->getCanonicalType()).second)
-              newBindings.push_back({eltType, binding.Kind, None});
+              newBindings.push_back(
+                  {eltType, binding.Kind, binding.BindingSource});
           }
         }
 
@@ -733,10 +750,12 @@
             if (auto otherTypeVar = objTy->getAs<TypeVariableType>()) {
               if (typeVar->getImpl().canBindToLValue() ==
                   otherTypeVar->getImpl().canBindToLValue()) {
-                newBindings.push_back({objTy, binding.Kind, None});
+                newBindings.push_back(
+                    {objTy, binding.Kind, binding.BindingSource});
               }
             } else {
-              newBindings.push_back({objTy, binding.Kind, None});
+              newBindings.push_back(
+                  {objTy, binding.Kind, binding.BindingSource});
             }
           }
         }
@@ -753,7 +772,11 @@
 
         // If we haven't seen this supertype, add it.
         if (exploredTypes.insert((*simpleSuper)->getCanonicalType()).second)
-          newBindings.push_back({*simpleSuper, binding.Kind, None});
+          newBindings.push_back({
+              *simpleSuper,
+              binding.Kind,
+              binding.BindingSource,
+          });
       }
     }
 
diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp
index b23a49c..8d68fa9 100644
--- a/lib/Sema/Constraint.cpp
+++ b/lib/Sema/Constraint.cpp
@@ -493,8 +493,6 @@
 
 StringRef Fix::getName(FixKind kind) {
   switch (kind) {
-  case FixKind::None:
-    return "prevent fixes";
   case FixKind::ForceOptional:
     return "fix: force optional";
   case FixKind::OptionalChaining:
diff --git a/lib/Sema/Constraint.h b/lib/Sema/Constraint.h
index 6c2f36e..fdf369d 100644
--- a/lib/Sema/Constraint.h
+++ b/lib/Sema/Constraint.h
@@ -232,10 +232,6 @@
 /// Describes the kind of fix to apply to the given constraint before
 /// visiting it.
 enum class FixKind : uint8_t {
-  /// No fix, which is used as a placeholder indicating that future processing
-  /// of this constraint should not attempt fixes.
-  None,
-
   /// Introduce a '!' to force an optional unwrap.
   ForceOptional,
     
@@ -264,9 +260,7 @@
   friend class Constraint;
 
 public:
-  Fix() : Kind(FixKind::None), Data(0) { }
-  
-  Fix(FixKind kind) : Kind(kind), Data(0) { 
+  Fix(FixKind kind) : Kind(kind), Data(0) {
     assert(kind != FixKind::ForceDowncast && "Use getForceDowncast()");
   }
 
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index bbdafd8..ca5f5b9 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -577,6 +577,18 @@
   return None;
 }
 
+bool ConstraintSystem::isCollectionType(Type type) {
+  auto &ctx = type->getASTContext();
+  if (auto *structType = type->getAs<BoundGenericStructType>()) {
+    auto *decl = structType->getDecl();
+    if (decl == ctx.getArrayDecl() || decl == ctx.getDictionaryDecl() ||
+        decl == ctx.getSetDecl())
+      return true;
+  }
+
+  return false;
+}
+
 bool ConstraintSystem::isAnyHashableType(Type type) {
   if (auto tv = type->getAs<TypeVariableType>()) {
     auto fixedType = getFixedType(tv);
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 34721cd..506a3d3 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -90,8 +90,10 @@
 
 /// Describes a conversion restriction or a fix.
 struct RestrictionOrFix {
-  ConversionRestrictionKind Restriction;
-  Fix TheFix;
+  union {
+    ConversionRestrictionKind Restriction;
+    Fix TheFix;
+  };
   bool IsRestriction;
 
 public:
@@ -1996,6 +1998,9 @@
   /// element type of the set.
   static Optional<Type> isSetType(Type t);
 
+  /// Determine if the type in question is one of the known collection types.
+  static bool isCollectionType(Type t);
+
   /// \brief Determine if the type in question is AnyHashable.
   bool isAnyHashableType(Type t);
 
@@ -2550,6 +2555,9 @@
     /// The kind of bindings permitted.
     AllowedBindingKind Kind;
 
+    /// The kind of the constraint this binding came from.
+    ConstraintKind BindingSource;
+
     /// The defaulted protocol associated with this binding.
     Optional<ProtocolDecl *> DefaultedProtocol;
 
@@ -2558,9 +2566,11 @@
     ConstraintLocator *DefaultableBinding = nullptr;
 
     PotentialBinding(Type type, AllowedBindingKind kind,
+                     ConstraintKind bindingSource,
                      Optional<ProtocolDecl *> defaultedProtocol = None,
                      ConstraintLocator *defaultableBinding = nullptr)
-        : BindingType(type), Kind(kind), DefaultedProtocol(defaultedProtocol),
+        : BindingType(type), Kind(kind), BindingSource(bindingSource),
+          DefaultedProtocol(defaultedProtocol),
           DefaultableBinding(defaultableBinding) {}
 
     bool isDefaultableBinding() const { return DefaultableBinding != nullptr; }
diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp
index 1a3012c..854bb9d 100644
--- a/lib/Sema/ITCDecl.cpp
+++ b/lib/Sema/ITCDecl.cpp
@@ -342,8 +342,10 @@
         typeAliasDecl->getGenericParams() == nullptr) {
       TypeResolutionOptions options =
                                    TypeResolutionFlags::TypeAliasUnderlyingType;
-      if (typeAliasDecl->getFormalAccess() <= AccessLevel::FilePrivate)
+      if (!typeAliasDecl->getDeclContext()->isCascadingContextForLookup(
+            /*functionsAreNonCascading*/true)) {
         options |= TypeResolutionFlags::KnownNonCascadingDependency;
+      }
 
       // Note: recursion into old type checker is okay when passing in an
       // unsatisfied-dependency callback.
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 3bf3270..08f48a3 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3002,13 +3002,7 @@
     // primitive literal protocols.
     auto conformsToProtocol = [&](KnownProtocolKind protoKind) {
         ProtocolDecl *proto = TC.getProtocol(ED->getLoc(), protoKind);
-        auto conformance =
-            TC.conformsToProtocol(rawTy, proto, ED->getDeclContext(), None);
-        if (conformance)
-          assert(conformance->getConditionalRequirements().empty() &&
-                 "conditionally conforming to literal protocol not currently "
-                 "supported");
-        return conformance;
+        return TC.conformsToProtocol(rawTy, proto, ED->getDeclContext(), None);
     };
 
     static auto otherLiteralProtocolKinds = {
@@ -7358,8 +7352,10 @@
 /// Validate the underlying type of the given typealias.
 static void validateTypealiasType(TypeChecker &tc, TypeAliasDecl *typeAlias) {
   TypeResolutionOptions options = TypeResolutionFlags::TypeAliasUnderlyingType;
-  if (typeAlias->getFormalAccess() <= AccessLevel::FilePrivate)
-    options |= TypeResolutionFlags::KnownNonCascadingDependency;
+  if (!typeAlias->getDeclContext()->isCascadingContextForLookup(
+        /*functionsAreNonCascading*/true)) {
+     options |= TypeResolutionFlags::KnownNonCascadingDependency;
+  }
 
   if (typeAlias->getDeclContext()->isModuleScopeContext() &&
       typeAlias->getGenericParams() == nullptr) {
@@ -7832,20 +7828,16 @@
     // Perform earlier validation of typealiases in protocols.
     if (isa<ProtocolDecl>(dc)) {
       if (!typealias->getGenericParams()) {
-        ProtocolRequirementTypeResolver resolver;
-        TypeResolutionOptions options;
-
         if (typealias->isBeingValidated()) return;
 
         typealias->setIsBeingValidated();
         SWIFT_DEFER { typealias->setIsBeingValidated(false); };
 
         validateAccessControl(typealias);
-        if (typealias->getFormalAccess() <= AccessLevel::FilePrivate)
-          options |= TypeResolutionFlags::KnownNonCascadingDependency;
 
+        ProtocolRequirementTypeResolver resolver;
         if (validateType(typealias->getUnderlyingTypeLoc(),
-                         typealias, options, &resolver)) {
+                         typealias, TypeResolutionOptions(), &resolver)) {
           typealias->setInvalid();
           typealias->getUnderlyingTypeLoc().setInvalidType(Context);
         }
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 9feb689..038d024 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -202,6 +202,11 @@
     if (auto proto =
           concrete->getDeclContext()
             ->getAsProtocolOrProtocolExtensionContext()) {
+      // Fast path: if there are no type parameters in the concrete type, just
+      // return it.
+      if (!concrete->getInterfaceType()->hasTypeParameter())
+        return concrete->getInterfaceType();
+
       tc.validateDecl(proto);
       auto subMap = SubstitutionMap::getProtocolSubstitutions(
                       proto, baseTy, ProtocolConformanceRef(proto));
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 215098f..a4611ed 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -672,28 +672,29 @@
   TypeLoc &TL = TP->getTypeLoc();
   bool hadError = TC.validateType(TL, DC, options, resolver);
 
-  if (hadError)
+  if (hadError) {
     TP->setType(ErrorType::get(TC.Context));
-  else {
-    TP->setType(TL.getType());
+    return hadError;
+  }
 
-    // Track whether the decl in this typed pattern should be
-    // implicitly unwrapped as needed during expression type checking.
-    if (TL.getTypeRepr() && TL.getTypeRepr()->getKind() ==
-        TypeReprKind::ImplicitlyUnwrappedOptional) {
-      auto *subPattern = TP->getSubPattern();
+  TP->setType(TL.getType());
 
-      while (auto *parenPattern = dyn_cast<ParenPattern>(subPattern))
-        subPattern = parenPattern->getSubPattern();
+  // Track whether the decl in this typed pattern should be
+  // implicitly unwrapped as needed during expression type checking.
+  if (TL.getTypeRepr() && TL.getTypeRepr()->getKind() ==
+      TypeReprKind::ImplicitlyUnwrappedOptional) {
+    auto *subPattern = TP->getSubPattern();
 
-      if (auto *namedPattern = dyn_cast<NamedPattern>(subPattern)) {
-        auto &C = DC->getASTContext();
-        namedPattern->getDecl()->getAttrs().add(
-            new (C) ImplicitlyUnwrappedOptionalAttr(/* implicit= */ true));
-      } else {
-        assert(isa<AnyPattern>(subPattern) &&
-               "Unexpected pattern nested in typed pattern!");
-      }
+    while (auto *parenPattern = dyn_cast<ParenPattern>(subPattern))
+      subPattern = parenPattern->getSubPattern();
+
+    if (auto *namedPattern = dyn_cast<NamedPattern>(subPattern)) {
+      auto &C = DC->getASTContext();
+      namedPattern->getDecl()->getAttrs().add(
+          new (C) ImplicitlyUnwrappedOptionalAttr(/* implicit= */ true));
+    } else {
+      assert(isa<AnyPattern>(subPattern) &&
+             "Unexpected pattern nested in typed pattern!");
     }
   }
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 85f444b..4e48289 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -6209,9 +6209,6 @@
                      (ConformanceCheckFlags::SuppressDependencyTracking|
                       ConformanceCheckFlags::Used));
   if (conformance && conformance->isConcrete()) {
-    assert(conformance->getConditionalRequirements().empty() &&
-           "cannot conform condtionally to _ErrorCodeProtocol");
-
     if (Type errorType = ProtocolConformanceRef::getTypeWitnessByName(
           type, *conformance, Context.Id_ErrorType, this)) {
       (void)conformsToProtocol(errorType, bridgedStoredNSError, dc,
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index a24595c..be860b1 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -670,9 +670,6 @@
                             sequence->getLoc());
     if (!genConformance)
       return nullptr;
-    assert(
-        genConformance->getConditionalRequirements().empty() &&
-        "conditionally conforming to IteratorProtocol not currently supported");
 
     Type elementTy = TC.getWitnessType(generatorTy, generatorProto,
                                        *genConformance, TC.Context.Id_Element,
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 28d1106..5bcfc48 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -1130,14 +1130,6 @@
 
   auto id = comp->getIdentifier();
 
-  // If we're compiling for Swift version < 5 and we have a mention of
-  // ImplicitlyUnwrappedOptional where it is not allowed, treat it as
-  // if it was spelled Optional.
-  if (id == TC.Context.Id_ImplicitlyUnwrappedOptional
-      && !options.contains(TypeResolutionFlags::AllowIUO)
-      && !TC.Context.isSwiftVersionAtLeast(5))
-    id = TC.Context.Id_Optional;
-
   NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
   if (options.contains(TypeResolutionFlags::KnownNonCascadingDependency))
     lookupOptions |= NameLookupFlags::KnownPrivate;
@@ -1239,7 +1231,7 @@
       }
     } else if (isa<GenericIdentTypeRepr>(comp)) {
       Diagnostic diag =
-          diag::implicitly_unwrapped_optional_spelling_decay_to_optional;
+          diag::implicitly_unwrapped_optional_spelling_suggest_optional;
 
       if (TC.Context.isSwiftVersionAtLeast(5))
         diag = diag::implicitly_unwrapped_optional_spelling_in_illegal_position;
@@ -1258,7 +1250,7 @@
               genericTyR->getAngleBrackets().End.getAdvancedLoc(1));
     } else {
       Diagnostic diag =
-          diag::implicitly_unwrapped_optional_spelling_decay_to_optional;
+          diag::implicitly_unwrapped_optional_spelling_suggest_optional;
 
       if (TC.Context.isSwiftVersionAtLeast(5))
         diag = diag::
@@ -2847,7 +2839,7 @@
        TypeResolutionOptions options) {
   if (!options.contains(TypeResolutionFlags::AllowIUO)) {
     Diagnostic diag = diag::
-        implicitly_unwrapped_optional_in_illegal_position_decay_to_optional;
+        implicitly_unwrapped_optional_in_illegal_position_suggest_optional;
 
     if (TC.Context.isSwiftVersionAtLeast(5))
       diag = diag::implicitly_unwrapped_optional_in_illegal_position;
@@ -2865,12 +2857,8 @@
   if (!baseTy || baseTy->hasError()) return baseTy;
 
   Type uncheckedOptionalTy;
-  if (!options.contains(TypeResolutionFlags::AllowIUO))
-    // Treat IUOs in illegal positions as optionals.
-    uncheckedOptionalTy = TC.getOptionalType(repr->getExclamationLoc(), baseTy);
-  else
-    uncheckedOptionalTy = TC.getImplicitlyUnwrappedOptionalType(
-        repr->getExclamationLoc(), baseTy);
+  uncheckedOptionalTy =
+      TC.getImplicitlyUnwrappedOptionalType(repr->getExclamationLoc(), baseTy);
 
   if (!uncheckedOptionalTy)
     return ErrorType::get(Context);
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index a9b83c7..cdb3c60 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/GenericSignature.h"
 #include "swift/AST/ModuleLoader.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/USRGeneration.h"
 #include "swift/Basic/Range.h"
 #include "swift/ClangImporter/ClangImporter.h"
@@ -1794,15 +1795,15 @@
 Optional<TinyPtrVector<ValueDecl *>>
 ModuleFile::loadNamedMembers(const IterableDeclContext *IDC, DeclName N,
                              uint64_t contextData) {
+  PrettyStackTraceDecl trace("loading members for", IDC->getDecl());
 
   assert(IDC->wasDeserialized());
+  assert(DeclMemberNames);
 
-  if (!DeclMemberNames)
-    return None;
-
+  TinyPtrVector<ValueDecl *> results;
   auto i = DeclMemberNames->find(N.getBaseName());
   if (i == DeclMemberNames->end())
-    return None;
+    return results;
 
   BitOffset subTableOffset = *i;
   std::unique_ptr<SerializedDeclMembersTable> &subTable =
@@ -1825,7 +1826,6 @@
   }
 
   assert(subTable);
-  TinyPtrVector<ValueDecl *> results;
   auto j = subTable->find(IDC->getDeclID());
   if (j != subTable->end()) {
     for (DeclID d : *j) {
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index 1afdb90..43d65ec 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -158,6 +158,9 @@
       if (!RawNode->isPattern())
         return makeUnknownSyntax(SyntaxKind::UnknownPattern, Parts);
       break;
+    case SyntaxContextKind::Syntax:
+      // We don't need to coerce in this case.
+      break;
     }
     return RawNode;
   } else {
@@ -178,6 +181,9 @@
     case SyntaxContextKind::Pattern:
       UnknownKind = SyntaxKind::UnknownPattern;
       break;
+    case SyntaxContextKind::Syntax:
+      UnknownKind = SyntaxKind::Unknown;
+      break;
     }
     return makeUnknownSyntax(UnknownKind, Parts);
   }
diff --git a/stdlib/private/SwiftPrivate/IO.swift b/stdlib/private/SwiftPrivate/IO.swift
index 4a4ca2b..f215887 100644
--- a/stdlib/private/SwiftPrivate/IO.swift
+++ b/stdlib/private/SwiftPrivate/IO.swift
@@ -57,7 +57,7 @@
       let fd = self.fd
       let addr = _buffer.baseAddress! + self._bufferUsed
       let size = bufferFree
-      return _swift_stdlib_read(fd, addr, size)
+      return _stdlib_read(fd, addr, size)
     }
     if readResult == 0 {
       isEOF = true
@@ -73,7 +73,7 @@
     if isClosed {
       return
     }
-    let result = _swift_stdlib_close(fd)
+    let result = _stdlib_close(fd)
     if result < 0 {
       fatalError("close() returned an error")
     }
@@ -106,7 +106,7 @@
       var writtenBytes = 0
       let bufferSize = utf8CStr.count - 1
       while writtenBytes != bufferSize {
-        let result = _swift_stdlib_write(
+        let result = _stdlib_write(
           self.fd, UnsafeRawPointer(utf8CStr.baseAddress! + Int(writtenBytes)),
           bufferSize - writtenBytes)
         if result < 0 {
@@ -121,7 +121,7 @@
     if isClosed {
       return
     }
-    let result = _swift_stdlib_close(fd)
+    let result = _stdlib_close(fd)
     if result < 0 {
       fatalError("close() returned an error")
     }
diff --git a/stdlib/private/SwiftPrivate/PRNG.swift b/stdlib/private/SwiftPrivate/PRNG.swift
index 9630d75..ee09da3 100644
--- a/stdlib/private/SwiftPrivate/PRNG.swift
+++ b/stdlib/private/SwiftPrivate/PRNG.swift
@@ -13,17 +13,17 @@
 import SwiftShims
 
 public func rand32() -> UInt32 {
-  return _swift_stdlib_cxx11_mt19937()
+  return _stdlib_cxx11_mt19937()
 }
 
 public func rand32(exclusiveUpperBound limit: UInt32) -> UInt32 {
-  return _swift_stdlib_cxx11_mt19937_uniform(limit)
+  return _stdlib_cxx11_mt19937_uniform(limit)
 }
 
 public func rand64() -> UInt64 {
   return
-    (UInt64(_swift_stdlib_cxx11_mt19937()) << 32) |
-    UInt64(_swift_stdlib_cxx11_mt19937())
+    (UInt64(_stdlib_cxx11_mt19937()) << 32) |
+    UInt64(_stdlib_cxx11_mt19937())
 }
 
 public func randInt() -> Int {
diff --git a/stdlib/private/SwiftPrivateLibcExtras/Subprocess.c b/stdlib/private/SwiftPrivateLibcExtras/Subprocess.c
index 2f75948..4ef6fdb 100644
--- a/stdlib/private/SwiftPrivateLibcExtras/Subprocess.c
+++ b/stdlib/private/SwiftPrivateLibcExtras/Subprocess.c
@@ -20,38 +20,33 @@
 #define availability(...)
 #include <spawn.h>
 #include <sys/types.h>
-#if defined(__APPLE__)
-// NOTE: forward declare this rather than including crt_externs.h as not all
-// SDKs provide it
-extern char ***_NSGetEnviron(void);
-#endif // defined(__APPLE__)
 
 SWIFT_CC(swift)
-int swift_posix_spawn_file_actions_init(
+int _stdlib_posix_spawn_file_actions_init(
     posix_spawn_file_actions_t *file_actions) {
   return posix_spawn_file_actions_init(file_actions);
 }
 
 SWIFT_CC(swift)
-int swift_posix_spawn_file_actions_destroy(
+int _stdlib_posix_spawn_file_actions_destroy(
     posix_spawn_file_actions_t *file_actions) {
   return posix_spawn_file_actions_destroy(file_actions);
 }
 
 SWIFT_CC(swift)
-int swift_posix_spawn_file_actions_addclose(
+int _stdlib_posix_spawn_file_actions_addclose(
     posix_spawn_file_actions_t *file_actions, int filedes) {
   return posix_spawn_file_actions_addclose(file_actions, filedes);
 }
 
 SWIFT_CC(swift)
-int swift_posix_spawn_file_actions_adddup2(
+int _stdlib_posix_spawn_file_actions_adddup2(
     posix_spawn_file_actions_t *file_actions, int filedes, int newfiledes) {
   return posix_spawn_file_actions_adddup2(file_actions, filedes, newfiledes);
 }
 
 SWIFT_CC(swift)
-int swift_posix_spawn(pid_t *__restrict pid, const char * __restrict path,
+int _stdlib_posix_spawn(pid_t *__restrict pid, const char * __restrict path,
                       const posix_spawn_file_actions_t *file_actions,
                       const posix_spawnattr_t *__restrict attrp,
                       char *const argv[__restrict],
@@ -59,11 +54,5 @@
   return posix_spawn(pid, path, file_actions, attrp, argv, envp);
 }
 
-#if defined(__APPLE__)
-SWIFT_CC(swift)
-char ***swift_SwiftPrivateLibcExtras_NSGetEnviron(void) {
-  return _NSGetEnviron();
-}
-#endif // defined(__APPLE__)
 #endif // !defined(__ANDROID__) && !defined(__HAIKU__) && (!defined(_WIN32) || defined(__CGYWIN__))
 
diff --git a/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift b/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
index 5d77a73..b4554bc 100644
--- a/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
+++ b/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
@@ -23,43 +23,43 @@
 // posix_spawn is not available on Android.
 // posix_spawn is not available on Haiku.
 #if !os(Android) && !os(Haiku)
-// swift_posix_spawn isn't available in the public watchOS SDK, we sneak by the
+// posix_spawn isn't available in the public watchOS SDK, we sneak by the
 // unavailable attribute declaration here of the APIs that we need.
 
 // FIXME: Come up with a better way to deal with APIs that are pointers on some
 // platforms but not others.
 #if os(Linux)
-typealias swift_posix_spawn_file_actions_t = posix_spawn_file_actions_t
+typealias _stdlib_posix_spawn_file_actions_t = posix_spawn_file_actions_t
 #else
-typealias swift_posix_spawn_file_actions_t = posix_spawn_file_actions_t?
+typealias _stdlib_posix_spawn_file_actions_t = posix_spawn_file_actions_t?
 #endif
 
-@_silgen_name("swift_posix_spawn_file_actions_init")
-func swift_posix_spawn_file_actions_init(
-  _ file_actions: UnsafeMutablePointer<swift_posix_spawn_file_actions_t>
+@_silgen_name("_stdlib_posix_spawn_file_actions_init")
+internal func _stdlib_posix_spawn_file_actions_init(
+  _ file_actions: UnsafeMutablePointer<_stdlib_posix_spawn_file_actions_t>
 ) -> CInt
 
-@_silgen_name("swift_posix_spawn_file_actions_destroy")
-func swift_posix_spawn_file_actions_destroy(
-  _ file_actions: UnsafeMutablePointer<swift_posix_spawn_file_actions_t>
+@_silgen_name("_stdlib_posix_spawn_file_actions_destroy")
+internal func _stdlib_posix_spawn_file_actions_destroy(
+  _ file_actions: UnsafeMutablePointer<_stdlib_posix_spawn_file_actions_t>
 ) -> CInt
 
-@_silgen_name("swift_posix_spawn_file_actions_addclose")
-func swift_posix_spawn_file_actions_addclose(
-  _ file_actions: UnsafeMutablePointer<swift_posix_spawn_file_actions_t>,
+@_silgen_name("_stdlib_posix_spawn_file_actions_addclose")
+internal func _stdlib_posix_spawn_file_actions_addclose(
+  _ file_actions: UnsafeMutablePointer<_stdlib_posix_spawn_file_actions_t>,
   _ filedes: CInt) -> CInt
 
-@_silgen_name("swift_posix_spawn_file_actions_adddup2")
-func swift_posix_spawn_file_actions_adddup2(
-  _ file_actions: UnsafeMutablePointer<swift_posix_spawn_file_actions_t>,
+@_silgen_name("_stdlib_posix_spawn_file_actions_adddup2")
+internal func _stdlib_posix_spawn_file_actions_adddup2(
+  _ file_actions: UnsafeMutablePointer<_stdlib_posix_spawn_file_actions_t>,
   _ filedes: CInt,
   _ newfiledes: CInt) -> CInt
 
-@_silgen_name("swift_posix_spawn")
-func swift_posix_spawn(
+@_silgen_name("_stdlib_posix_spawn")
+internal func _stdlib_posix_spawn(
   _ pid: UnsafeMutablePointer<pid_t>?,
   _ file: UnsafePointer<Int8>,
-  _ file_actions: UnsafePointer<swift_posix_spawn_file_actions_t>?,
+  _ file_actions: UnsafePointer<_stdlib_posix_spawn_file_actions_t>?,
   _ attrp: UnsafePointer<posix_spawnattr_t>?,
   _ argv: UnsafePointer<UnsafeMutablePointer<Int8>?>,
   _ envp: UnsafePointer<UnsafeMutablePointer<Int8>?>?) -> CInt
@@ -113,7 +113,7 @@
     // code after this block will never be executed, and the parent write pipe
     // will be closed.
     withArrayOfCStrings([CommandLine.arguments[0]] + args) {
-      execve(CommandLine.arguments[0], $0, _getEnviron())
+      execve(CommandLine.arguments[0], $0, environ)
     }
 
     // If execve() encountered an error, we write the errno encountered to the
@@ -142,44 +142,44 @@
   }
 #else
   var fileActions = _make_posix_spawn_file_actions_t()
-  if swift_posix_spawn_file_actions_init(&fileActions) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_init() failed")
+  if _stdlib_posix_spawn_file_actions_init(&fileActions) != 0 {
+    preconditionFailure("_stdlib_posix_spawn_file_actions_init() failed")
   }
 
   // Close the write end of the pipe on the child side.
-  if swift_posix_spawn_file_actions_addclose(
+  if _stdlib_posix_spawn_file_actions_addclose(
     &fileActions, childStdin.writeFD) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_addclose() failed")
+    preconditionFailure("_stdlib_posix_spawn_file_actions_addclose() failed")
   }
 
   // Remap child's stdin.
-  if swift_posix_spawn_file_actions_adddup2(
+  if _stdlib_posix_spawn_file_actions_adddup2(
     &fileActions, childStdin.readFD, STDIN_FILENO) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_adddup2() failed")
+    preconditionFailure("_stdlib_posix_spawn_file_actions_adddup2() failed")
   }
 
   // Close the read end of the pipe on the child side.
-  if swift_posix_spawn_file_actions_addclose(
+  if _stdlib_posix_spawn_file_actions_addclose(
     &fileActions, childStdout.readFD) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_addclose() failed")
+    preconditionFailure("_stdlib_posix_spawn_file_actions_addclose() failed")
   }
 
   // Remap child's stdout.
-  if swift_posix_spawn_file_actions_adddup2(
+  if _stdlib_posix_spawn_file_actions_adddup2(
     &fileActions, childStdout.writeFD, STDOUT_FILENO) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_adddup2() failed")
+    preconditionFailure("_stdlib_posix_spawn_file_actions_adddup2() failed")
   }
 
   // Close the read end of the pipe on the child side.
-  if swift_posix_spawn_file_actions_addclose(
+  if _stdlib_posix_spawn_file_actions_addclose(
     &fileActions, childStderr.readFD) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_addclose() failed")
+    preconditionFailure("_stdlib_posix_spawn_file_actions_addclose() failed")
   }
 
   // Remap child's stderr.
-  if swift_posix_spawn_file_actions_adddup2(
+  if _stdlib_posix_spawn_file_actions_adddup2(
     &fileActions, childStderr.writeFD, STDERR_FILENO) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_adddup2() failed")
+    preconditionFailure("_stdlib_posix_spawn_file_actions_adddup2() failed")
   }
 
   var pid: pid_t = -1
@@ -192,16 +192,16 @@
     }
   }
   let spawnResult = withArrayOfCStrings(childArgs) {
-    swift_posix_spawn(
-      &pid, childArgs[0], &fileActions, nil, $0, _getEnviron())
+    _stdlib_posix_spawn(
+      &pid, childArgs[0], &fileActions, nil, $0, environ)
   }
   if spawnResult != 0 {
     print(String(cString: strerror(spawnResult)))
-    preconditionFailure("swift_posix_spawn() failed")
+    preconditionFailure("_stdlib_posix_spawn() failed")
   }
 
-  if swift_posix_spawn_file_actions_destroy(&fileActions) != 0 {
-    preconditionFailure("swift_posix_spawn_file_actions_destroy() failed")
+  if _stdlib_posix_spawn_file_actions_destroy(&fileActions) != 0 {
+    preconditionFailure("_stdlib_posix_spawn_file_actions_destroy() failed")
   }
 #endif
 
@@ -226,12 +226,12 @@
 #if !os(Android) && !os(Haiku)
 #if os(Linux)
 internal func _make_posix_spawn_file_actions_t()
-  -> swift_posix_spawn_file_actions_t {
+  -> _stdlib_posix_spawn_file_actions_t {
   return posix_spawn_file_actions_t()
 }
 #else
 internal func _make_posix_spawn_file_actions_t()
-  -> swift_posix_spawn_file_actions_t {
+  -> _stdlib_posix_spawn_file_actions_t {
   return nil
 }
 #endif
@@ -292,27 +292,6 @@
   preconditionFailure("did not understand what happened to child process")
 }
 
-#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
-@_silgen_name("swift_SwiftPrivateLibcExtras_NSGetEnviron")
-func _NSGetEnviron() -> UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>>
-#endif
-
-internal func _getEnviron() -> UnsafeMutablePointer<UnsafeMutablePointer<CChar>?> {
-#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
-  return _NSGetEnviron().pointee
-#elseif os(FreeBSD)
-  return environ
-#elseif os(PS4)
-  return environ
-#elseif os(Android)
-  return environ
-#elseif os(Cygwin)
-  return environ
-#elseif os(Haiku)
-  return environ
-#else
-  return __environ
-#endif
-}
+// !os(Windows)
 #endif
 
diff --git a/stdlib/public/Platform/CMakeLists.txt b/stdlib/public/Platform/CMakeLists.txt
index a2327de..31e06f8 100644
--- a/stdlib/public/Platform/CMakeLists.txt
+++ b/stdlib/public/Platform/CMakeLists.txt
@@ -2,7 +2,6 @@
 set(swift_platform_flags)
 set(swift_platform_sources
     Platform.swift
-    Misc.c
     TiocConstants.swift
     tgmath.swift.gyb)
 
diff --git a/stdlib/public/Platform/Misc.c b/stdlib/public/Platform/Misc.c
deleted file mode 100644
index 8301bae..0000000
--- a/stdlib/public/Platform/Misc.c
+++ /dev/null
@@ -1,119 +0,0 @@
-//===--- Misc.c - Platform overlay helpers --------------------------------===//
-//
-// 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 <errno.h>
-#include <fcntl.h>
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#include <semaphore.h>
-#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <io.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#if !defined(_WIN32) || defined(__CYGWIN__)
-#include <sys/ioctl.h>
-#endif
-
-#include "swift/Runtime/Config.h"
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
-SWIFT_CC(swift)
-int _swift_Platform_open(const char *path, int oflag, mode_t mode) {
-  return open(path, oflag, mode);
-}
-#else
-SWIFT_CC(swift)
-int _swift_Platform_open(const char *path, int oflag, int mode) {
-  return _open(path, oflag, mode);
-}
-#endif
-
-#if !defined(_WIN32) || defined(__CYGWIN__)
-SWIFT_CC(swift)
-int _swift_Platform_openat(int fd, const char *path, int oflag,
-                                  mode_t mode) {
-  return openat(fd, path, oflag, mode);
-}
-
-SWIFT_CC(swift)
-sem_t *_swift_Platform_sem_open2(const char *name, int oflag) {
-  return sem_open(name, oflag);
-}
-
-SWIFT_CC(swift)
-sem_t *_swift_Platform_sem_open4(const char *name, int oflag,
-                                        mode_t mode, unsigned int value) {
-  return sem_open(name, oflag, mode, value);
-}
-
-SWIFT_CC(swift)
-int _swift_Platform_fcntl(int fd, int cmd, int value) {
-  return fcntl(fd, cmd, value);
-}
-
-SWIFT_CC(swift)
-int _swift_Platform_fcntlPtr(int fd, int cmd, void* ptr) {
-  return fcntl(fd, cmd, ptr);
-}
-
-SWIFT_CC(swift)
-int
-_swift_Platform_ioctl(int fd, unsigned long int request, int value) {
-  return ioctl(fd, request, value);
-}
-
-SWIFT_CC(swift)
-int
-_swift_Platform_ioctlPtr(int fd, unsigned long int request, void* ptr) {
-  return ioctl(fd, request, ptr);
-}
-#endif
-
-#if defined(__APPLE__)
-#define _REENTRANT
-#include <math.h>
-
-SWIFT_CC(swift)
-float _swift_Darwin_lgammaf_r(float x, int *psigngam) {
-  return lgammaf_r(x, psigngam);
-}
-
-SWIFT_CC(swift)
-double _swift_Darwin_lgamma_r(double x, int *psigngam) {
-  return lgamma_r(x, psigngam);
-}
-
-SWIFT_CC(swift)
-long double _swift_Darwin_lgammal_r(long double x, int *psigngam) {
-  return lgammal_r(x, psigngam);
-}
-#endif // defined(__APPLE__)
-
-#if defined(__FreeBSD__)
-SWIFT_CC(swift)
-char **_swift_FreeBSD_getEnv() {
-  extern char **environ;
-  return environ;
-}
-#endif // defined(__FreeBSD__)
-
-SWIFT_CC(swift)
-int _swift_Platform_getErrno() {
-  return errno;
-}
-
-SWIFT_CC(swift)
-void _swift_Platform_setErrno(int value) {
-  errno = value;
-}
-
diff --git a/stdlib/public/Platform/Platform.swift b/stdlib/public/Platform/Platform.swift
index fe5f219..6c4d619 100644
--- a/stdlib/public/Platform/Platform.swift
+++ b/stdlib/public/Platform/Platform.swift
@@ -10,6 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+import SwiftShims
+
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
 //===----------------------------------------------------------------------===//
 // MacTypes.h
@@ -75,18 +77,12 @@
 // sys/errno.h
 //===----------------------------------------------------------------------===//
 
-@_silgen_name("_swift_Platform_getErrno")
-func _swift_Platform_getErrno() -> Int32
-
-@_silgen_name("_swift_Platform_setErrno")
-func _swift_Platform_setErrno(_: Int32)
-
 public var errno : Int32 {
   get {
-    return _swift_Platform_getErrno()
+    return _stdlib_getErrno()
   }
   set(val) {
-    return _swift_Platform_setErrno(val)
+    return _stdlib_setErrno(val)
   }
 }
 
@@ -141,37 +137,11 @@
 // fcntl.h
 //===----------------------------------------------------------------------===//
 
-#if os(Windows)
-@_silgen_name("_swift_Platform_open")
-func _swift_Platform_open(
-  _ path: UnsafePointer<CChar>,
-  _ oflag: Int32,
-  _ mode: Int32
-) -> Int32
-#else
-@_silgen_name("_swift_Platform_open")
-func _swift_Platform_open(
-  _ path: UnsafePointer<CChar>,
-  _ oflag: Int32,
-  _ mode: mode_t
-) -> Int32
-#endif
-
-#if !os(Windows)
-@_silgen_name("_swift_Platform_openat")
-func _swift_Platform_openat(
-  _ fd: Int32,
-  _ path: UnsafePointer<CChar>,
-  _ oflag: Int32,
-  _ mode: mode_t
-) -> Int32
-#endif
-
 public func open(
   _ path: UnsafePointer<CChar>,
   _ oflag: Int32
 ) -> Int32 {
-  return _swift_Platform_open(path, oflag, 0)
+  return _stdlib_open(path, oflag, 0)
 }
 
 #if os(Windows)
@@ -180,7 +150,7 @@
   _ oflag: Int32,
   _ mode: Int32
 ) -> Int32 {
-  return _swift_Platform_open(path, oflag, mode)
+  return _stdlib_open(path, oflag, mode)
 }
 #else
 public func open(
@@ -188,7 +158,7 @@
   _ oflag: Int32,
   _ mode: mode_t
 ) -> Int32 {
-  return _swift_Platform_open(path, oflag, mode)
+  return _stdlib_open(path, oflag, mode)
 }
 
 public func openat(
@@ -196,7 +166,7 @@
   _ path: UnsafePointer<CChar>,
   _ oflag: Int32
 ) -> Int32 {
-  return _swift_Platform_openat(fd, path, oflag, 0)
+  return _stdlib_openat(fd, path, oflag, 0)
 }
 
 public func openat(
@@ -205,30 +175,14 @@
   _ oflag: Int32,
   _ mode: mode_t
 ) -> Int32 {
-  return _swift_Platform_openat(fd, path, oflag, mode)
+  return _stdlib_openat(fd, path, oflag, mode)
 }
-#endif
-
-#if !os(Windows)
-@_silgen_name("_swift_Platform_fcntl")
-internal func _swift_Platform_fcntl(
-  _ fd: Int32,
-  _ cmd: Int32,
-  _ value: Int32
-) -> Int32
-
-@_silgen_name("_swift_Platform_fcntlPtr")
-internal func _swift_Platform_fcntlPtr(
-  _ fd: Int32,
-  _ cmd: Int32,
-  _ ptr: UnsafeMutableRawPointer
-) -> Int32
 
 public func fcntl(
   _ fd: Int32,
   _ cmd: Int32
 ) -> Int32 {
-  return _swift_Platform_fcntl(fd, cmd, 0)
+  return _stdlib_fcntl(fd, cmd, 0)
 }
 
 public func fcntl(
@@ -236,7 +190,7 @@
   _ cmd: Int32,
   _ value: Int32
 ) -> Int32 {
-  return _swift_Platform_fcntl(fd, cmd, value)
+  return _stdlib_fcntl(fd, cmd, value)
 }
 
 public func fcntl(
@@ -244,8 +198,10 @@
   _ cmd: Int32,
   _ ptr: UnsafeMutableRawPointer
 ) -> Int32 {
-  return _swift_Platform_fcntlPtr(fd, cmd, ptr)
+  return _stdlib_fcntlPtr(fd, cmd, ptr)
 }
+
+// !os(Windows)
 #endif
 
 #if os(Windows)
@@ -304,26 +260,13 @@
 //===----------------------------------------------------------------------===//
 
 #if !os(Windows)
-@_silgen_name("_swift_Platform_ioctl")
-internal func _swift_Platform_ioctl(
-  _ fd: CInt,
-  _ request: UInt,
-  _ value: CInt
-) -> CInt
-
-@_silgen_name("_swift_Platform_ioctlPtr")
-internal func _swift_Platform_ioctlPtr(
-  _ fd: CInt,
-  _ request: UInt,
-  _ ptr: UnsafeMutableRawPointer
-) -> CInt
 
 public func ioctl(
   _ fd: CInt,
   _ request: UInt,
   _ value: CInt
 ) -> CInt {
-  return _swift_Platform_ioctl(fd, request, value)
+  return _stdlib_ioctl(fd, request, value)
 }
 
 public func ioctl(
@@ -331,15 +274,17 @@
   _ request: UInt,
   _ ptr: UnsafeMutableRawPointer
 ) -> CInt {
-  return _swift_Platform_ioctlPtr(fd, request, ptr)
+  return _stdlib_ioctlPtr(fd, request, ptr)
 }
 
 public func ioctl(
   _ fd: CInt,
   _ request: UInt
 ) -> CInt {
-  return _swift_Platform_ioctl(fd, request, 0)
+  return _stdlib_ioctl(fd, request, 0)
 }
+
+// !os(Windows)
 #endif
 
 //===----------------------------------------------------------------------===//
@@ -423,25 +368,12 @@
 #endif
 }
 
-@_silgen_name("_swift_Platform_sem_open2")
-internal func _swift_Platform_sem_open2(
-  _ name: UnsafePointer<CChar>,
-  _ oflag: Int32
-) -> UnsafeMutablePointer<sem_t>?
-
-@_silgen_name("_swift_Platform_sem_open4")
-internal func _swift_Platform_sem_open4(
-  _ name: UnsafePointer<CChar>,
-  _ oflag: Int32,
-  _ mode: mode_t,
-  _ value: CUnsignedInt
-) -> UnsafeMutablePointer<sem_t>?
-
 public func sem_open(
   _ name: UnsafePointer<CChar>,
   _ oflag: Int32
 ) -> UnsafeMutablePointer<sem_t>? {
-  return _swift_Platform_sem_open2(name, oflag)
+  return _stdlib_sem_open2(name, oflag)
+    .assumingMemoryBound(to: sem_t.self)
 }
 
 public func sem_open(
@@ -450,7 +382,8 @@
   _ mode: mode_t,
   _ value: CUnsignedInt
 ) -> UnsafeMutablePointer<sem_t>? {
-  return _swift_Platform_sem_open4(name, oflag, mode, value)
+  return _stdlib_sem_open4(name, oflag, mode, value)
+    .assumingMemoryBound(to: sem_t.self)
 }
 #endif
 
@@ -458,14 +391,13 @@
 // Misc.
 //===----------------------------------------------------------------------===//
 
-// FreeBSD defines extern char **environ differently than Linux.
-#if os(FreeBSD) || os(PS4)
-@_silgen_name("_swift_FreeBSD_getEnv")
-func _swift_FreeBSD_getEnv(
-) -> UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>>
-
+// Some platforms don't have `extern char** environ` imported from C.
+#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4)
 public var environ: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?> {
-  return _swift_FreeBSD_getEnv().pointee
+  return _stdlib_getEnviron()
+}
+#elseif os(Linux)
+public var environ: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?> {
+  return __environ
 }
 #endif
-
diff --git a/stdlib/public/Platform/tgmath.swift.gyb b/stdlib/public/Platform/tgmath.swift.gyb
index 1cb5a50..7c34d12 100644
--- a/stdlib/public/Platform/tgmath.swift.gyb
+++ b/stdlib/public/Platform/tgmath.swift.gyb
@@ -10,6 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+import SwiftShims
+
 // Generic functions implementable directly on FloatingPoint.
 @_transparent
 public func fabs<T: FloatingPoint>(_ x: T) -> T
@@ -308,19 +310,14 @@
 #elseif os(Windows)
 // TODO(compnerd): implement
 #else
-% # On Darwin platform,
-% # The real lgamma_r is not imported because it hides behind macro _REENTRANT.
-@_versioned
-@_silgen_name("_swift_Darwin_lgamma${f}_r")
-func _swift_Darwin_lgamma${f}_r(_: ${CT},
-                                _: UnsafeMutablePointer<Int32>) -> ${CT}
-
-@_transparent
+% # On Darwin platforms the real lgamma_r is not imported
+% # because it hides behind macro _REENTRANT.
+% # This is not @transparent because _stdlib_lgamma() is not public.
 public func lgamma(_ x: ${T}) -> (${T}, Int) {
   var sign = Int32(0)
   let value = withUnsafeMutablePointer(to: &sign) {
     (signp: UnsafeMutablePointer<Int32>) -> ${CT} in
-    return _swift_Darwin_lgamma${f}_r(${CT}(x), signp)
+    return _stdlib_lgamma${f}_r(${CT}(x), signp)
   }
   return (${T}(value), Int(sign))
 }
diff --git a/stdlib/public/SDK/Foundation/AffineTransform.swift b/stdlib/public/SDK/Foundation/AffineTransform.swift
index 87af725..f566d7f 100644
--- a/stdlib/public/SDK/Foundation/AffineTransform.swift
+++ b/stdlib/public/SDK/Foundation/AffineTransform.swift
@@ -12,7 +12,7 @@
 
 @_exported import Foundation // Clang module
 
-#if os(OSX)
+#if os(macOS)
 
 private let ε: CGFloat = 2.22045e-16
 
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index 7523a29..6919b52 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -12,7 +12,7 @@
 
 #if DEPLOYMENT_RUNTIME_SWIFT
     
-#if os(OSX) || os(iOS)
+#if os(macOS) || os(iOS)
 import Darwin
 #elseif os(Linux)
 import Glibc
@@ -1377,7 +1377,7 @@
     
         // Avoid a crash that happens on OS X 10.11.x and iOS 9.x or before when writing a bridged Data non-atomically with Foundation's standard write() implementation.
         if !options.contains(.atomic) {
-            #if os(OSX)
+            #if os(macOS)
                 return NSFoundationVersionNumber <= Double(NSFoundationVersionNumber10_11_Max)
             #else
                 return NSFoundationVersionNumber <= Double(NSFoundationVersionNumber_iOS_9_x_Max)
diff --git a/stdlib/public/SDK/Foundation/NSGeometry.swift b/stdlib/public/SDK/Foundation/NSGeometry.swift
index 9ceb532..ff02345 100644
--- a/stdlib/public/SDK/Foundation/NSGeometry.swift
+++ b/stdlib/public/SDK/Foundation/NSGeometry.swift
@@ -14,7 +14,7 @@
 import CoreGraphics
 
 
-#if os(OSX)
+#if os(macOS)
 
 //===----------------------------------------------------------------------===//
 // NSRectEdge
diff --git a/stdlib/public/SDK/Foundation/NSNumber.swift b/stdlib/public/SDK/Foundation/NSNumber.swift
index 1fd150e..1ca9cee 100644
--- a/stdlib/public/SDK/Foundation/NSNumber.swift
+++ b/stdlib/public/SDK/Foundation/NSNumber.swift
@@ -434,9 +434,17 @@
     }
 
     public init?(exactly number: NSNumber) {
-        guard let value = Double(exactly: number) else { return nil }
-        guard let result = Float(exactly: value) else { return nil }
-        self = result
+        let type = number.objCType.pointee
+        if type == 0x49 || type == 0x4c || type == 0x51 {
+            guard let result = Float(exactly: number.uint64Value) else { return nil }
+            self = result
+        } else if type == 0x69 || type == 0x6c || type == 0x71 {
+            guard let result = Float(exactly: number.int64Value) else { return nil }
+            self = result
+        } else {
+            guard let result = Float(exactly: number.doubleValue) else { return nil }
+            self = result
+        }
     }
 
     @_semantics("convertToObjectiveC")
@@ -451,25 +459,12 @@
     }
     
     public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Float?) -> Bool {
-        guard let value = Double(exactly: x) else { return false }
-        guard !value.isNaN else {
-            result = Float.nan
+        if x.floatValue.isNaN {
+            result = x.floatValue
             return true
         }
-        guard !value.isInfinite else {
-            if value.sign == .minus {
-                result = -Float.infinity
-            } else {
-                result = Float.infinity
-            }
-            return true
-        }
-        guard Swift.abs(value) <= Double(Float.greatestFiniteMagnitude) else {
-            return false
-        }
-        
-        result = Float(value)
-        return true
+        result = Float(exactly: x)
+        return result != nil
     }
     
     public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Float {
@@ -499,7 +494,10 @@
             guard let result = Double(exactly: number.int64Value) else  { return nil }
             self = result
         } else {
-            self = number.doubleValue
+            // All other integer types and single-precision floating points will
+            // fit in a `Double` without truncation.
+            guard let result = Double(exactly: number.doubleValue) else { return nil }
+            self = result
         }
     }
 
@@ -515,9 +513,12 @@
     }
     
     public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Double?) -> Bool {
-        guard let value = Double(exactly: x) else { return false }
-        result = value
-        return true
+        if x.doubleValue.isNaN {
+            result = x.doubleValue
+            return true
+        }
+        result = Double(exactly: x)
+        return result != nil
     }
     
     public static func _unconditionallyBridgeFromObjectiveC(_ source: NSNumber?) -> Double {
diff --git a/stdlib/public/SDK/Foundation/URL.swift b/stdlib/public/SDK/Foundation/URL.swift
index 3799dba..cf2dad3 100644
--- a/stdlib/public/SDK/Foundation/URL.swift
+++ b/stdlib/public/SDK/Foundation/URL.swift
@@ -124,7 +124,7 @@
     @available(OSX 10.11, iOS 9.0, *)
     public var isApplication: Bool? { return _get(.isApplicationKey) }
     
-#if os(OSX)
+#if os(macOS)
     /// True if the resource is scriptable. Only applies to applications.
     @available(OSX 10.11, *)
     public var applicationIsScriptable: Bool? { return _get(.applicationIsScriptableKey) }
@@ -237,7 +237,7 @@
         set { _set(.isExcludedFromBackupKey, newValue: newValue) }
     }
     
-#if os(OSX)
+#if os(macOS)
     /// The array of Tag names.
     public var tagNames: [String]? { return _get(.tagNamesKey) }
 #endif
@@ -267,7 +267,7 @@
     @available(OSX 10.10, iOS 8.0, *)
     public var addedToDirectoryDate: Date? { return _get(.addedToDirectoryDateKey) }
     
-#if os(OSX)
+#if os(macOS)
     /// The quarantine properties as defined in LSQuarantine.h. To remove quarantine information from a file, pass `nil` as the value when setting this property.
     @available(OSX 10.10, *)
     public var quarantineProperties: [String : Any]? {
@@ -300,7 +300,7 @@
     /// Total free space in bytes.
     public var volumeAvailableCapacity : Int? { return _get(.volumeAvailableCapacityKey) }
     
-#if os(OSX) || os(iOS)
+#if os(macOS) || os(iOS)
     /// Total available capacity in bytes for "Important" resources, including space expected to be cleared by purging non-essential and cached resources. "Important" means something that the user or application clearly expects to be present on the local system, but is ultimately replaceable. This would include items that the user has explicitly requested via the UI, and resources that an application requires in order to provide functionality.
     /// Examples: A video that the user has explicitly requested to watch but has not yet finished watching or an audio file that the user has requested to download.
     /// This value should not be used in determining if there is room for an irreplaceable resource. In the case of irreplaceable resources, always attempt to save the resource regardless of available capacity and handle failure as gracefully as possible.
@@ -444,7 +444,7 @@
     @available(OSX 10.10, iOS 8.0, *)
     public var ubiquitousItemContainerDisplayName : String? { return _get(.ubiquitousItemContainerDisplayNameKey) }
     
-#if os(OSX) || os(iOS)
+#if os(macOS) || os(iOS)
     // true if ubiquitous item is shared.
     @available(OSX 10.13, iOS 11.0, *) @available(tvOS, unavailable) @available(watchOS, unavailable)
     public var ubiquitousItemIsShared: Bool? { return _get(.ubiquitousItemIsSharedKey) }
@@ -466,7 +466,7 @@
     public var ubiquitousSharedItemMostRecentEditorNameComponents: PersonNameComponents? { return _get(.ubiquitousSharedItemMostRecentEditorNameComponentsKey) }
 #endif
     
-#if !os(OSX)
+#if !os(macOS)
     /// The protection level for this file
     @available(iOS 9.0, *)
     public var fileProtection : URLFileProtection? { return _get(.fileProtectionKey) }
diff --git a/stdlib/public/SDK/Metal/CMakeLists.txt b/stdlib/public/SDK/Metal/CMakeLists.txt
index 4ea2491..f3fe951 100644
--- a/stdlib/public/SDK/Metal/CMakeLists.txt
+++ b/stdlib/public/SDK/Metal/CMakeLists.txt
@@ -4,7 +4,7 @@
 add_swift_library(swiftMetal ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
     Metal.swift
 
-  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" "-swift-version" "3"
+  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   TARGET_SDKS OSX IOS IOS_SIMULATOR TVOS TVOS_SIMULATOR
   SWIFT_MODULE_DEPENDS_OSX Darwin CoreFoundation CoreGraphics Dispatch Foundation IOKit ObjectiveC XPC # auto-updated
diff --git a/stdlib/public/SDK/Metal/Metal.swift b/stdlib/public/SDK/Metal/Metal.swift
index 802e902..be63327 100644
--- a/stdlib/public/SDK/Metal/Metal.swift
+++ b/stdlib/public/SDK/Metal/Metal.swift
@@ -17,7 +17,7 @@
 extension MTLBlitCommandEncoder {
     
     public func fill(buffer: MTLBuffer, range: Range<Int>, value: UInt8) {
-        fill(buffer: buffer, range: NSMakeRange(range.lowerBound, range.count), value: value)
+        __fill(buffer, range: NSMakeRange(range.lowerBound, range.count), value: value)
     }
 }
 
@@ -28,13 +28,13 @@
 #if os(OSX)
     @available(macOS, introduced: 10.11)
     public func didModifyRange(_ range: Range<Int>) {
-        didModifyRange(NSMakeRange(range.lowerBound, range.count))
+        __didModifyRange(NSMakeRange(range.lowerBound, range.count))
     }
 #endif
     
     @available(macOS 10.12, iOS 10.0, tvOS 10.0, *)
     public func addDebugMarker(_ marker: String, range: Range<Int>) {
-        addDebugMarker(marker, range: NSMakeRange(range.lowerBound, range.count))
+        __addDebugMarker(marker, range: NSMakeRange(range.lowerBound, range.count))
     }
 }
 
@@ -44,28 +44,28 @@
     
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func useResources(_ resources: [MTLResource], usage: MTLResourceUsage) {
-        useResources(resources, count: resources.count, usage: usage)
+        __use(resources, count: resources.count, usage: usage)
     }
     
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func useHeaps(_ heaps: [MTLHeap]) {
-        useHeaps(heaps, count: heaps.count)
+        __use(heaps, count: heaps.count)
     }
     
     public func setBuffers(_ buffers: [MTLBuffer?], offsets: [Int], range: Range<Int>) {
-        setBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
+        __setBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setTextures(_ textures: [MTLTexture?], range: Range<Int>) {
-        setTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
+        __setTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setSamplerStates(_ samplers: [MTLSamplerState?], range: Range<Int>) {
-        setSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
+        __setSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setSamplerStates(_ samplers: [MTLSamplerState?], lodMinClamps: [Float], lodMaxClamps: [Float], range: Range<Int>) {
-        setSamplerStates(samplers, lodMinClamps: lodMinClamps, lodMaxClamps: lodMaxClamps, with: NSMakeRange(range.lowerBound, range.count))
+        __setSamplerStates(samplers, lodMinClamps: lodMinClamps, lodMaxClamps: lodMaxClamps, with: NSMakeRange(range.lowerBound, range.count))
     }
 }
 
@@ -76,7 +76,7 @@
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func getDefaultSamplePositions(sampleCount: Int) -> [MTLSamplePosition] {
         var positions = [MTLSamplePosition](repeating: MTLSamplePosition(x: 0,y: 0), count: sampleCount)
-        getDefaultSamplePositions(&positions, count: sampleCount)
+        __getDefaultSamplePositions(&positions, count: sampleCount)
         return positions
     }
 }
@@ -87,7 +87,7 @@
 public func MTLCopyAllDevicesWithObserver(handler: @escaping MTLDeviceNotificationHandler) -> (devices:[MTLDevice], observer:NSObject) {
     var resultTuple: (devices:[MTLDevice], observer:NSObject)
     resultTuple.observer = NSObject()
-    resultTuple.devices = MTLCopyAllDevicesWithObserver(AutoreleasingUnsafeMutablePointer<NSObjectProtocol?>(&resultTuple.observer), handler)
+    resultTuple.devices = __MTLCopyAllDevicesWithObserver(AutoreleasingUnsafeMutablePointer<NSObjectProtocol?>(&resultTuple.observer), handler)
     return resultTuple
 }
 #endif
@@ -97,7 +97,7 @@
 extension MTLFunctionConstantValues {
     
     public func setConstantValues(_ values: UnsafeRawPointer, type: MTLDataType, range: Range<Int>) {
-        setConstantValues(values, type: type, with: NSMakeRange(range.lowerBound, range.count))
+        __setConstantValues(values, type: type, with: NSMakeRange(range.lowerBound, range.count))
     }
     
 }
@@ -107,15 +107,15 @@
 extension MTLArgumentEncoder {
     
     public func setBuffers(_ buffers: [MTLBuffer?], offsets: [Int], range: Range<Int>) {
-        setBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
+        __setBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setTextures(_ textures: [MTLTexture?], range: Range<Int>) {
-        setTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
+        __setTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setSamplerStates(_ samplers: [MTLSamplerState?], range: Range<Int>) {
-        setSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
+        __setSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
     }
 }
 
@@ -125,56 +125,56 @@
     
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func useResources(_ resources: [MTLResource], usage: MTLResourceUsage) {
-        useResources(resources, count: resources.count, usage: usage)
+        __use(resources, count: resources.count, usage: usage)
     }
     
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func useHeaps(_ heaps: [MTLHeap]) {
-        useHeaps(heaps, count: heaps.count)
+        __use(heaps, count: heaps.count)
     }
     
 #if os(OSX)
     @available(macOS 10.13, *)
     public func setViewports(_ viewports: [MTLViewport]) {
-        setViewports(viewports, count: viewports.count)
+        __setViewports(viewports, count: viewports.count)
     }
     
     @available(macOS 10.13, *)
     public func setScissorRects(_ scissorRects: [MTLScissorRect]) {
-        setScissorRects(scissorRects, count: scissorRects.count)
+        __setScissorRects(scissorRects, count: scissorRects.count)
     }
 #endif
     
     public func setVertexBuffers(_ buffers: [MTLBuffer?], offsets: [Int], range: Range<Int>) {
-        setVertexBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
+        __setVertexBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setVertexTextures(_ textures: [MTLTexture?], range: Range<Int>) {
-        setVertexTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
+        __setVertexTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setVertexSamplerStates(_ samplers: [MTLSamplerState?], range: Range<Int>) {
-        setVertexSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
+        __setVertexSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setVertexSamplerStates(_ samplers: [MTLSamplerState?], lodMinClamps: [Float], lodMaxClamps: [Float], range: Range<Int>) {
-        setVertexSamplerStates(samplers, lodMinClamps: lodMinClamps, lodMaxClamps: lodMaxClamps, with: NSMakeRange(range.lowerBound, range.count))
+        __setVertexSamplerStates(samplers, lodMinClamps: lodMinClamps, lodMaxClamps: lodMaxClamps, with: NSMakeRange(range.lowerBound, range.count))
     }
 
     public func setFragmentBuffers(_ buffers: [MTLBuffer?], offsets: [Int], range: Range<Int>) {
-        setFragmentBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
+        __setFragmentBuffers(buffers, offsets: offsets, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setFragmentTextures(_ textures: [MTLTexture?], range: Range<Int>) {
-        setFragmentTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
+        __setFragmentTextures(textures, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setFragmentSamplerStates(_ samplers: [MTLSamplerState?], range: Range<Int>) {
-        setFragmentSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
+        __setFragmentSamplerStates(samplers, with: NSMakeRange(range.lowerBound, range.count))
     }
     
     public func setFragmentSamplerStates(_ samplers: [MTLSamplerState?], lodMinClamps: [Float], lodMaxClamps: [Float], range: Range<Int>) {
-        setFragmentSamplerStates(samplers, lodMinClamps: lodMinClamps, lodMaxClamps: lodMaxClamps, with: NSMakeRange(range.lowerBound, range.count))
+        __setFragmentSamplerStates(samplers, lodMinClamps: lodMinClamps, lodMaxClamps: lodMaxClamps, with: NSMakeRange(range.lowerBound, range.count))
     }
 
 #if os(iOS)
@@ -207,14 +207,14 @@
     
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func setSamplePositions(_ positions: [MTLSamplePosition]) {
-        setSamplePositions(positions, count: positions.count)
+        __setSamplePositions(positions, count: positions.count)
     }
     
     @available(macOS 10.13, iOS 11.0, tvOS 11.0, *)
     public func getSamplePositions() -> [MTLSamplePosition] {
-        let numPositions = getSamplePositions(nil, count: 0)
+        let numPositions = __getSamplePositions(nil, count: 0)
         var positions = [MTLSamplePosition](repeating: MTLSamplePosition(x: 0,y: 0), count: numPositions)
-        getSamplePositions(&positions, count: numPositions)
+        __getSamplePositions(&positions, count: numPositions)
         return positions
     }
     
@@ -226,6 +226,6 @@
     
     @available(macOS 10.11, iOS 9.0, tvOS 9.0, *)
     public func makeTextureView(pixelFormat: MTLPixelFormat, textureType: MTLTextureType, levels levelRange: Range<Int>, slices sliceRange: Range<Int>) -> MTLTexture? {
-        return makeTextureView(pixelFormat: pixelFormat, textureType: textureType, levels: NSMakeRange(levelRange.lowerBound, levelRange.count), slices: NSMakeRange(sliceRange.lowerBound, sliceRange.count))
+        return __newTextureView(with: pixelFormat, textureType: textureType, levels: NSMakeRange(levelRange.lowerBound, levelRange.count), slices: NSMakeRange(sliceRange.lowerBound, sliceRange.count))
     }
 }
diff --git a/stdlib/public/SDK/MetalKit/CMakeLists.txt b/stdlib/public/SDK/MetalKit/CMakeLists.txt
index a1f8a96..b0a2013 100644
--- a/stdlib/public/SDK/MetalKit/CMakeLists.txt
+++ b/stdlib/public/SDK/MetalKit/CMakeLists.txt
@@ -4,7 +4,7 @@
 add_swift_library(swiftMetalKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
     MetalKit.swift
 
-  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" "-swift-version" "3"
+  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   TARGET_SDKS OSX IOS IOS_SIMULATOR TVOS TVOS_SIMULATOR
   SWIFT_MODULE_DEPENDS_OSX Darwin AppKit CoreData CoreFoundation CoreGraphics CoreImage Dispatch Foundation IOKit Metal ModelIO ObjectiveC QuartzCore simd XPC # auto-updated
diff --git a/stdlib/public/SDK/MetalKit/MetalKit.swift b/stdlib/public/SDK/MetalKit/MetalKit.swift
index 607e3c5..02abb98 100644
--- a/stdlib/public/SDK/MetalKit/MetalKit.swift
+++ b/stdlib/public/SDK/MetalKit/MetalKit.swift
@@ -17,7 +17,7 @@
 extension MTKMesh {
     public class func newMeshes(asset: MDLAsset, device: MTLDevice) throws -> (modelIOMeshes: [MDLMesh], metalKitMeshes: [MTKMesh]) {
         var modelIOMeshes: NSArray?
-        var metalKitMeshes = try MTKMesh.newMeshes(from: asset, device: device, sourceMeshes: &modelIOMeshes)
+        let metalKitMeshes = try MTKMesh.__newMeshes(from: asset, device: device, sourceMeshes: &modelIOMeshes)
         return (modelIOMeshes: modelIOMeshes as! [MDLMesh], metalKitMeshes: metalKitMeshes)
     }
 }
@@ -26,7 +26,7 @@
 @available(macOS 10.12, iOS 10.0, tvOS 10.0, *)
 public func MTKModelIOVertexDescriptorFromMetalWithError(_ metalDescriptor: MTLVertexDescriptor) throws -> MDLVertexDescriptor {
     var error: NSError? = nil
-    let result = MTKModelIOVertexDescriptorFromMetalWithError(metalDescriptor, &error)
+    let result = __MTKModelIOVertexDescriptorFromMetalWithError(metalDescriptor, &error)
     if let error = error {
         throw error
     }
@@ -37,7 +37,7 @@
 @available(macOS 10.12, iOS 10.0, tvOS 10.0, *)
 public func MTKMetalVertexDescriptorFromModelIOWithError(_ modelIODescriptor: MDLVertexDescriptor) throws -> MTLVertexDescriptor? {
     var error: NSError? = nil
-    let result = MTKMetalVertexDescriptorFromModelIOWithError(modelIODescriptor, &error)
+    let result = __MTKMetalVertexDescriptorFromModelIOWithError(modelIODescriptor, &error)
     if let error = error {
         throw error
     }
diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h
index e726a62..ccc25a9 100644
--- a/stdlib/public/SwiftShims/LibcShims.h
+++ b/stdlib/public/SwiftShims/LibcShims.h
@@ -47,70 +47,136 @@
 typedef      long int __swift_ssize_t;
 #endif
 
+// This declaration might not be universally correct.
+// We verify its correctness for the current platform in the runtime code.
+#if defined(__linux__)
+typedef __swift_uint32_t __swift_mode_t;
+#elif defined(__APPLE__)
+typedef __swift_uint16_t __swift_mode_t;
+#elif defined(_WIN32)
+typedef __swift_int32_t __swift_mode_t;
+#else  // just guessing
+typedef __swift_uint16_t __swift_mode_t;
+#endif
+
+
 // General utilities <stdlib.h>
 // Memory management functions
-SWIFT_RUNTIME_STDLIB_INTERFACE
-void _swift_stdlib_free(void *ptr);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void _stdlib_free(void *ptr);
 
 // Input/output <stdio.h>
-SWIFT_RUNTIME_STDLIB_INTERFACE
-int _swift_stdlib_putchar_unlocked(int c);
-SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_size_t _swift_stdlib_fwrite_stdout(const void *ptr, __swift_size_t size,
-                                           __swift_size_t nitems);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_putchar_unlocked(int c);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_size_t _stdlib_fwrite_stdout(const void *ptr, __swift_size_t size,
+                                     __swift_size_t nitems);
 
 // String handling <string.h>
-SWIFT_READONLY SWIFT_RUNTIME_STDLIB_INTERFACE __swift_size_t
-_swift_stdlib_strlen(const char *s);
+SWIFT_READONLY SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_size_t _stdlib_strlen(const char *s);
 
-SWIFT_READONLY SWIFT_RUNTIME_STDLIB_INTERFACE __swift_size_t
-_swift_stdlib_strlen_unsigned(const unsigned char *s);
+SWIFT_READONLY SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_size_t _stdlib_strlen_unsigned(const unsigned char *s);
 
 SWIFT_READONLY
-SWIFT_RUNTIME_STDLIB_INTERFACE
-int _swift_stdlib_memcmp(const void *s1, const void *s2, __swift_size_t n);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_memcmp(const void *s1, const void *s2, __swift_size_t n);
 
 // <unistd.h>
-SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_ssize_t _swift_stdlib_read(int fd, void *buf, __swift_size_t nbyte);
-SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_ssize_t _swift_stdlib_write(int fd, const void *buf,
-                                    __swift_size_t nbyte);
-SWIFT_RUNTIME_STDLIB_INTERFACE
-int _swift_stdlib_close(int fd);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_ssize_t _stdlib_read(int fd, void *buf, __swift_size_t nbyte);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_ssize_t _stdlib_write(int fd, const void *buf, __swift_size_t nbyte);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_close(int fd);
+
+// Semaphores <semaphore.h>
+#if !defined(_WIN32) || defined(__CYGWIN__)
+// We can't use sem_t itself here, nor is there a platform-consistent
+// definition to copy for a __swift_sem_t type. Instead we use
+// void* in place of sem_t* and cast it back on the Swift side.
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void *_stdlib_sem_open2(const char *name, int oflag);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void *_stdlib_sem_open4(const char *name, int oflag,
+                        __swift_mode_t mode, unsigned int value);
+#endif
+
+// File control <fcntl.h>
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_open(const char *path, int oflag, __swift_mode_t mode);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_openat(int fd, const char *path, int oflag, __swift_mode_t mode);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_fcntl(int fd, int cmd, int value);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_fcntlPtr(int fd, int cmd, void* ptr);
+#endif
+
+// I/O control <ioctl.h>
+#if !defined(_WIN32) || defined(__CYGWIN__)
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_ioctl(int fd, unsigned long int request, int value);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_ioctlPtr(int fd, unsigned long int request, void* ptr);
+#endif
+
+// Environment
+#if defined(__APPLE__) || defined(__FreeBSD__)
+SWIFT_RUNTIME_STDLIB_INTERNAL
+char * _Nullable *_stdlib_getEnviron();
+#endif
+
+// System error numbers <errno.h>
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_getErrno();
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void _stdlib_setErrno(int value);
 
 // Non-standard extensions
-SWIFT_READNONE SWIFT_RUNTIME_STDLIB_INTERFACE __swift_size_t
-_swift_stdlib_malloc_size(const void *ptr);
+SWIFT_READNONE SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_size_t _stdlib_malloc_size(const void *ptr);
 
 // Random number <random>
-SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_uint32_t _swift_stdlib_cxx11_mt19937(void);
-SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_uint32_t
-_swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_uint32_t _stdlib_cxx11_mt19937(void);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+__swift_uint32_t _stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound);
 
 // Math library functions
 static inline SWIFT_ALWAYS_INLINE
-float _swift_stdlib_remainderf(float _self, float _other) {
+float _stdlib_remainderf(float _self, float _other) {
   return __builtin_remainderf(_self, _other);
 }
   
 static inline SWIFT_ALWAYS_INLINE
-float _swift_stdlib_squareRootf(float _self) {
+float _stdlib_squareRootf(float _self) {
   return __builtin_sqrtf(_self);
 }
 
 static inline SWIFT_ALWAYS_INLINE
-double _swift_stdlib_remainder(double _self, double _other) {
+double _stdlib_remainder(double _self, double _other) {
   return __builtin_remainder(_self, _other);
 }
 
 static inline SWIFT_ALWAYS_INLINE
-double _swift_stdlib_squareRoot(double _self) {
+double _stdlib_squareRoot(double _self) {
   return __builtin_sqrt(_self);
 }
 
+// Apple's math.h does not declare lgamma_r() etc by default
+#if defined(__APPLE__)
+SWIFT_RUNTIME_STDLIB_INTERNAL
+float _stdlib_lgammaf_r(float x, int *psigngam);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+double _stdlib_lgamma_r(double x, int *psigngam);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+long double _stdlib_lgammal_r(long double x, int *psigngam);
+#endif // defined(__APPLE__)
+
+
 // TLS - thread local storage
 
 #if defined(__ANDROID__)
@@ -127,28 +193,27 @@
 typedef unsigned long __swift_thread_key_t;
 #endif
 
-SWIFT_RUNTIME_STDLIB_INTERFACE
-int
-_swift_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
-                                void (* _Nullable destructor)(void * _Nullable));
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
+                              void (* _Nullable destructor)(void * _Nullable));
 
-SWIFT_RUNTIME_STDLIB_INTERFACE
-void * _Nullable _swift_stdlib_thread_getspecific(__swift_thread_key_t key);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void * _Nullable _stdlib_thread_getspecific(__swift_thread_key_t key);
 
-SWIFT_RUNTIME_STDLIB_INTERFACE
-int _swift_stdlib_thread_setspecific(__swift_thread_key_t key,
-                                     const void * _Nullable value);
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int _stdlib_thread_setspecific(__swift_thread_key_t key,
+                               const void * _Nullable value);
 
 // TODO: Remove horrible workaround when importer does Float80 <-> long double.
 #if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER
 static inline SWIFT_ALWAYS_INLINE
-void _swift_stdlib_remainderl(void *_self, const void *_other) {
+void _stdlib_remainderl(void *_self, const void *_other) {
   long double *_f80self = (long double *)_self;
   *_f80self = __builtin_remainderl(*_f80self, *(const long double *)_other);
 }
 
 static inline SWIFT_ALWAYS_INLINE
-void _swift_stdlib_squareRootl(void *_self) {
+void _stdlib_squareRootl(void *_self) {
   long double *_f80self = (long double *)_self;
   *_f80self = __builtin_sqrtl(*_f80self);
 }
diff --git a/stdlib/public/core/Algorithm.swift b/stdlib/public/core/Algorithm.swift
index 5e23f82..28dcc9a 100644
--- a/stdlib/public/core/Algorithm.swift
+++ b/stdlib/public/core/Algorithm.swift
@@ -90,9 +90,7 @@
 /// To create an instance of `EnumeratedIterator`, call
 /// `enumerated().makeIterator()` on a sequence or collection.
 @_fixed_layout
-public struct EnumeratedIterator<
-  Base : IteratorProtocol
-> : IteratorProtocol, Sequence {
+public struct EnumeratedIterator<Base: IteratorProtocol> {
   @_versioned
   internal var _base: Base
   @_versioned
@@ -105,7 +103,9 @@
     self._base = _base
     self._count = 0
   }
+}
 
+extension EnumeratedIterator: IteratorProtocol, Sequence {
   /// The type of element returned by `next()`.
   public typealias Element = (offset: Int, element: Base.Element)
 
@@ -139,7 +139,7 @@
 ///     // Prints "0: foo"
 ///     // Prints "1: bar"
 @_fixed_layout
-public struct EnumeratedSequence<Base : Sequence> : Sequence {
+public struct EnumeratedSequence<Base: Sequence> {
   @_versioned
   internal var _base: Base
 
@@ -149,7 +149,9 @@
   internal init(_base: Base) {
     self._base = _base
   }
+}
 
+extension EnumeratedSequence: Sequence {
   /// Returns an iterator over the elements of this sequence.
   @_inlineable
   public func makeIterator() -> EnumeratedIterator<Base.Iterator> {
diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb
index a8ad768..ed9fa54 100644
--- a/stdlib/public/core/Arrays.swift.gyb
+++ b/stdlib/public/core/Arrays.swift.gyb
@@ -455,13 +455,44 @@
 
 ${SelfDocComment}
 @_fixed_layout
-public struct ${Self}<Element>
-  : RandomAccessCollection,
-    MutableCollection,
-    _DestructorSafeContainer
-{
+public struct ${Self}<Element>: _DestructorSafeContainer {
+  %if Self == 'Array':
+  #if _runtime(_ObjC)
+    internal typealias _Buffer = _ArrayBuffer<Element>
+  #else
+    internal typealias _Buffer = _ContiguousArrayBuffer<Element>
+  #endif
+  %elif Self == 'ArraySlice':
+    internal typealias _Buffer = _SliceBuffer<Element>
+  %else:
+    internal typealias _Buffer = _${Self.strip('_')}Buffer<Element>
+  %end
 
+  @_versioned
+  internal var _buffer: _Buffer
+
+  /// Initialization from an existing buffer does not have "array.init"
+  /// semantics because the caller may retain an alias to buffer.
+  @_inlineable
+  @_versioned
+  internal init(_buffer: _Buffer) {
+    self._buffer = _buffer
+  }
+
+  %if Self == 'ArraySlice':
+  /// Initialization from an existing buffer does not have "array.init"
+  /// semantics because the caller may retain an alias to buffer.
+  @_inlineable
+  @_versioned
+  internal init(_buffer buffer: _ContiguousArrayBuffer<Element>) {
+    self.init(_buffer: _Buffer(_buffer: buffer, shiftedToStartIndex: 0))
+  }
+  %end
+}
+
+extension ${Self}: RandomAccessCollection, MutableCollection {
   public typealias Index = Int
+  public typealias Indices = CountableRange<Int>
   public typealias Iterator = IndexingIterator<${Self}>
 
 %if Self == 'ArraySlice':
@@ -662,8 +693,6 @@
     // NOTE: This method is a no-op for performance reasons.
   }
 
-  public typealias Indices = CountableRange<Int>
-
   /// Accesses the element at the specified position.
   ///
   /// The following example uses indexed subscripting to update an array's
@@ -751,9 +780,10 @@
       }
     }
   }
+}
 
-  //===--- private --------------------------------------------------------===//
-
+//===--- private helpers---------------------------------------------------===//
+extension ${Self} {
   /// Returns `true` if the array is native and does not need a deferred
   /// type check.  May be hoisted by the optimizer, which means its
   /// results may be stale by the time they are used if there is an
@@ -906,40 +936,6 @@
   internal func _getElementAddress(_ index: Int) -> UnsafeMutablePointer<Element> {
     return _buffer.subscriptBaseAddress + index
   }
-
-%if Self == 'Array':
-#if _runtime(_ObjC)
-  internal typealias _Buffer = _ArrayBuffer<Element>
-#else
-  internal typealias _Buffer = _ContiguousArrayBuffer<Element>
-#endif
-%elif Self == 'ArraySlice':
-  internal typealias _Buffer = _SliceBuffer<Element>
-%else:
-  internal typealias _Buffer = _${Self.strip('_')}Buffer<Element>
-%end
-
-  /// Initialization from an existing buffer does not have "array.init"
-  /// semantics because the caller may retain an alias to buffer.
-
-  @_inlineable
-  @_versioned
-  internal init(_buffer: _Buffer) {
-    self._buffer = _buffer
-  }
-
-%if Self == 'ArraySlice':
-  /// Initialization from an existing buffer does not have "array.init"
-  /// semantics because the caller may retain an alias to buffer.
-  @_inlineable
-  @_versioned
-  internal init(_buffer buffer: _ContiguousArrayBuffer<Element>) {
-    self.init(_buffer: _Buffer(_buffer: buffer, shiftedToStartIndex: 0))
-  }
-%end
-
-  @_versioned
-  internal var _buffer: _Buffer
 }
 
 extension ${Self} : ExpressibleByArrayLiteral {
diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift
index f741e34..8451c2c 100644
--- a/stdlib/public/core/BridgeObjectiveC.swift
+++ b/stdlib/public/core/BridgeObjectiveC.swift
@@ -170,9 +170,7 @@
   return _bridgeAnythingNonVerbatimToObjectiveC(x)
 }
 
-/// COMPILER_INTRINSIC
-@_inlineable // FIXME(sil-serialize-all)
-@_silgen_name("_swift_bridgeAnythingNonVerbatimToObjectiveC")
+@_silgen_name("")
 public func _bridgeAnythingNonVerbatimToObjectiveC<T>(_ x: T) -> AnyObject
 
 /// Convert a purportedly-nonnull `id` value from Objective-C into an Any.
@@ -214,8 +212,8 @@
 
 /// Convert `x` from its Objective-C representation to its Swift
 /// representation.
+/// COMPILER_INTRINSIC
 @_inlineable // FIXME(sil-serialize-all)
-@_silgen_name("_forceBridgeFromObjectiveC_bridgeable")
 public func _forceBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable> (
   _ x: T._ObjectiveCType,
   _: T.Type
@@ -253,8 +251,8 @@
 
 /// Attempt to convert `x` from its Objective-C representation to its Swift
 /// representation.
+/// COMPILER_INTRINSIC
 @_inlineable // FIXME(sil-serialize-all)
-@_silgen_name("_conditionallyBridgeFromObjectiveC_bridgeable")
 public func _conditionallyBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable>(
   _ x: T._ObjectiveCType,
   _: T.Type
@@ -264,10 +262,8 @@
   return result
 }
 
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned // FIXME(sil-serialize-all)
-@_silgen_name("_swift_bridgeNonVerbatimFromObjectiveC")
-internal func _bridgeNonVerbatimFromObjectiveC<T>(
+@_silgen_name("")
+public func _bridgeNonVerbatimFromObjectiveC<T>(
   _ x: AnyObject,
   _ nativeType: T.Type,
   _ result: inout T?
@@ -275,10 +271,8 @@
 
 /// Helper stub to upcast to Any and store the result to an inout Any?
 /// on the C++ runtime's behalf.
-// COMPILER_INTRINSIC
-@_inlineable // FIXME(sil-serialize-all)
-@_silgen_name("_swift_bridgeNonVerbatimFromObjectiveCToAny")
-public func _bridgeNonVerbatimFromObjectiveCToAny(
+@_silgen_name("_bridgeNonVerbatimFromObjectiveCToAny")
+internal func _bridgeNonVerbatimFromObjectiveCToAny(
     _ x: AnyObject,
     _ result: inout Any?
 ) {
@@ -286,10 +280,8 @@
 }
 
 /// Helper stub to upcast to Optional on the C++ runtime's behalf.
-// COMPILER_INTRINSIC
-@_inlineable // FIXME(sil-serialize-all)
-@_silgen_name("_swift_bridgeNonVerbatimBoxedValue")
-public func _bridgeNonVerbatimBoxedValue<NativeType>(
+@_silgen_name("_bridgeNonVerbatimBoxedValue")
+internal func _bridgeNonVerbatimBoxedValue<NativeType>(
     _ x: UnsafePointer<NativeType>,
     _ result: inout NativeType?
 ) {
@@ -303,10 +295,8 @@
 ///   unchanged otherwise.
 ///
 /// - Returns: `true` to indicate success, `false` to indicate failure.
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned // FIXME(sil-serialize-all)
-@_silgen_name("_swift_bridgeNonVerbatimFromObjectiveCConditional")
-internal func _bridgeNonVerbatimFromObjectiveCConditional<T>(
+@_silgen_name("")
+public func _bridgeNonVerbatimFromObjectiveCConditional<T>(
   _ x: AnyObject,
   _ nativeType: T.Type,
   _ result: inout T?
@@ -325,10 +315,8 @@
   return _isBridgedNonVerbatimToObjectiveC(T.self)
 }
 
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned // FIXME(sil-serialize-all)
-@_silgen_name("_swift_isBridgedNonVerbatimToObjectiveC")
-internal func _isBridgedNonVerbatimToObjectiveC<T>(_: T.Type) -> Bool
+@_silgen_name("")
+public func _isBridgedNonVerbatimToObjectiveC<T>(_: T.Type) -> Bool
 
 /// A type that's bridged "verbatim" does not conform to
 /// `_ObjectiveCBridgeable`, and can have its bits reinterpreted as an
@@ -348,10 +336,8 @@
   return _getBridgedNonVerbatimObjectiveCType(T.self)
 }
 
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned // FIXME(sil-serialize-all)
-@_silgen_name("_swift_getBridgedNonVerbatimObjectiveCType")
-internal func _getBridgedNonVerbatimObjectiveCType<T>(_: T.Type) -> Any.Type?
+@_silgen_name("")
+public func _getBridgedNonVerbatimObjectiveCType<T>(_: T.Type) -> Any.Type?
 
 // -- Pointer argument bridging
 
@@ -384,7 +370,7 @@
 /// already have writeback-scoped lifetime.
 @_fixed_layout
 public struct AutoreleasingUnsafeMutablePointer<Pointee /* TODO : class */>
-  : Equatable, _Pointer {
+  :  _Pointer {
 
   public let _rawValue: Builtin.RawPointer
 
@@ -508,7 +494,9 @@
     guard let unwrapped = from else { return nil }
     self.init(unwrapped)
   }
+}
 
+extension AutoreleasingUnsafeMutablePointer: Equatable {
   @_inlineable // FIXME(sil-serialize-all)
   @_transparent
   public static func == (
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index 2f06587..1ff861b 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -322,7 +322,7 @@
 // when using RuntimeShims.h
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned
-@_silgen_name("swift_objc_class_usesNativeSwiftReferenceCounting")
+@_silgen_name("_objcClassUsesNativeSwiftReferenceCounting")
 internal func _usesNativeSwiftReferenceCounting(_ theClass: AnyClass) -> Bool
 #else
 @_inlineable // FIXME(sil-serialize-all)
@@ -335,14 +335,14 @@
 
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned // FIXME(sil-serialize-all)
-@_silgen_name("swift_class_getInstanceExtents")
-internal func swift_class_getInstanceExtents(_ theClass: AnyClass)
+@_silgen_name("_getSwiftClassInstanceExtents")
+internal func getSwiftClassInstanceExtents(_ theClass: AnyClass)
   -> (negative: UInt, positive: UInt)
 
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned // FIXME(sil-serialize-all)
-@_silgen_name("swift_objc_class_unknownGetInstanceExtents")
-internal func swift_objc_class_unknownGetInstanceExtents(_ theClass: AnyClass)
+@_silgen_name("_getObjCClassInstanceExtents")
+internal func getObjCClassInstanceExtents(_ theClass: AnyClass)
   -> (negative: UInt, positive: UInt)
 
 @_inlineable // FIXME(sil-serialize-all)
@@ -350,9 +350,9 @@
 @inline(__always)
 internal func _class_getInstancePositiveExtentSize(_ theClass: AnyClass) -> Int {
 #if _runtime(_ObjC)
-  return Int(swift_objc_class_unknownGetInstanceExtents(theClass).positive)
+  return Int(getObjCClassInstanceExtents(theClass).positive)
 #else
-  return Int(swift_class_getInstanceExtents(theClass).positive)
+  return Int(getSwiftClassInstanceExtents(theClass).positive)
 #endif
 }
 
@@ -488,16 +488,12 @@
   )
 }
 
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
 @_silgen_name("_swift_class_getSuperclass")
 internal func _swift_class_getSuperclass(_ t: AnyClass) -> AnyClass?
 
 /// Returns the superclass of `t`, if any.  The result is `nil` if `t` is
 /// a root class or class protocol.
-@_inlineable // FIXME(sil-serialize-all)
-@inline(__always)
-public // @testable
+public
 func _getSuperclass(_ t: AnyClass) -> AnyClass? {
   return _swift_class_getSuperclass(t)
 }
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index b5371f1..9e17e41 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -47,7 +47,8 @@
   CString.swift
   CTypes.swift
   DebuggerSupport.swift
-  DoubleWidth.swift.gyb
+  # FIXME(double-width): <rdar://problem/32726173>
+  #DoubleWidth.swift.gyb
   DropWhile.swift.gyb
   Dump.swift
   EmptyCollection.swift
diff --git a/stdlib/public/core/CString.swift b/stdlib/public/core/CString.swift
index 823cfee..eb07f91 100644
--- a/stdlib/public/core/CString.swift
+++ b/stdlib/public/core/CString.swift
@@ -174,7 +174,7 @@
   guard let s = p else {
     return nil
   }
-  let count = Int(_swift_stdlib_strlen(s))
+  let count = Int(_stdlib_strlen(s))
   var result = [CChar](repeating: 0, count: count + 1)
   for i in 0..<count {
     result[i] = s[i]
diff --git a/stdlib/public/core/CTypes.swift b/stdlib/public/core/CTypes.swift
index 0d3af0d..b38de34 100644
--- a/stdlib/public/core/CTypes.swift
+++ b/stdlib/public/core/CTypes.swift
@@ -87,7 +87,7 @@
 /// Opaque pointers are used to represent C pointers to types that
 /// cannot be represented in Swift, such as incomplete struct types.
 @_fixed_layout
-public struct OpaquePointer : Hashable {
+public struct OpaquePointer {
   @_versioned
   internal var _rawValue: Builtin.RawPointer
 
@@ -147,7 +147,16 @@
     guard let unwrapped = from else { return nil }
     self.init(unwrapped)
   }
+}
 
+extension OpaquePointer: Equatable {
+  @_inlineable // FIXME(sil-serialize-all)
+  public static func == (lhs: OpaquePointer, rhs: OpaquePointer) -> Bool {
+    return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
+  }
+}
+
+extension OpaquePointer: Hashable {
   /// The pointer's hash value.
   ///
   /// The hash value is not guaranteed to be stable across different
@@ -195,13 +204,6 @@
   }
 }
 
-extension OpaquePointer : Equatable {
-  @_inlineable // FIXME(sil-serialize-all)
-  public static func == (lhs: OpaquePointer, rhs: OpaquePointer) -> Bool {
-    return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
-  }
-}
-
 /// A wrapper around a C `va_list` pointer.
 @_fixed_layout
 public struct CVaListPointer {
diff --git a/stdlib/public/core/Character.swift b/stdlib/public/core/Character.swift
index 79b31f1..f260b57 100644
--- a/stdlib/public/core/Character.swift
+++ b/stdlib/public/core/Character.swift
@@ -62,10 +62,7 @@
 /// [clusters]: http://www.unicode.org/glossary/#extended_grapheme_cluster
 /// [scalars]: http://www.unicode.org/glossary/#unicode_scalar_value
 @_fixed_layout
-public struct Character :
-  _ExpressibleByBuiltinUTF16ExtendedGraphemeClusterLiteral,
-  ExpressibleByExtendedGraphemeClusterLiteral, Hashable {
-
+public struct Character {
   // Fundamentally, it is just a String, but it is optimized for the common case
   // where the UTF-16 representation fits in 63 bits.  The remaining bit is used
   // to discriminate between small and large representations.  Since a grapheme
@@ -77,6 +74,47 @@
     case large(_StringBuffer._Storage)
   }
 
+  @_versioned
+  internal var _representation: Representation
+
+  // FIXME(sil-serialize-all): Should be @_inlineable  @_versioned
+  // <rdar://problem/34557187>
+  internal static func _smallValue(_ value: Builtin.Int63) -> UInt64 {
+    return UInt64(Builtin.zext_Int63_Int64(value))
+  }
+
+  typealias UTF16View = String.UTF16View
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned // FIXME(sil-serialize-all)
+  internal var utf16: UTF16View {
+    return String(self).utf16
+  }
+
+  /// Creates a Character from a String that is already known to require the
+  /// large representation.
+  ///
+  /// - Note: `s` should contain only a single grapheme, but we can't require
+  ///   that formally because of grapheme cluster literals and the shifting
+  ///   sands of Unicode.  https://bugs.swift.org/browse/SR-4955
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned
+  internal init(_largeRepresentationString s: String) {
+    if let native = s._core.nativeBuffer,
+      native.start == s._core._baseAddress!,
+      native.usedCount == s._core.count {
+      _representation = .large(native._storage)
+      return
+    }
+    var nativeString = ""
+    nativeString.append(s)
+    _representation = .large(nativeString._core.nativeBuffer!._storage)
+  }
+}
+
+extension Character
+ : _ExpressibleByBuiltinUTF16ExtendedGraphemeClusterLiteral,
+   ExpressibleByExtendedGraphemeClusterLiteral
+{
   /// Creates a character containing the given Unicode scalar value.
   ///
   /// - Parameter content: The Unicode scalar value to convert into a character.
@@ -238,53 +276,6 @@
     }
     self = Character(_largeRepresentationString: s)
   }
-
-  /// Creates a Character from a String that is already known to require the
-  /// large representation.
-  ///
-  /// - Note: `s` should contain only a single grapheme, but we can't require
-  ///   that formally because of grapheme cluster literals and the shifting
-  ///   sands of Unicode.  https://bugs.swift.org/browse/SR-4955
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned
-  internal init(_largeRepresentationString s: String) {
-    if let native = s._core.nativeBuffer,
-      native.start == s._core._baseAddress!,
-      native.usedCount == s._core.count {
-      _representation = .large(native._storage)
-      return
-    }
-    var nativeString = ""
-    nativeString.append(s)
-    _representation = .large(nativeString._core.nativeBuffer!._storage)
-  }
-
-  // FIXME(sil-serialize-all): Should be @_inlineable  @_versioned
-  // <rdar://problem/34557187>
-  internal static func _smallValue(_ value: Builtin.Int63) -> UInt64 {
-    return UInt64(Builtin.zext_Int63_Int64(value))
-  }
-
-  /// The character's hash value.
-  ///
-  /// Hash values are not guaranteed to be equal across different executions of
-  /// your program. Do not save hash values to use during a future execution.
-  @_inlineable // FIXME(sil-serialize-all)
-  public var hashValue: Int {
-    // FIXME(performance): constructing a temporary string is extremely
-    // wasteful and inefficient.
-    return String(self).hashValue
-  }
-
-  typealias UTF16View = String.UTF16View
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned // FIXME(sil-serialize-all)
-  internal var utf16: UTF16View {
-    return String(self).utf16
-  }
-
-  @_versioned
-  internal var _representation: Representation
 }
 
 extension Character : CustomStringConvertible {
@@ -294,7 +285,7 @@
   }
 }
 
-extension Character : LosslessStringConvertible {}
+extension Character : LosslessStringConvertible { }
 
 extension Character : CustomDebugStringConvertible {
   /// A textual representation of the character, suitable for debugging.
@@ -393,3 +384,16 @@
     return String(lhs) < String(rhs)
   }
 }
+
+extension Character: Hashable {
+  /// The character's hash value.
+  ///
+  /// Hash values are not guaranteed to be equal across different executions of
+  /// your program. Do not save hash values to use during a future execution.
+  @_inlineable // FIXME(sil-serialize-all)
+  public var hashValue: Int {
+    // FIXME(performance): constructing a temporary string is extremely
+    // wasteful and inefficient.
+    return String(self).hashValue
+  }
+}
diff --git a/stdlib/public/core/ClosedRange.swift b/stdlib/public/core/ClosedRange.swift
index 1003814..b3211dd 100644
--- a/stdlib/public/core/ClosedRange.swift
+++ b/stdlib/public/core/ClosedRange.swift
@@ -25,12 +25,11 @@
 // `ClosedRange`.
 /// A position in a `CountableClosedRange` instance.
 @_fixed_layout
-public struct ClosedRangeIndex<Bound>
-  where
-  // swift-3-indexing-model: should conform to _Strideable, otherwise
-  // CountableClosedRange is not interchangeable with CountableRange in all
-  // contexts.
-  Bound : Strideable, Bound.Stride : SignedInteger {
+public struct ClosedRangeIndex<Bound: Strideable>
+where Bound.Stride : SignedInteger {
+  @_versioned
+  internal var _value: _ClosedRangeIndexRepresentation<Bound>
+
   /// Creates the "past the end" position.
   @_inlineable
   @_versioned
@@ -41,8 +40,6 @@
   @_versioned
   internal init(_ x: Bound) { _value = .inRange(x) }
 
-  @_versioned
-  internal var _value: _ClosedRangeIndexRepresentation<Bound>
   @_inlineable
   @_versioned
   internal var _dereferenced: Bound {
@@ -143,9 +140,8 @@
 /// iterate over consecutive floating-point values, see the
 /// `stride(from:through:by:)` function.
 @_fixed_layout
-public struct CountableClosedRange<Bound> : RandomAccessCollection
-  where
-  Bound : Strideable, Bound.Stride : SignedInteger {
+public struct CountableClosedRange<Bound: Strideable>
+where Bound.Stride : SignedInteger {
 
   /// The range's lower bound.
   public let lowerBound: Bound
@@ -156,12 +152,27 @@
   /// more applications of `index(after:)`.
   public let upperBound: Bound
 
+  /// Creates an instance with the given bounds.
+  ///
+  /// Because this initializer does not perform any checks, it should be used
+  /// as an optimization only when you are absolutely certain that `lower` is
+  /// less than or equal to `upper`. Using the closed range operator (`...`)
+  /// to form `CountableClosedRange` instances is preferred.
+  ///
+  /// - Parameter bounds: A tuple of the lower and upper bounds of the range.
+  @_inlineable
+  public init(uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
+    self.lowerBound = bounds.lower
+    self.upperBound = bounds.upper
+  }
+}
+
+extension CountableClosedRange: RandomAccessCollection {
   /// The element type of the range; the same type as the range's bounds.
   public typealias Element = Bound
 
   /// A type that represents a position in the range.
   public typealias Index = ClosedRangeIndex<Bound>
-
   public typealias IndexDistance = Bound.Stride
 
   /// The position of the first element in the range.
@@ -265,20 +276,6 @@
     return Slice(base: self, bounds: bounds)
   }
 
-  /// Creates an instance with the given bounds.
-  ///
-  /// Because this initializer does not perform any checks, it should be used
-  /// as an optimization only when you are absolutely certain that `lower` is
-  /// less than or equal to `upper`. Using the closed range operator (`...`)
-  /// to form `CountableClosedRange` instances is preferred.
-  ///
-  /// - Parameter bounds: A tuple of the lower and upper bounds of the range.
-  @_inlineable
-  public init(uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
-    self.lowerBound = bounds.lower
-    self.upperBound = bounds.upper
-  }
-
   @_inlineable
   public func _customContainsEquatableElement(_ element: Bound) -> Bool? {
     return element >= self.lowerBound && element <= self.upperBound
@@ -331,9 +328,13 @@
 ///     print(lowercaseA.isEmpty)
 ///     // Prints "false"
 @_fixed_layout
-public struct ClosedRange<
-  Bound : Comparable
-> {
+public struct ClosedRange<Bound : Comparable> {
+
+  /// The range's lower bound.
+  public let lowerBound: Bound
+
+  /// The range's upper bound.
+  public let upperBound: Bound
 
   /// Creates an instance with the given bounds.
   ///
@@ -349,12 +350,6 @@
     self.upperBound = bounds.upper
   }
 
-  /// The range's lower bound.
-  public let lowerBound: Bound
-
-  /// The range's upper bound.
-  public let upperBound: Bound
-
   /// Returns a Boolean value indicating whether the given element is contained
   /// within the range.
   ///
@@ -396,8 +391,7 @@
   ///   - maximum: The upper bound for the range.
   @_inlineable // FIXME(sil-serialize-all)
   @_transparent
-  public static func ... (minimum: Self, maximum: Self)
-    -> ClosedRange<Self> {
+  public static func ... (minimum: Self, maximum: Self) -> ClosedRange<Self> {
     _precondition(
       minimum <= maximum, "Can't form Range with upperBound < lowerBound")
     return ClosedRange(uncheckedBounds: (lower: minimum, upper: maximum))
diff --git a/stdlib/public/core/CollectionOfOne.swift b/stdlib/public/core/CollectionOfOne.swift
index d90cf25..00f5585 100644
--- a/stdlib/public/core/CollectionOfOne.swift
+++ b/stdlib/public/core/CollectionOfOne.swift
@@ -12,7 +12,10 @@
 
 /// An iterator that produces one or fewer instances of `Element`.
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct IteratorOverOne<Element> : IteratorProtocol, Sequence {
+public struct IteratorOverOne<Element> {
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _elements: Element?
+
   /// Construct an instance that generates `_element!`, or an empty
   /// sequence if `_element == nil`.
   @_inlineable // FIXME(sil-serialize-all)
@@ -20,7 +23,9 @@
   init(_elements: Element?) {
     self._elements = _elements
   }
+}
 
+extension IteratorOverOne: IteratorProtocol, Sequence {
   /// Advances to the next element and returns it, or `nil` if no next element
   /// exists.
   ///
@@ -34,23 +39,25 @@
     _elements = nil
     return result
   }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _elements: Element?
 }
 
 /// A collection containing a single element of type `Element`.
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct CollectionOfOne<Element>
-  : MutableCollection, RandomAccessCollection {
+public struct CollectionOfOne<Element> {
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _element: Element
 
   /// Creates an instance containing just `element`.
   @_inlineable // FIXME(sil-serialize-all)
   public init(_ element: Element) {
     self._element = element
   }
+}
+
+extension CollectionOfOne: RandomAccessCollection, MutableCollection {
 
   public typealias Index = Int
+  public typealias Indices = CountableRange<Int>
 
   /// The position of the first element.
   @_inlineable // FIXME(sil-serialize-all)
@@ -82,8 +89,6 @@
     return startIndex
   }
 
-  public typealias Indices = CountableRange<Int>
-
   /// Returns an iterator over the elements of this sequence.
   ///
   /// - Complexity: O(1).
@@ -129,9 +134,6 @@
   public var count: Int {
     return 1
   }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _element: Element
 }
 
 extension CollectionOfOne : CustomDebugStringConvertible {
diff --git a/stdlib/public/core/ContiguousArrayBuffer.swift b/stdlib/public/core/ContiguousArrayBuffer.swift
index b2cd3c6..47c7f3f 100644
--- a/stdlib/public/core/ContiguousArrayBuffer.swift
+++ b/stdlib/public/core/ContiguousArrayBuffer.swift
@@ -215,7 +215,7 @@
          realMinimumCapacity._builtinWordValue, Element.self)
 
       let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(_storage))
-      let endAddr = storageAddr + _swift_stdlib_malloc_size(storageAddr)
+      let endAddr = storageAddr + _stdlib_malloc_size(storageAddr)
       let realCapacity = endAddr.assumingMemoryBound(to: Element.self) - firstElementAddress
 
       _initStorageHeader(
diff --git a/stdlib/public/core/EmptyCollection.swift b/stdlib/public/core/EmptyCollection.swift
index d665dfe..a8b43de 100644
--- a/stdlib/public/core/EmptyCollection.swift
+++ b/stdlib/public/core/EmptyCollection.swift
@@ -19,11 +19,15 @@
 
 /// An iterator that never produces an element.
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct EmptyIterator<Element> : IteratorProtocol, Sequence {
+public struct EmptyIterator<Element> {
+  // no properties
+  
   /// Creates an instance.
   @_inlineable // FIXME(sil-serialize-all)
   public init() {}
+}
 
+extension EmptyIterator: IteratorProtocol, Sequence {
   /// Returns `nil`, indicating that there are no more elements.
   @_inlineable // FIXME(sil-serialize-all)
   public mutating func next() -> Element? {
@@ -33,21 +37,24 @@
 
 /// A collection whose element type is `Element` but that is always empty.
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct EmptyCollection<Element> :
-  RandomAccessCollection, MutableCollection
-{
+public struct EmptyCollection<Element> {
+  // no properties
+
+  /// Creates an instance.
+  @_inlineable // FIXME(sil-serialize-all)
+  public init() {}
+}
+
+extension EmptyCollection: RandomAccessCollection, MutableCollection {
   /// A type that represents a valid position in the collection.
   ///
   /// Valid indices consist of the position of every element and a
   /// "past the end" position that's not valid for use as a subscript.
   public typealias Index = Int
   public typealias IndexDistance = Int
+  public typealias Indices = CountableRange<Int>
   public typealias SubSequence = EmptyCollection<Element>
 
-  /// Creates an instance.
-  @_inlineable // FIXME(sil-serialize-all)
-  public init() {}
-
   /// Always zero, just like `endIndex`.
   @_inlineable // FIXME(sil-serialize-all)
   public var startIndex: Index {
@@ -155,8 +162,6 @@
     _debugPrecondition(bounds == Range(indices),
       "invalid bounds for an empty collection")
   }
-
-  public typealias Indices = CountableRange<Int>
 }
 
 extension EmptyCollection : Equatable {
diff --git a/stdlib/public/core/ExistentialCollection.swift.gyb b/stdlib/public/core/ExistentialCollection.swift.gyb
index 709f167..e585ba5 100644
--- a/stdlib/public/core/ExistentialCollection.swift.gyb
+++ b/stdlib/public/core/ExistentialCollection.swift.gyb
@@ -43,7 +43,10 @@
 /// iterator having the same `Element` type, hiding the specifics of the
 /// underlying `IteratorProtocol`.
 @_fixed_layout
-public struct AnyIterator<Element> : IteratorProtocol {
+public struct AnyIterator<Element> {
+  @_versioned
+  internal let _box: _AnyIteratorBoxBase<Element>
+
   /// Creates an iterator that wraps a base iterator but whose type depends
   /// only on the base iterator's element type.
   ///
@@ -96,7 +99,9 @@
   internal init(_box: _AnyIteratorBoxBase<Element>) {
     self._box = _box
   }
+}
 
+extension AnyIterator: IteratorProtocol {
   /// Advances to the next element and returns it, or `nil` if no next element
   /// exists.
   ///
@@ -105,14 +110,11 @@
   public func next() -> Element? {
     return _box.next()
   }
-
-  @_versioned
-  internal let _box: _AnyIteratorBoxBase<Element>
 }
 
 /// Every `IteratorProtocol` can also be a `Sequence`.  Note that
 /// traversing the sequence consumes the iterator.
-extension AnyIterator : Sequence {}
+extension AnyIterator: Sequence { }
 
 @_versioned
 @_fixed_layout
@@ -722,23 +724,23 @@
 
 @_versioned
 @_fixed_layout
-internal struct _ClosureBasedSequence<Iterator : IteratorProtocol>
-  : Sequence {
+internal struct _ClosureBasedSequence<Iterator : IteratorProtocol> {
+  @_versioned
+  internal var _makeUnderlyingIterator: () -> Iterator
 
   @_versioned
   @_inlineable
   internal init(_ makeUnderlyingIterator: @escaping () -> Iterator) {
     self._makeUnderlyingIterator = makeUnderlyingIterator
   }
+}
 
+extension _ClosureBasedSequence: Sequence {
   @_versioned
   @_inlineable
   internal func makeIterator() -> Iterator {
     return _makeUnderlyingIterator()
   }
-
-  @_versioned
-  internal var _makeUnderlyingIterator: () -> Iterator
 }
 
 /// A type-erased sequence.
@@ -748,15 +750,10 @@
 /// underlying sequence.
 //@_versioned
 @_fixed_layout
-public struct AnySequence<Element> : Sequence {
-  /// Creates a new sequence that wraps and forwards operations to `base`.
-  @_inlineable
-  public init<S : Sequence>(_ base: S)
-    where
-    S.Element == Element {
-    self._box = _SequenceBox(_base: base)
-  }
-
+public struct AnySequence<Element> {
+  @_versioned
+  internal let _box: _AnySequenceBox<Element>
+  
   /// Creates a sequence whose `makeIterator()` method forwards to
   /// `makeUnderlyingIterator`.
   @_inlineable
@@ -766,16 +763,23 @@
     self.init(_ClosureBasedSequence(makeUnderlyingIterator))
   }
 
-  public typealias Iterator = AnyIterator<Element>
-
   @_versioned
   @_inlineable
   internal init(_box: _AnySequenceBox<Element>) {
     self._box = _box
   }
+}
 
-  @_versioned
-  internal let _box: _AnySequenceBox<Element>
+extension  AnySequence: Sequence {
+  public typealias Iterator = AnyIterator<Element>
+
+  /// Creates a new sequence that wraps and forwards operations to `base`.
+  @_inlineable
+  public init<S : Sequence>(_ base: S)
+    where
+    S.Element == Element {
+    self._box = _SequenceBox(_base: base)
+  }
 }
 
 % for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
@@ -952,6 +956,9 @@
 /// A wrapper over an underlying index that hides the specific underlying type.
 @_fixed_layout
 public struct AnyIndex {
+  @_versioned
+  internal var _box: _AnyIndexBox
+
   /// Creates a new index wrapping `base`.
   @_inlineable
   public init<BaseIndex : Comparable>(_ base: BaseIndex) {
@@ -969,9 +976,6 @@
   internal var _typeID: ObjectIdentifier {
     return _box._typeID
   }
-
-  @_versioned
-  internal var _box: _AnyIndexBox
 }
 
 extension AnyIndex : Comparable {
@@ -1024,19 +1028,25 @@
 /// same `Element` type, hiding the specifics of the underlying
 /// collection.
 @_fixed_layout
-public struct ${Self}<Element>
-  : _AnyCollectionProtocol, ${SelfProtocol} {
-
-  public typealias Indices
-    = Default${Traversal.replace('Forward', '')}Indices<${Self}>
-
-  public typealias Iterator = AnyIterator<Element>
+public struct ${Self}<Element> {
+  @_versioned
+  internal let _box: _${Self}Box<Element>
 
   @_versioned
   @_inlineable
   internal init(_box: _${Self}Box<Element>) {
     self._box = _box
   }
+}
+
+extension ${Self}: ${SelfProtocol} {
+  public typealias Indices
+    = Default${Traversal.replace('Forward', '')}Indices<${Self}>
+
+  public typealias Iterator = AnyIterator<Element>
+  public typealias Index = AnyIndex
+  public typealias IndexDistance = Int64
+  public typealias SubSequence = ${Self}<Element> 
 
 %   for SubTraversal in TRAVERSALS[ti:]:
 %     SubProtocol = collectionForTraversal(SubTraversal)
@@ -1046,10 +1056,7 @@
   ///
   /// - Complexity: O(1).
   @_inlineable
-  public init<C : ${SubProtocol}>(_ base: C)
-  where
-    C.Element == Element
-     {
+  public init<C : ${SubProtocol}>(_ base: C) where C.Element == Element {
     // Traversal: ${Traversal}
     // SubTraversal: ${SubTraversal}
     self._box = _${SubProtocol}Box<C>(
@@ -1060,9 +1067,7 @@
   ///
   /// - Complexity: O(1)
   @_inlineable
-  public init(
-    _ other: Any${SubProtocol}<Element>
-  ) {
+  public init(_ other: Any${SubProtocol}<Element>) {
     self._box = other._box
   }
 %   end
@@ -1075,9 +1080,7 @@
   ///
   /// - Complexity: O(1)
   @_inlineable
-  public init?(
-    _ other: Any${collectionForTraversal(SuperTraversal)}<Element>
-  ) {
+  public init?(_ other: Any${collectionForTraversal(SuperTraversal)}<Element>) {
     guard let box =
       other._box as? _${Self}Box<Element> else {
       return nil
@@ -1086,14 +1089,11 @@
   }
 %   end
 
-  public typealias Index = AnyIndex
-  public typealias IndexDistance = Int64
-
   /// The position of the first element in a non-empty collection.
   ///
   /// In an empty collection, `startIndex == endIndex`.
   @_inlineable
-  public var startIndex: AnyIndex {
+  public var startIndex: Index {
     return AnyIndex(_box: _box._startIndex)
   }
 
@@ -1103,7 +1103,7 @@
   /// `endIndex` is always reachable from `startIndex` by zero or more
   /// applications of `index(after:)`.
   @_inlineable
-  public var endIndex: AnyIndex {
+  public var endIndex: Index {
     return AnyIndex(_box: _box._endIndex)
   }
 
@@ -1112,18 +1112,18 @@
   /// - Precondition: `position` indicates a valid position in `self` and
   ///   `position != endIndex`.
   @_inlineable
-  public subscript(position: AnyIndex) -> Element {
+  public subscript(position: Index) -> Element {
     return _box[position._box]
   }
 
   @_inlineable
-  public subscript(bounds: Range<AnyIndex>) -> ${Self}<Element> {
+  public subscript(bounds: Range<Index>) -> SubSequence {
     return ${Self}(_box:
       _box[start: bounds.lowerBound._box, end: bounds.upperBound._box])
   }
 
   @_inlineable
-  public func _failEarlyRangeCheck(_ index: AnyIndex, bounds: Range<AnyIndex>) {
+  public func _failEarlyRangeCheck(_ index: Index, bounds: Range<Index>) {
     // Do nothing.  Doing a range check would involve unboxing indices,
     // performing dynamic dispatch etc.  This seems to be too costly for a fast
     // range check for QoI purposes.
@@ -1137,12 +1137,12 @@
   }
 
   @_inlineable
-  public func index(after i: AnyIndex) -> AnyIndex {
+  public func index(after i: Index) -> Index {
     return AnyIndex(_box: _box._index(after: i._box))
   }
 
   @_inlineable
-  public func formIndex(after i: inout AnyIndex) {
+  public func formIndex(after i: inout Index) {
     if _isUnique(&i._box) {
       _box._formIndex(after: i._box)
     }
@@ -1152,22 +1152,20 @@
   }
 
   @_inlineable
-  public func index(_ i: AnyIndex, offsetBy n: Int64) -> AnyIndex {
+  public func index(_ i: Index, offsetBy n: Int64) -> Index {
     return AnyIndex(_box: _box._index(i._box, offsetBy: n))
   }
 
   @_inlineable
   public func index(
-    _ i: AnyIndex,
-    offsetBy n: Int64,
-    limitedBy limit: AnyIndex
-  ) -> AnyIndex? {
+    _ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index
+  ) -> Index? {
     return _box._index(i._box, offsetBy: n, limitedBy: limit._box)
       .map { AnyIndex(_box:$0) }
   }
 
   @_inlineable
-  public func formIndex(_ i: inout AnyIndex, offsetBy n: Int64) {
+  public func formIndex(_ i: inout Index, offsetBy n: IndexDistance) {
     if _isUnique(&i._box) {
       return _box._formIndex(&i._box, offsetBy: n)
     } else {
@@ -1177,9 +1175,9 @@
 
   @_inlineable
   public func formIndex(
-    _ i: inout AnyIndex,
-    offsetBy n: Int64,
-    limitedBy limit: AnyIndex
+    _ i: inout Index,
+    offsetBy n: IndexDistance,
+    limitedBy limit: Index
   ) -> Bool {
     if _isUnique(&i._box) {
       return _box._formIndex(&i._box, offsetBy: n, limitedBy: limit._box)
@@ -1193,7 +1191,7 @@
   }
 
   @_inlineable
-  public func distance(from start: AnyIndex, to end: AnyIndex) -> Int64 {
+  public func distance(from start: Index, to end: Index) -> IndexDistance {
     return _box._distance(from: start._box, to: end._box)
   }
 
@@ -1207,7 +1205,7 @@
 % end
   /// - Complexity: ${'O(1)' if Traversal == 'RandomAccess' else 'O(*n*)'}
   @_inlineable
-  public var count: Int64 {
+  public var count: IndexDistance {
     return _box._count
   }
 
@@ -1218,12 +1216,12 @@
 
 %   if Traversal == 'Bidirectional' or Traversal == 'RandomAccess':
   @_inlineable
-  public func index(before i: AnyIndex) -> AnyIndex {
+  public func index(before i: Index) -> Index {
     return AnyIndex(_box: _box._index(before: i._box))
   }
 
   @_inlineable
-  public func formIndex(before i: inout AnyIndex) {
+  public func formIndex(before i: inout Index) {
     if _isUnique(&i._box) {
       _box._formIndex(before: i._box)
     }
@@ -1237,15 +1235,14 @@
     return _box._last
   }
 %   end
+}
 
+extension ${Self}: _AnyCollectionProtocol {
   /// Uniquely identifies the stored underlying collection.
   @_inlineable
   public // Due to language limitations only
   var _boxID: ObjectIdentifier {
     return ObjectIdentifier(_box)
   }
-
-  @_versioned
-  internal let _box: _${Self}Box<Element>
 }
 % end
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index 79c021f..4b10abf 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -985,9 +985,9 @@
   public mutating func formRemainder(dividingBy other: ${Self}) {
 %if bits == 80:
     var other = other
-    _swift_stdlib_remainderl(&self, &other)
+    _stdlib_remainderl(&self, &other)
 %else:
-    self = _swift_stdlib_remainder${cFuncSuffix}(self, other)
+    self = _stdlib_remainder${cFuncSuffix}(self, other)
 %end
   }
 
@@ -1032,9 +1032,9 @@
   @_transparent
   public mutating func formSquareRoot( ) {
 %if bits == 80:
-    _swift_stdlib_squareRootl(&self)
+    _stdlib_squareRootl(&self)
 %else:
-    self = _swift_stdlib_squareRoot${cFuncSuffix}(self)
+    self = _stdlib_squareRoot${cFuncSuffix}(self)
 %end
   }
 
diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb
index b68de19..3eec29b 100644
--- a/stdlib/public/core/HashedCollections.swift.gyb
+++ b/stdlib/public/core/HashedCollections.swift.gyb
@@ -2153,9 +2153,11 @@
     get {
       return _variantBuffer.maybeGet(key) ?? defaultValue()
     }
-    set(newValue) {
-      // FIXME(performance): this loads and discards the old value.
-      _variantBuffer.updateValue(newValue, forKey: key)
+    mutableAddressWithNativeOwner {
+      let (_, address) = _variantBuffer
+        .pointerToValue(forKey: key, insertingDefault: defaultValue)
+      return (address, Builtin.castToNativeObject(
+        _variantBuffer.asNative._storage))
     }
   }
 
@@ -4865,6 +4867,17 @@
     }
   }
 
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned // FIXME(sil-serialize-all)
+  internal mutating func ensureNativeBuffer() {
+#if _runtime(_ObjC)
+    if _fastPath(guaranteedNative) { return }
+    if case .cocoa(let cocoaBuffer) = self {
+      migrateDataToNativeBuffer(cocoaBuffer)
+    }
+#endif
+  }
+
 #if _runtime(_ObjC)
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
@@ -5314,6 +5327,42 @@
 #endif
     }
   }
+
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned // FIXME(sil-serialize-all)
+  internal mutating func nativePointerToValue(
+    forKey key: Key, insertingDefault defaultValue: () -> Value
+  ) -> (inserted: Bool, pointer: UnsafeMutablePointer<Value>) {
+
+    var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))
+    if found {
+      let pointer = nativePointerToValue(at: ._native(i))
+      return (inserted: false, pointer: pointer)
+    }
+
+    let minCapacity = NativeBuffer.minimumCapacity(
+      minimumCount: asNative.count + 1,
+      maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)
+
+    let (_, capacityChanged) = ensureUniqueNativeBuffer(minCapacity)
+
+    if capacityChanged {
+      i = asNative._find(key, startBucket: asNative._bucket(key)).pos
+    }
+
+    asNative.initializeKey(key, value: defaultValue(), at: i.offset)
+    asNative.count += 1
+    return (inserted: true, pointer: asNative.values + i.offset)
+  }
+
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned // FIXME(sil-serialize-all)
+  internal mutating func pointerToValue(
+    forKey key: Key, insertingDefault defaultValue: () -> Value
+  ) -> (inserted: Bool, pointer: UnsafeMutablePointer<Value>) {
+    ensureNativeBuffer()
+    return nativePointerToValue(forKey: key, insertingDefault: defaultValue)
+  }
 %end
 
   @_inlineable // FIXME(sil-serialize-all)
@@ -5358,20 +5407,8 @@
   internal mutating func insert(
     _ value: Value, forKey key: Key
   ) -> (inserted: Bool, memberAfterInsert: Value) {
-
-    if _fastPath(guaranteedNative) {
-      return nativeInsert(value, forKey: key)
-    }
-
-    switch self {
-    case .native:
-      return nativeInsert(value, forKey: key)
-#if _runtime(_ObjC)
-    case .cocoa(let cocoaBuffer):
-      migrateDataToNativeBuffer(cocoaBuffer)
-      return nativeInsert(value, forKey: key)
-#endif
-    }
+    ensureNativeBuffer()
+    return nativeInsert(value, forKey: key)
   }
 
 %if Self == 'Dictionary':
@@ -5475,20 +5512,8 @@
     _ keysAndValues: S,
     uniquingKeysWith combine: (Value, Value) throws -> Value
   ) rethrows where S.Element == (Key, Value) {
-    if _fastPath(guaranteedNative) {
-      try nativeMerge(keysAndValues, uniquingKeysWith: combine)
-      return
-    }
-
-    switch self {
-    case .native:
-      try nativeMerge(keysAndValues, uniquingKeysWith: combine)
-#if _runtime(_ObjC)
-    case .cocoa(let cocoaStorage):
-      migrateDataToNativeBuffer(cocoaStorage)
-      try nativeMerge(keysAndValues, uniquingKeysWith: combine)
-#endif
-    }
+    ensureNativeBuffer()
+    try nativeMerge(keysAndValues, uniquingKeysWith: combine)
   }
 
   @_inlineable // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/InputStream.swift b/stdlib/public/core/InputStream.swift
index ad2da04..aa435f5 100644
--- a/stdlib/public/core/InputStream.swift
+++ b/stdlib/public/core/InputStream.swift
@@ -69,6 +69,6 @@
     input: UnsafeMutableBufferPointer(
       start: linePtr,
       count: readBytes)).0
-  _swift_stdlib_free(linePtr)
+  _stdlib_free(linePtr)
   return result
 }
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index f5fadc6..dba809e 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -3378,14 +3378,15 @@
   ) -> (quotient: ${Self}, remainder: ${Self}) {
     // FIXME(integers): tests
 %   # 128 bit types are not provided by the 32-bit LLVM
-%   #if word_bits == 32 and bits == 64:
-%   if bits == 64:
-    let lhs = DoubleWidth<${Self}>(dividend)
-    let rhs = DoubleWidth<${Self}>(self)
+%   if word_bits == 32 and bits == 64:
+%   #if bits == 64: #FIXME(double-width): uncomment when DoubleWidth is back
+    // let lhs = DoubleWidth<${Self}>(dividend)
+    // let rhs = DoubleWidth<${Self}>(self)
 
-    let (quotient, remainder) = lhs.quotientAndRemainder(dividingBy: rhs)
+    // let (quotient, remainder) = lhs.quotientAndRemainder(dividingBy: rhs)
     // FIXME(integers): check for high words in quotient and remainder
-    return (${Self}(quotient.low), ${Self}(remainder.low))
+    // return (${Self}(quotient.low), ${Self}(remainder.low))
+    fatalError("Operation is not supported")
 %   else:
     // FIXME(integers): handle division by zero and overflows
     _precondition(self != 0, "Division by zero")
diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift
index 0738020..49c7774 100644
--- a/stdlib/public/core/KeyPath.swift
+++ b/stdlib/public/core/KeyPath.swift
@@ -1906,8 +1906,8 @@
 
       if let rootPtr = root._kvcKeyPathStringPtr,
          let leafPtr = leaf._kvcKeyPathStringPtr {
-        rootKVCLength = Int(_swift_stdlib_strlen(rootPtr))
-        leafKVCLength = Int(_swift_stdlib_strlen(leafPtr))
+        rootKVCLength = Int(_stdlib_strlen(rootPtr))
+        leafKVCLength = Int(_stdlib_strlen(leafPtr))
         // root + "." + leaf
         appendedKVCLength = rootKVCLength + 1 + leafKVCLength
       } else {
diff --git a/stdlib/public/core/LazyCollection.swift.gyb b/stdlib/public/core/LazyCollection.swift.gyb
index 2ada678..8244cd7 100644
--- a/stdlib/public/core/LazyCollection.swift.gyb
+++ b/stdlib/public/core/LazyCollection.swift.gyb
@@ -266,6 +266,9 @@
 
 % end
 
+extension Slice: LazySequenceProtocol where Base: LazySequenceProtocol { }
+extension Slice: LazyCollectionProtocol where Base: LazyCollectionProtocol { }
+
 // ${'Local Variables'}:
 // eval: (read-only-mode 1)
 // End:
diff --git a/stdlib/public/core/ManagedBuffer.swift b/stdlib/public/core/ManagedBuffer.swift
index 734245a..def0d75 100644
--- a/stdlib/public/core/ManagedBuffer.swift
+++ b/stdlib/public/core/ManagedBuffer.swift
@@ -66,7 +66,7 @@
   @_inlineable // FIXME(sil-serialize-all)
   public final var capacity: Int {
     let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(self))
-    let endAddr = storageAddr + _swift_stdlib_malloc_size(storageAddr)
+    let endAddr = storageAddr + _stdlib_malloc_size(storageAddr)
     let realCapacity = endAddr.assumingMemoryBound(to: Element.self) -
       firstElementAddress
     return realCapacity
@@ -430,7 +430,7 @@
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
   internal var _capacityInBytes: Int {
-    return _swift_stdlib_malloc_size(_address)
+    return _stdlib_malloc_size(_address)
   }
 
   /// The address of this instance in a convenient pointer-to-bytes form
diff --git a/stdlib/public/core/Misc.swift b/stdlib/public/core/Misc.swift
index 6ece5eb0..88a91cc 100644
--- a/stdlib/public/core/Misc.swift
+++ b/stdlib/public/core/Misc.swift
@@ -92,9 +92,7 @@
     input: UnsafeBufferPointer(start: stringPtr, count: count))
 }
 
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned // FIXME(sil-serialize-all)
-@_silgen_name("swift_getTypeByName")
+@_silgen_name("")
 internal func _getTypeByName(
     _ name: UnsafePointer<UInt8>,
     _ nameLength: UInt)
@@ -102,7 +100,6 @@
 
 /// Lookup a class given a name. Until the demangled encoding of type
 /// names is stabilized, this is limited to top-level class names (Foo.bar).
-@_inlineable // FIXME(sil-serialize-all)
 public // SPI(Foundation)
 func _typeByName(_ name: String) -> Any.Type? {
   let nameUTF8 = Array(name.utf8)
diff --git a/stdlib/public/core/ObjectIdentifier.swift b/stdlib/public/core/ObjectIdentifier.swift
index afe218d..a004490 100644
--- a/stdlib/public/core/ObjectIdentifier.swift
+++ b/stdlib/public/core/ObjectIdentifier.swift
@@ -15,21 +15,10 @@
 /// In Swift, only class instances and metatypes have unique identities. There
 /// is no notion of identity for structs, enums, functions, or tuples.
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct ObjectIdentifier : Hashable {
+public struct ObjectIdentifier {
   @_versioned // FIXME(sil-serialize-all)
   internal let _value: Builtin.RawPointer
 
-  // FIXME: Better hashing algorithm
-  /// The identifier's hash value.
-  ///
-  /// The hash value is not guaranteed to be stable across different
-  /// invocations of the same program.  Do not persist the hash value across
-  /// program runs.
-  @_inlineable // FIXME(sil-serialize-all)
-  public var hashValue: Int {
-    return Int(Builtin.ptrtoint_Word(_value))
-  }
-
   /// Creates an instance that uniquely identifies the given class instance.
   ///
   /// The following example creates an example class `A` and compares instances
@@ -80,15 +69,30 @@
   }
 }
 
-extension ObjectIdentifier : Comparable {
+extension ObjectIdentifier: Equatable {
+  @_inlineable // FIXME(sil-serialize-all)
+  public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool {
+    return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value))
+  }
+}
+
+extension ObjectIdentifier: Comparable {
   @_inlineable // FIXME(sil-serialize-all)
   public static func < (lhs: ObjectIdentifier, rhs: ObjectIdentifier) -> Bool {
     return UInt(bitPattern: lhs) < UInt(bitPattern: rhs)
   }
+}
 
+extension ObjectIdentifier: Hashable {
+  // FIXME: Better hashing algorithm
+  /// The identifier's hash value.
+  ///
+  /// The hash value is not guaranteed to be stable across different
+  /// invocations of the same program.  Do not persist the hash value across
+  /// program runs.
   @_inlineable // FIXME(sil-serialize-all)
-  public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool {
-    return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value))
+  public var hashValue: Int {
+    return Int(Builtin.ptrtoint_Word(_value))
   }
 }
 
diff --git a/stdlib/public/core/OutputStream.swift b/stdlib/public/core/OutputStream.swift
index 6c5fc23..a48a4f6 100644
--- a/stdlib/public/core/OutputStream.swift
+++ b/stdlib/public/core/OutputStream.swift
@@ -534,7 +534,7 @@
     if let asciiBuffer = string._core.asciiBuffer {
       defer { _fixLifetime(string) }
 
-      _swift_stdlib_fwrite_stdout(
+      _stdlib_fwrite_stdout(
         UnsafePointer(asciiBuffer.baseAddress!),
         asciiBuffer.count,
         1)
@@ -542,7 +542,7 @@
     }
 
     for c in string.utf8 {
-      _swift_stdlib_putchar_unlocked(Int32(c))
+      _stdlib_putchar_unlocked(Int32(c))
     }
   }
 }
diff --git a/stdlib/public/core/Range.swift.gyb b/stdlib/public/core/Range.swift.gyb
index 1fc52fa..b717db6 100644
--- a/stdlib/public/core/Range.swift.gyb
+++ b/stdlib/public/core/Range.swift.gyb
@@ -140,10 +140,8 @@
 ///     print(brackets(-99..<100, 0))
 ///     // Prints "0"
 @_fixed_layout
-public struct CountableRange<Bound> : RandomAccessCollection
-  where
-  Bound : Strideable, Bound.Stride : SignedInteger {
-
+public struct CountableRange<Bound>
+where Bound : Strideable, Bound.Stride : SignedInteger {
   /// The range's lower bound.
   ///
   /// In an empty range, `lowerBound` is equal to `upperBound`.
@@ -158,13 +156,31 @@
   /// In an empty range, `upperBound` is equal to `lowerBound`.
   public let upperBound: Bound
 
+  /// Creates an instance with the given bounds.
+  ///
+  /// Because this initializer does not perform any checks, it should be used
+  /// as an optimization only when you are absolutely certain that `lower` is
+  /// less than or equal to `upper`. Using the half-open range operator
+  /// (`..<`) to form `CountableRange` instances is preferred.
+  ///
+  /// - Parameter bounds: A tuple of the lower and upper bounds of the range.
+  @_inlineable
+  public init(uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
+    self.lowerBound = bounds.lower
+    self.upperBound = bounds.upper
+  }
+}
+
+extension CountableRange: RandomAccessCollection {
+
   /// The bound type of the range.
   public typealias Element = Bound
 
   /// A type that represents a position in the range.
   public typealias Index = Element
-
   public typealias IndexDistance = Bound.Stride
+  public typealias Indices = CountableRange<Bound>
+  public typealias SubSequence = CountableRange<Bound>
 
   @_inlineable
   public var startIndex: Index {
@@ -204,14 +220,12 @@
     return start.distance(to: end)
   }
 
-  public typealias SubSequence = CountableRange<Bound>
-
   /// Accesses the subsequence bounded by the given range.
   ///
   /// - Parameter bounds: A range of the range's indices. The upper and lower
   ///   bounds of the `bounds` range must be valid indices of the collection.
   @_inlineable
-  public subscript(bounds: Range<Index>) -> CountableRange<Bound> {
+  public subscript(bounds: Range<Index>) -> SubSequence {
     return CountableRange(bounds)
   }
 
@@ -224,8 +238,6 @@
     return self[Range(bounds)]
   }
 
-  public typealias Indices = CountableRange<Bound>
-
   /// The indices that are valid for subscripting the range, in ascending
   /// order.
   @_inlineable
@@ -233,20 +245,6 @@
     return self
   }
 
-  /// Creates an instance with the given bounds.
-  ///
-  /// Because this initializer does not perform any checks, it should be used
-  /// as an optimization only when you are absolutely certain that `lower` is
-  /// less than or equal to `upper`. Using the half-open range operator
-  /// (`..<`) to form `CountableRange` instances is preferred.
-  ///
-  /// - Parameter bounds: A tuple of the lower and upper bounds of the range.
-  @_inlineable
-  public init(uncheckedBounds bounds: (lower: Bound, upper: Bound)) {
-    self.lowerBound = bounds.lower
-    self.upperBound = bounds.upper
-  }
-
   @_inlineable
   public func _customContainsEquatableElement(_ element: Element) -> Bool? {
     return lowerBound <= element && element < upperBound
@@ -315,7 +313,7 @@
 }
 
 extension CountableRange
-  where
+where
   Bound._DisabledRangeIndex : Strideable,
   Bound._DisabledRangeIndex.Stride : SignedInteger {
 
@@ -394,9 +392,18 @@
 ///     print(empty.contains(0.0))          // Prints "false"
 ///     print(empty.isEmpty)                // Prints "true"
 @_fixed_layout
-public struct Range<
-  Bound : Comparable
-> {
+public struct Range<Bound : Comparable> {
+  /// The range's lower bound.
+  ///
+  /// In an empty range, `lowerBound` is equal to `upperBound`.
+  public let lowerBound: Bound
+
+  /// The range's upper bound.
+  ///
+  /// In an empty range, `upperBound` is equal to `lowerBound`. A `Range`
+  /// instance does not contain its upper bound.
+  public let upperBound: Bound
+
   /// Creates an instance with the given bounds.
   ///
   /// Because this initializer does not perform any checks, it should be used
@@ -411,17 +418,6 @@
     self.upperBound = bounds.upper
   }
 
-  /// The range's lower bound.
-  ///
-  /// In an empty range, `lowerBound` is equal to `upperBound`.
-  public let lowerBound: Bound
-
-  /// The range's upper bound.
-  ///
-  /// In an empty range, `upperBound` is equal to `lowerBound`. A `Range`
-  /// instance does not contain its upper bound.
-  public let upperBound: Bound
-
   /// Returns a Boolean value indicating whether the given element is contained
   /// within the range.
   ///
@@ -760,13 +756,15 @@
 ///     print(numbers[..<3])
 ///     // Prints "[10, 20, 30]"
 @_fixed_layout
-public struct PartialRangeUpTo<Bound: Comparable>: RangeExpression {
-  @_inlineable // FIXME(sil-serialize-all)
-  public init(_ upperBound: Bound) { self.upperBound = upperBound }
-  
+public struct PartialRangeUpTo<Bound: Comparable> {
   public let upperBound: Bound
   
   @_inlineable // FIXME(sil-serialize-all)
+  public init(_ upperBound: Bound) { self.upperBound = upperBound }
+}
+
+extension PartialRangeUpTo: RangeExpression {
+  @_inlineable // FIXME(sil-serialize-all)
   @_transparent
   public func relative<C: Collection>(to collection: C) -> Range<Bound>
   where C.Index == Bound {
@@ -802,13 +800,15 @@
 ///     print(numbers[...3])
 ///     // Prints "[10, 20, 30, 40]"
 @_fixed_layout
-public struct PartialRangeThrough<Bound: Comparable>: RangeExpression {  
-  @_inlineable // FIXME(sil-serialize-all)
-  public init(_ upperBound: Bound) { self.upperBound = upperBound }
-  
+public struct PartialRangeThrough<Bound: Comparable> {  
   public let upperBound: Bound
   
   @_inlineable // FIXME(sil-serialize-all)
+  public init(_ upperBound: Bound) { self.upperBound = upperBound }
+}
+
+extension PartialRangeThrough: RangeExpression {
+  @_inlineable // FIXME(sil-serialize-all)
   @_transparent
   public func relative<C: Collection>(to collection: C) -> Range<Bound>
   where C.Index == Bound {
@@ -843,19 +843,21 @@
 ///     print(numbers[3...])
 ///     // Prints "[40, 50, 60, 70]"
 @_fixed_layout
-public struct PartialRangeFrom<Bound: Comparable>: RangeExpression {
+public struct PartialRangeFrom<Bound: Comparable> {
+  public let lowerBound: Bound
+
   @_inlineable // FIXME(sil-serialize-all)
   public init(_ lowerBound: Bound) { self.lowerBound = lowerBound }
-  
-  public let lowerBound: Bound
-  
+}
+
+extension PartialRangeFrom: RangeExpression {
   @_inlineable // FIXME(sil-serialize-all)
   @_transparent
   public func relative<C: Collection>(to collection: C) -> Range<Bound>
   where C.Index == Bound {
     return self.lowerBound..<collection.endIndex
   }
-  
+
   @_inlineable // FIXME(sil-serialize-all)
   @_transparent
   public func contains(_ element: Bound) -> Bool {
@@ -944,12 +946,15 @@
 /// `CountablePartialRangeFrom<Int>` traps when the sequence's next value
 /// would be above `Int.max`.
 @_fixed_layout
-public struct CountablePartialRangeFrom<
-  Bound: Strideable
->: RangeExpression where Bound.Stride : SignedInteger  {
+public struct CountablePartialRangeFrom<Bound: Strideable>
+where Bound.Stride : SignedInteger  {
+  public let lowerBound: Bound
+
   @_inlineable // FIXME(sil-serialize-all)
   public init(_ lowerBound: Bound) { self.lowerBound = lowerBound }
-  public let lowerBound: Bound
+}
+
+extension CountablePartialRangeFrom: RangeExpression {
   @_inlineable // FIXME(sil-serialize-all)
   @_transparent
   public func relative<C: Collection>(
@@ -966,6 +971,8 @@
 extension CountablePartialRangeFrom: Sequence {
   @_fixed_layout
   public struct Iterator: IteratorProtocol {
+    @_versioned
+    internal var _current: Bound
     @_inlineable
     public init(_current: Bound) { self._current = _current }
     @_inlineable
@@ -973,8 +980,6 @@
       defer { _current = _current.advanced(by: 1) }
       return _current
     }
-    @_versioned
-    internal var _current: Bound
   }
   @_inlineable
   public func makeIterator() -> Iterator { 
diff --git a/stdlib/public/core/Repeat.swift b/stdlib/public/core/Repeat.swift
index 7bfaf07..ec2ed8c 100644
--- a/stdlib/public/core/Repeat.swift
+++ b/stdlib/public/core/Repeat.swift
@@ -26,8 +26,15 @@
 ///     // "Humperdinck"
 ///     // "Humperdinck"
 @_fixed_layout
-public struct Repeated<Element> : RandomAccessCollection {
+public struct Repeated<Element> {
+  /// The number of elements in this collection.
+  public let count: Int
 
+  /// The value of every element in this collection.
+  public let repeatedValue: Element
+}
+
+extension Repeated: RandomAccessCollection {
   public typealias Indices = CountableRange<Int>
 
   /// A type that represents a valid position in the collection.
@@ -75,12 +82,6 @@
     _precondition(position >= 0 && position < count, "Index out of range")
     return repeatedValue
   }
-
-  /// The number of elements in this collection.
-  public let count: Int
-
-  /// The value of every element in this collection.
-  public let repeatedValue: Element
 }
 
 /// Creates a collection containing the specified number of the given element.
diff --git a/stdlib/public/core/Reverse.swift b/stdlib/public/core/Reverse.swift
index eb3897c..cb35cc3 100644
--- a/stdlib/public/core/Reverse.swift
+++ b/stdlib/public/core/Reverse.swift
@@ -164,7 +164,9 @@
 ///
 /// - See also: `ReversedRandomAccessCollection`
 @_fixed_layout
-public struct ReversedCollection<Base: BidirectionalCollection>: BidirectionalCollection {
+public struct ReversedCollection<Base: BidirectionalCollection> {
+  public let _base: Base
+
   /// Creates an instance that presents the elements of `base` in
   /// reverse order.
   ///
@@ -174,13 +176,14 @@
   internal init(_base: Base) {
     self._base = _base
   }
+}
 
+extension ReversedCollection: BidirectionalCollection {
   /// A type that represents a valid position in the collection.
   ///
   /// Valid indices consist of the position of every element and a
   /// "past the end" position that's not valid for use as a subscript.
   public typealias Index = ReversedIndex<Base>
-
   public typealias IndexDistance = Base.IndexDistance
 
   @_fixed_layout
@@ -262,8 +265,6 @@
   public subscript(bounds: Range<Index>) -> Slice<ReversedCollection> {
     return Slice(base: self, bounds: bounds)
   }
-
-  public let _base: Base
 }
 
 extension ReversedCollection: RandomAccessCollection where Base: RandomAccessCollection { }
@@ -334,7 +335,3 @@
     return ReversedCollection(_base: elements).lazy
   }
 }
-
-// ${'Local Variables'}:
-// eval: (read-only-mode 1)
-// End:
diff --git a/stdlib/public/core/Sequence.swift b/stdlib/public/core/Sequence.swift
index 834b4ab..deaf468 100644
--- a/stdlib/public/core/Sequence.swift
+++ b/stdlib/public/core/Sequence.swift
@@ -1433,15 +1433,18 @@
 ///
 ///     for x in IteratorSequence(i) { ... }
 @_fixed_layout
-public struct IteratorSequence<
-  Base : IteratorProtocol
-> : IteratorProtocol, Sequence {
+public struct IteratorSequence<Base : IteratorProtocol> {
+  @_versioned
+  internal var _base: Base
+
   /// Creates an instance whose iterator is a copy of `base`.
   @_inlineable
   public init(_ base: Base) {
     _base = base
   }
+}
 
+extension IteratorSequence: IteratorProtocol, Sequence {
   /// Advances to the next element and returns it, or `nil` if no next element
   /// exists.
   ///
@@ -1453,7 +1456,4 @@
   public mutating func next() -> Base.Element? {
     return _base.next()
   }
-
-  @_versioned
-  internal var _base: Base
 }
diff --git a/stdlib/public/core/Slice.swift b/stdlib/public/core/Slice.swift
index d9ec14c..a5400c4 100644
--- a/stdlib/public/core/Slice.swift
+++ b/stdlib/public/core/Slice.swift
@@ -81,6 +81,12 @@
 ///   requirements into account.
 @_fixed_layout // FIXME(sil-serialize-all)
 public struct Slice<Base: Collection> {
+  public var _startIndex: Base.Index
+  public var _endIndex: Base.Index
+
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _base: Base
+
   /// Creates a view into the given collection that allows access to elements
   /// within the specified range.
   ///
@@ -107,12 +113,6 @@
     self._endIndex = bounds.upperBound
   }
 
-  public var _startIndex: Base.Index
-  public var _endIndex: Base.Index
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _base: Base
-
   /// The underlying collection of the slice.
   ///
   /// You can use a slice's `base` property to access its base collection. The
diff --git a/stdlib/public/core/Stride.swift.gyb b/stdlib/public/core/Stride.swift.gyb
index 1466a30..0c42e4b 100644
--- a/stdlib/public/core/Stride.swift.gyb
+++ b/stdlib/public/core/Stride.swift.gyb
@@ -163,7 +163,7 @@
 
 /// An iterator for `StrideTo<Element>`.
 @_fixed_layout
-public struct StrideToIterator<Element : Strideable> : IteratorProtocol {
+public struct StrideToIterator<Element : Strideable> {
   @_versioned
   internal let _start: Element
 
@@ -184,12 +184,13 @@
     _stride = stride
     _current = (0, _start)
   }
+}
 
+extension StrideToIterator: IteratorProtocol {
   /// Advances to the next element and returns it, or `nil` if no next element
   /// exists.
   ///
   /// Once `nil` has been returned, all subsequent calls return `nil`.
-
   @_inlineable
   public mutating func next() -> Element? {
     let result = _current.value
@@ -202,10 +203,31 @@
 }
 
 /// A `Sequence` of values formed by striding over a half-open interval.
+// FIXME: should really be a Collection, as it is multipass
 @_fixed_layout
-public struct StrideTo<Element : Strideable> : Sequence, CustomReflectable {
-  // FIXME: should really be a Collection, as it is multipass
+public struct StrideTo<Element : Strideable> {
+  @_versioned
+  internal let _start: Element
 
+  @_versioned
+  internal let _end: Element
+
+  @_versioned
+  internal let _stride: Element.Stride
+
+  @_inlineable
+  @_versioned
+  internal init(_start: Element, end: Element, stride: Element.Stride) {
+    _precondition(stride != 0, "Stride size must not be zero")
+    // At start, striding away from end is allowed; it just makes for an
+    // already-empty Sequence.
+    self._start = _start
+    self._end = end
+    self._stride = stride
+  }
+}
+
+extension StrideTo: Sequence {
   /// Returns an iterator over the elements of this sequence.
   ///
   /// - Complexity: O(1).
@@ -214,6 +236,18 @@
     return StrideToIterator(_start: _start, end: _end, stride: _stride)
   }
 
+  // FIXME(conditional-conformances): this is O(N) instead of O(1), leaving it
+  // here until a proper Collection conformance is possible
+  @_inlineable
+  public var underestimatedCount: Int {
+    var it = self.makeIterator()
+    var count = 0
+    while it.next() != nil {
+      count += 1
+    }
+    return count
+  }
+
   @_inlineable
   public func _preprocessingPass<R>(
     _ preprocess: () throws -> R
@@ -230,43 +264,13 @@
     }
     return nil
   }
+}
 
-  @_inlineable
-  @_versioned
-  internal init(_start: Element, end: Element, stride: Element.Stride) {
-    _precondition(stride != 0, "Stride size must not be zero")
-    // At start, striding away from end is allowed; it just makes for an
-    // already-empty Sequence.
-    self._start = _start
-    self._end = end
-    self._stride = stride
-  }
-
-  @_versioned
-  internal let _start: Element
-
-  @_versioned
-  internal let _end: Element
-
-  @_versioned
-  internal let _stride: Element.Stride
-
+extension StrideTo: CustomReflectable {
   @_inlineable // FIXME(sil-serialize-all)
   public var customMirror: Mirror {
     return Mirror(self, children: ["from": _start, "to": _end, "by": _stride])
   }
-
-  // FIXME(conditional-conformances): this is O(N) instead of O(1), leaving it
-  // here until a proper Collection conformance is possible
-  @_inlineable
-  public var underestimatedCount: Int {
-    var it = self.makeIterator()
-    var count = 0
-    while it.next() != nil {
-      count += 1
-    }
-    return count
-  }
 }
 
 // FIXME(conditional-conformances): This does not yet compile (SR-6474).
@@ -326,7 +330,7 @@
 
 /// An iterator for `StrideThrough<Element>`.
 @_fixed_layout
-public struct StrideThroughIterator<Element : Strideable> : IteratorProtocol {
+public struct StrideThroughIterator<Element : Strideable> {
   @_versioned
   internal let _start: Element
 
@@ -350,7 +354,9 @@
     _stride = stride
     _current = (0, _start)
   }
+}
 
+extension StrideThroughIterator: IteratorProtocol {
   /// Advances to the next element and returns it, or `nil` if no next element
   /// exists.
   ///
@@ -374,12 +380,27 @@
 }
 
 /// A `Sequence` of values formed by striding over a closed interval.
+// FIXME: should really be a CollectionType, as it is multipass
 @_fixed_layout
-public struct StrideThrough<
-  Element : Strideable
-> : Sequence, CustomReflectable {
-  // FIXME: should really be a CollectionType, as it is multipass
+public struct StrideThrough<Element: Strideable> {
+  @_versioned
+  internal let _start: Element
+  @_versioned
+  internal let _end: Element
+  @_versioned
+  internal let _stride: Element.Stride
+  
+  @_inlineable
+  @_versioned
+  internal init(_start: Element, end: Element, stride: Element.Stride) {
+    _precondition(stride != 0, "Stride size must not be zero")
+    self._start = _start
+    self._end = end
+    self._stride = stride
+  }
+}
 
+extension StrideThrough: Sequence {
   /// Returns an iterator over the elements of this sequence.
   ///
   /// - Complexity: O(1).
@@ -388,6 +409,18 @@
     return StrideThroughIterator(_start: _start, end: _end, stride: _stride)
   }
 
+  // FIXME(conditional-conformances): this is O(N) instead of O(1), leaving it
+  // here until a proper Collection conformance is possible
+  @_inlineable
+  public var underestimatedCount: Int {
+    var it = self.makeIterator()
+    var count = 0
+    while it.next() != nil {
+      count += 1
+    }
+    return count
+  }
+
   @_inlineable
   public func _preprocessingPass<R>(
     _ preprocess: () throws -> R
@@ -404,40 +437,14 @@
     }
     return nil
   }
+}
 
-  @_inlineable
-  @_versioned
-  internal init(_start: Element, end: Element, stride: Element.Stride) {
-    _precondition(stride != 0, "Stride size must not be zero")
-    self._start = _start
-    self._end = end
-    self._stride = stride
-  }
-
-  @_versioned
-  internal let _start: Element
-  @_versioned
-  internal let _end: Element
-  @_versioned
-  internal let _stride: Element.Stride
-
+extension StrideThrough: CustomReflectable {
   @_inlineable // FIXME(sil-serialize-all)
   public var customMirror: Mirror {
     return Mirror(self,
       children: ["from": _start, "through": _end, "by": _stride])
   }
-
-  // FIXME(conditional-conformances): this is O(N) instead of O(1), leaving it
-  // here until a proper Collection conformance is possible
-  @_inlineable
-  public var underestimatedCount: Int {
-    var it = self.makeIterator()
-    var count = 0
-    while it.next() != nil {
-      count += 1
-    }
-    return count
-  }
 }
 
 // FIXME(conditional-conformances): This does not yet compile (SR-6474).
diff --git a/stdlib/public/core/StringComparable.swift b/stdlib/public/core/StringComparable.swift
index fb9f39f..35ca581 100644
--- a/stdlib/public/core/StringComparable.swift
+++ b/stdlib/public/core/StringComparable.swift
@@ -62,7 +62,7 @@
       compare = 0 
     }
     else {
-      compare = Int(truncatingIfNeeded: _swift_stdlib_memcmp(
+      compare = Int(truncatingIfNeeded: _stdlib_memcmp(
         self._core.startASCII, rhs._core.startASCII,
         Swift.min(self._core.count, rhs._core.count)))      
     }
@@ -145,7 +145,7 @@
       if lhs._core.startASCII == rhs._core.startASCII {
         return true
       }
-      return _swift_stdlib_memcmp(
+      return _stdlib_memcmp(
         lhs._core.startASCII, rhs._core.startASCII,
         rhs._core.count) == (0 as CInt)
     }
diff --git a/stdlib/public/core/StringLegacy.swift b/stdlib/public/core/StringLegacy.swift
index 90f53b9..9e3eee4 100644
--- a/stdlib/public/core/StringLegacy.swift
+++ b/stdlib/public/core/StringLegacy.swift
@@ -132,7 +132,7 @@
         // Prefix is longer than self.
         return false
       }
-      return _swift_stdlib_memcmp(
+      return _stdlib_memcmp(
         selfASCIIBuffer.baseAddress!,
         prefixASCIIBuffer.baseAddress!,
         prefixASCIIBuffer.count) == (0 as CInt)
@@ -191,7 +191,7 @@
         // Suffix is longer than self.
         return false
       }
-      return _swift_stdlib_memcmp(
+      return _stdlib_memcmp(
         selfASCIIBuffer.baseAddress!
           + (selfASCIIBuffer.count - suffixASCIIBuffer.count),
         suffixASCIIBuffer.baseAddress!,
diff --git a/stdlib/public/core/ThreadLocalStorage.swift b/stdlib/public/core/ThreadLocalStorage.swift
index 0f4818c..c9e0bce 100644
--- a/stdlib/public/core/ThreadLocalStorage.swift
+++ b/stdlib/public/core/ThreadLocalStorage.swift
@@ -71,7 +71,7 @@
   static internal func getPointer()
     -> UnsafeMutablePointer<_ThreadLocalStorage>
   {
-    let tlsRawPtr = _swift_stdlib_thread_getspecific(_tlsKey)
+    let tlsRawPtr = _stdlib_thread_getspecific(_tlsKey)
     if _fastPath(tlsRawPtr != nil) {
       return tlsRawPtr._unsafelyUnwrappedUnchecked.assumingMemoryBound(
         to: _ThreadLocalStorage.self)
@@ -114,7 +114,7 @@
 // owned.
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned // FIXME(sil-serialize-all)
-@_silgen_name("_swift_stdlib_destroyTLS")
+@_silgen_name("_stdlib_destroyTLS")
 internal func _destroyTLS(_ ptr: UnsafeMutableRawPointer?) {
   _sanityCheck(ptr != nil,
     "_destroyTLS was called, but with nil...")
@@ -134,7 +134,7 @@
 internal let _tlsKey: __swift_thread_key_t = {
   let sentinelValue = __swift_thread_key_t.max
   var key: __swift_thread_key_t = sentinelValue
-  let success = _swift_stdlib_thread_key_create(&key, _destroyTLS)
+  let success = _stdlib_thread_key_create(&key, _destroyTLS)
   _sanityCheck(success == 0, "somehow failed to create TLS key")
   _sanityCheck(key != sentinelValue, "Didn't make a new key")
   return key
@@ -146,7 +146,7 @@
 internal func _initializeThreadLocalStorage()
   -> UnsafeMutablePointer<_ThreadLocalStorage>
 {
-  _sanityCheck(_swift_stdlib_thread_getspecific(_tlsKey) == nil,
+  _sanityCheck(_stdlib_thread_getspecific(_tlsKey) == nil,
     "already initialized")
 
   // Create and initialize one.
@@ -163,7 +163,7 @@
   tlsPtr.initialize(
     to: _ThreadLocalStorage(_uBreakIterator: newUBreakIterator)
   )
-  let success = _swift_stdlib_thread_setspecific(_tlsKey, tlsPtr)
+  let success = _stdlib_thread_setspecific(_tlsKey, tlsPtr)
   _sanityCheck(success == 0, "setspecific failed")
   return tlsPtr
 }
diff --git a/stdlib/public/core/Unicode.swift b/stdlib/public/core/Unicode.swift
index d332723..f51a3fd 100644
--- a/stdlib/public/core/Unicode.swift
+++ b/stdlib/public/core/Unicode.swift
@@ -303,14 +303,14 @@
   public static func _nullCodeUnitOffset(
     in input: UnsafePointer<CodeUnit>
   ) -> Int {
-    return Int(_swift_stdlib_strlen_unsigned(input))
+    return Int(_stdlib_strlen_unsigned(input))
   }
   // Support parsing C strings as-if they are UTF8 strings.
   @_inlineable // FIXME(sil-serialize-all)
   public static func _nullCodeUnitOffset(
     in input: UnsafePointer<CChar>
   ) -> Int {
-    return Int(_swift_stdlib_strlen(input))
+    return Int(_stdlib_strlen(input))
   }
 }
 
diff --git a/stdlib/public/core/UnsafePointer.swift.gyb b/stdlib/public/core/UnsafePointer.swift.gyb
index bb7aeb9..f437211 100644
--- a/stdlib/public/core/UnsafePointer.swift.gyb
+++ b/stdlib/public/core/UnsafePointer.swift.gyb
@@ -272,8 +272,7 @@
 ///       let numberPointer = Unsafe${Mutable}Pointer<Int>(&number)
 ///       // Accessing 'numberPointer' is undefined behavior.
 @_fixed_layout
-public struct ${Self}<Pointee>
-  : Strideable, Hashable, _Pointer {
+public struct ${Self}<Pointee>: _Pointer {
 
   /// A type that represents the distance between two pointers.
   public typealias Distance = Int
@@ -851,11 +850,45 @@
     }
 %  end
   }
+}
 
-  //
-  // Protocol conformance
-  //
+extension ${Self}: Equatable {
+  // - Note: Strideable's implementation is potentially less efficient and cannot
+  //   handle misaligned pointers.
+  /// Returns a Boolean value indicating whether two pointers are equal.
+  ///
+  /// - Parameters:
+  ///   - lhs: A pointer.
+  ///   - rhs: Another pointer.
+  /// - Returns: `true` if `lhs` and `rhs` reference the same memory address;
+  ///   otherwise, `false`.
+  @_inlineable // FIXME(sil-serialize-all)
+  @_transparent
+  public static func == (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
+    return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
+  }
+}
 
+extension ${Self}: Comparable {
+  // - Note: Strideable's implementation is potentially less efficient and
+  // cannot handle misaligned pointers.
+  //
+  // - Note: This is an unsigned comparison unlike Strideable's implementation.
+  /// Returns a Boolean value indicating whether the first pointer references
+  /// an earlier memory location than the second pointer.
+  ///
+  /// - Parameters:
+  ///   - lhs: A pointer.
+  ///   - rhs: Another pointer.
+  /// - Returns: `true` if `lhs` references a memory address earlier than
+  ///   `rhs`; otherwise, `false`.
+  @_inlineable // FIXME(sil-serialize-all)
+  @_transparent
+  public static func < (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
+    return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue))
+  }
+}
+extension ${Self}: Hashable {
   /// The pointer's hash value.
   ///
   /// The hash value is not guaranteed to be stable across different
@@ -865,7 +898,9 @@
   public var hashValue: Int {
     return Int(bitPattern: self)
   }
-
+}
+  
+extension ${Self}: Strideable {
   /// Returns a pointer to the next consecutive instance.
   ///
   /// The resulting pointer must be within the bounds of the same allocation as
@@ -964,44 +999,10 @@
   }
 }
 
+// - Note: The following family of operator overloads are redundant
+//   with Strideable. However, optimizer improvements are needed
+//   before they can be removed without affecting performance.
 extension ${Self} {
-  // - Note: Strideable's implementation is potentially less efficient and cannot
-  //   handle misaligned pointers.
-  /// Returns a Boolean value indicating whether two pointers are equal.
-  ///
-  /// - Parameters:
-  ///   - lhs: A pointer.
-  ///   - rhs: Another pointer.
-  /// - Returns: `true` if `lhs` and `rhs` reference the same memory address;
-  ///   otherwise, `false`.
-  @_inlineable // FIXME(sil-serialize-all)
-  @_transparent
-  public static func == (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
-    return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
-  }
-
-  // - Note: Strideable's implementation is potentially less efficient and
-  // cannot handle misaligned pointers.
-  //
-  // - Note: This is an unsigned comparison unlike Strideable's implementation.
-  /// Returns a Boolean value indicating whether the first pointer references
-  /// an earlier memory location than the second pointer.
-  ///
-  /// - Parameters:
-  ///   - lhs: A pointer.
-  ///   - rhs: Another pointer.
-  /// - Returns: `true` if `lhs` references a memory address earlier than
-  ///   `rhs`; otherwise, `false`.
-  @_inlineable // FIXME(sil-serialize-all)
-  @_transparent
-  public static func < (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
-    return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue))
-  }
-
-  // - Note: The following family of operator overloads are redundant
-  //   with Strideable. However, optimizer improvements are needed
-  //   before they can be removed without affecting performance.
-
   /// Creates a new pointer, offset from a pointer by a specified number of
   /// instances of the pointer's `Pointee` type.
   ///
diff --git a/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb b/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
index 7039720..674e108 100644
--- a/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
@@ -93,19 +93,17 @@
 ///     destBytes[0..<n] = someBytes[n..<(n + n)]
 % end
 @_fixed_layout
-public struct Unsafe${Mutable}RawBufferPointer
-  : ${Mutable}Collection, RandomAccessCollection {
-  // TODO: Specialize `index` and `formIndex` and
-  // `_failEarlyRangeCheck` as in `UnsafeBufferPointer`.
+public struct Unsafe${Mutable}RawBufferPointer {
+  @_versioned
+  internal let _position, _end: Unsafe${Mutable}RawPointer?
+}
 
-  public typealias Index = Int
-  public typealias IndexDistance = Int
-  public typealias SubSequence = ${Mutable}Slice<${Self}>
+extension Unsafe${Mutable}RawBufferPointer: Sequence {
+  public typealias SubSequence = Slice<${Self}>
 
   /// An iterator over the bytes viewed by a raw buffer pointer.
   @_fixed_layout
   public struct Iterator : IteratorProtocol, Sequence {
-
     /// Advances to the next byte and returns it, or `nil` if no next byte
     /// exists.
     ///
@@ -133,6 +131,105 @@
     }
   }
 
+  /// Returns an iterator over the bytes of this sequence.
+  @_inlineable
+  public func makeIterator() -> Iterator {
+    return Iterator(_position: _position, _end: _end)
+  }
+}
+
+extension Unsafe${Mutable}RawBufferPointer: ${Mutable}Collection {
+  // TODO: Specialize `index` and `formIndex` and
+  // `_failEarlyRangeCheck` as in `UnsafeBufferPointer`.
+  public typealias Element = UInt8
+  public typealias Index = Int
+  public typealias IndexDistance = Int
+  public typealias Indices = CountableRange<Int>
+
+  /// Always zero, which is the index of the first byte in a nonempty buffer.
+  @_inlineable
+  public var startIndex: Index {
+    return 0
+  }
+
+  /// The "past the end" position---that is, the position one greater than the
+  /// last valid subscript argument.
+  ///
+  /// The `endIndex` property of an `Unsafe${Mutable}RawBufferPointer`
+  /// instance is always identical to `count`.
+  @_inlineable
+  public var endIndex: Index {
+    return count
+  }
+
+  @_inlineable
+  public var indices: Indices {
+    return startIndex..<endIndex
+  }
+
+  /// Accesses the byte at the given offset in the memory region as a `UInt8`
+  /// value.
+  ///
+  /// - Parameter i: The offset of the byte to access. `i` must be in the range
+  ///   `0..<count`.
+  @_inlineable
+  public subscript(i: Int) -> Element {
+    get {
+      _debugPrecondition(i >= 0)
+      _debugPrecondition(i < endIndex)
+      return _position!.load(fromByteOffset: i, as: UInt8.self)
+    }
+%  if mutable:
+    nonmutating set {
+      _debugPrecondition(i >= 0)
+      _debugPrecondition(i < endIndex)
+      _position!.storeBytes(of: newValue, toByteOffset: i, as: UInt8.self)
+    }
+%  end # mutable
+  }
+
+  /// Accesses the bytes in the specified memory region.
+  ///
+  /// - Parameter bounds: The range of byte offsets to access. The upper and
+  ///   lower bounds of the range must be in the range `0...count`.
+  @_inlineable
+  public subscript(bounds: Range<Int>) -> SubSequence {
+    get {
+      _debugPrecondition(bounds.lowerBound >= startIndex)
+      _debugPrecondition(bounds.upperBound <= endIndex)
+      return Slice(base: self, bounds: bounds)
+    }
+%  if mutable:
+    nonmutating set {
+      _debugPrecondition(bounds.lowerBound >= startIndex)
+      _debugPrecondition(bounds.upperBound <= endIndex)
+      _debugPrecondition(bounds.count == newValue.count)
+
+      if !newValue.isEmpty {
+        (baseAddress! + bounds.lowerBound).copyMemory(
+          from: newValue.base.baseAddress! + newValue.startIndex,
+          byteCount: newValue.count)
+      }
+    }
+%  end # mutable
+  }
+
+  /// The number of bytes in the buffer.
+  ///
+  /// If the `baseAddress` of this buffer is `nil`, the count is zero. However,
+  /// a buffer can have a `count` of zero even with a non-`nil` base address.
+  @_inlineable
+  public var count: Int {
+    if let pos = _position {
+      return _end! - pos
+    }
+    return 0
+  }
+}
+
+extension Unsafe${Mutable}RawBufferPointer: RandomAccessCollection { }
+
+extension Unsafe${Mutable}RawBufferPointer {
 %  if mutable:
   @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "allocate(byteCount:alignment:)")
   public static func allocate(count: Int) -> UnsafeMutableRawBufferPointer { 
@@ -413,91 +510,11 @@
   ///
   /// - Parameter slice: The raw buffer slice to rebase.
   @_inlineable
-  public init(
-    rebasing slice: Slice<UnsafeMutableRawBufferPointer>
-  ) {
+  public init(rebasing slice: Slice<UnsafeMutableRawBufferPointer>) {
     self.init(start: slice.base.baseAddress! + slice.startIndex,
       count: slice.count)
   }
 
-  /// Always zero, which is the index of the first byte in a nonempty buffer.
-  @_inlineable
-  public var startIndex: Int {
-    return 0
-  }
-
-  /// The "past the end" position---that is, the position one greater than the
-  /// last valid subscript argument.
-  ///
-  /// The `endIndex` property of an `Unsafe${Mutable}RawBufferPointer`
-  /// instance is always identical to `count`.
-  @_inlineable
-  public var endIndex: Int {
-    return count
-  }
-
-  public typealias Indices = CountableRange<Int>
-
-  @_inlineable
-  public var indices: Indices {
-    return startIndex..<endIndex
-  }
-
-  /// Accesses the byte at the given offset in the memory region as a `UInt8`
-  /// value.
-  ///
-  /// - Parameter i: The offset of the byte to access. `i` must be in the range
-  ///   `0..<count`.
-  @_inlineable
-  public subscript(i: Int) -> UInt8 {
-    get {
-      _debugPrecondition(i >= 0)
-      _debugPrecondition(i < endIndex)
-      return _position!.load(fromByteOffset: i, as: UInt8.self)
-    }
-%  if mutable:
-    nonmutating set {
-      _debugPrecondition(i >= 0)
-      _debugPrecondition(i < endIndex)
-      _position!.storeBytes(of: newValue, toByteOffset: i, as: UInt8.self)
-    }
-%  end # mutable
-  }
-
-  /// Accesses the bytes in the specified memory region.
-  ///
-  /// - Parameter bounds: The range of byte offsets to access. The upper and
-  ///   lower bounds of the range must be in the range `0...count`.
-  @_inlineable
-  public subscript(
-    bounds: Range<Int>
-  ) -> Slice<Unsafe${Mutable}RawBufferPointer> {
-    get {
-      _debugPrecondition(bounds.lowerBound >= startIndex)
-      _debugPrecondition(bounds.upperBound <= endIndex)
-      return Slice(base: self, bounds: bounds)
-    }
-%  if mutable:
-    nonmutating set {
-      _debugPrecondition(bounds.lowerBound >= startIndex)
-      _debugPrecondition(bounds.upperBound <= endIndex)
-      _debugPrecondition(bounds.count == newValue.count)
-
-      if !newValue.isEmpty {
-        (baseAddress! + bounds.lowerBound).copyMemory(
-          from: newValue.base.baseAddress! + newValue.startIndex,
-          byteCount: newValue.count)
-      }
-    }
-%  end # mutable
-  }
-
-  /// Returns an iterator over the bytes of this sequence.
-  @_inlineable
-  public func makeIterator() -> Iterator {
-    return Iterator(_position: _position, _end: _end)
-  }
-
   /// A pointer to the first byte of the buffer.
   ///
   /// If the `baseAddress` of this buffer is `nil`, the count is zero. However,
@@ -507,18 +524,6 @@
     return _position
   }
 
-  /// The number of bytes in the buffer.
-  ///
-  /// If the `baseAddress` of this buffer is `nil`, the count is zero. However,
-  /// a buffer can have a `count` of zero even with a non-`nil` base address.
-  @_inlineable
-  public var count: Int {
-    if let pos = _position {
-      return _end! - pos
-    }
-    return 0
-  }
-
   %  if mutable:
   
   /// Initializes the memory referenced by this buffer with the given value,
@@ -649,9 +654,6 @@
     return Unsafe${Mutable}BufferPointer<T>(
       start: Unsafe${Mutable}Pointer<T>(base._rawValue), count: capacity)
   }
-  
-  @_versioned
-  internal let _position, _end: Unsafe${Mutable}RawPointer?
 }
 
 extension Unsafe${Mutable}RawBufferPointer : CustomDebugStringConvertible {
diff --git a/stdlib/public/core/UnsafeRawPointer.swift.gyb b/stdlib/public/core/UnsafeRawPointer.swift.gyb
index d8d3ed0..4a3e4aa 100644
--- a/stdlib/public/core/UnsafeRawPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeRawPointer.swift.gyb
@@ -219,7 +219,7 @@
 ///       let numberPointer = ${Self}(&number)
 ///       // Accessing 'numberPointer' is undefined behavior.
 @_fixed_layout
-public struct Unsafe${Mutable}RawPointer : Strideable, Hashable, _Pointer {
+public struct Unsafe${Mutable}RawPointer: _Pointer {
   /// The underlying raw pointer.
   /// Implements conformance to the public protocol `_Pointer`.
   public let _rawValue: Builtin.RawPointer
@@ -895,21 +895,9 @@
     _memmove(dest: self, src: source, size: UInt(byteCount))
   }
 %  end # mutable
+}
 
-  //
-  // Protocol conformance
-  //
-
-  /// The pointer's hash value.
-  ///
-  /// The hash value is not guaranteed to be stable across different
-  /// invocations of the same program.  Do not persist the hash value across
-  /// program runs.
-  @_inlineable
-  public var hashValue: Int {
-    return Int(bitPattern: self)
-  }
-
+extension ${Self}: Strideable {
   /// Returns the distance from this pointer to the given pointer.
   ///
   /// With pointers `p` and `q`, the result of `p.distance(to: q)` is
@@ -941,7 +929,7 @@
   }
 }
 
-extension ${Self} {
+extension ${Self}: Equatable {
   // - Note: This may be more efficient than Strideable's implementation
   //   calling ${Self}.distance().
   /// Returns a Boolean value indicating whether two pointers are equal.
@@ -956,7 +944,9 @@
   public static func == (lhs: ${Self}, rhs: ${Self}) -> Bool {
     return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
   }
+}
 
+extension ${Self}: Comparable {
   // - Note: This is an unsigned comparison unlike Strideable's
   //   implementation.
   /// Returns a Boolean value indicating whether the first pointer references
@@ -974,6 +964,18 @@
   }
 }
 
+extension ${Self}: Hashable {
+  /// The pointer's hash value.
+  ///
+  /// The hash value is not guaranteed to be stable across different
+  /// invocations of the same program.  Do not persist the hash value across
+  /// program runs.
+  @_inlineable
+  public var hashValue: Int {
+    return Int(bitPattern: self)
+  }
+}
+
 extension Unsafe${Mutable}RawPointer : CustomDebugStringConvertible {
   /// A textual representation of the pointer, suitable for debugging.
   @_inlineable // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/ValidUTF8Buffer.swift b/stdlib/public/core/ValidUTF8Buffer.swift
index 9a9cb35..b516382 100644
--- a/stdlib/public/core/ValidUTF8Buffer.swift
+++ b/stdlib/public/core/ValidUTF8Buffer.swift
@@ -17,9 +17,7 @@
 //
 //===----------------------------------------------------------------------===//
 @_fixed_layout
-public struct _ValidUTF8Buffer<
-  Storage: UnsignedInteger & FixedWidthInteger
-> {
+public struct _ValidUTF8Buffer<Storage: UnsignedInteger & FixedWidthInteger> {
   public typealias Element = Unicode.UTF8.CodeUnit
   internal typealias _Storage = Storage
   
diff --git a/stdlib/public/core/Zip.swift b/stdlib/public/core/Zip.swift
index 4e23ed3..48fe444 100644
--- a/stdlib/public/core/Zip.swift
+++ b/stdlib/public/core/Zip.swift
@@ -50,19 +50,26 @@
 
 /// An iterator for `Zip2Sequence`.
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct Zip2Iterator<
-  Iterator1 : IteratorProtocol, Iterator2 : IteratorProtocol
-> : IteratorProtocol {
+public struct Zip2Iterator<Iterator1: IteratorProtocol, Iterator2: IteratorProtocol> {
   /// The type of element returned by `next()`.
   public typealias Element = (Iterator1.Element, Iterator2.Element)
 
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _baseStream1: Iterator1
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _baseStream2: Iterator2
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _reachedEnd: Bool = false
+
   /// Creates an instance around a pair of underlying iterators.
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
   internal init(_ iterator1: Iterator1, _ iterator2: Iterator2) {
     (_baseStream1, _baseStream2) = (iterator1, iterator2)
   }
+}
 
+extension Zip2Iterator: IteratorProtocol {
   /// Advances to the next element and returns it, or `nil` if no next element
   /// exists.
   ///
@@ -87,13 +94,6 @@
 
     return (element1, element2)
   }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _baseStream1: Iterator1
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _baseStream2: Iterator2
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _reachedEnd: Bool = false
 }
 
 /// A sequence of pairs built out of two underlying sequences.
@@ -116,19 +116,17 @@
 ///     // Prints "three: 3"
 ///     // Prints "four: 4"
 @_fixed_layout // FIXME(sil-serialize-all)
-public struct Zip2Sequence<Sequence1 : Sequence, Sequence2 : Sequence>
-  : Sequence {
+public struct Zip2Sequence<Sequence1 : Sequence, Sequence2 : Sequence> {
+  @_versioned // FIXME(sil-serialize-all)
+  internal let _sequence1: Sequence1
+  @_versioned // FIXME(sil-serialize-all)
+  internal let _sequence2: Sequence2
 
-    
   @available(*, deprecated, renamed: "Sequence1.Iterator")
   public typealias Stream1 = Sequence1.Iterator
   @available(*, deprecated, renamed: "Sequence2.Iterator")
   public typealias Stream2 = Sequence2.Iterator
 
-  /// A type whose instances can produce the elements of this
-  /// sequence, in order.
-  public typealias Iterator = Zip2Iterator<Sequence1.Iterator, Sequence2.Iterator>
-
   /// Creates an instance that makes pairs of elements from `sequence1` and
   /// `sequence2`.
   @_inlineable // FIXME(sil-serialize-all)
@@ -136,6 +134,12 @@
   init(_sequence1 sequence1: Sequence1, _sequence2 sequence2: Sequence2) {
     (_sequence1, _sequence2) = (sequence1, sequence2)
   }
+}
+
+extension Zip2Sequence: Sequence {
+  /// A type whose instances can produce the elements of this
+  /// sequence, in order.
+  public typealias Iterator = Zip2Iterator<Sequence1.Iterator, Sequence2.Iterator>
 
   /// Returns an iterator over the elements of this sequence.
   @_inlineable // FIXME(sil-serialize-all)
@@ -144,9 +148,4 @@
       _sequence1.makeIterator(),
       _sequence2.makeIterator())
   }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal let _sequence1: Sequence1
-  @_versioned // FIXME(sil-serialize-all)
-  internal let _sequence2: Sequence2
 }
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index 543936d..9622bd6 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -113,7 +113,6 @@
   return result;
 }
 
-SWIFT_CC(swift)
 TwoWordPair<const char *, uintptr_t>::Return
 swift::swift_getTypeName(const Metadata *type, bool qualified) {
   using Pair = TwoWordPair<const char *, uintptr_t>;
@@ -2972,9 +2971,13 @@
   return (id)bridgeAnythingToSwiftValueObject(src, srcType, consume);
 }
 
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-id _swift_bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src,
-                                                const Metadata *srcType) {
+/// public func _bridgeAnythingNonVerbatimToObjectiveC<T>(_ x: T) -> AnyObject
+/// Called by inlined stdlib code.
+#define _bridgeAnythingNonVerbatimToObjectiveC \
+  MANGLE_SYM(s38_bridgeAnythingNonVerbatimToObjectiveCyXlxlF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
+id _bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src,
+                                          const Metadata *srcType) {
   return bridgeAnythingNonVerbatimToObjectiveC(src, srcType, /*consume*/ true);
 }
 
@@ -3031,8 +3034,12 @@
   return nullptr;
 }
 
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-const Metadata *_swift_getBridgedNonVerbatimObjectiveCType(
+// public func _getBridgedNonVerbatimObjectiveCType<T>(_: T.Type) -> Any.Type?
+// Called by inlined stdlib code.
+#define _getBridgedNonVerbatimObjectiveCType \
+  MANGLE_SYM(s36_getBridgedNonVerbatimObjectiveCTypeypXpSgxmlF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
+const Metadata *_getBridgedNonVerbatimObjectiveCType(
   const Metadata *value, const Metadata *T
 ) {
   // Classes and Objective-C existentials bridge verbatim.
@@ -3047,26 +3054,26 @@
   return nullptr;
 }
 
-// @_silgen_name("_swift_bridgeNonVerbatimFromObjectiveCToAny")
+// @_silgen_name("_bridgeNonVerbatimFromObjectiveCToAny")
 // func _bridgeNonVerbatimFromObjectiveCToAny(
 //     x: AnyObject,
 //     inout result: Any?
 // )
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 void
-_swift_bridgeNonVerbatimFromObjectiveCToAny(HeapObject *sourceValue,
-                                            OpaqueValue *destValue);
+_bridgeNonVerbatimFromObjectiveCToAny(HeapObject *sourceValue,
+                                      OpaqueValue *destValue);
 
-// @_silgen_name("_swift_bridgeNonVerbatimBoxedValue")
+// @_silgen_name("_bridgeNonVerbatimBoxedValue")
 // func _bridgeNonVerbatimBoxedValue<NativeType>(
 //     x: UnsafePointer<NativeType>,
 //     inout result: NativeType?
 // )
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 void
-_swift_bridgeNonVerbatimBoxedValue(const OpaqueValue *sourceValue,
-                                   OpaqueValue *destValue,
-                                   const Metadata *nativeType);
+_bridgeNonVerbatimBoxedValue(const OpaqueValue *sourceValue,
+                             OpaqueValue *destValue,
+                             const Metadata *nativeType);
 
 // Try bridging by conversion to Any or boxing if applicable.
 static bool tryBridgeNonVerbatimFromObjectiveCUniversal(
@@ -3079,8 +3086,7 @@
   if (auto nativeExistential = dyn_cast<ExistentialTypeMetadata>(nativeType)) {
     if (nativeExistential->Protocols.NumProtocols == 0 &&
         !nativeExistential->isClassBounded()) {
-      _swift_bridgeNonVerbatimFromObjectiveCToAny(sourceValue,
-                                                  destValue);
+      _bridgeNonVerbatimFromObjectiveCToAny(sourceValue, destValue);
       return true;
     }
   }
@@ -3092,9 +3098,7 @@
     
     std::tie(sourceType, sourceBoxedValue) = getValueFromSwiftValue(srcBox);
     if (sourceType == nativeType) {
-      _swift_bridgeNonVerbatimBoxedValue(sourceBoxedValue,
-                                         destValue,
-                                         nativeType);
+      _bridgeNonVerbatimBoxedValue(sourceBoxedValue, destValue, nativeType);
       return true;
     }
   }
@@ -3102,15 +3106,17 @@
   return false;
 }
 
-// @_silgen_name("_swift_bridgeNonVerbatimFromObjectiveC")
 // func _bridgeNonVerbatimFromObjectiveC<NativeType>(
 //     x: AnyObject, 
 //     nativeType: NativeType.Type
 //     inout result: T?
 // )
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+// Called by inlined stdlib code.
+#define _bridgeNonVerbatimFromObjectiveC \
+  MANGLE_SYM(s32_bridgeNonVerbatimFromObjectiveCyyXl_xmxSgztlF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
 void
-_swift_bridgeNonVerbatimFromObjectiveC(
+_bridgeNonVerbatimFromObjectiveC(
   HeapObject *sourceValue,
   const Metadata *nativeType,
   OpaqueValue *destValue,
@@ -3145,15 +3151,14 @@
   swift::crash("value type is not bridged to Objective-C");
 }
 
-// @_silgen_name("_swift_bridgeNonVerbatimFromObjectiveCConditional")
-// func _bridgeNonVerbatimFromObjectiveCConditional<NativeType>(
-//   x: AnyObject, 
-//   nativeType: T.Type,
-//   inout result: T?
-// ) -> Bool
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+/// func _bridgeNonVerbatimFromObjectiveCConditional<NativeType>(
+///   x: AnyObject, nativeType: T.Type, inout result: T?) -> Bool
+/// Called by inlined stdlib code.
+#define _bridgeNonVerbatimFromObjectiveCConditional \
+  MANGLE_SYM(s43_bridgeNonVerbatimFromObjectiveCConditionalSbyXl_xmxSgztlF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
 bool
-_swift_bridgeNonVerbatimFromObjectiveCConditional(
+_bridgeNonVerbatimFromObjectiveCConditional(
   HeapObject *sourceValue,
   const Metadata *nativeType,
   OpaqueValue *destValue,
@@ -3195,10 +3200,12 @@
 }
 
 // func _isBridgedNonVerbatimToObjectiveC<T>(x: T.Type) -> Bool
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-bool _swift_isBridgedNonVerbatimToObjectiveC(
-  const Metadata *value, const Metadata *T
-) {
+// Called by inlined stdlib code.
+#define _isBridgedNonVerbatimToObjectiveC \
+  MANGLE_SYM(s33_isBridgedNonVerbatimToObjectiveCSbxmlF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
+bool _isBridgedNonVerbatimToObjectiveC(const Metadata *value,
+                                       const Metadata *T) {
   assert(!swift_isClassOrObjCExistentialTypeImpl(T));
 
   auto bridgeWitness = findBridgeWitness(T);
@@ -3213,7 +3220,7 @@
   return swift_isClassOrObjCExistentialTypeImpl(T);
 }
 
-SWIFT_CC(swift)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 const Metadata *swift::_swift_class_getSuperclass(const Metadata *theClass) {
   if (const ClassMetadata *classType = theClass->getClassObject())
     if (classHasSuperclass(classType))
@@ -3221,12 +3228,14 @@
   return nullptr;
 }
 
-SWIFT_CC(c) SWIFT_RUNTIME_EXPORT
+// Called by compiler-generated cast code.
+SWIFT_CC(c) SWIFT_RUNTIME_STDLIB_API
 bool swift_isClassType(const Metadata *type) {
   return Metadata::isAnyKindOfClass(type->getKind());
 }
 
-SWIFT_CC(c) SWIFT_RUNTIME_EXPORT
+// Called by compiler-generated code.
+SWIFT_CC(c) SWIFT_RUNTIME_STDLIB_API
 bool swift_isOptionalType(const Metadata *type) {
   return type->getKind() == MetadataKind::Optional;
 }
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index f092b76..06ec92d 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -258,10 +258,14 @@
 
 /// \param typeName The name of a class in the form: <module>.<class>
 /// \return Returns the metadata of the type, if found.
-SWIFT_CC(swift)
-SWIFT_RUNTIME_EXPORT
+
+/// internal func _getTypeByName(_ name: UnsafePointer<UInt8>,
+///                              _ nameLength: UInt)  -> Any.Type?
+#define _getTypeByName \
+  MANGLE_SYM(s14_getTypeByNameypXpSgSPys5UInt8VG_SutF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 const Metadata *
-swift_getTypeByName(const char *typeName, size_t typeNameLength) {
+_getTypeByName(const char *typeName, size_t typeNameLength) {
   llvm::StringRef name(typeName, typeNameLength);
   return _classByName(name);
 }
diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp
index a028917..dfd4710 100644
--- a/stdlib/public/runtime/ProtocolConformance.cpp
+++ b/stdlib/public/runtime/ProtocolConformance.cpp
@@ -84,6 +84,10 @@
       printf("witness table accessor %s\n",
              symbolName((const void *)(uintptr_t)getWitnessTableAccessor()));
       break;
+    case ProtocolConformanceReferenceKind::ConditionalWitnessTableAccessor:
+      printf("conditional witness table accessor %s\n",
+             symbolName((const void *)(uintptr_t)getWitnessTableAccessor()));
+      break;
   }
 }
 #endif
@@ -136,8 +140,12 @@
     return getStaticWitnessTable();
 
   case ProtocolConformanceReferenceKind::WitnessTableAccessor:
-    // FIXME: this needs information about conditional conformances.
     return getWitnessTableAccessor()(type, nullptr, 0);
+
+  case ProtocolConformanceReferenceKind::ConditionalWitnessTableAccessor:
+    // FIXME: this needs to query the conditional requirements to form the
+    // array of witness tables to pass along to the accessor.
+    return nullptr;
   }
 
   swift_runtime_unreachable(
@@ -558,6 +566,7 @@
           break;
 
         case ProtocolConformanceReferenceKind::WitnessTableAccessor:
+        case ProtocolConformanceReferenceKind::ConditionalWitnessTableAccessor:
           // If the record provides a dependent witness table accessor,
           // cache the result for the instantiated type metadata.
           C.cacheSuccess(type, P, record.getWitnessTable(type));
diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm
index fa8ac6a..b86a85d 100644
--- a/stdlib/public/runtime/SwiftObject.mm
+++ b/stdlib/public/runtime/SwiftObject.mm
@@ -453,10 +453,9 @@
 /// reference-counting.  The metadata is known to correspond to a class
 /// type, but note that does not imply being known to be a ClassMetadata
 /// due to the existence of ObjCClassWrapper.
-SWIFT_CC(swift)
-SWIFT_RUNTIME_EXPORT
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 bool
-swift_objc_class_usesNativeSwiftReferenceCounting(const Metadata *theClass) {
+_objcClassUsesNativeSwiftReferenceCounting(const Metadata *theClass) {
 #if SWIFT_OBJC_INTEROP
   // If this is ObjC wrapper metadata, the class is definitely not using
   // Swift ref-counting.
@@ -1426,9 +1425,9 @@
 
 using ClassExtents = TwoWordPair<size_t, size_t>;
 
-SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 ClassExtents::Return
-swift_class_getInstanceExtents(const Metadata *c) {
+_getSwiftClassInstanceExtents(const Metadata *c) {
   assert(c && c->isClassObject());
   auto metaData = c->getClassObject();
   return ClassExtents{
@@ -1439,15 +1438,14 @@
 
 #if SWIFT_OBJC_INTEROP
 
-SWIFT_CC(swift)
-SWIFT_RUNTIME_EXPORT
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 ClassExtents::Return
-swift_objc_class_unknownGetInstanceExtents(const ClassMetadata* c) {
+_getObjCClassInstanceExtents(const ClassMetadata* c) {
   // Pure ObjC classes never have negative extents.
   if (c->isPureObjC())
     return ClassExtents{0, class_getInstanceSize(class_const_cast(c))};
 
-  return swift_class_getInstanceExtents(c);
+  return _getSwiftClassInstanceExtents(c);
 }
 
 SWIFT_CC(swift)
diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp
index 86cc09a..6a15c8e 100644
--- a/stdlib/public/stubs/LibcShims.cpp
+++ b/stdlib/public/stubs/LibcShims.cpp
@@ -10,6 +10,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(__APPLE__)
+#define _REENTRANT
+#include <math.h>
+#endif
 #include <random>
 #include <type_traits>
 #include <cmath>
@@ -20,11 +24,17 @@
 #else
 #include <unistd.h>
 #include <pthread.h>
+#include <semaphore.h>
+#include <sys/ioctl.h>
 #endif
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include "swift/Basic/Lazy.h"
 #include "swift/Runtime/Config.h"
 #include "../SwiftShims/LibcShims.h"
@@ -33,15 +43,19 @@
 using namespace swift;
 
 static_assert(std::is_same<ssize_t, swift::__swift_ssize_t>::value,
-              "__swift_ssize_t must be defined as equivalent to ssize_t");
+              "__swift_ssize_t must be defined as equivalent to ssize_t in LibcShims.h");
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static_assert(std::is_same<mode_t, swift::__swift_mode_t>::value,
+              "__swift_mode_t must be defined as equivalent to mode_t in LibcShims.h");
+#endif
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-void swift::_swift_stdlib_free(void *ptr) {
+void swift::_stdlib_free(void *ptr) {
   free(ptr);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-int swift::_swift_stdlib_putchar_unlocked(int c) {
+int swift::_stdlib_putchar_unlocked(int c) {
 #if defined(_WIN32)
   return _putc_nolock(c, stdout);
 #else
@@ -50,31 +64,31 @@
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_size_t swift::_swift_stdlib_fwrite_stdout(const void *ptr,
-                                                  __swift_size_t size,
-                                                  __swift_size_t nitems) {
-  return fwrite(ptr, size, nitems, stdout);
+__swift_size_t swift::_stdlib_fwrite_stdout(const void *ptr,
+                                         __swift_size_t size,
+                                         __swift_size_t nitems) {
+    return fwrite(ptr, size, nitems, stdout);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_size_t swift::_swift_stdlib_strlen(const char *s) {
-  return strlen(s);
+__swift_size_t swift::_stdlib_strlen(const char *s) {
+    return strlen(s);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_size_t swift::_swift_stdlib_strlen_unsigned(const unsigned char *s) {
+__swift_size_t swift::_stdlib_strlen_unsigned(const unsigned char *s) {
   return strlen(reinterpret_cast<const char *>(s));
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-int swift::_swift_stdlib_memcmp(const void *s1, const void *s2,
-                                __swift_size_t n) {
+int swift::_stdlib_memcmp(const void *s1, const void *s2,
+                       __swift_size_t n) {
   return memcmp(s1, s2, n);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 __swift_ssize_t
-swift::_swift_stdlib_read(int fd, void *buf, __swift_size_t nbyte) {
+swift::_stdlib_read(int fd, void *buf, __swift_size_t nbyte) {
 #if defined(_WIN32)
   return _read(fd, buf, nbyte);
 #else
@@ -84,7 +98,7 @@
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 __swift_ssize_t
-swift::_swift_stdlib_write(int fd, const void *buf, __swift_size_t nbyte) {
+swift::_stdlib_write(int fd, const void *buf, __swift_size_t nbyte) {
 #if defined(_WIN32)
   return _write(fd, buf, nbyte);
 #else
@@ -93,7 +107,7 @@
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-int swift::_swift_stdlib_close(int fd) {
+int swift::_stdlib_close(int fd) {
 #if defined(_WIN32)
   return _close(fd);
 #else
@@ -101,38 +115,140 @@
 #endif
 }
 
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+// Windows
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_open(const char *path, int oflag, __swift_mode_t mode) {
+  return _open(path, oflag, static_cast<int>(mode));
+}
+
+#else
+// not Windows
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_open(const char *path, int oflag, __swift_mode_t mode) {
+  return open(path, oflag, mode);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_openat(int fd, const char *path, int oflag,
+                          __swift_mode_t mode) {
+  return openat(fd, path, oflag, mode);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void *swift::_stdlib_sem_open2(const char *name, int oflag) {
+  return sem_open(name, oflag);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void *swift::_stdlib_sem_open4(const char *name, int oflag,
+                               __swift_mode_t mode, unsigned int value) {
+  return sem_open(name, oflag, mode, value);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_fcntl(int fd, int cmd, int value) {
+  return fcntl(fd, cmd, value);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_fcntlPtr(int fd, int cmd, void* ptr) {
+  return fcntl(fd, cmd, ptr);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_ioctl(int fd, unsigned long int request, int value) {
+  return ioctl(fd, request, value);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_ioctlPtr(int fd, unsigned long int request, void* ptr) {
+  return ioctl(fd, request, ptr);
+}
+
+#if defined(__FreeBSD__)
+SWIFT_RUNTIME_STDLIB_INTERNAL
+char * _Nullable *swift::_stdlib_getEnviron() {
+  extern char **environ;
+  return environ;
+}
+#elif defined(__APPLE__)
+SWIFT_RUNTIME_STDLIB_INTERNAL
+char * _Nullable *swift::_stdlib_getEnviron() {
+  extern char * _Nullable **_NSGetEnviron(void);
+  return *_NSGetEnviron();
+}
+#endif
+
+#endif // !(defined(_WIN32) && !defined(__CYGWIN__))
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+int swift::_stdlib_getErrno() {
+  return errno;
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+void swift::_stdlib_setErrno(int value) {
+  errno = value;
+}
+
+
+
+#if defined(__APPLE__)
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+float swift::_stdlib_lgammaf_r(float x, int *psigngam) {
+  return lgammaf_r(x, psigngam);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+double swift::_stdlib_lgamma_r(double x, int *psigngam) {
+  return lgamma_r(x, psigngam);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERNAL
+long double swift::_stdlib_lgammal_r(long double x, int *psigngam) {
+  return lgammal_r(x, psigngam);
+}
+
+#endif // defined(__APPLE__)
+
+
 #if defined(_WIN32)
 static_assert(std::is_same<__swift_thread_key_t, DWORD>::value,
               "__swift_thread_key_t is not a DWORD");
 
 SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-void _swift_stdlib_destroyTLS(void *);
+void _stdlib_destroyTLS(void *);
 
 static void
 #if defined(_M_IX86)
 __stdcall
 #endif
-_swift_stdlib_destroyTLS_CCAdjustmentThunk(void *ptr) {
-  _swift_stdlib_destroyTLS(ptr);
+destroyTLS_CCAdjustmentThunk(void *ptr) {
+  _stdlib_destroyTLS(ptr);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 int
-swift::_swift_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
-                                       void (* _Nullable destructor)(void *)) {
-  *key = FlsAlloc(_swift_stdlib_destroyTLS_CCAdjustmentThunk);
+swift::_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
+                              void (* _Nullable destructor)(void *)) {
+  *key = FlsAlloc(destroyTLS_CCAdjustmentThunk);
   return *key != FLS_OUT_OF_INDEXES;
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 void * _Nullable
-swift::_swift_stdlib_thread_getspecific(__swift_thread_key_t key) {
+swift::_stdlib_thread_getspecific(__swift_thread_key_t key) {
   return FlsGetValue(key);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-int swift::_swift_stdlib_thread_setspecific(__swift_thread_key_t key,
-                                            const void * _Nullable value) {
+int swift::_stdlib_thread_setspecific(__swift_thread_key_t key,
+                                   const void * _Nullable value) {
   return FlsSetValue(key, const_cast<void *>(value)) == TRUE;
 }
 #else
@@ -145,20 +261,20 @@
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 int
-swift::_swift_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
-                                       void (* _Nullable destructor)(void *)) {
+swift::_stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
+                              void (* _Nullable destructor)(void *)) {
   return pthread_key_create(key, destructor);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 void * _Nullable
-swift::_swift_stdlib_thread_getspecific(__swift_thread_key_t key) {
+swift::_stdlib_thread_getspecific(__swift_thread_key_t key) {
   return pthread_getspecific(key);
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-int swift::_swift_stdlib_thread_setspecific(__swift_thread_key_t key,
-                                            const void * _Nullable value) {
+int swift::_stdlib_thread_setspecific(__swift_thread_key_t key,
+                                      const void * _Nullable value) {
   return pthread_setspecific(key, value);
 }
 #endif
@@ -166,7 +282,7 @@
 #if defined(__APPLE__)
 #include <malloc/malloc.h>
 SWIFT_RUNTIME_STDLIB_INTERFACE
-size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
+size_t swift::_stdlib_malloc_size(const void *ptr) {
   return malloc_size(ptr);
 }
 #elif defined(__GNU_LIBRARY__) || defined(__CYGWIN__) || defined(__ANDROID__) || defined(__HAIKU__)
@@ -175,19 +291,19 @@
 #endif
 #include <malloc.h>
 SWIFT_RUNTIME_STDLIB_INTERFACE
-size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
+size_t swift::_stdlib_malloc_size(const void *ptr) {
   return malloc_usable_size(const_cast<void *>(ptr));
 }
 #elif defined(_WIN32)
 #include <malloc.h>
 SWIFT_RUNTIME_STDLIB_INTERFACE
-size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
+size_t swift::_stdlib_malloc_size(const void *ptr) {
   return _msize(const_cast<void *>(ptr));
 }
 #elif defined(__FreeBSD__)
 #include <malloc_np.h>
 SWIFT_RUNTIME_STDLIB_INTERFACE
-size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
+size_t swift::_stdlib_malloc_size(const void *ptr) {
   return malloc_usable_size(const_cast<void *>(ptr));
 }
 #else
@@ -201,13 +317,13 @@
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
-__swift_uint32_t swift::_swift_stdlib_cxx11_mt19937() {
+__swift_uint32_t swift::_stdlib_cxx11_mt19937() {
   return getGlobalMT19937()();
 }
 
 SWIFT_RUNTIME_STDLIB_INTERFACE
 __swift_uint32_t
-swift::_swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound) {
+swift::_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound) {
   if (upper_bound > 0)
     upper_bound--;
   std::uniform_int_distribution<__swift_uint32_t> RandomUniform(0, upper_bound);
diff --git a/test/ClangImporter/macros.swift b/test/ClangImporter/macros.swift
index cb8809d..370f8ae 100644
--- a/test/ClangImporter/macros.swift
+++ b/test/ClangImporter/macros.swift
@@ -168,4 +168,7 @@
 func testRecursion() {
   _ = RECURSION // expected-error {{use of unresolved identifier 'RECURSION'}}
   _ = REF_TO_RECURSION // expected-error {{use of unresolved identifier 'REF_TO_RECURSION'}}
+  _ = RECURSION_IN_EXPR // expected-error {{use of unresolved identifier 'RECURSION_IN_EXPR'}}
+  _ = RECURSION_IN_EXPR2 // expected-error {{use of unresolved identifier 'RECURSION_IN_EXPR2'}}
+  _ = RECURSION_IN_EXPR3 // expected-error {{use of unresolved identifier 'RECURSION_IN_EXPR3'}}
 }
diff --git a/test/Constraints/array_literal.swift b/test/Constraints/array_literal.swift
index 1d12aee..e5c212e 100644
--- a/test/Constraints/array_literal.swift
+++ b/test/Constraints/array_literal.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -enable-experimental-conditional-conformances
 
 struct IntList : ExpressibleByArrayLiteral {
   typealias Element = Int
@@ -322,3 +322,21 @@
 //        accident.
 let SR3786a: [Int] = [1, 2, 3]
 let SR3786aa = [SR3786a.reversed(), SR3786a]
+
+// Conditional conformance
+protocol P { }
+
+struct PArray<T> { }
+
+extension PArray : ExpressibleByArrayLiteral where T: P {
+  typealias ArrayLiteralElement = T
+
+  init(arrayLiteral elements: T...) { }
+}
+
+extension Int: P { }
+
+func testConditional(i: Int, s: String) {
+  let _: PArray<Int> = [i, i, i]
+  let _: PArray<String> = [s, s, s] // expected-error{{contextual type 'PArray<String>' cannot be used with array literal}}
+}
diff --git a/test/Constraints/diagnostics_swift4.swift b/test/Constraints/diagnostics_swift4.swift
index 9571efc..fa2917f 100644
--- a/test/Constraints/diagnostics_swift4.swift
+++ b/test/Constraints/diagnostics_swift4.swift
@@ -54,4 +54,5 @@
 infix operator +=+ : AdditionPrecedence
 func +=+(_ lhs: Int, _ rhs: Int) -> Bool { return lhs == rhs }
 func +=+<T: BinaryInteger>(_ lhs: T, _ rhs: Int) -> Bool { return lhs == rhs }
-let _ = DoubleWidth<Int>(Int.min) - 1 +=+ Int.min // Ok
+// FIXME: uncomment when <rdar://problem/32726173> is resolved and DoubleWidth is back
+// let _ = DoubleWidth<Int>(Int.min) - 1 +=+ Int.min // Ok
diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift
index fc46cf5..8e9ae7d 100644
--- a/test/Constraints/generics.swift
+++ b/test/Constraints/generics.swift
@@ -528,3 +528,16 @@
     _ = { baz($0) }(construct_generic { d }) // Ok
   }
 }
+
+// rdar://problem/35541153 - Generic parameter inference bug
+
+func rdar35541153() {
+  func foo<U: Equatable, V: Equatable, C: Collection>(_ c: C) where C.Element == (U, V) {}
+  func bar<K: Equatable, V, C: Collection>(_ c: C, _ k: K, _ v: V) where C.Element == (K, V) {}
+
+  let x: [(a: Int, b: Int)] = []
+  let y: [(k: String, v: Int)] = []
+
+  foo(x) // Ok
+  bar(y, "ultimate question", 42) // Ok
+}
diff --git a/test/DebugInfo/LoadableByAddress.swift b/test/DebugInfo/LoadableByAddress.swift
new file mode 100644
index 0000000..e61dcc1
--- /dev/null
+++ b/test/DebugInfo/LoadableByAddress.swift
@@ -0,0 +1,25 @@
+// RUN: %target-swift-frontend %s -module-name A -emit-ir -g -o - | %FileCheck %s
+// REQUIRES: CPU=x86_64
+public struct Continuation<A> {
+   private let magicToken = "Hello World"
+   fileprivate let f: (() -> A)?
+
+  public func run() {}
+}
+
+public typealias ContinuationU = Continuation<()>
+
+// CHECK: %2 = alloca %T1A12ContinuationV, align 8
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata %T1A12ContinuationV* %2,
+// CHECK-SAME:    metadata ![[X:.*]], metadata !DIExpression())
+// CHECK: ![[X]] = !DILocalVariable(name: "x",
+
+public func f<A>(_ xs: [Continuation<A>]) -> (() -> A?) {
+   return {
+       for x in xs {
+           x.run()
+       }
+       return nil
+   }
+}
+
diff --git a/test/Frontend/embed-bitcode.ll b/test/Frontend/embed-bitcode.ll
index 940bd5e..99128d2 100644
--- a/test/Frontend/embed-bitcode.ll
+++ b/test/Frontend/embed-bitcode.ll
@@ -10,7 +10,7 @@
 ; RUN: llvm-objdump -macho -section="__LLVM,__swift_cmdline" %t2.o | %FileCheck -check-prefix=CHECK-CMD %s
 ; RUN: %FileCheck -check-prefix CHECK-COMPILER %s < %t.diags.txt
 
-; RUN: %swiftc_driver_plain -frontend -O -target x86_64-apple-darwin10 -c -module-name someModule -embed-bitcode -disable-llvm-optzns -Xllvm -time-passes -o %t2-opt.o %t.bc -dump-clang-diagnostics 2> %t.diags-opt.txt
+; RUN: %swiftc_driver_plain -frontend -O -target x86_64-apple-darwin10 -c -module-name someModule -embed-bitcode -disable-llvm-optzns -Xllvm -time-passes -o %t2-opt.o %t.bc -dump-clang-diagnostics -Xllvm -debug-pass=Structure 2> %t.diags-opt.txt
 ; RUN: llvm-objdump -macho -section="__LLVM,__bitcode" %t2-opt.o | %FileCheck %s
 ; RUN: llvm-objdump -macho -section="__LLVM,__swift_cmdline" %t2-opt.o | %FileCheck -check-prefix=CHECK-CMD-OPT %s
 ; RUN: %FileCheck -check-prefix CHECK-COMPILER-OPT %s < %t.diags-opt.txt
diff --git a/test/Frontend/immediate-mode-no-output.swift b/test/Frontend/immediate-mode-no-output.swift
new file mode 100644
index 0000000..b225b15
--- /dev/null
+++ b/test/Frontend/immediate-mode-no-output.swift
@@ -0,0 +1,4 @@
+// REQUIRES: swift_interpreter
+// RUN: %empty-directory(%t)
+// RUN: cd %t && %target-swift-frontend -interpret %S/../Inputs/empty.swift
+// RUN: not ls %t/*
diff --git a/test/Generics/conditional_conformances.swift b/test/Generics/conditional_conformances.swift
index b1a9e00..c71bd0f 100644
--- a/test/Generics/conditional_conformances.swift
+++ b/test/Generics/conditional_conformances.swift
@@ -334,3 +334,29 @@
   _ = Free<T>() as P2 // expected-error{{'Free<T>' is not convertible to 'P2'; did you mean to use 'as!' to force downcast?}}
 }
 
+// rdar://problem/35837054
+protocol P7 { }
+
+protocol P8 {
+  associatedtype A
+}
+
+struct X0 { }
+
+struct X1 { }
+
+extension X1: P8 {
+  typealias A = X0
+}
+
+struct X2<T> { }
+
+extension X2: P7 where T: P8, T.A: P7 { }
+
+func takesF7<T: P7>(_: T) { }
+func passesConditionallyNotF7(x21: X2<X1>) {
+  takesF7(x21) // expected-error{{type 'X1.A' (aka 'X0') does not conform to protocol 'P7'}}
+  // expected-error@-1{{'<T where T : P7> (T) -> ()' requires that 'X1.A' (aka 'X0') conform to 'P7'}}
+  // expected-note@-2{{requirement specified as 'X1.A' (aka 'X0') : 'P7'}}
+  // expected-note@-3{{requirement from conditional conformance of 'X2<X1>' to 'P7'}}
+}
diff --git a/test/IRGen/Inputs/usr/include/ObjCInterop.h b/test/IRGen/Inputs/usr/include/ObjCInterop.h
new file mode 100644
index 0000000..40c04e2
--- /dev/null
+++ b/test/IRGen/Inputs/usr/include/ObjCInterop.h
@@ -0,0 +1,12 @@
+
+@protocol P
+@optional
+- (void)method;
+@end
+
+@interface I
+- (instancetype _Nonnull)init;
+@end
+
+I * _Nonnull f(I * _Nonnull);
+
diff --git a/test/IRGen/Inputs/usr/include/module.map b/test/IRGen/Inputs/usr/include/module.map
index 44fdc95..772bde2 100644
--- a/test/IRGen/Inputs/usr/include/module.map
+++ b/test/IRGen/Inputs/usr/include/module.map
@@ -22,3 +22,7 @@
 module CoreFoundation {
   header "BridgeTestCoreFoundation.h"
 }
+
+module ObjCInterop {
+  header "ObjCInterop.h"
+}
diff --git a/test/IRGen/objc-sections.swift b/test/IRGen/objc-sections.swift
new file mode 100644
index 0000000..487c63c
--- /dev/null
+++ b/test/IRGen/objc-sections.swift
@@ -0,0 +1,47 @@
+// RUN: %swift -target x86_64-unknown-windows-msvc -parse-stdlib -enable-objc-interop -disable-objc-attr-requires-foundation-module -I %S/Inputs/usr/include -emit-ir %s -o - | %FileCheck %s -check-prefix CHECK-COFF
+// RUN: %swift -target x86_64-unknown-linux-gnu -parse-stdlib -enable-objc-interop -disable-objc-attr-requires-foundation-module -I %S/Inputs/usr/include -Xcc --sysroot=/var/empty -emit-ir %s -o - | %FileCheck %s -check-prefix CHECK-ELF
+// RUN: %swift -target x86_64-apple-ios8.0 -parse-stdlib -enable-objc-interop -disable-objc-attr-requires-foundation-module -I %S/Inputs/usr/include -emit-ir %s -o - | %FileCheck %s -check-prefix CHECK-MACHO
+
+import ObjCInterop
+
+@objc
+class C {
+}
+
+extension C : P {
+  public func method() {
+    f(I())
+  }
+}
+
+@objc_non_lazy_realization
+class D {
+}
+
+// CHECK-COFF-NOT: @_T04main1CCMf = {{.*}}, section "__DATA,__objc_data, regular"
+// CHECK-COFF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section ".objc_protolist$B"
+// CHECK-COFF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section ".objc_protorefs$B"
+// CHECK-COFF: @"OBJC_CLASS_REF_$_I" = {{.*}}, section ".objc_classrefs$B"
+// CHECK-COFF: @"\01L_selector(init)" = {{.*}}, section ".objc_selrefs$B"
+// CHECK-COFF: @objc_classes = {{.*}}, section ".objc_classlist$B"
+// CHECK-COFF: @objc_categories = {{.*}}, section ".objc_catlist$B"
+// CHECK-COFF: @objc_non_lazy_classes = {{.*}}, section ".objc_nlclslist$B"
+
+// CHECK-ELF-NOT: @_T04main1CCMf = {{.*}}, section "__DATA,__objc_data, regular"
+// CHECK-ELF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "objc_protolist"
+// CHECK-ELF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "objc_protorefs", align 8
+// CHECK-ELF: @"OBJC_CLASS_REF_$_I" = {{.*}}, section "objc_classrefs", align 8
+// CHECK-ELF: @"\01L_selector(init)" = {{.*}}, section "objc_selrefs"
+// CHECK-ELF: @objc_classes = {{.*}}, section "objc_classlist"
+// CHECK-ELF: @objc_categories = {{.*}}, section "objc_catlist"
+// CHECK-ELF: @objc_non_lazy_classes = {{.*}}, section "objc_nlclslist", align 8
+
+// CHECK-MACHO: @_T04main1CCMf = {{.*}}, section "__DATA,__objc_data, regular"
+// CHECK-MACHO: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "__DATA,__objc_protolist,coalesced,no_dead_strip"
+// CHECK-MACHO: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "__DATA,__objc_protorefs,coalesced,no_dead_strip"
+// CHECK-MACHO: @"OBJC_CLASS_REF_$_I" = {{.*}}, section "__DATA,__objc_classrefs,regular,no_dead_strip"
+// CHECK-MACHO: @"\01L_selector(init)" = {{.*}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip"
+// CHECK-MACHO: @objc_classes = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
+// CHECK-MACHO: @objc_categories = {{.*}}, section "__DATA,__objc_catlist,regular,no_dead_strip"
+// CHECK-MACHO: @objc_non_lazy_classes = {{.*}}, section "__DATA,__objc_nlclslist,regular,no_dead_strip"
+
diff --git a/test/IRGen/objc_subclass.swift b/test/IRGen/objc_subclass.swift
index 7984556..3377404 100644
--- a/test/IRGen/objc_subclass.swift
+++ b/test/IRGen/objc_subclass.swift
@@ -271,9 +271,9 @@
 // CHECK-64: ] }
 
 
-// CHECK: @objc_classes = internal global [2 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass10SwiftGizmoCN to i8*), i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA, __objc_classlist, regular, no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
+// CHECK: @objc_classes = internal global [2 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass10SwiftGizmoCN to i8*), i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA,__objc_classlist,regular,no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
 
-// CHECK: @objc_non_lazy_classes = internal global [1 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA, __objc_nlclslist, regular, no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
+// CHECK: @objc_non_lazy_classes = internal global [1 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA,__objc_nlclslist,regular,no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
 
 import Foundation
 import gizmo
diff --git a/test/IRGen/protocol_conformance_records.swift b/test/IRGen/protocol_conformance_records.swift
index ebf0168..2d4fec9 100644
--- a/test/IRGen/protocol_conformance_records.swift
+++ b/test/IRGen/protocol_conformance_records.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend -primary-file %s -emit-ir -enable-resilience -enable-source-import -I %S/../Inputs | %FileCheck %s
-// RUN: %target-swift-frontend %s -emit-ir -num-threads 8 -enable-resilience -enable-source-import -I %S/../Inputs | %FileCheck %s
+// RUN: %target-swift-frontend -enable-experimental-conditional-conformances -primary-file %s -emit-ir -enable-resilience -enable-source-import -I %S/../Inputs | %FileCheck %s
+// RUN: %target-swift-frontend -enable-experimental-conditional-conformances %s -emit-ir -num-threads 8 -enable-resilience -enable-source-import -I %S/../Inputs | %FileCheck %s
 
 import resilient_struct
 
@@ -78,10 +78,25 @@
 // -- flags 0x04: unique direct metadata
 // CHECK-SAME:           i32 1
 // CHECK-SAME:         }
-// CHECK-SAME:       ]
 
 extension Size: Runcible {
   public func runce() {}
 }
 
 // TODO: conformances that need lazy initialization
+public protocol Spoon { }
+
+// Conditional conformances
+// CHECK: %swift.protocol_conformance {
+// -- protocol descriptor
+// CHECK-SAME:           [[SPOON:@_T028protocol_conformance_records5SpoonMp]]
+// -- nominal type descriptor
+// CHECK-SAME:           @_T028protocol_conformance_records17NativeGenericTypeVMn
+// -- witness table accessor
+// CHECK-SAME:           @_T028protocol_conformance_records17NativeGenericTypeVyxGAA5SpoonA2aERzlWa
+// -- flags 0x04: unique nominal type descriptor + conditional accessor
+// CHECK-SAME:           i32 36
+// CHECK-SAME:         }
+extension NativeGenericType : Spoon where T: Spoon {
+  public func runce() {}
+}
diff --git a/test/IRGen/subclass.swift b/test/IRGen/subclass.swift
index 2a4e4ee..b658432 100644
--- a/test/IRGen/subclass.swift
+++ b/test/IRGen/subclass.swift
@@ -35,7 +35,7 @@
 // CHECK:   i64 ([[B]]*)* @_T08subclass1BC1fSiyF,
 // CHECK:   [[A]]* ([[TYPE]]*)* @_T08subclass1AC1gACyFZ
 // CHECK: }>
-// CHECK: @objc_classes = internal global [2 x i8*] [i8* {{.*}} @_T08subclass1ACN {{.*}}, i8* {{.*}} @_T08subclass1BCN {{.*}}], section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK: @objc_classes = internal global [2 x i8*] [i8* {{.*}} @_T08subclass1ACN {{.*}}, i8* {{.*}} @_T08subclass1BCN {{.*}}], section "__DATA,__objc_classlist,regular,no_dead_strip", align 8
 
 class A {
   var x = 0
diff --git a/test/Inputs/clang-importer-sdk/usr/include/macros.h b/test/Inputs/clang-importer-sdk/usr/include/macros.h
index 334b789..234e592 100644
--- a/test/Inputs/clang-importer-sdk/usr/include/macros.h
+++ b/test/Inputs/clang-importer-sdk/usr/include/macros.h
@@ -134,3 +134,13 @@
 #define L_OR_FALSE    (0 || 0)
 #define L_OR_TRUE_B   (EQUAL_FALSE || EQUAL_TRUE)
 #define L_OR_FALSE_B  (EQUAL_FALSE || L_OR_FALSE)
+
+// Recursion with expressions
+#define RECURSION_WITH_EXPR RECURSION_WITH_EXPR_HELPER + 1
+#define RECURSION_WITH_EXPR_HELPER RECURSION_WITH_EXPR
+
+#define RECURSION_WITH_EXPR2 RECURSION_WITH_EXPR2_HELPER
+#define RECURSION_WITH_EXPR2_HELPER RECURSION_WITH_EXPR2 + 1
+
+#define RECURSION_WITH_EXPR3 RECURSION_WITH_EXPR3_HELPER + 1
+#define RECURSION_WITH_EXPR3_HELPER RECURSION_WITH_EXPR3 + 1
diff --git a/test/Inputs/conditional_conformance_basic_conformances.swift b/test/Inputs/conditional_conformance_basic_conformances.swift
index 0a839a3..58f355e 100644
--- a/test/Inputs/conditional_conformance_basic_conformances.swift
+++ b/test/Inputs/conditional_conformance_basic_conformances.swift
@@ -320,3 +320,6 @@
 // CHECK-NEXT:    unreachable
 // CHECK-NEXT:  }
 
+func dynamicCastToP1(_ value: Any) -> P1? {
+  return value as? P1
+}
diff --git a/test/Interpreter/FunctionConversion.swift b/test/Interpreter/FunctionConversion.swift
index d3c6f35..31d2d02 100644
--- a/test/Interpreter/FunctionConversion.swift
+++ b/test/Interpreter/FunctionConversion.swift
@@ -241,4 +241,61 @@
   do { try print(g()) } catch {}
 }
 
+class A: Quilt {
+  var n: Int8 {
+    return 42
+  }
+}
+
+func rdar35702810_arr<T: Quilt>(type: T.Type, _ fn: ([T]?) -> Int8) -> Int8 {
+  let x: [T] = [A() as! T]
+  return fn(x)
+}
+
+func rdar35702810_map<T: Quilt>(type: T.Type, _ fn: ([String: T]) -> Int8) -> Int8 {
+  let x: [String: T] = ["ultimate question": A() as! T]
+  return fn(x)
+}
+
+FunctionConversionTestSuite.test("CollectionUpCastsInFuncParameters") {
+  let fn_arr: ([Quilt]?) -> Int8 = { v in v![0].n }
+  let fn_map: ([String: Quilt]) -> Int8 = { v in v["ultimate question"]!.n }
+
+  expectEqual(rdar35702810_arr(type: A.self, fn_arr), 42)
+  expectEqual(rdar35702810_map(type: A.self, fn_map), 42)
+}
+
+protocol X: Hashable {}
+class B: X {
+  var hashValue: Int { return 42 }
+  static func == (lhs: B, rhs: B) -> Bool {
+    return lhs.hashValue == rhs.hashValue
+  }
+}
+
+func rdar35702810_arr_hashable<T: X>(type: T.Type, _ fn: ([T]?) -> Int) -> Int {
+  let x: [T] = [B() as! T]
+  return fn(x)
+}
+
+func rdar35702810_map_hashable<T: X>(type: T.Type, _ fn: ([String: T]) -> Int) -> Int {
+  let x: [String: T] = ["ultimate question": B() as! T]
+  return fn(x)
+}
+
+func rdar35702810_set_hashable<T: X>(type: T.Type, _ fn: (Set<T>) -> Int) -> Int {
+  let x: Set<T> = [B() as! T]
+  return fn(x)
+}
+
+FunctionConversionTestSuite.test("CollectionUpCastsWithHashableInFuncParameters") {
+  let fn_arr: ([AnyHashable]?) -> Int = { v in v![0].hashValue }
+  let fn_map: ([String: AnyHashable]) -> Int = { v in v["ultimate question"]!.hashValue }
+  let fn_set: (Set<AnyHashable>) -> Int = { v in v.first!.hashValue }
+
+  expectEqual(rdar35702810_arr_hashable(type: B.self, fn_arr), 42)
+  expectEqual(rdar35702810_map_hashable(type: B.self, fn_map), 42)
+  expectEqual(rdar35702810_set_hashable(type: B.self, fn_set), 42)
+}
+
 runAllTests()
diff --git a/test/Interpreter/conditional_conformances.swift b/test/Interpreter/conditional_conformances.swift
index a90f295..0981767 100644
--- a/test/Interpreter/conditional_conformances.swift
+++ b/test/Interpreter/conditional_conformances.swift
@@ -19,6 +19,9 @@
 double_generic_concrete(IsP2.self)
 double_concrete_concrete()
 
+assert(dynamicCastToP1(Single<IsP3>()) == nil)
+assert(dynamicCastToP1(Single<IsP2>()) == nil) // FIXME: incorrect result!
+
 #elseif with_assoc
 generic_generic(IsAlsoP2.self, IsP3.self)
 generic_concrete(IsAlsoP2.self)
diff --git a/test/Migrator/Inputs/API.json b/test/Migrator/Inputs/API.json
index 1288127..822b318 100644
--- a/test/Migrator/Inputs/API.json
+++ b/test/Migrator/Inputs/API.json
@@ -319,7 +319,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "WrapOptional",
     "ChildIndex": "1",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -330,7 +330,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "WrapOptional",
     "ChildIndex": "1",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -341,7 +341,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "WrapOptional",
     "ChildIndex": "1",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -352,7 +352,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "ImplicitOptionalToOptional",
     "ChildIndex": "1:0",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
@@ -363,7 +363,7 @@
     "NodeKind": "Function",
     "NodeAnnotation": "UnwrapOptional",
     "ChildIndex": "1:1:0",
-    "LeftUsr": "s:6Cities05ExtraA0P6blibliySSSgAE_SStc1x_tF",
+    "LeftUsr": "s:6Cities05ExtraA0P6blibliySQySSGSSSg_SStc1x_tF",
     "LeftComment": "",
     "RightUsr": "",
     "RightComment": "",
diff --git a/test/Migrator/tuple-arguments.swift b/test/Migrator/tuple-arguments.swift
index 33df8a1..19c75b4 100644
--- a/test/Migrator/tuple-arguments.swift
+++ b/test/Migrator/tuple-arguments.swift
@@ -59,3 +59,7 @@
 
 let dictionary: [String: String] = [:]
 _ = dictionary.first { (column, value) in true }!.value
+
+func doit(_ x: Int) -> Bool { return x > 0 }
+let _: ((String, Int)) -> [String:Bool] = { [$0: doit($1)] }
+func returnClosure() -> ((Int, Int)) -> Bool { return {$1 > $0} }
diff --git a/test/Migrator/tuple-arguments.swift.expected b/test/Migrator/tuple-arguments.swift.expected
index f64a3a7..65eb8a1 100644
--- a/test/Migrator/tuple-arguments.swift.expected
+++ b/test/Migrator/tuple-arguments.swift.expected
@@ -59,3 +59,7 @@
 
 let dictionary: [String: String] = [:]
 _ = dictionary.first { (column, value) in true }!.value
+
+func doit(_ x: Int) -> Bool { return x > 0 }
+let _: ((String, Int)) -> [String:Bool] = { [$0.0: doit($0.1)] }
+func returnClosure() -> ((Int, Int)) -> Bool { return {$0.1 > $0.0} }
diff --git a/test/NameBinding/Dependencies/Inputs/InterestingType.swift b/test/NameBinding/Dependencies/Inputs/InterestingType.swift
new file mode 100644
index 0000000..25defb0
--- /dev/null
+++ b/test/NameBinding/Dependencies/Inputs/InterestingType.swift
@@ -0,0 +1,23 @@
+protocol IntMaker {}
+extension IntMaker {
+  func make() -> Int { return 0 }
+}
+
+protocol DoubleMaker {}
+extension DoubleMaker {
+  func make() -> Double { return 0 }
+}
+
+
+#if OLD
+typealias InterestingType = Int
+typealias InterestingProto = IntMaker
+
+#elseif NEW
+typealias InterestingType = Double
+typealias InterestingProto = DoubleMaker
+
+#else
+typealias InterestingType = ErrorMustSetOLDOrNew
+
+#endif
diff --git a/test/NameBinding/Dependencies/private-function-return-type.swift b/test/NameBinding/Dependencies/private-function-return-type.swift
new file mode 100644
index 0000000..4643af8
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-function-return-type.swift
@@ -0,0 +1,14 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private func testReturnType() -> InterestingType { fatalError() }
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = testReturnType() + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingType"
diff --git a/test/NameBinding/Dependencies/private-function.swift b/test/NameBinding/Dependencies/private-function.swift
new file mode 100644
index 0000000..2c42414
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-function.swift
@@ -0,0 +1,14 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private func testParamType(_: InterestingType) {}
+
+// CHECK-OLD: sil_global hidden @_T04main1x{{[^ ]+}} : ${{(@[a-zA-Z_]+ )?}}(Int) -> ()
+// CHECK-NEW: sil_global hidden @_T04main1x{{[^ ]+}} : ${{(@[a-zA-Z_]+ )?}}(Double) -> ()
+internal var x = testParamType
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingType"
diff --git a/test/NameBinding/Dependencies/private-protocol-conformer-ext.swift b/test/NameBinding/Dependencies/private-protocol-conformer-ext.swift
new file mode 100644
index 0000000..d4aca3e
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-protocol-conformer-ext.swift
@@ -0,0 +1,21 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private struct Test {}
+extension Test : InterestingProto {}
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = Test().make() + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingProto"
+
+// CHECK-DEPS-LABEL: depends-member:
+// CHECK-DEPS: - ["4main{{8IntMaker|11DoubleMaker}}P", "make"]
+
+// CHECK-DEPS-LABEL: depends-nominal:
+// CHECK-DEPS: - "4main{{8IntMaker|11DoubleMaker}}P"
diff --git a/test/NameBinding/Dependencies/private-protocol-conformer.swift b/test/NameBinding/Dependencies/private-protocol-conformer.swift
new file mode 100644
index 0000000..47c879c
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-protocol-conformer.swift
@@ -0,0 +1,20 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private struct Test : InterestingProto {}
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = Test().make() + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingProto"
+
+// CHECK-DEPS-LABEL: depends-member:
+// CHECK-DEPS: - ["4main{{8IntMaker|11DoubleMaker}}P", "make"]
+
+// CHECK-DEPS-LABEL: depends-nominal:
+// CHECK-DEPS: - "4main{{8IntMaker|11DoubleMaker}}P"
diff --git a/test/NameBinding/Dependencies/private-struct-member.swift b/test/NameBinding/Dependencies/private-struct-member.swift
new file mode 100644
index 0000000..c50d475
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-struct-member.swift
@@ -0,0 +1,16 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private struct Wrapper {
+  static func test() -> InterestingType { fatalError() }
+}
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = Wrapper.test() + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingType"
diff --git a/test/NameBinding/Dependencies/private-subscript.swift b/test/NameBinding/Dependencies/private-subscript.swift
new file mode 100644
index 0000000..f90f062
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-subscript.swift
@@ -0,0 +1,16 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+struct Wrapper {
+  fileprivate subscript() -> InterestingType { fatalError() }
+}
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = Wrapper()[] + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingType"
diff --git a/test/NameBinding/Dependencies/private-typealias.swift b/test/NameBinding/Dependencies/private-typealias.swift
new file mode 100644
index 0000000..c50d475
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-typealias.swift
@@ -0,0 +1,16 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private struct Wrapper {
+  static func test() -> InterestingType { fatalError() }
+}
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = Wrapper.test() + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingType"
diff --git a/test/NameBinding/Dependencies/private-var.swift b/test/NameBinding/Dependencies/private-var.swift
new file mode 100644
index 0000000..6cdf8b4
--- /dev/null
+++ b/test/NameBinding/Dependencies/private-var.swift
@@ -0,0 +1,14 @@
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DOLD -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/InterestingType.swift -DNEW -emit-reference-dependencies-path %t.swiftdeps -module-name main | %FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %FileCheck -check-prefix=CHECK-DEPS %s < %t.swiftdeps
+
+private var privateVar: InterestingType { fatalError() }
+
+// CHECK-OLD: sil_global @_T04main1x{{[^ ]+}} : $Int
+// CHECK-NEW: sil_global @_T04main1x{{[^ ]+}} : $Double
+public var x = privateVar + 0
+
+// CHECK-DEPS-LABEL: depends-top-level:
+// CHECK-DEPS: - "InterestingType"
diff --git a/test/NameBinding/Inputs/NamedLazyMembers/NamedLazyMembers.h b/test/NameBinding/Inputs/NamedLazyMembers/NamedLazyMembers.h
index 9e94f1a..69e119a 100644
--- a/test/NameBinding/Inputs/NamedLazyMembers/NamedLazyMembers.h
+++ b/test/NameBinding/Inputs/NamedLazyMembers/NamedLazyMembers.h
@@ -50,3 +50,50 @@
 
 @end
 
+
+// Don't conform to the protocol; that loads all protocol members.
+@interface SimpleDoer (Category)
+- (void)categoricallyDoSomeWork;
+- (void)categoricallyDoSomeWorkWithSpeed:(int)s;
+- (void)categoricallyDoSomeWorkWithSpeed:(int)s thoroughness:(int)t
+  NS_SWIFT_NAME(categoricallyDoVeryImportantWork(speed:thoroughness:));
+- (void)categoricallyDoSomeWorkWithSpeed:(int)s alacrity:(int)a
+  NS_SWIFT_NAME(categoricallyDoSomeWorkWithSpeed(speed:levelOfAlacrity:));
+
+// These we are generally trying to not-import, via laziness.
+- (void)categoricallyGoForWalk;
+- (void)categoricallyTakeNap;
+- (void)categoricallyEatMeal;
+- (void)categoricallyTidyHome;
+- (void)categoricallyCallFamily;
+- (void)categoricallySingSong;
+- (void)categoricallyReadBook;
+- (void)categoricallyAttendLecture;
+- (void)categoricallyWriteLetter;
+@end
+
+
+@protocol MirroredBase
++ (void)mirroredBaseClassMethod;
+- (void)mirroredBaseInstanceMethod;
+@end
+
+@protocol MirroredDoer <MirroredBase>
++ (void)mirroredDerivedClassMethod;
+- (void)mirroredDerivedInstanceMethod;
+@end
+
+@interface MirroringDoer : NSObject<MirroredDoer>
+- (void)unobtrusivelyGoForWalk;
+- (void)unobtrusivelyTakeNap;
+- (void)unobtrusivelyEatMeal;
+- (void)unobtrusivelyTidyHome;
+- (void)unobtrusivelyCallFamily;
+- (void)unobtrusivelySingSong;
+- (void)unobtrusivelyReadBook;
+- (void)unobtrusivelyAttendLecture;
+- (void)unobtrusivelyWriteLetter;
+@end
+
+@interface DerivedFromMirroringDoer : MirroringDoer
+@end
diff --git a/test/NameBinding/named_lazy_member_loading_objc_category.swift b/test/NameBinding/named_lazy_member_loading_objc_category.swift
new file mode 100644
index 0000000..81c33e2
--- /dev/null
+++ b/test/NameBinding/named_lazy_member_loading_objc_category.swift
@@ -0,0 +1,20 @@
+// REQUIRES: objc_interop
+// REQUIRES: OS=macosx
+// RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
+//
+// Prime module cache
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -typecheck %s
+//
+// Check that named-lazy-member-loading reduces the number of Decls deserialized
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -disable-named-lazy-member-loading -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -stats-output-dir %t/stats-post %s
+// RUN: %utils/process-stats-dir.py --evaluate-delta 'NumTotalClangImportedEntities < -10' %t/stats-pre %t/stats-post
+
+import NamedLazyMembers
+
+public func foo(d: SimpleDoer) {
+  let _ = d.categoricallyDoSomeWork()
+  let _ = d.categoricallyDoSomeWork(withSpeed:10)
+  let _ = d.categoricallyDoVeryImportantWork(speed:10, thoroughness:12)
+  let _ = d.categoricallyDoSomeWorkWithSpeed(speed:10, levelOfAlacrity:12)
+}
diff --git a/test/NameBinding/named_lazy_member_loading_objc_interface.swift b/test/NameBinding/named_lazy_member_loading_objc_interface.swift
index d434237..70d5085 100644
--- a/test/NameBinding/named_lazy_member_loading_objc_interface.swift
+++ b/test/NameBinding/named_lazy_member_loading_objc_interface.swift
@@ -6,8 +6,8 @@
 // RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -typecheck %s
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -disable-named-lazy-member-loading -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumTotalClangImportedEntities < -10' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_objc_protocol.swift b/test/NameBinding/named_lazy_member_loading_objc_protocol.swift
index 1530ecc..7be53af 100644
--- a/test/NameBinding/named_lazy_member_loading_objc_protocol.swift
+++ b/test/NameBinding/named_lazy_member_loading_objc_protocol.swift
@@ -6,9 +6,9 @@
 // RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -typecheck %s
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
-// RUN: %utils/process-stats-dir.py --evaluate-delta 'NumTotalClangImportedEntities < -10' %t/stats-pre %t/stats-post
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -disable-named-lazy-member-loading -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -stats-output-dir %t/stats-post %s
+// RUN: %utils/process-stats-dir.py --evaluate-delta 'NumTotalClangImportedEntities < -9' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
 
diff --git a/test/NameBinding/named_lazy_member_loading_protocol_mirroring.swift b/test/NameBinding/named_lazy_member_loading_protocol_mirroring.swift
new file mode 100644
index 0000000..c9933cb
--- /dev/null
+++ b/test/NameBinding/named_lazy_member_loading_protocol_mirroring.swift
@@ -0,0 +1,26 @@
+// REQUIRES: objc_interop
+// REQUIRES: OS=macosx
+// RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
+//
+// Prime module cache
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -typecheck %s
+//
+// Check that named-lazy-member-loading reduces the number of Decls deserialized
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -disable-named-lazy-member-loading -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/NamedLazyMembers -stats-output-dir %t/stats-post %s
+
+import NamedLazyMembers
+
+public func foo(d: MirroringDoer) {
+  let _ = MirroringDoer.mirroredBaseClassMethod()
+  let _ = MirroringDoer.mirroredDerivedClassMethod()
+  let _ = d.mirroredBaseInstanceMethod()
+  let _ = d.mirroredDerivedInstanceMethod()
+}
+
+public func foo(d: DerivedFromMirroringDoer) {
+  let _ = MirroringDoer.mirroredBaseClassMethod()
+  let _ = MirroringDoer.mirroredDerivedClassMethod()
+  let _ = d.mirroredBaseInstanceMethod()
+  let _ = d.mirroredDerivedInstanceMethod()
+}
diff --git a/test/NameBinding/named_lazy_member_loading_swift_class.swift b/test/NameBinding/named_lazy_member_loading_swift_class.swift
index 130068c..9b11cf1 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_class.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_class.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -10' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_swift_class_type.swift b/test/NameBinding/named_lazy_member_loading_swift_class_type.swift
index cc9af4c..9012133 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_class_type.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_class_type.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -10' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_swift_derived_class.swift b/test/NameBinding/named_lazy_member_loading_swift_derived_class.swift
index 7a432b9..1afe64a 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_derived_class.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_derived_class.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -10' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_swift_derived_class_type.swift b/test/NameBinding/named_lazy_member_loading_swift_derived_class_type.swift
index 957073e..37a02ac 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_derived_class_type.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_derived_class_type.swift
@@ -1,13 +1,15 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -10' %t/stats-pre %t/stats-post
 
+// REQUIRES: rdar35799113
+
 import NamedLazyMembers
 
 public func test(i: DerivedClass.derivedMemberType1) -> DerivedClass.derivedMemberType1 {
diff --git a/test/NameBinding/named_lazy_member_loading_swift_enum.swift b/test/NameBinding/named_lazy_member_loading_swift_enum.swift
index 23f90b5..ea5b112 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_enum.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_enum.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -5' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_swift_proto.swift b/test/NameBinding/named_lazy_member_loading_swift_proto.swift
index e82eca3..60f179c 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_proto.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_proto.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -3' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_swift_struct.swift b/test/NameBinding/named_lazy_member_loading_swift_struct.swift
index 8dc79bf..d837a2f 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_struct.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_struct.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -5' %t/stats-pre %t/stats-post
 
 // REQUIRES: rdar_35639403
diff --git a/test/NameBinding/named_lazy_member_loading_swift_struct_ext.swift b/test/NameBinding/named_lazy_member_loading_swift_struct_ext.swift
index ee6f4d0..70d78a3 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_struct_ext.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_struct_ext.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -5' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/named_lazy_member_loading_swift_struct_ext_mem.swift b/test/NameBinding/named_lazy_member_loading_swift_struct_ext_mem.swift
index 9f8e129..98041db 100644
--- a/test/NameBinding/named_lazy_member_loading_swift_struct_ext_mem.swift
+++ b/test/NameBinding/named_lazy_member_loading_swift_struct_ext_mem.swift
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t && mkdir -p %t/stats-pre && mkdir -p %t/stats-post
 //
 // Compile swiftmodule with decl member name tables
-// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule -enable-named-lazy-member-loading %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
+// RUN: %target-swift-frontend -emit-module -o %t/NamedLazyMembers.swiftmodule %S/Inputs/NamedLazyMembers/NamedLazyMembers.swift
 //
 // Check that named-lazy-member-loading reduces the number of Decls deserialized
-// RUN: %target-swift-frontend -typecheck -I %t -typecheck -stats-output-dir %t/stats-pre %s
-// RUN: %target-swift-frontend -typecheck -I %t -enable-named-lazy-member-loading -stats-output-dir %t/stats-post %s
+// RUN: %target-swift-frontend -typecheck -I %t -disable-named-lazy-member-loading -typecheck -stats-output-dir %t/stats-pre %s
+// RUN: %target-swift-frontend -typecheck -I %t -stats-output-dir %t/stats-post %s
 // RUN: %utils/process-stats-dir.py --evaluate-delta 'NumDeclsDeserialized < -5' %t/stats-pre %t/stats-post
 
 import NamedLazyMembers
diff --git a/test/NameBinding/reference-dependencies.swift b/test/NameBinding/reference-dependencies.swift
index 09b4ce0..2fa1098 100644
--- a/test/NameBinding/reference-dependencies.swift
+++ b/test/NameBinding/reference-dependencies.swift
@@ -126,7 +126,7 @@
 protocol ExpressibleByExtraFloatLiteral
     : ExpressibleByOtherFileAliasForFloatLiteral {
 }
-// CHECK-DAG: !private "ExpressibleByUnicodeScalarLiteral"
+// CHECK-DAG: - "ExpressibleByUnicodeScalarLiteral"
 private protocol ExpressibleByExtraCharLiteral : ExpressibleByUnicodeScalarLiteral {
 }
 
@@ -341,8 +341,8 @@
 
 // CHECK-DAG: !private "privateTopLevel1"
 func private1(_ a: Int = privateTopLevel1()) {}
-// CHECK-DAG: !private "privateTopLevel2"
-// CHECK-DAG: !private "PrivateProto1"
+// CHECK-DAG: - "privateTopLevel2"
+// CHECK-DAG: - "PrivateProto1"
 private struct Private2 : PrivateProto1 {
   var private2 = privateTopLevel2()
 }
@@ -351,11 +351,11 @@
   let _ = { privateTopLevel3() }
 }
 
-// CHECK-DAG: !private "PrivateTopLevelTy1"
+// CHECK-DAG: - "PrivateTopLevelTy1"
 private extension Use4 {
   var privateTy1: PrivateTopLevelTy1? { return nil }
 } 
-// CHECK-DAG: !private "PrivateTopLevelTy2"
+// CHECK-DAG: - "PrivateTopLevelTy2"
 // CHECK-DAG: "PrivateProto2"
 extension Private2 : PrivateProto2 {
   // FIXME: This test is supposed to check that we get this behavior /without/
@@ -367,21 +367,21 @@
   func inner(_ a: PrivateTopLevelTy3?) {}
   inner(nil)
 }
-// CHECK-DAG: !private "PrivateTopLevelStruct3"
+// CHECK-DAG: - "PrivateTopLevelStruct3"
 private typealias PrivateTy4 = PrivateTopLevelStruct3.ValueType
-// CHECK-DAG: !private "PrivateTopLevelStruct4"
+// CHECK-DAG: - "PrivateTopLevelStruct4"
 private func privateTy5(_ x: PrivateTopLevelStruct4.ValueType) -> PrivateTopLevelStruct4.ValueType {
   return x
 }
 
 // Deliberately empty.
 private struct PrivateTy6 {}
-// CHECK-DAG: !private "PrivateProto3"
+// CHECK-DAG: - "PrivateProto3"
 extension PrivateTy6 : PrivateProto3 {}
 
 // CHECK-DAG: - "ProtoReferencedOnlyInGeneric"
 func genericTest<T: ProtoReferencedOnlyInGeneric>(_: T) {}
-// CHECK-DAG: !private "ProtoReferencedOnlyInPrivateGeneric"
+// CHECK-DAG: - "ProtoReferencedOnlyInPrivateGeneric"
 private func privateGenericTest<T: ProtoReferencedOnlyInPrivateGeneric>(_: T) {}
 
 struct PrivateStoredProperty {
@@ -436,8 +436,8 @@
 // CHECK-DAG: - ["4main15TopLevelStruct5V", "ValueType"]
 // CHECK-DAG: - !private ["4main21PrivateTopLevelStructV", "ValueType"]
 // CHECK-DAG: - !private ["4main22PrivateTopLevelStruct2V", "ValueType"]
-// CHECK-DAG: - !private ["4main22PrivateTopLevelStruct3V", "ValueType"]
-// CHECK-DAG: - !private ["4main22PrivateTopLevelStruct4V", "ValueType"]
+// CHECK-DAG: - ["4main22PrivateTopLevelStruct3V", "ValueType"]
+// CHECK-DAG: - ["4main22PrivateTopLevelStruct4V", "ValueType"]
 
 // CHECK-DAG: - ["4main14TopLevelProto1P", ""]
 // CHECK-DAG: - ["4main14TopLevelProto2P", ""]
@@ -463,13 +463,13 @@
 // CHECK: - !private "4main18OtherFileOuterTypeV"
 // CHECK: - !private "4main25OtherFileProtoImplementorV"
 // CHECK: - !private "4main26OtherFileProtoImplementor2V"
-// CHECK: - !private "4main13PrivateProto1P"
-// CHECK: - !private "4main13PrivateProto2P"
+// CHECK: - "4main13PrivateProto1P"
+// CHECK: - "4main13PrivateProto2P"
 // CHECK: - !private "4main13PrivateProto3P"
 // CHECK: - !private "4main21PrivateTopLevelStructV"
 // CHECK: - !private "4main22PrivateTopLevelStruct2V"
-// CHECK: - !private "4main22PrivateTopLevelStruct3V"
-// CHECK: - !private "4main22PrivateTopLevelStruct4V"
+// CHECK: - "4main22PrivateTopLevelStruct3V"
+// CHECK: - "4main22PrivateTopLevelStruct4V"
 // CHECK: - !private "4main26OtherFileSecretTypeWrapperV0dE0V"
 // CHECK: - !private "s10StrideableP"
 // CHECK: - "4main23TopLevelForMemberLookupV"
diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift
index e08a19b4..bdc2502 100644
--- a/test/SILGen/function_conversion.swift
+++ b/test/SILGen/function_conversion.swift
@@ -598,3 +598,59 @@
 // CHECK-NEXT:    dealloc_stack [[OPTIONAL_VALUE]]
 // CHECK-NEXT:    dealloc_stack [[ANY_VALUE]]
 // CHECK-NEXT:    return
+
+// ==== Support collection subtyping in function argument position
+
+protocol Z {}
+class A: Z {}
+
+func foo_arr<T: Z>(type: T.Type, _ fn: ([T]?) -> Void) {}
+func foo_map<T: Z>(type: T.Type, _ fn: ([Int: T]) -> Void) {}
+
+func rdar35702810() {
+  let fn_arr: ([Z]?) -> Void = { _ in }
+  let fn_map: ([Int: Z]) -> Void = { _ in }
+
+  // CHECK: function_ref @_T0s15_arrayForceCastSayq_GSayxGr0_lF : $@convention(thin) <τ_0_0, τ_0_1> (@owned Array<τ_0_0>) -> @owned Array<τ_0_1>
+  // CHECK: apply %4<A, Z>(%3) : $@convention(thin) <τ_0_0, τ_0_1> (@owned Array<τ_0_0>) -> @owned Array<τ_0_1>
+  foo_arr(type: A.self, fn_arr)
+
+  // CHECK: function_ref @_T0s17_dictionaryUpCasts10DictionaryVyq0_q1_GACyxq_Gs8HashableRzsAFR0_r2_lF : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
+  // CHECK: apply %2<Int, A, Int, Z>(%0) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2, τ_0_3 where τ_0_0 : Hashable, τ_0_2 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned Dictionary<τ_0_2, τ_0_3>
+  // CHECK: apply %1(%3) : $@callee_guaranteed (@owned Dictionary<Int, Z>) -> ()
+  foo_map(type: A.self, fn_map)
+}
+
+protocol X: Hashable {}
+class B: X {
+  var hashValue: Int { return 42 }
+  static func == (lhs: B, rhs: B) -> Bool {
+    return lhs.hashValue == rhs.hashValue
+  }
+}
+
+func bar_arr<T: X>(type: T.Type, _ fn: ([T]?) -> Void) {}
+func bar_map<T: X>(type: T.Type, _ fn: ([T: Int]) -> Void) {}
+func bar_set<T: X>(type: T.Type, _ fn: (Set<T>) -> Void) {}
+
+func rdar35702810_anyhashable() {
+  let fn_arr: ([AnyHashable]?) -> Void = { _ in }
+  let fn_map: ([AnyHashable: Int]) -> Void = { _ in }
+  let fn_set: (Set<AnyHashable>) -> Void = { _ in }
+
+
+  // CHECK: function_ref @_T0Says11AnyHashableVGSgIegx_Say19function_conversion1BCGSgIgx_TR : $@convention(thin) (@owned Optional<Array<B>>, @guaranteed @callee_guaranteed (@owned Optional<Array<AnyHashable>>) -> ()) -> ()
+  // CHECK: partial_apply [callee_guaranteed] %12(%11) : $@convention(thin) (@owned Optional<Array<B>>, @guaranteed @callee_guaranteed (@owned Optional<Array<AnyHashable>>) -> ()) -> ()
+  // CHECK: convert_function %13 : $@callee_guaranteed (@owned Optional<Array<B>>) -> () to $@noescape @callee_guaranteed (@owned Optional<Array<B>>) -> ()
+  bar_arr(type: B.self, fn_arr)
+
+  // CHECK: function_ref @_T0s10DictionaryVys11AnyHashableVSiGIegx_ABy19function_conversion1BCSiGIgx_TR : $@convention(thin) (@owned Dictionary<B, Int>, @guaranteed @callee_guaranteed (@owned Dictionary<AnyHashable, Int>) -> ()) -> ()
+  // CHECK: partial_apply [callee_guaranteed] %21(%20) : $@convention(thin) (@owned Dictionary<B, Int>, @guaranteed @callee_guaranteed (@owned Dictionary<AnyHashable, Int>) -> ()) -> ()
+  // CHECK: convert_function %22 : $@callee_guaranteed (@owned Dictionary<B, Int>) -> () to $@noescape @callee_guaranteed (@owned Dictionary<B, Int>) -> ()
+  bar_map(type: B.self, fn_map)
+
+  // CHECK: function_ref @_T0s3SetVys11AnyHashableVGIegx_ABy19function_conversion1BCGIgx_TR : $@convention(thin) (@owned Set<B>, @guaranteed @callee_guaranteed (@owned Set<AnyHashable>) -> ()) -> ()
+  // CHECK: partial_apply [callee_guaranteed] %30(%29) : $@convention(thin) (@owned Set<B>, @guaranteed @callee_guaranteed (@owned Set<AnyHashable>) -> ()) -> ()
+  // CHECK: convert_function %31 : $@callee_guaranteed (@owned Set<B>) -> () to $@noescape @callee_guaranteed (@owned Set<B>) -> ()
+  bar_set(type: B.self, fn_set)
+}
diff --git a/test/SILOptimizer/Inputs/Outliner.h b/test/SILOptimizer/Inputs/Outliner.h
index d5de013..a50dd1c 100644
--- a/test/SILOptimizer/Inputs/Outliner.h
+++ b/test/SILOptimizer/Inputs/Outliner.h
@@ -1,9 +1,17 @@
 #import <Foundation/Foundation.h>
 
+@protocol Proto
+- (id)requirement;
+@end
+
 @interface Gizmo : NSObject
 @property (nonatomic)NSString *stringProperty;
 - (NSString*) modifyString: (NSString *)str withNumber: (NSInteger) num withFoobar: (id)foobar;
 - (id) doSomething : (NSArray<NSString*>*) arr;
 @end
 
+@interface Gizmo2<ObjectType: id<Proto>> : NSObject
+- (NSString*) doSomething;
+@end
+
 
diff --git a/test/SILOptimizer/devirt_class_witness_method.sil b/test/SILOptimizer/devirt_class_witness_method.sil
index 21e7796..6632c0f 100644
--- a/test/SILOptimizer/devirt_class_witness_method.sil
+++ b/test/SILOptimizer/devirt_class_witness_method.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -devirtualizer -sil-combine -enable-resilience | tee /tmp/xxx | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -devirtualizer -sil-combine -enable-resilience | %FileCheck %s
 sil_stage canonical
 
 import Builtin
diff --git a/test/SILOptimizer/existential_type_propagation.sil b/test/SILOptimizer/existential_type_propagation.sil
index 1b7fe01..4121728 100644
--- a/test/SILOptimizer/existential_type_propagation.sil
+++ b/test/SILOptimizer/existential_type_propagation.sil
@@ -293,6 +293,51 @@
   return %11 : $()
 }
 
+@objc protocol Q : class {
+  @objc func bar()
+}
+
+// rdar://35800315: crash in SILBuilder::addOpenedArchetypeOperands.
+//
+// When SILCombineApply propagates concrete types it temporarily installed an
+// opened archetype tracker to rewrite witness_method. It may then fail because
+// the copied existential is destroyed before the method is applied leaving a
+// dangling stack pointer. If silcombine continues iterating it may hit an
+// objc_method, which does a lookup in the archetype tracker.
+sil @silcombine_apply_opened_archetype : $@convention(thin) (@in P, Q) -> () {
+bb0(%0 : $*P, %1 : $Q):
+  // A single operand instruction that uses an opened existential.
+  // For some reason this is handled specialy in
+  // SILBuilder::addOpenedArchetypeOperands.
+  %ref = open_existential_ref %1 : $Q to $@opened("D66B9398-D800-11E7-8432-0A0000BBF6C0") Q
+  %om = objc_method %ref : $@opened("D66B9398-D800-11E7-8432-0A0000BBF6C0") Q, #Q.bar!1.foreign : <Self where Self : Q> (Self) -> () -> (), $@convention(objc_method) <τ_0_0 where τ_0_0 : Q> (τ_0_0) -> ()
+  %call1 = apply %om<@opened("D66B9398-D800-11E7-8432-0A0000BBF6C0") Q>(%ref) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Q> (τ_0_0) -> ()
+
+  // Some code to simplify in iteration #1
+  %ptr = address_to_pointer %0 : $*P to $Builtin.RawPointer
+  %adr = pointer_to_address %ptr : $Builtin.RawPointer to $*P
+
+  // Some code to confuse SILCombineApply.
+  %p0 = alloc_stack $P
+  %opened = open_existential_addr immutable_access %adr : $*P to $*@opened("A66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  %p1 = alloc_stack $P
+  %v1 = init_existential_addr %p1 : $*P, $@opened("A66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  copy_addr %opened to [initialization] %v1 : $*@opened("A66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  copy_addr [take] %p1 to [initialization] %p0 : $*P
+  destroy_addr %0 : $*P
+  %v0 = open_existential_addr immutable_access %p0 : $*P to $*@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  %p2 = alloc_stack $@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  copy_addr %v0 to [initialization] %p2 : $*@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  %wm = witness_method $@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P, #P.foo : <T where T : P> (T) -> () -> Int64, %opened : $*@opened("A66B9398-D800-11E7-8432-0A0000BBF6C0") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int64
+  %call2 = apply %wm<@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P>(%p2) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int64
+  destroy_addr %p2 : $*@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  dealloc_stack %p2 : $*@opened("B66B9398-D800-11E7-8432-0A0000BBF6C0") P
+  dealloc_stack %p1 : $*P
+  dealloc_stack %p0 : $*P
+  %r = tuple ()
+  return %r : $()
+}
+
 sil @_TTWC4nix23XXXS_3PPPS_FS1_3foofT_T_ : $@convention(witness_method: PPP) (@guaranteed XXX) -> ()
 
 sil_witness_table XXX: PPP module nix2 {
diff --git a/test/SILOptimizer/outliner.swift b/test/SILOptimizer/outliner.swift
index 76e6fe3..cabc9e5 100644
--- a/test/SILOptimizer/outliner.swift
+++ b/test/SILOptimizer/outliner.swift
@@ -134,3 +134,9 @@
 // CHECK:   %7 = apply %2(%6, %1) : $@convention(objc_method) (Optional<NSArray>, Gizmo) -> @autoreleased Optional<AnyObject>
 // CHECK:   strong_release %4 : $NSArray
 // CHECK:   return %7 : $Optional<AnyObject>
+
+public func dontCrash<T: Proto>(x : Gizmo2<T>) {
+  let s = x.doSomething()
+  print(s)
+
+}
diff --git a/test/Sema/diag_deprecated_iuo.swift b/test/Sema/diag_deprecated_iuo.swift
index be357e0..8a44304 100644
--- a/test/Sema/diag_deprecated_iuo.swift
+++ b/test/Sema/diag_deprecated_iuo.swift
@@ -27,10 +27,7 @@
 let _: ImplicitlyUnwrappedOptional<Int> = 1 // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name}}{{8-36=}} {{39-39=!}} {{39-40=}}
 let _: ImplicitlyUnwrappedOptional = 1 // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use an explicit type followed by '!'}}
 
-extension ImplicitlyUnwrappedOptional { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{11-38=Optional}}
-  func unwrap() -> Wrapped {
-   return self.unsafelyUnwrapped
-  }
+extension ImplicitlyUnwrappedOptional { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{11-38=Optional}}
 }
 
 func functionSpelling(
@@ -48,8 +45,8 @@
 
 // Not okay because '!' is not at the top level of the type.
 func functionSigilArray(
-  _: [Int!] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-) -> [Int!] { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
+  _: [Int!] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+) -> [Int!] { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
   return [1]
 }
 
@@ -68,12 +65,12 @@
 
 func genericFunctionSigilArray<T>(
   // FIXME: We validate these types multiple times resulting in multiple diagnostics
-  iuo: [T!] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-  // expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-  // expected-warning@-2 {{'!' is not allowed here; interpreting this as '?' instead}}{{10-11=?}}
-) -> [T!] { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  // expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  // expected-warning@-2 {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
+  iuo: [T!] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+  // expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+  // expected-warning@-2 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{10-11=?}}
+) -> [T!] { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  // expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  // expected-warning@-2 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
   return iuo
 }
 
@@ -83,16 +80,16 @@
 }
 
 struct S : P {
-  typealias T = ImplicitlyUnwrappedOptional<Int> // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{17-45=}} {{48-48=?}} {{48-49=}}
-  typealias U = Optional<ImplicitlyUnwrappedOptional<Int>> // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{26-54=}} {{57-57=?}} {{57-58=}}
+  typealias T = ImplicitlyUnwrappedOptional<Int> // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{17-45=}} {{48-48=?}} {{48-49=}}
+  typealias U = Optional<ImplicitlyUnwrappedOptional<Int>> // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{26-54=}} {{57-57=?}} {{57-58=}}
 
-  typealias V = Int!  // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{20-21=?}}
-  typealias W = Int!? // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{20-21=?}}
+  typealias V = Int!  // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{20-21=?}}
+  typealias W = Int!? // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{20-21=?}}
 
   var x: V
   var y: W
-  var fn1: (Int!) -> Int // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{16-17=?}}
-  var fn2: (Int) -> Int! // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{24-25=?}}
+  var fn1: (Int!) -> Int // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{16-17=?}}
+  var fn2: (Int) -> Int! // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{24-25=?}}
 
   subscript (
     index: ImplicitlyUnwrappedOptional<Int> // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name}}{{12-40=}} {{43-43=!}} {{43-44=}}
@@ -107,100 +104,100 @@
   }
 }
 
-func generic<T : P>(_: T) where T.T == ImplicitlyUnwrappedOptional<Int> { } // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{40-68=}} {{71-71=?}} {{71-72=}}
-func genericOptIUO<T : P>(_: T) where T.U == Optional<ImplicitlyUnwrappedOptional<Int>> {} // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{55-83=}} {{86-86=?}} {{86-87=}}
+func generic<T : P>(_: T) where T.T == ImplicitlyUnwrappedOptional<Int> { } // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{40-68=}} {{71-71=?}} {{71-72=}}
+func genericOptIUO<T : P>(_: T) where T.U == Optional<ImplicitlyUnwrappedOptional<Int>> {} // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{55-83=}} {{86-86=?}} {{86-87=}}
 
 func testClosure() -> Int {
   return {
     (i: ImplicitlyUnwrappedOptional<Int>) // expected-warning {{the spelling 'ImplicitlyUnwrappedOptional' is deprecated; use '!' after the type name}}{{9-37=}} {{40-40=!}} {{40-41=}}
-     -> ImplicitlyUnwrappedOptional<Int> in // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{9-37=}} {{40-40=?}} {{40-41=}}
+     -> ImplicitlyUnwrappedOptional<Int> in // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{9-37=}} {{40-40=?}} {{40-41=}}
     return i
   }(1)!
 }
 
-_ = Array<Int!>() // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{14-15=?}}
-let _: Array<Int!> = [1] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{17-18=?}}
-_ = [Int!]() // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{9-10=?}}
-let _: [Int!] = [1] // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{12-13=?}}
-_ = Optional<Int!>(nil) // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{17-18=?}}
-let _: Optional<Int!> = nil // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{20-21=?}}
-_ = Int!?(0) // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-let _: Int!? = 0 // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{11-12=?}}
+_ = Array<Int!>() // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{14-15=?}}
+let _: Array<Int!> = [1] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{17-18=?}}
+_ = [Int!]() // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{9-10=?}}
+let _: [Int!] = [1] // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{12-13=?}}
+_ = Optional<Int!>(nil) // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{17-18=?}}
+let _: Optional<Int!> = nil // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{20-21=?}}
+_ = Int!?(0) // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+let _: Int!? = 0 // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{11-12=?}}
 _ = (
-  Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{6-7=?}}
-  Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  String! // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{9-10=?}}
+  Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{6-7=?}}
+  Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  String! // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{9-10=?}}
 )(1, 2.0, "3")
 let _: (
-  Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{6-7=?}}
-  Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{8-9=?}}
-  String! // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{9-10=?}}
+  Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{6-7=?}}
+  Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{8-9=?}}
+  String! // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{9-10=?}}
 ) = (1, 2.0, "3")
 
 struct Generic<T, U, C> {
   init(_ t: T, _ u: U, _ c: C) {}
 }
-_ = Generic<Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{16-17=?}}
-            Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{18-19=?}}
-            String!>(1, 2.0, "3") // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{19-20=?}}
-let _: Generic<Int!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{19-20=?}}
-               Float!, // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{21-22=?}}
-               String!> = Generic(1, 2.0, "3") // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{22-23=?}}
+_ = Generic<Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{16-17=?}}
+            Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{18-19=?}}
+            String!>(1, 2.0, "3") // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{19-20=?}}
+let _: Generic<Int!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{19-20=?}}
+               Float!, // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{21-22=?}}
+               String!> = Generic(1, 2.0, "3") // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{22-23=?}}
 
-func vararg(_ first: Int, more: Int!...) { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{36-37=?}}
+func vararg(_ first: Int, more: Int!...) { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{36-37=?}}
 }
 
-func varargIdentifier(_ first: Int, more: ImplicitlyUnwrappedOptional<Int>...) { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
+func varargIdentifier(_ first: Int, more: ImplicitlyUnwrappedOptional<Int>...) { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
 }
 
-func iuoInTuple() -> (Int!) { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{26-27=?}}
+func iuoInTuple() -> (Int!) { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{26-27=?}}
   return 1
 }
 
-func iuoInTupleIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
+func iuoInTupleIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
   return 1
 }
 
-func iuoInTuple2() -> (Float, Int!) { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{34-35=?}}
+func iuoInTuple2() -> (Float, Int!) { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{34-35=?}}
   return (1.0, 1)
 }
 
-func iuoInTuple2Identifier() -> (Float, ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{41-69=}} {{72-72=?}} {{72-73=}}
+func iuoInTuple2Identifier() -> (Float, ImplicitlyUnwrappedOptional<Int>) { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{41-69=}} {{72-72=?}} {{72-73=}}
   return (1.0, 1)
 }
 
-func takesFunc(_ fn: (Int!) -> Int) -> Int { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{26-27=?}}
+func takesFunc(_ fn: (Int!) -> Int) -> Int { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{26-27=?}}
   return fn(0)
 }
 
-func takesFuncIdentifier(_ fn: (ImplicitlyUnwrappedOptional<Int>) -> Int) -> Int { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
+func takesFuncIdentifier(_ fn: (ImplicitlyUnwrappedOptional<Int>) -> Int) -> Int { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{33-61=}} {{64-64=?}} {{64-65=}}
   return fn(0)
 }
 
-func takesFunc2(_ fn: (Int) -> Int!) -> Int { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{35-36=?}}
+func takesFunc2(_ fn: (Int) -> Int!) -> Int { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{35-36=?}}
   return fn(0)!
 }
 
-func takesFunc2Identifier(_ fn: (Int) -> ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{42-70=}} {{73-73=?}} {{73-74=}}
+func takesFunc2Identifier(_ fn: (Int) -> ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{42-70=}} {{73-73=?}} {{73-74=}}
   return fn(0)!
 }
 
-func returnsFunc() -> (Int!) -> Int { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{27-28=?}}
+func returnsFunc() -> (Int!) -> Int { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{27-28=?}}
   return { $0! }
 }
 
-func returnsFuncIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{34-62=}} {{65-65=?}} {{65-66=}}
+func returnsFuncIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{34-62=}} {{65-65=?}} {{65-66=}}
   return { $0! }
 }
 
-func returnsFunc2() -> (Int) -> Int! { // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}{{36-37=?}}
+func returnsFunc2() -> (Int) -> Int! { // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}{{36-37=?}}
   return { $0 }
 }
 
-func returnsFunc2Identifier() -> (Int) -> ImplicitlyUnwrappedOptional<Int> { // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
+func returnsFunc2Identifier() -> (Int) -> ImplicitlyUnwrappedOptional<Int> { // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{43-71=}} {{74-74=?}} {{74-75=}}
   return { $0 }
 }
 
-let x = 1 as ImplicitlyUnwrappedOptional // expected-warning {{'ImplicitlyUnwrappedOptional' is not allowed here; interpreting this as 'Optional' instead}}{{14-41=Optional}}
+let x = 1 as ImplicitlyUnwrappedOptional // expected-warning {{using 'ImplicitlyUnwrappedOptional' in this location is deprecated and will be removed in a future release; consider changing this to 'Optional' instead}}{{14-41=Optional}}
 let y = x!
 let z: Int = x // expected-error {{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}{{15-15=!}}
diff --git a/test/Serialization/xref-extensions.swift b/test/Serialization/xref-extensions.swift
index 0430bb9..fbd1257 100644
--- a/test/Serialization/xref-extensions.swift
+++ b/test/Serialization/xref-extensions.swift
@@ -14,14 +14,12 @@
 // REQUIRES: asserts
 
 // CHECK_NESTED-LABEL: Statistics
-// CHECK_NESTED: 6 Serialization - # of decls deserialized
-// outer struct, initializer + self param,
-// inner struct, initializer + self param,
-// extension, func + self param
+// CHECK_NESTED: 4 Serialization - # of decls deserialized
+// outer struct, inner struct, extension, func + self param
 
 // CHECK_NON_NESTED-LABEL: Statistics
-// CHECK_NON_NESTED: 4 Serialization - # of decls deserialized
-// struct, initializer + self param, extension, func + self param
+// CHECK_NON_NESTED: 3 Serialization - # of decls deserialized
+// struct, extension, func + self param
 
 import def_xref_extensions
 import def_xref_extensions_distraction
diff --git a/test/SourceKit/DocSupport/doc_clang_module.swift b/test/SourceKit/DocSupport/doc_clang_module.swift
index 63d95ec..ec01ab5 100644
--- a/test/SourceKit/DocSupport/doc_clang_module.swift
+++ b/test/SourceKit/DocSupport/doc_clang_module.swift
@@ -2,3 +2,6 @@
 // RUN: %sourcekitd-test -req=doc-info -module Foo -- -F %S/../Inputs/libIDE-mock-sdk \
 // RUN:         %mcp_opt %clang-importer-sdk | %sed_clean > %t.response
 // RUN: diff -u %s.response %t.response
+//
+// REQUIRES: rdar35799113
+//
diff --git a/test/SourceKit/DocSupport/doc_clang_module.swift.response b/test/SourceKit/DocSupport/doc_clang_module.swift.response
index 5a3c336..1584fd5 100644
--- a/test/SourceKit/DocSupport/doc_clang_module.swift.response
+++ b/test/SourceKit/DocSupport/doc_clang_module.swift.response
@@ -5712,7 +5712,7 @@
     key.kind: source.lang.swift.decl.function.free,
     key.name: "fooFunc1(_:)",
     key.usr: "c:@F@fooFunc1",
-    key.doc.full_as_xml: "<Function file=Foo.h line=\"66\" column=\"5\"><Name>fooFunc1</Name><USR>c:@F@fooFunc1</USR><Declaration>func fooFunc1(_ a: Int32) -> Int32</Declaration><Abstract><Para> Aaa.  fooFunc1.  Bbb.</Para></Abstract></Function>",
+    key.doc.full_as_xml: "<Function file=Foo.h line=\"66\" column=\"5\"><Name>fooFunc1</Name><USR>c:@F@fooFunc1</USR><Declaration>func fooFunc1(_ a: Int32) -&gt; Int32</Declaration><Abstract><Para> Aaa.  fooFunc1.  Bbb.</Para></Abstract></Function>",
     key.offset: 3282,
     key.length: 34,
     key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooFunc1</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>_</decl.var.parameter.argument_label> <decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.function.returntype></decl.function.free>",
@@ -5879,7 +5879,7 @@
     key.kind: source.lang.swift.decl.function.free,
     key.name: "redeclaredInMultipleModulesFunc1(_:)",
     key.usr: "c:@F@redeclaredInMultipleModulesFunc1",
-    key.doc.full_as_xml: "<Function file=Foo.h line=\"118\" column=\"5\"><Name>redeclaredInMultipleModulesFunc1</Name><USR>c:@F@redeclaredInMultipleModulesFunc1</USR><Declaration>func redeclaredInMultipleModulesFunc1(_ a: Int32) -> Int32</Declaration><Abstract><Para> Aaa.  redeclaredInMultipleModulesFunc1.  Bbb.</Para></Abstract></Function>",
+    key.doc.full_as_xml: "<Function file=Foo.h line=\"118\" column=\"5\"><Name>redeclaredInMultipleModulesFunc1</Name><USR>c:@F@redeclaredInMultipleModulesFunc1</USR><Declaration>func redeclaredInMultipleModulesFunc1(_ a: Int32) -&gt; Int32</Declaration><Abstract><Para> Aaa.  redeclaredInMultipleModulesFunc1.  Bbb.</Para></Abstract></Function>",
     key.offset: 3773,
     key.length: 58,
     key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>redeclaredInMultipleModulesFunc1</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>_</decl.var.parameter.argument_label> <decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.function.returntype></decl.function.free>",
diff --git a/test/SourceKit/InterfaceGen/gen_swift_type.swift b/test/SourceKit/InterfaceGen/gen_swift_type.swift
index 1422d41..a068083 100644
--- a/test/SourceKit/InterfaceGen/gen_swift_type.swift
+++ b/test/SourceKit/InterfaceGen/gen_swift_type.swift
@@ -5,6 +5,8 @@
 // RUN: %sourcekitd-test -req=interface-gen -usr _TtGC14gen_swift_type1DCS_2T1_ %s -- %s | %FileCheck -check-prefix=CHECK5 %s
 // RUN: %sourcekitd-test -req=interface-gen -usr _TtGC14gen_swift_type1DSi_ %s -- %s | %FileCheck -check-prefix=CHECK6 %s
 
+// REQUIRES: rdar35799113
+
 public struct A {
 	public func fa() {}
 }
diff --git a/test/SourceKit/Refactoring/syntactic-rename.swift b/test/SourceKit/Refactoring/syntactic-rename.swift
index bf818ab..2e2d160 100644
--- a/test/SourceKit/Refactoring/syntactic-rename.swift
+++ b/test/SourceKit/Refactoring/syntactic-rename.swift
@@ -69,10 +69,10 @@
 
 struct Memberwise2 {
   let m: Memberwise1
-  let n: Memberwise1
+  let n: Memberwise1; subscript(x: Int) -> Int { return x }
 }
 
-_ = Memberwise2(m: Memberwise1(x: 1), n: Memberwise1.init(x: 2))
+_ = Memberwise2(m: Memberwise1(x: 1), n: Memberwise1.init(x: 2))[1]
 
 protocol Layer {
   associatedtype Content
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 49b9194..effefd5 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -74,3 +74,15 @@
   }</MemberDeclBlock>
   struct foo <MemberDeclBlock>{}</MemberDeclBlock>
 }</MemberDeclBlock>
+
+struct foo <MemberDeclBlock>{<Attribute>
+  @available(*, unavailable)</Attribute>
+  struct foo <MemberDeclBlock>{}</MemberDeclBlock><DeclModifier>
+  public </DeclModifier>class foo {<Attribute>
+    @available(*, unavailable)</Attribute><Attribute>
+    @objc(fooObjc)</Attribute><DeclModifier>
+    private </DeclModifier><DeclModifier>static </DeclModifier>func foo() <CodeBlock>{}</CodeBlock>
+  }
+}</MemberDeclBlock>
+
+struct S<A, B, C, D> <GenericWhereClause>where <ConformanceRequirement><SimpleTypeIdentifier>A</SimpleTypeIdentifier>:<SimpleTypeIdentifier>B</SimpleTypeIdentifier>, </ConformanceRequirement><SameTypeRequirement><SimpleTypeIdentifier>B</SimpleTypeIdentifier>==<SimpleTypeIdentifier>C</SimpleTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><SimpleTypeIdentifier>A </SimpleTypeIdentifier>: <SimpleTypeIdentifier>C</SimpleTypeIdentifier>, </ConformanceRequirement><SameTypeRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>B</SimpleTypeIdentifier>.C </MemberTypeIdentifier>== <MemberTypeIdentifier><SimpleTypeIdentifier>D</SimpleTypeIdentifier>.A</MemberTypeIdentifier>, </SameTypeRequirement><ConformanceRequirement><MemberTypeIdentifier><SimpleTypeIdentifier>A</SimpleTypeIdentifier>.B</MemberTypeIdentifier>: <MemberTypeIdentifier><SimpleTypeIdentifier>C</SimpleTypeIdentifier>.D </MemberTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{}</MemberDeclBlock>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 55a9dab..06da77e 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -74,3 +74,15 @@
   }
   struct foo {}
 }
+
+struct foo {
+  @available(*, unavailable)
+  struct foo {}
+  public class foo {
+    @available(*, unavailable)
+    @objc(fooObjc)
+    private static func foo() {}
+  }
+}
+
+struct S<A, B, C, D> where A:B, B==C, A : C, B.C == D.A, A.B: C.D {}
diff --git a/test/decl/objc_redeclaration.swift b/test/decl/objc_redeclaration.swift
index 27c5bd6..3250bc3 100644
--- a/test/decl/objc_redeclaration.swift
+++ b/test/decl/objc_redeclaration.swift
@@ -57,7 +57,7 @@
 }
 
 extension DummyClass {
-  func nsstringProperty2() -> Int { return 0 } // expected-error{{method 'nsstringProperty2()' with Objective-C selector 'nsstringProperty2' conflicts with previous declaration with the same Objective-C selector}}
+  func nsstringProperty2() -> Int { return 0 } // expected-error{{method 'nsstringProperty2()' with Objective-C selector 'nsstringProperty2' conflicts with getter for 'nsstringProperty2' with the same Objective-C selector}}
 }
 
 // FIXME: Remove -verify-ignore-unknown.
diff --git a/test/decl/typealias/protocol.swift b/test/decl/typealias/protocol.swift
index 856863a..e625f23 100644
--- a/test/decl/typealias/protocol.swift
+++ b/test/decl/typealias/protocol.swift
@@ -245,3 +245,10 @@
 // Edible.Snack is witnessed by 'typealias Snack' inside the
 // constrained extension of CandyWrapper above
 extension CandyBar : Edible {}
+
+protocol P9 {
+  typealias A = Int
+}
+
+func testT9a<T: P9, U>(_: T, _: U) where T.A == U { }
+func testT9b<T: P9>(_: T) where T.A == Float { } // expected-error{{'T.A' cannot be equal to both 'Float' and 'P9.A' (aka 'Int')}}
diff --git a/test/stdlib/DoubleWidth.swift b/test/stdlib/DoubleWidth.swift
index d6d874e..7103e9c 100644
--- a/test/stdlib/DoubleWidth.swift
+++ b/test/stdlib/DoubleWidth.swift
@@ -1,5 +1,7 @@
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
+// FIXME(double-width): <rdar://problem/32726173>
+// REQUIRES: rdar32726173
 
 import StdlibUnittest
 
diff --git a/test/stdlib/Inputs/DictionaryKeyValueTypes.swift b/test/stdlib/Inputs/DictionaryKeyValueTypes.swift
index e951b82..9fd935a 100644
--- a/test/stdlib/Inputs/DictionaryKeyValueTypes.swift
+++ b/test/stdlib/Inputs/DictionaryKeyValueTypes.swift
@@ -25,6 +25,31 @@
   return lhs.sorted().elementsEqual(rhs.sorted())
 }
 
+// A COW wrapper type that holds an Int.
+struct TestValueCOWTy {
+  
+  class Base {
+    var value: Int
+    init(_ value: Int) { self.value = value }
+  }
+
+  private var base: Base
+  init(_ value: Int = 0) { self.base = Base(value) }
+
+  var value: Int {
+    get { return base.value }
+    set {
+      if !isKnownUniquelyReferenced(&base) {
+        base = Base(newValue)
+      } else {
+        base.value = newValue
+      }
+    }
+  }
+
+  var baseAddress: Int { return unsafeBitCast(base, to: Int.self) }
+}
+
 var _keyCount = _stdlib_AtomicInt(0)
 var _keySerial = _stdlib_AtomicInt(0)
 
diff --git a/test/stdlib/Integers.swift.gyb b/test/stdlib/Integers.swift.gyb
index 330047d..c3addef 100644
--- a/test/stdlib/Integers.swift.gyb
+++ b/test/stdlib/Integers.swift.gyb
@@ -524,7 +524,7 @@
   expectEqualSequence([(1 as UInt) << 63], Int64.min.words)
   expectEqualSequence([UInt.max], (-1 as Int64).words)
 % else:
-  expectEqualSequence([UInt.max, UInt.max], Int64.max.words)
+  expectEqualSequence([UInt.max, UInt.max], UInt64.max.words)
   expectEqualSequence([0 as UInt, 0], UInt64.min.words)
   expectEqualSequence([UInt.max, UInt.max >> 1], Int64.max.words)
   expectEqualSequence([0 as UInt, 1 << 31], Int64.min.words)
diff --git a/test/stdlib/LazySlice.swift b/test/stdlib/LazySlice.swift
new file mode 100644
index 0000000..9580d18
--- /dev/null
+++ b/test/stdlib/LazySlice.swift
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t ; mkdir -p %t
+// RUN: %target-build-swift %s -o %t/a.out3 -swift-version 3 && %target-run %t/a.out3
+// REQUIRES: executable_test
+
+import StdlibUnittest
+
+var tests = TestSuite("LazySlice")
+
+tests.test("CommuteLazyness") {
+  let a = [1,2,3].lazy
+  let b = a[...]
+  var c = b.filter { $0 == 0 }
+  // NOTE, this test will fail once lazy collectionness becomes a conditiona
+  // conformance, and will need updating to be a LazyBidirectional thingy
+  expectType(LazyFilterBidirectionalCollection<Slice<LazyRandomAccessCollection<[Int]>>>.self, &c)
+}
+
+runAllTests()
diff --git a/test/stdlib/Runtime.swift.gyb b/test/stdlib/Runtime.swift.gyb
index 667c4de..6b1a0be 100644
--- a/test/stdlib/Runtime.swift.gyb
+++ b/test/stdlib/Runtime.swift.gyb
@@ -38,7 +38,7 @@
 
     if let demangledNamePtr = demangledNamePtr {
       let demangledName = String(cString: demangledNamePtr)
-      _swift_stdlib_free(demangledNamePtr)
+      _stdlib_free(demangledNamePtr)
       return demangledName
     }
     return mangledName
diff --git a/test/stdlib/TestNSNumberBridging.swift b/test/stdlib/TestNSNumberBridging.swift
index 489261a..208889c 100644
--- a/test/stdlib/TestNSNumberBridging.swift
+++ b/test/stdlib/TestNSNumberBridging.swift
@@ -19,63 +19,17 @@
 // REQUIRES: executable_test
 // REQUIRES: objc_interop
 
+// FIXME: rdar://35814988
+// UNSUPPORTED: CPU=armv7
+// UNSUPPORTED: CPU=armv7s
+// UNSUPPORTED: CPU=armv7k
+// UNSUPPORTED: CPU=arm64
+
 import StdlibUnittest
 import Foundation
 import CoreGraphics
 import FoundationBridgeObjC
 
-extension Float {
-    init?(reasonably value: Float) {
-        self = value
-    }
-
-    init?(reasonably value: Double) {
-        guard !value.isNaN else {
-            self = Float.nan
-            return
-        }
-
-        guard !value.isInfinite else {
-            if value.sign == .minus {
-                self = -Float.infinity
-            } else {
-                self = Float.infinity
-            }
-            return
-        }
-
-        guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
-            return nil
-        }
-        
-        self = Float(value)
-    }
-}
-
-extension Double {
-    init?(reasonably value: Float) {
-        guard !value.isNaN else {
-            self = Double.nan
-            return
-        }
-
-        guard !value.isInfinite else {
-            if value.sign == .minus {
-                self = -Double.infinity
-            } else {
-                self = Double.infinity
-            }
-            return
-        }
-
-        self = Double(value)
-    }
-
-    init?(reasonably value: Double) {
-        self = value
-    }
-}
-
 var nsNumberBridging = TestSuite("NSNumberBridging")
 
 func testFloat(_ lhs: Float?, _ rhs: Float?, file: String = #file, line: UInt = #line) {
@@ -476,12 +430,7 @@
             
             let float = (number!) as? Float
             let expectedFloat = Float(exactly: int32!)
-            // these are disabled because of https://bugs.swift.org/browse/SR-4634
-            if (int32! != Int32.min && int32! != Int32.max &&
-                int32! != Int32.min + 1 && int32! != Int32.max - 1) {
-                testFloat(expectedFloat, float)
-            }
-            
+            testFloat(expectedFloat, float)
             
             let double = (number!) as? Double
             let expectedDouble = Double(int32!)
@@ -520,12 +469,9 @@
             expectEqual(UInt(exactly: interestingValue), uint)
             
             let float = (number!) as? Float
-            let expectedFloat = Float(uint32!)
-            // these are disabled because of https://bugs.swift.org/browse/SR-4634
-            if (uint32! != UInt32.max && uint32! != UInt32.max - UInt32(1)) {
-                testFloat(expectedFloat, float)
-            }
-            
+            let expectedFloat = Float(exactly: uint32!)
+            testFloat(expectedFloat, float)
+          
             let double = (number!) as? Double
             let expectedDouble = Double(uint32!)
             testDouble(expectedDouble, double)
@@ -703,12 +649,22 @@
             expectEqual(UInt(exactly: interestingValue), uint)
 
             let float = (number!) as? Float
-            let expectedFloat = Float(reasonably: interestingValue)
-            testFloat(expectedFloat, float)
+            let expectedFloat = Float(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(float?.isNaN == true)
+                expectNil(expectedFloat)
+            } else {
+                testFloat(expectedFloat, float)
+            }
             
             let double = (number!) as? Double
-            let expectedDouble = Double(interestingValue)
-            testDouble(expectedDouble, double)
+            let expectedDouble = Double(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(double?.isNaN == true)
+                expectNil(expectedDouble)
+            } else {
+                testDouble(expectedDouble, double)
+            }
         }
         let bridged = interestingValue as NSNumber
         testNumber(bridged)
@@ -743,12 +699,22 @@
             expectEqual(UInt(exactly: interestingValue), uint)
 
             let float = (number!) as? Float
-            let expectedFloat = Float(reasonably: interestingValue)
-            testFloat(expectedFloat, float)
+            let expectedFloat = Float(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(float?.isNaN == true)
+                expectNil(expectedFloat)
+            } else {
+                testFloat(expectedFloat, float)
+            }
             
             let double = (number!) as? Double
-            let expectedDouble = interestingValue
-            testDouble(expectedDouble, double)
+            let expectedDouble = Double(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(double?.isNaN == true)
+                expectNil(expectedDouble)
+            } else {
+                testDouble(expectedDouble, double)
+            }
         }
         let bridged = interestingValue as NSNumber
         testNumber(bridged)
@@ -783,12 +749,22 @@
             expectEqual(UInt(exactly: interestingValue.native), uint)
             
             let float = (number!) as? Float
-            let expectedFloat = Float(reasonably: interestingValue.native)
-            testFloat(expectedFloat, float)
+            let expectedFloat = Float(exactly: interestingValue.native)
+            if interestingValue.isNaN {
+                expectTrue(float?.isNaN == true)
+                expectNil(expectedFloat)
+            } else {
+                testFloat(expectedFloat, float)
+            }
             
             let double = (number!) as? Double
-            let expectedDouble = Double(interestingValue)
-            testDouble(expectedDouble, double)
+            let expectedDouble = Double(exactly: interestingValue.native)
+            if interestingValue.isNaN {
+                expectTrue(double?.isNaN == true)
+                expectNil(expectedDouble)
+            } else {
+                testDouble(expectedDouble, double)
+            }
         }
         let bridged = interestingValue as NSNumber
         testNumber(bridged)
diff --git a/test/stmt/foreach.swift b/test/stmt/foreach.swift
index 6b89f7c..12df84c 100644
--- a/test/stmt/foreach.swift
+++ b/test/stmt/foreach.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -enable-experimental-conditional-conformances
 
 // Bad containers and ranges
 struct BadContainer1 {
@@ -178,3 +178,42 @@
     _ = x
   }
 }
+
+// Conditional conformance to Sequence and IteratorProtocol.
+protocol P { }
+
+struct RepeatedSequence<T> {
+  var value: T
+  var count: Int
+}
+
+struct RepeatedIterator<T> {
+  var value: T
+  var count: Int
+}
+
+extension RepeatedIterator: IteratorProtocol where T: P {
+  typealias Element = T
+
+  mutating func next() -> T? {
+    if count == 0 { return nil }
+    count = count - 1
+    return value
+  }
+}
+
+extension RepeatedSequence: Sequence where T: P {
+  typealias Element = T
+  typealias Iterator = RepeatedIterator<T>
+  typealias SubSequence = AnySequence<T>
+
+  func makeIterator() -> RepeatedIterator<T> {
+    return Iterator(value: value, count: count)
+  }
+}
+
+extension Int : P { }
+
+func testRepeated(ri: RepeatedSequence<Int>) {
+  for x in ri { _ = x }
+}
diff --git a/test/type/protocol_composition.swift b/test/type/protocol_composition.swift
index 0d9e2c2..aa49e39 100644
--- a/test/type/protocol_composition.swift
+++ b/test/type/protocol_composition.swift
@@ -139,15 +139,15 @@
 typealias F = protocol<Any, Any> // expected-error {{'protocol<...>' composition syntax has been removed and is not needed here}} {{15-33=Any}}
 typealias G = protocol<P1>.Type // expected-error {{'protocol<...>' composition syntax has been removed and is not needed here}} {{15-27=P1}}
 typealias H = protocol<P1>! // expected-error {{'protocol<...>' composition syntax has been removed and is not needed here}} {{15-28=P1!}}
-// expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}
+// expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}
 typealias J = protocol<P1, P2>.Protocol // expected-error {{'protocol<...>' composition syntax has been removed; join the protocols using '&'}} {{15-31=(P1 & P2)}}
 typealias K = protocol<P1, P2>? // expected-error {{'protocol<...>' composition syntax has been removed; join the protocols using '&'}} {{15-32=(P1 & P2)?}}
 
 typealias T01 = P1.Protocol & P2 // expected-error {{non-protocol, non-class type 'P1.Protocol' cannot be used within a protocol-constrained type}}
 typealias T02 = P1.Type & P2 // expected-error {{non-protocol, non-class type 'P1.Type' cannot be used within a protocol-constrained type}}
 typealias T03 = P1? & P2 // expected-error {{non-protocol, non-class type 'P1?' cannot be used within a protocol-constrained type}}
-typealias T04 = P1 & P2! // expected-error {{non-protocol, non-class type 'P2?' cannot be used within a protocol-constrained type}}
-// expected-warning@-1 {{'!' is not allowed here; interpreting this as '?' instead}}
+typealias T04 = P1 & P2! // expected-error {{non-protocol, non-class type 'P2!' cannot be used within a protocol-constrained type}}
+// expected-warning@-1 {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}
 typealias T05 = P1 & P2 -> P3 // expected-error {{single argument function types require parentheses}} {{17-17=(}} {{24-24=)}}
 typealias T06 = P1 -> P2 & P3 // expected-error {{single argument function types require parentheses}} {{17-17=(}} {{19-19=)}}
 typealias T07 = P1 & protocol<P2, P3> // expected-error {{protocol<...>' composition syntax has been removed; join the protocols using '&'}} {{22-38=P2 & P3}}
diff --git a/test/type/types.swift b/test/type/types.swift
index de9b136..5d16cef 100644
--- a/test/type/types.swift
+++ b/test/type/types.swift
@@ -152,7 +152,7 @@
 let dictWithTuple = [String: (age:Int, count:Int)]()
 
 // <rdar://problem/21684837> typeexpr not being formed for postfix !
-let bb2 = [Int!](repeating: nil, count: 2) // expected-warning {{'!' is not allowed here; interpreting this as '?' instead}}
+let bb2 = [Int!](repeating: nil, count: 2) // expected-warning {{using '!' in this location is deprecated and will be removed in a future release; consider changing this to '?' instead}}
 
 // <rdar://problem/21560309> inout allowed on function return type
 func r21560309<U>(_ body: (_: inout Int) -> inout U) {}  // expected-error {{'inout' may only be used on parameters}}
diff --git a/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h b/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h
index 5140eb1..edfaae6 100644
--- a/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h
+++ b/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h
@@ -120,7 +120,8 @@
   }
 
   operator llvm::IntrusiveRefCntPtr<T>() const {
-    llvm::sys::ScopedLock L(*getMutex((void*)this));
+    llvm::sys::ScopedLock L(*getMutex(
+        reinterpret_cast<void *>(const_cast<ThreadSafeRefCntPtr *>(this))));
     llvm::IntrusiveRefCntPtr<T> Ref(Obj.load());
     return Ref;
   }
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
index 0d16d95..ab2283e 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
@@ -83,7 +83,7 @@
     // Assert invocation with a primary file. We want to avoid full typechecking
     // for all files.
     assert(!this->PrimaryFile.empty());
-    assert(this->Invok.getFrontendOptions().Inputs.haveUniquePrimaryInput() &&
+    assert(this->Invok.getFrontendOptions().Inputs.hasUniquePrimaryInput() &&
            "Must have exactly one primary input for code completion, etc.");
   }
 
@@ -355,7 +355,7 @@
 
   StringRef Filename = Invocation.getOutputFilename();
   if (Filename.empty()) {
-    if (!Invocation.getFrontendOptions().Inputs.haveInputFilenames()) {
+    if (!Invocation.getFrontendOptions().Inputs.hasInputFilenames()) {
       Invocation.setModuleName("__main__");
       return;
     }
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
index 2b6795c..501641f 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
@@ -144,7 +144,7 @@
   if (Failed) {
     return false;
   }
-  if (!Invocation.getFrontendOptions().Inputs.haveInputFilenames()) {
+  if (!Invocation.getFrontendOptions().Inputs.hasInputFilenames()) {
     Error = "no input filenames specified";
     return false;
   }
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
index 6d63d6b..640ce9b 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
@@ -391,8 +391,10 @@
     if (auto *VD = dyn_cast<ValueDecl>(D)) {
       llvm::raw_svector_ostream OS(Info.FullyAnnotatedDecl);
       if (SynthesizedTarget)
-        SwiftLangSupport::printFullyAnnotatedSynthesizedDeclaration(VD,
-          (NominalTypeDecl*)SynthesizedTarget, OS);
+        SwiftLangSupport::printFullyAnnotatedSynthesizedDeclaration(
+            VD, const_cast<NominalTypeDecl *>(
+                    static_cast<const NominalTypeDecl *>(SynthesizedTarget)),
+            OS);
       else
         SwiftLangSupport::printFullyAnnotatedDeclaration(VD, Type(), OS);
     }
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp b/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
index a4018bd..918bbf7 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp
@@ -279,7 +279,7 @@
     return;
   }
 
-  if (!Invocation.getFrontendOptions().Inputs.haveInputFilenames()) {
+  if (!Invocation.getFrontendOptions().Inputs.hasInputFilenames()) {
     IdxConsumer.failed("no input filenames specified");
     return;
   }
diff --git a/tools/driver/modulewrap_main.cpp b/tools/driver/modulewrap_main.cpp
index 9742b27..397a394 100644
--- a/tools/driver/modulewrap_main.cpp
+++ b/tools/driver/modulewrap_main.cpp
@@ -43,7 +43,7 @@
   std::vector<std::string> InputFilenames;
 
 public:
-  bool haveUniqueInputFilename() const { return InputFilenames.size() == 1; }
+  bool hasUniqueInputFilename() const { return InputFilenames.size() == 1; }
   const std::string &getFilenameOfFirstInput() const {
     return InputFilenames[0];
   }
@@ -131,7 +131,7 @@
     return 1;
   }
 
-  if (!Invocation.haveUniqueInputFilename()) {
+  if (!Invocation.hasUniqueInputFilename()) {
     Instance.getDiags().diagnose(SourceLoc(),
                                  diag::error_mode_requires_one_input_file);
     return 1;
diff --git a/unittests/Parse/LexerTests.cpp b/unittests/Parse/LexerTests.cpp
index 7d3f1dc..31a2903 100644
--- a/unittests/Parse/LexerTests.cpp
+++ b/unittests/Parse/LexerTests.cpp
@@ -260,6 +260,55 @@
   ASSERT_EQ(tok::eof, Tok.getKind());
 }
 
+TEST_F(LexerTest, RestoreWithTrivia) {
+  using namespace swift::syntax;
+  StringRef SourceStr = "aaa \n bbb /*C*/ccc";
+
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(SourceStr);
+
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::AttachToNextToken,
+          TriviaRetentionMode::WithTrivia);
+
+  Token Tok;
+  Trivia LeadingTrivia, TrailingTrivia;
+
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_TRUE(Tok.isAtStartOfLine());
+  ASSERT_EQ(LeadingTrivia, Trivia());
+  ASSERT_EQ(TrailingTrivia, (Trivia{{TriviaPiece::spaces(1)}}));
+
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("bbb", Tok.getText());
+  ASSERT_TRUE(Tok.isAtStartOfLine());
+  ASSERT_EQ(LeadingTrivia,
+            (Trivia{{TriviaPiece::newlines(1), TriviaPiece::spaces(1)}}));
+  ASSERT_EQ(TrailingTrivia, (Trivia{{TriviaPiece::spaces(1)}}));
+
+  Lexer::State S = L.getStateForBeginningOfToken(Tok, LeadingTrivia);
+
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("ccc", Tok.getText());
+  ASSERT_FALSE(Tok.isAtStartOfLine());
+  ASSERT_EQ(LeadingTrivia, (Trivia{{TriviaPiece::blockComment("/*C*/")}}));
+  ASSERT_EQ(TrailingTrivia, Trivia());
+
+  L.restoreState(S);
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("bbb", Tok.getText());
+  ASSERT_TRUE(Tok.isAtStartOfLine());
+  ASSERT_EQ(LeadingTrivia,
+            (Trivia{{TriviaPiece::newlines(1), TriviaPiece::spaces(1)}}));
+  ASSERT_EQ(TrailingTrivia, (Trivia{{TriviaPiece::spaces(1)}}));
+}
+
 TEST_F(LexerTest, getLocForStartOfToken) {
   const char *Source = "aaa \n \tbbb \"hello\" \"-\\(val)-\"";
 
diff --git a/unittests/Parse/TokenizerTests.cpp b/unittests/Parse/TokenizerTests.cpp
index 7ddc78e..42b8166 100644
--- a/unittests/Parse/TokenizerTests.cpp
+++ b/unittests/Parse/TokenizerTests.cpp
@@ -155,7 +155,7 @@
      "integer_literal: 100\n"
      "r_brace: }\n"
      "kw_func: func\n"
-     "identifier: ⊕\n"
+     "oper_binary_spaced: ⊕\n"
      "oper_binary_unspaced: <\n"
      "identifier: T\n"
      "oper_binary_unspaced: >\n"
diff --git a/unittests/Syntax/DeclSyntaxTests.cpp b/unittests/Syntax/DeclSyntaxTests.cpp
index 5e737c8..15c1c70 100644
--- a/unittests/Syntax/DeclSyntaxTests.cpp
+++ b/unittests/Syntax/DeclSyntaxTests.cpp
@@ -17,7 +17,8 @@
   auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
   auto Set = SyntaxFactory::makeIdentifier("set", {}, {});
   auto RParen = SyntaxFactory::makeRightParenToken({}, {});
-  return SyntaxFactory::makeDeclModifier(Private, LParen, Set, RParen);
+  return SyntaxFactory::makeDeclModifier(Private,
+    SyntaxFactory::makeTokenList({ LParen, Set, RParen}));
 }
 
 TEST(DeclSyntaxTests, DeclModifierMakeAPIs) {
@@ -40,12 +41,13 @@
   auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
   auto Set = SyntaxFactory::makeIdentifier("set", {}, {});
   auto RParen = SyntaxFactory::makeRightParenToken({}, {});
-  auto Mod = SyntaxFactory::makeDeclModifier(Private, LParen, Set, RParen);
+  auto Mod = SyntaxFactory::makeDeclModifier(Private,
+    SyntaxFactory::makeTokenList({LParen, Set, RParen}));
 
   ASSERT_EQ(Private.getRaw(), Mod.getName().getRaw());
-  ASSERT_EQ(LParen.getRaw(), Mod.getLeftParen()->getRaw());
-  ASSERT_EQ(Set.getRaw(), Mod.getArgument()->getRaw());
-  ASSERT_EQ(RParen.getRaw(), Mod.getRightParen()->getRaw());
+  ASSERT_EQ(LParen.getRaw(), Mod.getDetail()[0].getRaw());
+  ASSERT_EQ(Set.getRaw(), Mod.getDetail()[1].getRaw());
+  ASSERT_EQ(RParen.getRaw(), Mod.getDetail()[2].getRaw());
 }
 
 TEST(DeclSyntaxTests, DeclModifierWithAPIs) {
@@ -58,9 +60,7 @@
   llvm::raw_svector_ostream OS(Scratch);
   SyntaxFactory::makeBlankDeclModifier()
     .withName(Private)
-    .withLeftParen(LParen)
-    .withArgument(Set)
-    .withRightParen(RParen)
+    .withDetail(SyntaxFactory::makeTokenList({LParen, Set, RParen}))
     .print(OS);
   ASSERT_EQ(OS.str().str(), "private(set)");
 }
@@ -480,12 +480,12 @@
   auto NoLParen = TokenSyntax::missingToken(tok::l_paren, "(");
   auto NoArgument = TokenSyntax::missingToken(tok::identifier, "");
   auto NoRParen = TokenSyntax::missingToken(tok::r_paren, ")");
-  auto Public = SyntaxFactory::makeDeclModifier(PublicID, NoLParen, NoArgument,
-                                                NoRParen);
+  auto Public = SyntaxFactory::makeDeclModifier(PublicID,
+    SyntaxFactory::makeTokenList({NoLParen, NoArgument, NoRParen}));
 
   auto StaticKW = SyntaxFactory::makeStaticKeyword({}, Trivia::spaces(1));
-  auto Static = SyntaxFactory::makeDeclModifier(StaticKW, NoLParen, NoArgument,
-                                                NoRParen);
+  auto Static = SyntaxFactory::makeDeclModifier(StaticKW,
+    SyntaxFactory::makeTokenList({NoLParen, NoArgument, NoRParen}));
 
   return SyntaxFactory::makeBlankModifierList()
     .appending(Public)
diff --git a/unittests/Syntax/TypeSyntaxTests.cpp b/unittests/Syntax/TypeSyntaxTests.cpp
index 40762ea..b3f6009 100644
--- a/unittests/Syntax/TypeSyntaxTests.cpp
+++ b/unittests/Syntax/TypeSyntaxTests.cpp
@@ -19,7 +19,7 @@
     llvm::raw_svector_ostream OS { Scratch };
     auto Autoclosure = SyntaxFactory::makeBlankAttribute()
       .withAtSignToken(At)
-      .withIdentifier(AutoclosureID);
+      .withAttributeName(AutoclosureID);
     Autoclosure.print(OS);
     ASSERT_EQ(OS.str().str(), "@autoclosure");
   }
@@ -31,15 +31,14 @@
 
     auto Convention = SyntaxFactory::makeBlankAttribute()
       .withAtSignToken(At)
-      .withIdentifier(conventionID)
-      .withLeftParen(LeftParen)
-      .withRightParen(RightParen);
+      .withAttributeName(conventionID)
+      .withBalancedTokens(SyntaxFactory::makeTokenList({LeftParen, RightParen}));
 
     {
       SmallString<48> Scratch;
       llvm::raw_svector_ostream OS { Scratch };
       auto cID = SyntaxFactory::makeIdentifier("c", {}, {});
-      auto cArgs = SyntaxFactory::makeTokenList({cID});
+      auto cArgs = SyntaxFactory::makeTokenList({LeftParen, cID, RightParen});
       Convention.withBalancedTokens(cArgs).print(OS);
       ASSERT_EQ(OS.str().str(), "@convention(c)");
     }
@@ -48,7 +47,7 @@
       SmallString<48> Scratch;
       llvm::raw_svector_ostream OS { Scratch };
       auto swiftID = SyntaxFactory::makeIdentifier("swift", {}, {});
-      auto swiftArgs = SyntaxFactory::makeTokenList({swiftID});
+      auto swiftArgs = SyntaxFactory::makeTokenList({LeftParen, swiftID, RightParen});
       Convention.withBalancedTokens(swiftArgs).print(OS);
       ASSERT_EQ(OS.str().str(), "@convention(swift)");
     }
@@ -57,7 +56,7 @@
       SmallString<48> Scratch;
       llvm::raw_svector_ostream OS { Scratch };
       auto blockID = SyntaxFactory::makeIdentifier("block", {}, {});
-      auto blockArgs = SyntaxFactory::makeTokenList({blockID});
+      auto blockArgs = SyntaxFactory::makeTokenList({LeftParen, blockID, RightParen});
       Convention.withBalancedTokens(blockArgs).print(OS);
       ASSERT_EQ(OS.str().str(), "@convention(block)");
     }
@@ -69,7 +68,7 @@
     auto EscapingID = SyntaxFactory::makeIdentifier("escaping", {}, {});
     auto Escaping = SyntaxFactory::makeBlankAttribute()
       .withAtSignToken(At)
-      .withIdentifier(EscapingID);
+      .withAttributeName(EscapingID);
     Escaping.print(OS);
     ASSERT_EQ(OS.str().str(), "@escaping");
   }
@@ -83,7 +82,7 @@
     llvm::raw_svector_ostream OS { Scratch };
     auto Autoclosure = SyntaxFactory::makeBlankAttribute()
     .withAtSignToken(At)
-    .withIdentifier(AutoclosureID);
+    .withAttributeName(AutoclosureID);
     Autoclosure.print(OS);
     ASSERT_EQ(OS.str().str(), "@autoclosure");
   }
@@ -97,9 +96,8 @@
       SmallString<48> Scratch;
       llvm::raw_svector_ostream OS { Scratch };
       auto cID = SyntaxFactory::makeIdentifier("c", {}, {});
-      auto cArgs = SyntaxFactory::makeTokenList({cID});
-      SyntaxFactory::makeAttribute(At, conventionID, LeftParen, cArgs,
-                                   RightParen)
+      auto cArgs = SyntaxFactory::makeTokenList({LeftParen, cID, RightParen});
+      SyntaxFactory::makeAttribute(At, conventionID, cArgs)
         .print(OS);
       ASSERT_EQ(OS.str().str(), "@convention(c)");
     }
@@ -108,9 +106,9 @@
       SmallString<48> Scratch;
       llvm::raw_svector_ostream OS { Scratch };
       auto swiftID = SyntaxFactory::makeIdentifier("swift", {}, {});
-      auto swiftArgs = SyntaxFactory::makeTokenList({swiftID});
-      SyntaxFactory::makeAttribute(At, conventionID, LeftParen,
-                                   swiftArgs, RightParen)
+      auto swiftArgs = SyntaxFactory::makeTokenList({LeftParen, swiftID,
+        RightParen});
+      SyntaxFactory::makeAttribute(At, conventionID, swiftArgs)
         .print(OS);
       ASSERT_EQ(OS.str().str(), "@convention(swift)");
     }
@@ -119,9 +117,9 @@
       SmallString<48> Scratch;
       llvm::raw_svector_ostream OS { Scratch };
       auto blockID = SyntaxFactory::makeIdentifier("block", {}, {});
-      auto blockArgs = SyntaxFactory::makeTokenList({blockID});
-      SyntaxFactory::makeAttribute(At, conventionID, LeftParen,
-                                   blockArgs,RightParen)
+      auto blockArgs = SyntaxFactory::makeTokenList({LeftParen, blockID,
+        RightParen});
+      SyntaxFactory::makeAttribute(At, conventionID, blockArgs)
         .print(OS);
       ASSERT_EQ(OS.str().str(), "@convention(block)");
     }
@@ -133,7 +131,7 @@
     auto EscapingID = SyntaxFactory::makeIdentifier("escaping", {}, {});
     auto Escaping = SyntaxFactory::makeBlankAttribute()
       .withAtSignToken(At)
-      .withIdentifier(EscapingID);
+      .withAttributeName(EscapingID);
     Escaping.print(OS);
     ASSERT_EQ(OS.str().str(), "@escaping");
   }
diff --git a/unittests/runtime/Stdlib.cpp b/unittests/runtime/Stdlib.cpp
index 09fd844..cd59fba 100644
--- a/unittests/runtime/Stdlib.cpp
+++ b/unittests/runtime/Stdlib.cpp
@@ -121,6 +121,22 @@
 }
 
 SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+void _bridgeNonVerbatimBoxedValue(const OpaqueValue *sourceValue,
+                                  OpaqueValue *destValue,
+                                  const Metadata *nativeType) {
+  abort();
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+void _bridgeNonVerbatimFromObjectiveCToAny(HeapObject *sourceValue,
+                                           OpaqueValue *destValue) {
+  abort();
+}
+
+
+// ErrorObject
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 int _T0s13_getErrorCodeSiSPyxGs0B0RzlF(void *) {
   abort();
 }
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index b09a1d2..fbd4996 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -517,6 +517,9 @@
 # Set the vendor to apple
 compiler-vendor=apple
 
+# Build LLDB
+lldb
+
 dash-dash
 
 # Always reconfigure cmake
@@ -542,10 +545,15 @@
 skip-test-tvos
 skip-build-watchos
 skip-test-watchos
+skip-test-lldb
 stdlib-deployment-targets=macosx-x86_64
 swift-primary-variant-sdk=OSX
 swift-primary-variant-arch=x86_64
 
+lldb-no-debugserver
+lldb-use-system-debugserver
+lldb-build-type=Release
+
 # Don't build the benchmarks
 skip-build-benchmarks
 
diff --git a/utils/gyb_syntax_support/AttributeNodes.py b/utils/gyb_syntax_support/AttributeNodes.py
index 832f824..6825b5e 100644
--- a/utils/gyb_syntax_support/AttributeNodes.py
+++ b/utils/gyb_syntax_support/AttributeNodes.py
@@ -10,12 +10,9 @@
     Node('Attribute', kind='Syntax',
          children=[
              Child('AtSignToken', kind='AtSignToken'),
-             Child('Identifier', kind='IdentifierToken'),
-             Child('LeftParen', kind='LeftParenToken',
-                   is_optional=True),
+             Child('AttributeName', kind='Token'),
+             # FIXME: more structure
              Child('BalancedTokens', kind='TokenList'),
-             Child('RightParen', kind='RightParenToken',
-                   is_optional=True),
          ]),
 
     # attribute-list -> attribute attribute-list?
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index 979be6a..a361952 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -78,15 +78,7 @@
                        'fileprivate', 'internal', 'public', 'open',
                        'mutating', 'nonmutating',
                    ]),
-             Child('LeftParen', kind='LeftParenToken',
-                   is_optional=True),
-             Child('Argument', kind='IdentifierToken',
-                   is_optional=True,
-                   text_choices=[
-                       'unowned', 'safe', 'unsafe', 'set',
-                   ]),
-             Child('RightParen', kind='RightParenToken',
-                   is_optional=True),
+             Child('Detail', kind='TokenList'),
          ]),
 
     # type-inheritance-clause -> ':' type
diff --git a/utils/resolve-crashes.py b/utils/resolve-crashes.py
index 0348041..19d8449 100755
--- a/utils/resolve-crashes.py
+++ b/utils/resolve-crashes.py
@@ -35,16 +35,21 @@
         git_mv_cmd = 'git mv %s %s' % (from_filename, to_filename)
         execute_cmd(git_mv_cmd)
 
-        # Replace "not --crash" with "not", and remove XFAIL lines.
+        # Replace "not --crash" with "not".
         sed_replace_not_cmd = 'sed -e "s/not --crash/not/" -i "" %s' % (
             to_filename)
         execute_cmd(sed_replace_not_cmd)
 
         # Remove "// XFAIL: whatever" lines.
-        sed_remove_xfail_cmd = 'sed -e "s/^\\/\\/.*XFAIL.*$//g" -i "" %s' % (
+        sed_remove_xfail_cmd = 'sed -e "s|^//.*XFAIL.*$||g" -i "" %s' % (
             to_filename)
         execute_cmd(sed_remove_xfail_cmd)
 
+        # Remove "// REQUIRES: asserts" lines.
+        sed_remove_requires_asserts_cmd = \
+            'sed -e "s|^//.*REQUIRES: asserts.*$||g" -i "" %s' % (to_filename)
+        execute_cmd(sed_remove_requires_asserts_cmd)
+
         # "git add" the result.
         git_add_cmd = 'git add %s' % (to_filename)
         execute_cmd(git_add_cmd)
diff --git a/validation-test/SIL/crashers/039-swift-iterativetypechecker-processresolvetypedecl.sil b/validation-test/SIL/crashers/039-swift-iterativetypechecker-processresolvetypedecl.sil
deleted file mode 100644
index 664a99e..0000000
--- a/validation-test/SIL/crashers/039-swift-iterativetypechecker-processresolvetypedecl.sil
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: not --crash %target-sil-opt %s
-// REQUIRES: asserts
-struct I:b:typealias b:a
-typealias a=f
\ No newline at end of file
diff --git a/validation-test/SIL/crashers_fixed/039-swift-iterativetypechecker-processresolvetypedecl.sil b/validation-test/SIL/crashers_fixed/039-swift-iterativetypechecker-processresolvetypedecl.sil
new file mode 100644
index 0000000..921101a
--- /dev/null
+++ b/validation-test/SIL/crashers_fixed/039-swift-iterativetypechecker-processresolvetypedecl.sil
@@ -0,0 +1,3 @@
+// RUN: not %target-sil-opt %s
+struct I:b:typealias b:a
+typealias a=f
diff --git a/validation-test/Sema/type_checker_perf/slow/rdar30606089.swift.gyb b/validation-test/Sema/type_checker_perf/slow/rdar30606089.swift.gyb
index 9cb19a1..d5e17f5 100644
--- a/validation-test/Sema/type_checker_perf/slow/rdar30606089.swift.gyb
+++ b/validation-test/Sema/type_checker_perf/slow/rdar30606089.swift.gyb
@@ -2,6 +2,9 @@
 // REQUIRES: OS=macosx
 // REQUIRES: asserts
 
+// FIXME: https://bugs.swift.org/browse/SR-6520
+// REQUIRES: SR6520
+
 let derivative = { (t: Double) -> (Double) in
   return -2.0 / (
   (1.0 + t)
diff --git a/validation-test/compiler_crashers/28779-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift b/validation-test/compiler_crashers_fixed/28779-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
similarity index 88%
rename from validation-test/compiler_crashers/28779-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
rename to validation-test/compiler_crashers_fixed/28779-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
index 631ea5a..e507d78 100644
--- a/validation-test/compiler_crashers/28779-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
+++ b/validation-test/compiler_crashers_fixed/28779-parent-parent-is-nominaltype-parent-is-boundgenerictype-parent-is-unboundgeneric.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol P{func a:Self.a.a{}class a{class a
diff --git a/validation-test/stdlib/Dictionary.swift b/validation-test/stdlib/Dictionary.swift
index 8da6fe4..32d9b54 100644
--- a/validation-test/stdlib/Dictionary.swift
+++ b/validation-test/stdlib/Dictionary.swift
@@ -127,6 +127,14 @@
   return d
 }
 
+func getCOWFastDictionaryWithCOWValues() -> Dictionary<Int, TestValueCOWTy> {
+  var d = Dictionary<Int, TestValueCOWTy>(minimumCapacity: 10)
+  d[10] = TestValueCOWTy(1010)
+  d[20] = TestValueCOWTy(1020)
+  d[30] = TestValueCOWTy(1030)
+  return d
+}
+
 func getCOWSlowDictionary() -> Dictionary<TestKeyTy, TestValueTy> {
   var d = Dictionary<TestKeyTy, TestValueTy>(minimumCapacity: 10)
   d[TestKeyTy(10)] = TestValueTy(1010)
@@ -804,6 +812,32 @@
   }
 }
 
+DictionaryTestSuite.test("COW.Fast.DefaultedSubscriptDoesNotCopyValue") {
+  do {
+    var d = getCOWFastDictionaryWithCOWValues()
+    let identityValue30 = d[30]!.baseAddress
+
+    // Increment the value without having to reallocate the underlying Base
+    // instance, as uniquely referenced.
+    d[30, default: TestValueCOWTy()].value += 1
+    assert(identityValue30 == d[30]!.baseAddress)
+    assert(d[30]!.value == 1031)
+
+    let value40 = TestValueCOWTy()
+    let identityValue40 = value40.baseAddress
+
+    // Increment the value, reallocating the underlying Base, as not uniquely
+    // referenced.
+    d[40, default: value40].value += 1
+    assert(identityValue40 != d[40]!.baseAddress)
+    assert(d[40]!.value == 1)
+
+    // Keep variables alive.
+    _fixLifetime(d)
+    _fixLifetime(value40)
+  }
+}
+
 DictionaryTestSuite.test("COW.Fast.IndexForKeyDoesNotReallocate") {
   var d = getCOWFastDictionary()
   var identity1 = d._rawIdentifier()
diff --git a/validation-test/stdlib/InvalidStrideable.swift b/validation-test/stdlib/InvalidStrideable.swift
index 3306f63..1c760f5 100644
--- a/validation-test/stdlib/InvalidStrideable.swift
+++ b/validation-test/stdlib/InvalidStrideable.swift
@@ -5,6 +5,9 @@
 // RUN: ! %target-run %t/InvalidStrideableCmp 2>&1 | %FileCheck %s --check-prefix=CHECK-COMPARABLE
 // REQUIRES: executable_test
 
+// FIXME: rdar://35780657
+// UNSUPPORTED: swift_test_mode_optimize_size
+
 //
 // Check that a circular Strideable inheriting witnesses from Stdlib crashes
 // with a rich error message.
diff --git a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
index 9b4a5a3..89bb34c 100644
--- a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
+++ b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
@@ -161,25 +161,6 @@
   }
 }
 
-struct _Stdout : TextOutputStream {
-  mutating func _lock() {
-    _swift_stdlib_flockfile_stdout()
-  }
-
-  mutating func _unlock() {
-    _swift_stdlib_funlockfile_stdout()
-  }
-
-  mutating func write(_ string: String) {
-    // FIXME: buffering?
-    // It is important that we use stdio routines in order to correctly
-    // interoperate with stdio buffering.
-    for c in string.utf8 {
-      _swift_stdlib_putchar_unlocked(Int32(c))
-    }
-  }
-}
-
 % for (name, underlyingType) in [
 %   ('Int', 'UInt'), ('Int32', 'UInt32')
 % ]:
diff --git a/validation-test/stdlib/ValidationNSNumberBridging.swift b/validation-test/stdlib/ValidationNSNumberBridging.swift
index 29eae21..53036a3 100644
--- a/validation-test/stdlib/ValidationNSNumberBridging.swift
+++ b/validation-test/stdlib/ValidationNSNumberBridging.swift
@@ -13,63 +13,15 @@
 // REQUIRES: executable_test
 // REQUIRES: objc_interop
 
+// FIXME: rdar://35814988
+// UNSUPPORTED: CPU=armv7
+// UNSUPPORTED: CPU=armv7s
+// UNSUPPORTED: CPU=armv7k
 
 import StdlibUnittest
 import Foundation
 import CoreGraphics
 
-extension Float {
-    init?(reasonably value: Float) {
-        self = value
-    }
-
-    init?(reasonably value: Double) {
-        guard !value.isNaN else {
-            self = Float.nan
-            return
-        }
-
-        guard !value.isInfinite else {
-            if value.sign == .minus {
-                self = -Float.infinity
-            } else {
-                self = Float.infinity
-            }
-            return
-        }
-
-        guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
-            return nil
-        }
-        
-        self = Float(value)
-    }
-}
-
-extension Double {
-    init?(reasonably value: Float) {
-        guard !value.isNaN else {
-            self = Double.nan
-            return
-        }
-
-        guard !value.isInfinite else {
-            if value.sign == .minus {
-                self = -Double.infinity
-            } else {
-                self = Double.infinity
-            }
-            return
-        }
-
-        self = Double(value)
-    }
-
-    init?(reasonably value: Double) {
-        self = value
-    }
-}
-
 var nsNumberBridging = TestSuite("NSNumberBridgingValidation")
 
 func testFloat(_ lhs: Float?, _ rhs: Float?, file: String = #file, line: UInt = #line) {
@@ -697,12 +649,22 @@
             expectEqual(UInt(exactly: interestingValue), uint)
 
             let float = (number!) as? Float
-            let expectedFloat = Float(reasonably: interestingValue)
-            testFloat(expectedFloat, float)
-            
+            let expectedFloat = Float(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(float?.isNaN == true)
+                expectNil(expectedFloat)
+            } else {
+                testFloat(expectedFloat, float)
+            }
+          
             let double = (number!) as? Double
-            let expectedDouble = Double(interestingValue)
-            testDouble(expectedDouble, double)
+            let expectedDouble = Double(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(double?.isNaN == true)
+                expectNil(expectedDouble)
+            } else {
+                testDouble(expectedDouble, double)
+            }
         }
         let bridged = interestingValue as NSNumber
         testNumber(bridged)
@@ -737,12 +699,22 @@
             expectEqual(UInt(exactly: interestingValue), uint)
 
             let float = (number!) as? Float
-            let expectedFloat = Float(reasonably: interestingValue)
-            testFloat(expectedFloat, float)
-            
+            let expectedFloat = Float(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(float?.isNaN == true)
+                expectNil(expectedFloat)
+            } else {
+                testFloat(expectedFloat, float)
+            }
+          
             let double = (number!) as? Double
-            let expectedDouble = interestingValue
-            testDouble(expectedDouble, double)
+            let expectedDouble = Double(exactly: interestingValue)
+            if interestingValue.isNaN {
+                expectTrue(double?.isNaN == true)
+                expectNil(expectedDouble)
+            } else {
+                testDouble(expectedDouble, double)
+            }
         }
         let bridged = interestingValue as NSNumber
         testNumber(bridged)
@@ -777,12 +749,22 @@
             expectEqual(UInt(exactly: interestingValue.native), uint)
             
             let float = (number!) as? Float
-            let expectedFloat = Float(reasonably: interestingValue.native)
-            testFloat(expectedFloat, float)
-            
+            let expectedFloat = Float(exactly: interestingValue.native)
+            if interestingValue.isNaN {
+                expectTrue(float?.isNaN == true)
+                expectNil(expectedFloat)
+            } else {
+                testFloat(expectedFloat, float)
+            }
+          
             let double = (number!) as? Double
-            let expectedDouble = Double(interestingValue)
-            testDouble(expectedDouble, double)
+            let expectedDouble = Double(exactly: interestingValue.native)
+            if interestingValue.isNaN {
+                expectTrue(double?.isNaN == true)
+                expectNil(expectedDouble)
+            } else {
+                testDouble(expectedDouble, double)
+            }
         }
         let bridged = interestingValue as NSNumber
         testNumber(bridged)