Merge pull request #21505 from DougGregor/dynamic-replacement-ambiguity-5.0

[5.0] [Type checker] Basic ambiguity resolution + diagnostics for dynamic replacement
diff --git a/include/swift/SILOptimizer/Utils/CastOptimizer.h b/include/swift/SILOptimizer/Utils/CastOptimizer.h
index 49f73711..2dbb79b 100644
--- a/include/swift/SILOptimizer/Utils/CastOptimizer.h
+++ b/include/swift/SILOptimizer/Utils/CastOptimizer.h
@@ -129,6 +129,10 @@
                                        SILValue Dest, CanType Source,
                                        CanType Target, SILBasicBlock *SuccessBB,
                                        SILBasicBlock *FailureBB);
+
+  SILInstruction *
+  optimizeMetatypeConversion(ConversionInst *MCI,
+                             MetatypeRepresentation Representation);
 };
 
 } // namespace swift
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index a814feb..336274b 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -353,19 +353,17 @@
       return None;
     };
 
+  // Check whether the superclass conforms.
+  if (auto superclass = genericSig->getSuperclassBound(type)) {
+    LookUpConformanceInSignature lookup(*getGenericSignature());
+    if (auto conformance = lookup(type->getCanonicalType(), superclass, proto))
+      return conformance;
+  }
+
   // If the type doesn't conform to this protocol, the result isn't formed
   // from these requirements.
-  if (!genericSig->conformsToProtocol(type, proto)) {
-    // Check whether the superclass conforms.
-    if (auto superclass = genericSig->getSuperclassBound(type)) {
-      return LookUpConformanceInSignature(*getGenericSignature())(
-                                                 type->getCanonicalType(),
-                                                 superclass,
-                                                 proto);
-    }
-
+  if (!genericSig->conformsToProtocol(type, proto))
     return None;
-  }
 
   auto accessPath =
     genericSig->getConformanceAccessPath(type, proto);
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index fe009fa..15b0b7f 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -1908,8 +1908,9 @@
       else
         (void)0;
       
-      // If the property has storage, emit the ivar name last.
-      if (prop->hasStorage())
+      // If the property is an instance property and has storage, emit the ivar
+      // name last.
+      if (!prop->isStatic() && prop->hasStorage())
         outs << ",V" << prop->getName();
     }
 
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
index 64d2141..d231d6b 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
@@ -289,16 +289,19 @@
 SILInstruction *
 SILCombiner::
 visitUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *UCCAI) {
-  CastOpt.optimizeUnconditionalCheckedCastAddrInst(UCCAI);
+  if (CastOpt.optimizeUnconditionalCheckedCastAddrInst(UCCAI))
+    MadeChange = true;
+
   return nullptr;
 }
 
 SILInstruction *
 SILCombiner::
 visitUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *UCCI) {
-  if (CastOpt.optimizeUnconditionalCheckedCastInst(UCCI))
+  if (CastOpt.optimizeUnconditionalCheckedCastInst(UCCI)) {
+    MadeChange = true;
     return nullptr;
-
+  }
   // FIXME: rename from RemoveCondFails to RemoveRuntimeAsserts.
   if (RemoveCondFails) {
     auto LoweredTargetType = UCCI->getType();
@@ -388,32 +391,6 @@
   return nullptr;
 }
 
-/// Helper function for simplifying conversions between
-/// thick and objc metatypes.
-static SILInstruction *
-visitMetatypeConversionInst(SILBuilder &Builder, ConversionInst *MCI,
-                            MetatypeRepresentation Representation) {
-  SILValue Op = MCI->getOperand(0);
-  // Instruction has a proper target type already.
-  SILType Ty = MCI->getType();
-  auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
-
-  if (MetatypeTy->getRepresentation() != Representation)
-    return nullptr;
-
-  if (isa<MetatypeInst>(Op))
-    return Builder.createMetatype(MCI->getLoc(), Ty);
-
-  if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op))
-    return Builder.createValueMetatype(MCI->getLoc(), Ty, VMI->getOperand());
-
-  if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op))
-    return Builder.createExistentialMetatype(MCI->getLoc(), Ty,
-                                             EMI->getOperand());
-
-  return nullptr;
-}
-
 SILInstruction *
 SILCombiner::visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *TTOCMI) {
   // Perform the following transformations:
@@ -425,8 +402,10 @@
   //
   // (thick_to_objc_metatype (existential_metatype @thick)) ->
   // (existential_metatype @objc_metatype)
-  return visitMetatypeConversionInst(Builder, TTOCMI,
-                                     MetatypeRepresentation::Thick);
+  if (CastOpt.optimizeMetatypeConversion(TTOCMI, MetatypeRepresentation::Thick))
+    MadeChange = true;
+
+  return nullptr;
 }
 
 SILInstruction *
@@ -440,20 +419,26 @@
   //
   // (objc_to_thick_metatype (existential_metatype @objc_metatype)) ->
   // (existential_metatype @thick)
-  return visitMetatypeConversionInst(Builder, OCTTMI,
-                                     MetatypeRepresentation::ObjC);
+  if (CastOpt.optimizeMetatypeConversion(OCTTMI, MetatypeRepresentation::ObjC))
+    MadeChange = true;
+
+  return nullptr;
 }
 
 SILInstruction *
 SILCombiner::visitCheckedCastBranchInst(CheckedCastBranchInst *CBI) {
-  CastOpt.optimizeCheckedCastBranchInst(CBI);
+  if (CastOpt.optimizeCheckedCastBranchInst(CBI))
+    MadeChange = true;
+
   return nullptr;
 }
 
 SILInstruction *
 SILCombiner::
 visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CCABI) {
-  CastOpt.optimizeCheckedCastAddrBranchInst(CCABI);
+  if (CastOpt.optimizeCheckedCastAddrBranchInst(CCABI))
+    MadeChange = true;
+
   return nullptr;
 }
 
diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp
index f5f2545..fb87294 100644
--- a/lib/SILOptimizer/Utils/CastOptimizer.cpp
+++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp
@@ -1576,3 +1576,40 @@
 
   return nullptr;
 }
+
+/// Simplify conversions between thick and objc metatypes.
+SILInstruction *CastOptimizer::optimizeMetatypeConversion(
+    ConversionInst *MCI, MetatypeRepresentation Representation) {
+  SILValue Op = MCI->getOperand(0);
+  // Instruction has a proper target type already.
+  SILType Ty = MCI->getType();
+  auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
+
+  if (MetatypeTy->getRepresentation() != Representation)
+    return nullptr;
+
+  // Rematerialize the incoming metatype instruction with the outgoing type.
+  auto replaceCast = [&](SingleValueInstruction *NewCast) {
+    assert(Ty.getAs<AnyMetatypeType>()->getRepresentation()
+           == NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation());
+    MCI->replaceAllUsesWith(NewCast);
+    EraseInstAction(MCI);
+    return NewCast;
+  };
+  if (auto *MI = dyn_cast<MetatypeInst>(Op)) {
+    return replaceCast(
+        SILBuilderWithScope(MCI).createMetatype(MCI->getLoc(), Ty));
+  }
+  // For metatype instructions that require an operand, generate the new
+  // metatype at the same position as the original to avoid extending the
+  // lifetime of `Op` past its destroy.
+  if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op)) {
+    return replaceCast(SILBuilderWithScope(VMI).createValueMetatype(
+        MCI->getLoc(), Ty, VMI->getOperand()));
+  }
+  if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op)) {
+    return replaceCast(SILBuilderWithScope(EMI).createExistentialMetatype(
+        MCI->getLoc(), Ty, EMI->getOperand()));
+  }
+  return nullptr;
+}
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 5100bd6..b03ffab 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1877,7 +1877,7 @@
       (isa<OverloadedDeclRefExpr>(subExpr->getValueProvidingExpr()))) {
     return subExpr;
   }
-  
+
   // Save any existing type data of the subexpr tree, and reset it to null in
   // prep for re-type-checking the tree.  If things fail, we can revert the
   // types back to their original state.
@@ -1921,9 +1921,12 @@
   // holding on to an expression containing open existential types but
   // no OpenExistentialExpr, which breaks invariants enforced by the
   // ASTChecker.
-  if (isa<OpenExistentialExpr>(subExpr))
-    eraseOpenedExistentials(CS, subExpr);
-  
+  // Another reason why we need to do this is because diagnostics might pick
+  // constraint anchor for re-typechecking which would only have opaque value
+  // expression and not enclosing open existential, which is going to trip up
+  // sanitizer.
+  eraseOpenedExistentials(CS, subExpr);
+
   // If recursive type checking failed, then an error was emitted.  Return
   // null to indicate this to the caller.
   if (!resultTy)
diff --git a/stdlib/private/StdlibUnittest/RaceTest.swift b/stdlib/private/StdlibUnittest/RaceTest.swift
index b4a214f..e4093a4 100644
--- a/stdlib/private/StdlibUnittest/RaceTest.swift
+++ b/stdlib/private/StdlibUnittest/RaceTest.swift
@@ -395,7 +395,7 @@
   var stopNow = _stdlib_AtomicInt(0)
 
   var trialBarrier: _stdlib_Barrier
-  var trialSpinBarrier: _stdlib_AtomicInt = _stdlib_AtomicInt()
+  var trialSpinBarrier = _stdlib_AtomicInt()
 
   var raceData: [RT.RaceData] = []
   var workerStates: [_RaceTestWorkerState<RT>] = []
diff --git a/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb b/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
index bcc138a..1c58dca 100644
--- a/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
+++ b/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
@@ -12,6 +12,8 @@
 
 import Swift
 
+// This type intentionally shadows the stdlib one
+@available(swift, introduced: 5.0)
 public final class _stdlib_AtomicInt {
   internal var _value: Int
 
@@ -47,7 +49,7 @@
 
   public func compareExchange(expected: inout Int, desired: Int) -> Bool {
     var expectedVar = expected
-    let result = _stdlib_atomicCompareExchangeStrongInt(
+    let result = _swift_stdlib_atomicCompareExchangeStrongInt(
       object: _valuePtr,
       expected: &expectedVar,
       desired: desired)
@@ -56,74 +58,3 @@
   }
 }
 
-public func _swift_stdlib_atomicLoadInt(
-  object target: UnsafeMutablePointer<Int>) -> Int {
-#if arch(i386) || arch(arm)
-  let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
-  return Int(value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
-  return Int(value)
-#endif
-}
-
-public func _swift_stdlib_atomicStoreInt(
-  object target: UnsafeMutablePointer<Int>,
-  desired: Int) {
-#if arch(i386) || arch(arm)
-  Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
-#endif
-}
-
-public func _stdlib_atomicCompareExchangeStrongInt(
-  object target: UnsafeMutablePointer<Int>,
-  expected: UnsafeMutablePointer<Int>,
-  desired: Int) -> Bool {
-#if arch(i386) || arch(arm)
-  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
-    target._rawValue, expected.pointee._value, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
-    target._rawValue, expected.pointee._value, desired._value)
-#endif
-  expected.pointee._value = oldValue
-  return Bool(won)
-}
-
-% for operation in ['Add', 'And', 'Or', 'Xor']:
-// Warning: no overflow checking.
-public func _swift_stdlib_atomicFetch${operation}Int(
-  object target: UnsafeMutablePointer<Int>,
-  operand: Int) -> Int {
-  let rawTarget = UnsafeMutableRawPointer(target)
-#if arch(i386) || arch(arm)
-  let value = _swift_stdlib_atomicFetch${operation}Int32(
-    object: rawTarget.assumingMemoryBound(to: Int32.self),
-    operand: Int32(operand))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let value = _swift_stdlib_atomicFetch${operation}Int64(
-    object: rawTarget.assumingMemoryBound(to: Int64.self),
-    operand: Int64(operand))
-#endif
-  return Int(value)
-}
-
-%   for bits in [ 32, 64 ]:
-
-// Warning: no overflow checking.
-public func _swift_stdlib_atomicFetch${operation}Int${bits}(
-  object target: UnsafeMutablePointer<Int${bits}>,
-  operand: Int${bits}) -> Int${bits} {
-
-  let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
-    target._rawValue, operand._value)
-
-  return Int${bits}(value)
-}
-
-%   end
-
-% end
-
diff --git a/stdlib/public/core/AtomicInt.swift.gyb b/stdlib/public/core/AtomicInt.swift.gyb
new file mode 100644
index 0000000..17d3484
--- /dev/null
+++ b/stdlib/public/core/AtomicInt.swift.gyb
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+@available(swift, deprecated: 4.2, obsoleted: 5.0)
+public final class _stdlib_AtomicInt {
+  internal var _value: Int
+
+  internal var _valuePtr: UnsafeMutablePointer<Int> {
+    return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
+      to: Int.self)
+  }
+
+  public init(_ value: Int = 0) {
+    _value = value
+  }
+
+  public func store(_ desired: Int) {
+    return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
+  }
+
+  public func load() -> Int {
+    return _swift_stdlib_atomicLoadInt(object: _valuePtr)
+  }
+
+% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
+  @discardableResult
+  public func fetchAnd${operation_name}(_ operand: Int) -> Int {
+    return _swift_stdlib_atomicFetch${operation_name}Int(
+      object: _valuePtr,
+      operand: operand)
+  }
+
+  public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
+    return fetchAnd${operation_name}(operand) ${operation} operand
+  }
+% end
+
+  public func compareExchange(expected: inout Int, desired: Int) -> Bool {
+    var expectedVar = expected
+    let result = _swift_stdlib_atomicCompareExchangeStrongInt(
+      object: _valuePtr,
+      expected: &expectedVar,
+      desired: desired)
+    expected = expectedVar
+    return result
+  }
+}
+
+@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
+internal func _swift_stdlib_atomicCompareExchangeStrongInt(
+  object target: UnsafeMutablePointer<Int>,
+  expected: UnsafeMutablePointer<Int>,
+  desired: Int) -> Bool {
+#if arch(i386) || arch(arm)
+  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
+    target._rawValue, expected.pointee._value, desired._value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
+    target._rawValue, expected.pointee._value, desired._value)
+#endif
+  expected.pointee._value = oldValue
+  return Bool(won)
+}
+
+
+// FIXME: ideally it should not be here, at the very least not public, but
+// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
+public // Existing uses outside stdlib
+func _swift_stdlib_atomicLoadInt(
+  object target: UnsafeMutablePointer<Int>) -> Int {
+#if arch(i386) || arch(arm)
+  let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
+  return Int(value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
+  return Int(value)
+#endif
+}
+
+@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
+internal func _swift_stdlib_atomicStoreInt(
+  object target: UnsafeMutablePointer<Int>,
+  desired: Int) {
+#if arch(i386) || arch(arm)
+  Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
+#endif
+}
+
+% for operation in ['Add', 'And', 'Or', 'Xor']:
+// Warning: no overflow checking.
+// FIXME: ideally it should not be here, at the very least not public, but
+// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
+public // Existing uses outside stdlib
+func _swift_stdlib_atomicFetch${operation}Int(
+  object target: UnsafeMutablePointer<Int>,
+  operand: Int) -> Int {
+  let rawTarget = UnsafeMutableRawPointer(target)
+#if arch(i386) || arch(arm)
+  let value = _swift_stdlib_atomicFetch${operation}Int32(
+    object: rawTarget.assumingMemoryBound(to: Int32.self),
+    operand: Int32(operand))
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let value = _swift_stdlib_atomicFetch${operation}Int64(
+    object: rawTarget.assumingMemoryBound(to: Int64.self),
+    operand: Int64(operand))
+#endif
+  return Int(value)
+}
+
+%   for bits in [ 32, 64 ]:
+
+// Warning: no overflow checking.
+@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
+internal func _swift_stdlib_atomicFetch${operation}Int${bits}(
+  object target: UnsafeMutablePointer<Int${bits}>,
+  operand: Int${bits}) -> Int${bits} {
+
+  let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
+    target._rawValue, operand._value)
+
+  return Int${bits}(value)
+}
+
+%   end
+
+% end
+
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 169941c..7323a89 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -30,6 +30,7 @@
   ASCII.swift
   Assert.swift
   AssertCommon.swift
+  AtomicInt.swift.gyb
   BidirectionalCollection.swift
   Bitset.swift
   Bool.swift
diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json
index 55d01d5..bd20989 100644
--- a/stdlib/public/core/GroupInfo.json
+++ b/stdlib/public/core/GroupInfo.json
@@ -197,6 +197,7 @@
     "Bitset.swift"
   ],
   "Misc": [
+    "AtomicInt.swift",
     "Interval.swift",
     "ErrorType.swift",
     "InputStream.swift",
diff --git a/stdlib/public/core/Runtime.swift.gyb b/stdlib/public/core/Runtime.swift.gyb
index 1c06d78..41e9940 100644
--- a/stdlib/public/core/Runtime.swift.gyb
+++ b/stdlib/public/core/Runtime.swift.gyb
@@ -115,54 +115,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// These pieces are used in ThreadLocalStorage.swift in debug builds.
-// For tests, see similar functions from SwiftPrivate/AtomicInt.swift.gyb
-//===----------------------------------------------------------------------===//
-internal func _swift_stdlib_atomicLoadInt(
-  object target: UnsafeMutablePointer<Int>) -> Int {
-#if arch(i386) || arch(arm)
-  let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
-  return Int(value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
-  return Int(value)
-#endif
-}
-
-% for bits in [ 32, 64 ]:
-
-// Warning: no overflow checking.
-internal func _swift_stdlib_atomicFetchAddInt${bits}(
-  object target: UnsafeMutablePointer<Int${bits}>,
-  operand: Int${bits}) -> Int${bits} {
-
-  let value = Builtin.atomicrmw_add_seqcst_Int${bits}(
-    target._rawValue, operand._value)
-
-  return Int${bits}(value)
-}
-
-% end
-
-// Warning: no overflow checking.
-internal func _swift_stdlib_atomicFetchAddInt(
-  object target: UnsafeMutablePointer<Int>,
-  operand: Int) -> Int {
-  let rawTarget = UnsafeMutableRawPointer(target)
-#if arch(i386) || arch(arm)
-  let value = _swift_stdlib_atomicFetchAddInt32(
-    object: rawTarget.assumingMemoryBound(to: Int32.self),
-    operand: Int32(operand))
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let value = _swift_stdlib_atomicFetchAddInt64(
-    object: rawTarget.assumingMemoryBound(to: Int64.self),
-    operand: Int64(operand))
-#endif
-  return Int(value)
-}
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
 // Conversion of primitive types to `String`
 //===----------------------------------------------------------------------===//
 
diff --git a/test/Constraints/rdar46544601.swift b/test/Constraints/rdar46544601.swift
new file mode 100644
index 0000000..7002cde
--- /dev/null
+++ b/test/Constraints/rdar46544601.swift
@@ -0,0 +1,34 @@
+// RUN: %target-typecheck-verify-swift
+
+struct D {}
+
+class Future<T> {
+  func then<U>(_ fn: @escaping (T) -> Future<U>) -> Future<U> { fatalError() }
+  func thenThrowing<U>(_ fn: @escaping (T) throws -> U) -> Future<U> { fatalError() }
+  func whenFailure(_ fn: @escaping (Error) -> Void) {}
+
+  func and<U>(result: U) -> Future<(T,U)> { fatalError() }
+}
+
+protocol P {
+  func foo(arr: [D], data: ArraySlice<UInt8>) -> Future<D>
+  // expected-note@-1 {{found this candidate}}
+  func bar(root: D, from: P) -> Future<D>
+}
+
+extension P {
+  func foo(arr: [D] = [], data: [UInt8]) -> Future<D> { fatalError() }
+  // expected-note@-1 {{found this candidate}}
+}
+
+func crash(_ p: P, payload: [UInt8]) throws {
+  p.foo(data: payload).then { _ in
+    return Future<(D, [D])>()
+  }.then { (id, arr) in
+    p.foo(arr: arr, data: []).and(result: (id, arr))
+    // expected-error@-1 {{mbiguous reference to member 'foo(arr:data:)'}}
+  }.then { args0 in
+    let (parentID, args1) = args0
+    p.bar(root: parentID, from: p).and(args1)
+  }.whenFailure { _ in }
+}
diff --git a/test/IRGen/objc_properties.swift b/test/IRGen/objc_properties.swift
index 8e87328..45d3737 100644
--- a/test/IRGen/objc_properties.swift
+++ b/test/IRGen/objc_properties.swift
@@ -47,6 +47,8 @@
   @objc class var extensionClassProp : SomeObject.Type {
     return self
   }
+
+  @objc static var extensionStoredStaticProp: Int64 = 0
 }
 
 // <rdar://problem/16952186> Crash with @lazy in @objc class
@@ -77,14 +79,14 @@
 }
 
 // CHECK-NEW: [[SHARED_NAME:@.*]] = private unnamed_addr constant [11 x i8] c"sharedProp\00"
-// CHECK-NEW: [[SHARED_ATTRS:@.*]] = private unnamed_addr constant [17 x i8] c"Tq,N,VsharedProp\00"
+// CHECK-NEW: [[SHARED_ATTRS:@.*]] = private unnamed_addr constant [5 x i8] c"Tq,N\00"
 
 // CHECK-NEW: @_CLASS_PROPERTIES__TtC15objc_properties10SomeObject = private constant { {{.*}}] } {
 // CHECK-NEW:   i32 16,
 // CHECK-NEW:   i32 1,
 // CHECK-NEW:   [1 x { i8*, i8* }] [{
 // CHECK-NEW:     i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SHARED_NAME]], i64 0, i64 0),
-// CHECK-NEW:     i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[SHARED_ATTRS]], i64 0, i64 0)
+// CHECK-NEW:     i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[SHARED_ATTRS]], i64 0, i64 0)
 // CHECK-NEW:   }]
 // CHECK-NEW: }, section "__DATA, __objc_const", align 8
 
@@ -209,14 +211,17 @@
 
 // CHECK-NEW: [[EXTENSIONCLASSPROPERTY_NAME:@.*]] = private unnamed_addr constant [19 x i8] c"extensionClassProp\00"
 // CHECK-NEW: [[EXTENSIONCLASSPROPERTY_ATTRS:@.*]] = private unnamed_addr constant [7 x i8] c"T#,N,R\00"
+// CHECK-NEW: [[EXTENSIONSTATICPROPERTY_NAME:@.*]] = private unnamed_addr constant [26 x i8] c"extensionStoredStaticProp\00"
 
 // CHECK-NEW: @"_CATEGORY_CLASS_PROPERTIES__TtC15objc_properties10SomeObject_$_objc_properties" = private constant { {{.*}}] } {
 // CHECK-NEW:   i32 16,
-// CHECK-NEW:   i32 1,
-// CHECK-NEW:   [1 x { i8*, i8* }] [{
+// CHECK-NEW:   i32 2,
+// CHECK-NEW:   [2 x { i8*, i8* }] [{
 // CHECK-NEW:     i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[EXTENSIONCLASSPROPERTY_NAME]], i64 0, i64 0),
 // CHECK-NEW:     i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[EXTENSIONCLASSPROPERTY_ATTRS]], i64 0, i64 0)
-// CHECK-NEW:   }]
+// CHECK-NEW:   }, {
+// CHECK-NEW:	  i8* getelementptr inbounds ([26 x i8], [26 x i8]* [[EXTENSIONSTATICPROPERTY_NAME]], i64 0, i64 0),
+// CHECK-NEW:	  i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[SHARED_ATTRS]], i64 0, i64 0) }]
 // CHECK-NEW: }, section "__DATA, __objc_const", align 8
 
 // CHECK: @"_CATEGORY__TtC15objc_properties10SomeObject_$_objc_properties" = private constant { {{.+}} } {
diff --git a/test/Prototypes/CollectionTransformers.swift b/test/Prototypes/CollectionTransformers.swift
index 83ef091..4e4832b 100644
--- a/test/Prototypes/CollectionTransformers.swift
+++ b/test/Prototypes/CollectionTransformers.swift
@@ -641,7 +641,7 @@
   internal let _maxThreads: Int
   /// Total number of threads: number of running threads plus the number of
   /// threads that are preparing to start).
-  internal let _totalThreads: _stdlib_AtomicInt = _stdlib_AtomicInt(0)
+  internal let _totalThreads = _stdlib_AtomicInt(0)
 
   internal var _runningThreads: [_ForkJoinWorkerThread] = []
   internal var _runningThreadsMutex: _ForkJoinMutex = _ForkJoinMutex()
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 2cfe911..53d4316 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -3673,3 +3673,42 @@
   return %4 : $Builtin.Int64
 }
 
+// <rdar://46746188> crash in swift_getObjCClassFromObject
+// class TestDocument: NSPersistentDocument {
+//   override init() {
+//     super.init()
+//   }
+//   convenience init(type: String) throws {
+//     self.init()
+//   }
+// }
+// After inlining the __allocating_init, we have two uses of the value_metatype.
+// The second use goes through a thick_to_objc_metatype. When SILCombine replaces 
+// thick_to_objc_metatype with value_metatype, it cannot extend the liverange
+// of value_metatype's operand.
+@objc class TestObjCInit {
+  init()
+
+  convenience init(type: String) throws
+}
+// CHECK-LABEL: sil hidden [thunk] @objc_init_partial_dealloc : $@convention(objc_method) (@owned TestObjCInit) -> Optional<TestObjCInit> {
+// CHECK: bb0(%0 : $TestObjCInit):
+// CHECK:   [[VMT2:%.*]] = value_metatype $@objc_metatype TestObjCInit.Type, %0 : $TestObjCInit
+// CHECK:   [[VMT:%.*]] = value_metatype $@thick TestObjCInit.Type, %0 : $TestObjCInit
+// CHECK:   dealloc_partial_ref %0 : $TestObjCInit, [[VMT]] : $@thick TestObjCInit.Type
+// CHECK-NOT: value_metatype
+// CHECK:   [[O:%.*]] = alloc_ref_dynamic [objc] [[VMT2]] : $@objc_metatype TestObjCInit.Type, $TestObjCInit
+// CHECK:   [[M:%.*]] = objc_method [[O]] : $TestObjCInit, #TestObjCInit.init!initializer.1.foreign : (TestObjCInit.Type) -> () -> TestObjCInit, $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+// CHECK:   apply [[M]]([[O]]) : $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+// CHECK-LABEL: } // end sil function 'objc_init_partial_dealloc'
+sil hidden [thunk] @objc_init_partial_dealloc : $@convention(objc_method) (@owned TestObjCInit) -> Optional<TestObjCInit> {
+bb0(%2 : $TestObjCInit):
+  %8 = value_metatype $@thick TestObjCInit.Type, %2 : $TestObjCInit
+  dealloc_partial_ref %2 : $TestObjCInit, %8 : $@thick TestObjCInit.Type
+  %11 = thick_to_objc_metatype %8 : $@thick TestObjCInit.Type to $@objc_metatype TestObjCInit.Type
+  %12 = alloc_ref_dynamic [objc] %11 : $@objc_metatype TestObjCInit.Type, $TestObjCInit
+  %13 = objc_method %12 : $TestObjCInit, #TestObjCInit.init!initializer.1.foreign : (TestObjCInit.Type) -> () -> TestObjCInit, $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+  %14 = apply %13(%12) : $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+  %19 = enum $Optional<TestObjCInit>, #Optional.some!enumelt.1, %14 : $TestObjCInit
+  return %19 : $Optional<TestObjCInit>
+}
diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
index e85e841..aa10b37 100644
--- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
@@ -120,39 +120,28 @@
 Var __swift_stdlib_UErrorCode.isFailure has been removed
 Var __swift_stdlib_UErrorCode.isSuccess has been removed
 Var __swift_stdlib_UErrorCode.isWarning has been removed
+Var _stdlib_AtomicInt._value has been removed
+Var _stdlib_AtomicInt._valuePtr has been removed
 
-Class _stdlib_AtomicInt has been removed
-Func _stdlib_atomicCompareExchangeStrongInt(object:expected:desired:) has been removed
+
+Class _stdlib_AtomicInt is now without @_fixed_layout
+Func _stdlib_atomicCompareExchangeStrongInt(object:expected:desired:) has been renamed to Func _swift_stdlib_atomicCompareExchangeStrongInt(object:expected:desired:)
 Func _stdlib_atomicCompareExchangeStrongInt32(object:expected:desired:) has been removed
 Func _stdlib_atomicCompareExchangeStrongInt64(object:expected:desired:) has been removed
 Func _stdlib_atomicCompareExchangeStrongUInt32(object:expected:desired:) has been removed
 Func _stdlib_atomicCompareExchangeStrongUInt64(object:expected:desired:) has been removed
-Func _swift_stdlib_atomicFetchAddInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAddInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAddInt64(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchAddUInt32(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchAddUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAndInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAndInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchAndInt64(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchAndUInt32(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchAndUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchOrInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchOrInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchOrInt64(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchOrUInt32(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchOrUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchXorInt(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchXorInt32(object:operand:) has been removed
-Func _swift_stdlib_atomicFetchXorInt64(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchXorUInt32(object:operand:) has been removed
 Func _swift_stdlib_atomicFetchXorUInt64(object:operand:) has been removed
-Func _swift_stdlib_atomicLoadInt(object:) has been removed
 Func _swift_stdlib_atomicLoadInt32(object:) has been removed
 Func _swift_stdlib_atomicLoadInt64(object:) has been removed
 Func _swift_stdlib_atomicLoadUInt32(object:) has been removed
 Func _swift_stdlib_atomicLoadUInt64(object:) has been removed
-Func _swift_stdlib_atomicStoreInt(object:desired:) has been removed
 Func _swift_stdlib_atomicStoreInt32(object:desired:) has been removed
 Func _swift_stdlib_atomicStoreInt64(object:desired:) has been removed
 Func _swift_stdlib_atomicStoreUInt32(object:desired:) has been removed
diff --git a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
index d7cb1d1..632b6eb 100644
--- a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
+++ b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %gyb %s -o %t/PersistentVector.swift
-// RUN: %line-directive %t/PersistentVector.swift -- %target-build-swift -parse-stdlib %t/PersistentVector.swift -o %t/a.out
+// RUN: %line-directive %t/PersistentVector.swift -- %target-build-swift -parse-stdlib -Xfrontend -disable-access-control %t/PersistentVector.swift -o %t/a.out
 // RUN: %target-codesign %t/a.out
 // RUN: %line-directive %t/PersistentVector.swift -- %target-run %t/a.out
 // REQUIRES: executable_test