Merge pull request #18032 from rudkx/restore-order

Return to the old disjunction ordering until some test regressions are addressed.
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index 5bc4dcf..5126ffa 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -4306,6 +4306,11 @@
 ///
 /// Spelled 'a as T' and produces a value of type 'T'.
 class CoerceExpr : public ExplicitCastExpr {
+  /// Since there is already `asLoc` location,
+  /// we use it to store `start` of the initializer
+  /// call source range to save some storage.
+  SourceLoc InitRangeEnd;
+
 public:
   CoerceExpr(Expr *sub, SourceLoc asLoc, TypeLoc type)
     : ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type, type.getType())
@@ -4315,6 +4320,29 @@
     : CoerceExpr(nullptr, asLoc, type)
   { }
 
+private:
+  CoerceExpr(SourceRange initRange, Expr *literal, TypeLoc type)
+    : ExplicitCastExpr(ExprKind::Coerce, literal, initRange.Start,
+                       type, type.getType()), InitRangeEnd(initRange.End)
+  { setImplicit(); }
+
+public:
+  /// Create an implicit coercion expression for literal initialization
+  /// preserving original source information, this way original call
+  /// could be recreated if needed.
+  static CoerceExpr *forLiteralInit(ASTContext &ctx, Expr *literal,
+                                    SourceRange range, TypeLoc literalType) {
+    return new (ctx) CoerceExpr(range, literal, literalType);
+  }
+
+  bool isLiteralInit() const { return InitRangeEnd.isValid(); }
+
+  SourceRange getSourceRange() const {
+    return isLiteralInit()
+            ? SourceRange(getAsLoc(), InitRangeEnd)
+            : ExplicitCastExpr::getSourceRange();
+  }
+
   static bool classof(const Expr *E) {
     return E->getKind() == ExprKind::Coerce;
   }
diff --git a/include/swift/SILOptimizer/Analysis/Analysis.def b/include/swift/SILOptimizer/Analysis/Analysis.def
index 1e37745..28564a2 100644
--- a/include/swift/SILOptimizer/Analysis/Analysis.def
+++ b/include/swift/SILOptimizer/Analysis/Analysis.def
@@ -44,5 +44,6 @@
 ANALYSIS(RCIdentity)
 ANALYSIS(SideEffect)
 ANALYSIS(TypeExpansion)
+ANALYSIS(PassManagerVerifier)
 
 #undef ANALYSIS
diff --git a/include/swift/SILOptimizer/Analysis/PassManagerVerifierAnalysis.h b/include/swift/SILOptimizer/Analysis/PassManagerVerifierAnalysis.h
new file mode 100644
index 0000000..99a4d0f
--- /dev/null
+++ b/include/swift/SILOptimizer/Analysis/PassManagerVerifierAnalysis.h
@@ -0,0 +1,65 @@
+//===--- PassManagerVerifierAnalysis.h ------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_PASSMANAGERVERIFIERANALYSIS_H
+#define SWIFT_SILOPTIMIZER_ANALYSIS_PASSMANAGERVERIFIERANALYSIS_H
+
+#include "swift/SIL/SILFunction.h"
+#include "swift/SILOptimizer/Analysis/Analysis.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace swift {
+
+/// An analysis that validates that the pass manager properly sends add/delete
+/// messages as functions are added/deleted from the module.
+///
+/// All methods are no-ops when asserts are disabled.
+class PassManagerVerifierAnalysis : public SILAnalysis {
+  /// The module that we are processing.
+  SILModule &mod;
+
+  /// The set of "live" functions that we are tracking.
+  ///
+  /// All functions in mod must be in liveFunctions and vis-a-versa.
+  llvm::DenseSet<SILFunction *> liveFunctions;
+
+public:
+  PassManagerVerifierAnalysis(SILModule *mod);
+
+  static bool classof(const SILAnalysis *analysis) {
+    return analysis->getKind() == SILAnalysisKind::PassManagerVerifier;
+  }
+
+  /// Validate that the analysis is able to look up all functions and that those
+  /// functions are live.
+  void invalidate() override final;
+
+  /// Validate that the analysis is able to look up the given function.
+  void invalidate(SILFunction *f, InvalidationKind k) override final;
+
+  /// If a function has not yet been seen start tracking it.
+  void notifyAddedOrModifiedFunction(SILFunction *f) override final;
+
+  /// Stop tracking a function.
+  void notifyWillDeleteFunction(SILFunction *f) override final;
+
+  /// Make sure that when we invalidate a function table, make sure we can find
+  /// all functions for all witness tables.
+  void invalidateFunctionTables() override final;
+
+  /// Run the entire verification.
+  void verify() const override final;
+};
+
+} // namespace swift
+
+#endif
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4999f9f..4bad14c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1784,24 +1784,26 @@
 /// that instead.
 static ProtocolConformance *collapseSpecializedConformance(
                                              Type type,
-                                             ProtocolConformance *conformance) {
+                                             ProtocolConformance *conformance,
+                                             SubstitutionMap substitutions) {
   while (true) {
-    // If the conformance matches, return it.
-    if (conformance->getType()->isEqual(type))
-      return conformance;
-
     switch (conformance->getKind()) {
-    case ProtocolConformanceKind::Inherited:
-      conformance = cast<InheritedProtocolConformance>(conformance)
-                      ->getInheritedConformance();
-      break;
-
     case ProtocolConformanceKind::Specialized:
       conformance = cast<SpecializedProtocolConformance>(conformance)
                       ->getGenericConformance();
       break;
 
     case ProtocolConformanceKind::Normal:
+    case ProtocolConformanceKind::Inherited:
+      // If the conformance matches, return it.
+      if (conformance->getType()->isEqual(type)) {
+        for (auto subConformance : substitutions.getConformances())
+          if (!subConformance.isAbstract())
+            return nullptr;
+
+        return conformance;
+      }
+
       return nullptr;
     }
   }
@@ -1814,7 +1816,8 @@
   // If we are performing a substitution that would get us back to the
   // a prior conformance (e.g., mapping into and then out of a conformance),
   // return the existing conformance.
-  if (auto existing = collapseSpecializedConformance(type, generic)) {
+  if (auto existing = collapseSpecializedConformance(type, generic,
+                                                     substitutions)) {
     ++NumCollapsedSpecializedProtocolConformances;
     return existing;
   }
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 1c23f7e..08f1ac6 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -2167,17 +2167,19 @@
     }
   }
 
-  // If we haven't found anything yet but have a superclass, look for a type
-  // in the superclass.
-  // FIXME: Shouldn't we always look in the superclass?
-  if (!bestAssocType && concreteDecls.empty() && superclass) {
-    if (auto classDecl = superclass->getClassOrBoundGenericClass()) {
-      SmallVector<ValueDecl *, 2> superclassMembers;
-      classDecl->getParentModule()->lookupQualified(
-          superclass, name,
+  // If we haven't found anything yet but have a concrete type or a superclass,
+  // look for a type in that.
+  // FIXME: Shouldn't we always look here?
+  if (!bestAssocType && concreteDecls.empty()) {
+    Type typeToSearch = concreteType ? concreteType : superclass;
+    auto *decl = typeToSearch ? typeToSearch->getAnyNominal() : nullptr;
+    if (decl) {
+      SmallVector<ValueDecl *, 2> foundMembers;
+      decl->getParentModule()->lookupQualified(
+          typeToSearch, name,
           NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers, nullptr,
-          superclassMembers);
-      for (auto member : superclassMembers) {
+          foundMembers);
+      for (auto member : foundMembers) {
         if (auto type = dyn_cast<TypeDecl>(member)) {
           // Resolve the signature of this type.
           if (!type->hasInterfaceType()) {
@@ -3938,11 +3940,13 @@
     type = type.subst(subMap, SubstFlags::UseErrorType);
   } else {
     // Substitute in the superclass type.
-    parentType = basePA->getEquivalenceClassIfPresent()->superclass;
-    auto superclassDecl = parentType->getClassOrBoundGenericClass();
+    auto parentPA = basePA->getEquivalenceClassIfPresent();
+    parentType =
+        parentPA->concreteType ? parentPA->concreteType : parentPA->superclass;
+    auto parentDecl = parentType->getAnyNominal();
 
-    subMap = parentType->getMemberSubstitutionMap(
-                           superclassDecl->getParentModule(), concreteDecl);
+    subMap = parentType->getMemberSubstitutionMap(parentDecl->getParentModule(),
+                                                  concreteDecl);
     type = type.subst(subMap, SubstFlags::UseErrorType);
   }
 
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 9f40989..74e3e5f 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2942,7 +2942,8 @@
 MakeAbstractConformanceForGenericType::operator()(CanType dependentType,
                                        Type conformingReplacementType,
                                        ProtocolDecl *conformedProtocol) const {
-  assert((conformingReplacementType->is<SubstitutableType>()
+  assert((conformingReplacementType->is<ErrorType>()
+          || conformingReplacementType->is<SubstitutableType>()
           || conformingReplacementType->is<DependentMemberType>())
          && "replacement requires looking up a concrete conformance");
   return ProtocolConformanceRef(conformedProtocol);
diff --git a/lib/SILOptimizer/Analysis/CMakeLists.txt b/lib/SILOptimizer/Analysis/CMakeLists.txt
index 7344019..009fea5 100644
--- a/lib/SILOptimizer/Analysis/CMakeLists.txt
+++ b/lib/SILOptimizer/Analysis/CMakeLists.txt
@@ -19,6 +19,7 @@
   LoopAnalysis.cpp
   LoopRegionAnalysis.cpp
   MemoryBehavior.cpp
+  PassManagerVerifierAnalysis.cpp
   ProtocolConformanceAnalysis.cpp
   RCIdentityAnalysis.cpp
   SideEffectAnalysis.cpp
diff --git a/lib/SILOptimizer/Analysis/PassManagerVerifierAnalysis.cpp b/lib/SILOptimizer/Analysis/PassManagerVerifierAnalysis.cpp
new file mode 100644
index 0000000..99ae970
--- /dev/null
+++ b/lib/SILOptimizer/Analysis/PassManagerVerifierAnalysis.cpp
@@ -0,0 +1,100 @@
+//===--- PassManagerVerifierAnalysis.cpp ----------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "sil-passmanager-verifier-analysis"
+#include "swift/SILOptimizer/Analysis/PassManagerVerifierAnalysis.h"
+#include "swift/SIL/SILModule.h"
+#include "llvm/Support/CommandLine.h"
+
+static llvm::cl::opt<bool>
+    EnableVerifier("enable-sil-passmanager-verifier-analysis",
+                   llvm::cl::desc("Enable verification of the passmanagers "
+                                  "function notification infrastructure"),
+                   llvm::cl::init(false));
+
+using namespace swift;
+
+PassManagerVerifierAnalysis::PassManagerVerifierAnalysis(SILModule *mod)
+    : SILAnalysis(SILAnalysisKind::PassManagerVerifier), mod(*mod) {
+#ifndef NDEBUG
+  if (!EnableVerifier)
+    return;
+  for (auto &fn : *mod) {
+    DEBUG(llvm::dbgs() << "PMVerifierAnalysis. Add: " << fn.getName() << '\n');
+    liveFunctions.insert(&fn);
+  }
+#endif
+}
+
+/// Validate that the analysis is able to look up all functions and that those
+/// functions are live.
+void PassManagerVerifierAnalysis::invalidate() {}
+
+/// Validate that the analysis is able to look up the given function.
+void PassManagerVerifierAnalysis::invalidate(SILFunction *f,
+                                             InvalidationKind k) {}
+
+/// If a function has not yet been seen start tracking it.
+void PassManagerVerifierAnalysis::notifyAddedOrModifiedFunction(
+    SILFunction *f) {
+#ifndef NDEBUG
+  if (!EnableVerifier)
+    return;
+  DEBUG(llvm::dbgs() << "PMVerifierAnalysis. Add|Mod: " << f->getName()
+                     << '\n');
+  liveFunctions.insert(f);
+#endif
+}
+
+/// Stop tracking a function.
+void PassManagerVerifierAnalysis::notifyWillDeleteFunction(SILFunction *f) {
+#ifndef NDEBUG
+  if (!EnableVerifier)
+    return;
+  DEBUG(llvm::dbgs() << "PMVerifierAnalysis. Delete: " << f->getName() << '\n');
+  assert(liveFunctions.count(f) &&
+         "Tried to delete function that analysis was not aware of?!");
+  liveFunctions.erase(f);
+#endif
+}
+
+/// Make sure that when we invalidate a function table, make sure we can find
+/// all functions for all witness tables.
+void PassManagerVerifierAnalysis::invalidateFunctionTables() {}
+
+/// Run the entire verification.
+void PassManagerVerifierAnalysis::verify() const {
+#ifndef NDEBUG
+  if (!EnableVerifier)
+    return;
+
+  // We check that all functions in the module are in liveFunctions /and/ then
+  // make sure that liveFunctions has the same number of elements. If we have
+  // too many elements, this means we missed a delete event.
+  unsigned funcCount = 0;
+  for (auto &fn : mod) {
+    ++funcCount;
+    assert(liveFunctions.count(&fn) &&
+           "Found function in module that verifier is not aware of?!");
+  }
+  assert(liveFunctions.size() == funcCount &&
+         "Analysis has state for deleted functions?!");
+#endif
+}
+
+//===----------------------------------------------------------------------===//
+//                              Main Entry Point
+//===----------------------------------------------------------------------===//
+
+SILAnalysis *swift::createPassManagerVerifierAnalysis(SILModule *m) {
+  return new PassManagerVerifierAnalysis(m);
+}
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 2ba558a..c74645d 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -3621,6 +3621,36 @@
 
       auto &tc = cs.getTypeChecker();
 
+      // Since this is literal initialization, we don't
+      // really need to keep wrapping coercion around.
+      if (expr->isLiteralInit()) {
+        auto *literalInit = expr->getSubExpr();
+        // If literal got converted into constructor call
+        // lets put proper source information in place.
+        if (auto *call = dyn_cast<CallExpr>(literalInit)) {
+          call->getFn()->forEachChildExpr([&](Expr *subExpr) -> Expr * {
+            auto *TE = dyn_cast<TypeExpr>(subExpr);
+            if (!TE)
+              return subExpr;
+
+            auto type = TE->getInstanceType(
+                [&](const Expr *expr) { return cs.hasType(expr); },
+                [&](const Expr *expr) { return cs.getType(expr); });
+
+            assert(!type->hasError());
+
+            if (!type->isEqual(toType))
+              return subExpr;
+
+            return cs.cacheType(new (tc.Context)
+                                    TypeExpr(expr->getCastTypeLoc()));
+          });
+        }
+
+        literalInit->setImplicit(false);
+        return literalInit;
+      }
+
       // Turn the subexpression into an rvalue.
       auto rvalueSub = cs.coerceToRValue(expr->getSubExpr());
       expr->setSubExpr(rvalueSub);
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 1e5b9cc..788a5043 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -2814,7 +2814,10 @@
   if (!isIntegerType(fromType, CS) || !isIntegerType(toType, CS))
     return false;
 
-  auto getInnerCastedExpr = [&]() -> Expr* {
+  auto getInnerCastedExpr = [&]() -> Expr * {
+    if (auto *CE = dyn_cast<CoerceExpr>(expr))
+      return CE->getSubExpr();
+
     auto *CE = dyn_cast<CallExpr>(expr);
     if (!CE)
       return nullptr;
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 15133a5..9433848 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1394,11 +1394,12 @@
     Type visitTypeExpr(TypeExpr *E) {
       Type type;
       // If this is an implicit TypeExpr, don't validate its contents.
-      if (auto *rep = E->getTypeRepr()) {
-        type = resolveTypeReferenceInExpression(rep);
-      } else {
+      if (E->getTypeLoc().wasValidated()) {
         type = E->getTypeLoc().getType();
+      } else if (auto *rep = E->getTypeRepr()) {
+        type = resolveTypeReferenceInExpression(rep);
       }
+
       if (!type || type->hasError()) return Type();
       
       auto locator = CS.getConstraintLocator(E);
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 3392da0..5f7d20f 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1004,7 +1004,7 @@
 
     // Counts the number of overload sets present in the tree so far.
     // Note that the traversal is depth-first.
-    llvm::SmallVector<std::pair<ApplyExpr *, unsigned>, 4> ApplyExprs;
+    llvm::SmallVector<std::pair<Expr *, unsigned>, 4> ApplyExprs;
 
     // A collection of original domains of all of the expressions,
     // so they can be restored in case of failure.
@@ -1031,6 +1031,8 @@
       }
 
       if (auto coerceExpr = dyn_cast<CoerceExpr>(expr)) {
+        if (coerceExpr->isLiteralInit())
+          ApplyExprs.push_back({coerceExpr, 1});
         visitCoerceExpr(coerceExpr);
         return {false, expr};
       }
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 619ea2c..eb593eb 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -974,6 +974,10 @@
     /// Simplify a key path expression into a canonical form.
     void resolveKeyPathExpr(KeyPathExpr *KPE);
 
+    /// Simplify constructs like `UInt32(1)` into `1 as UInt32` if
+    /// the type conforms to the expected literal protocol.
+    Expr *simplifyTypeConstructionWithLiteralArg(Expr *E);
+
   public:
     PreCheckExpression(TypeChecker &tc, DeclContext *dc, Expr *parent)
         : TC(tc), DC(dc), ParentExpr(parent) {}
@@ -1217,6 +1221,9 @@
         return KPE;
       }
 
+      if (auto *simplified = simplifyTypeConstructionWithLiteralArg(expr))
+        return simplified;
+
       return expr;
     }
 
@@ -1824,6 +1831,66 @@
   KPE->resolveComponents(TC.Context, components);
 }
 
+Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
+  // If constructor call is expected to produce an optional let's not attempt
+  // this optimization because literal initializers aren't failable.
+  if (!TC.getLangOpts().isSwiftVersionAtLeast(5)) {
+    if (!ExprStack.empty()) {
+      auto *parent = ExprStack.back();
+      if (isa<BindOptionalExpr>(parent) || isa<ForceValueExpr>(parent))
+        return nullptr;
+    }
+  }
+
+  auto *call = dyn_cast<CallExpr>(E);
+  if (!call || call->getNumArguments() != 1)
+    return nullptr;
+
+  auto *typeExpr = dyn_cast<TypeExpr>(call->getFn());
+  if (!typeExpr)
+    return nullptr;
+
+  auto *argExpr = call->getArg()->getSemanticsProvidingExpr();
+  auto *literal = dyn_cast<LiteralExpr>(argExpr);
+  if (!literal)
+    return nullptr;
+
+  auto *protocol = TC.getLiteralProtocol(literal);
+  if (!protocol)
+    return nullptr;
+
+  Type type;
+  if (typeExpr->getTypeLoc().wasValidated()) {
+    type = typeExpr->getTypeLoc().getType();
+  } else if (auto *rep = typeExpr->getTypeRepr()) {
+    TypeResolutionOptions options;
+    options |= TypeResolutionFlags::AllowUnboundGenerics;
+    options |= TypeResolutionFlags::InExpression;
+    type = TC.resolveType(rep, DC, options);
+    typeExpr->getTypeLoc().setType(type);
+  }
+
+  if (!type)
+    return nullptr;
+
+  // Don't bother to convert deprecated selector syntax.
+  if (auto selectorTy = TC.getObjCSelectorType(DC)) {
+    if (type->isEqual(selectorTy))
+      return nullptr;
+  }
+
+  ConformanceCheckOptions options;
+  options |= ConformanceCheckFlags::InExpression;
+  options |= ConformanceCheckFlags::SkipConditionalRequirements;
+
+  auto result = TC.conformsToProtocol(type, protocol, DC, options);
+  if (!result || !result->isConcrete())
+    return nullptr;
+
+  return CoerceExpr::forLiteralInit(TC.Context, argExpr, call->getSourceRange(),
+                                    typeExpr->getTypeLoc());
+}
+
 /// \brief Clean up the given ill-formed expression, removing any references
 /// to type variables and setting error types on erroneous expression nodes.
 void CleanupIllFormedExpressionRAII::doIt(Expr *expr) {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index ccf913b..a440a5e 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3664,8 +3664,6 @@
   // up to the caller, who must call hasValidSignature() to
   // check that validateDecl() returned a fully-formed decl.
   if (D->hasValidationStarted()) {
-    if (!(D->isBeingValidated() || D->hasValidSignature()))
-      D->dump();
     // If this isn't reentrant (i.e. D has already been validated), the
     // signature better be valid.
     assert(D->isBeingValidated() || D->hasValidSignature());
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 445d338..68479e1 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -220,9 +220,11 @@
       return concrete->getDeclaredInterfaceType().subst(subMap);
     }
 
-    if (auto superclass = baseEquivClass->superclass) {
-      return superclass->getTypeOfMember(
-                                       DC->getParentModule(), concrete,
+    Type baseType = baseEquivClass->concreteType ? baseEquivClass->concreteType
+                                                 : baseEquivClass->superclass;
+
+    if (baseType) {
+      return baseType->getTypeOfMember(DC->getParentModule(), concrete,
                                        concrete->getDeclaredInterfaceType());
     }
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 9bd6133..aa534e3 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -3318,57 +3318,36 @@
     = Conformance->populateSignatureConformances();
 
   class GatherConformancesListener : public GenericRequirementsCheckListener {
-    TypeChecker &tc;
     NormalProtocolConformance *conformance;
     std::function<void(ProtocolConformanceRef)> &writer;
   public:
     GatherConformancesListener(
-                         TypeChecker &tc,
-                        NormalProtocolConformance *conformance,
-                         std::function<void(ProtocolConformanceRef)> &writer)
-      : tc(tc), conformance(conformance), writer(writer) { }
+        NormalProtocolConformance *conformance,
+        std::function<void(ProtocolConformanceRef)> &writer)
+      : conformance(conformance), writer(writer) { }
 
     void satisfiedConformance(Type depTy, Type replacementTy,
                               ProtocolConformanceRef conformance) override {
       // The conformance will use contextual types, but we want the
       // interface type equivalent.
-
-      // If we have an inherited conformance for an archetype, dig out the
-      // superclass conformance to translate.
-      Type inheritedInterfaceType;
       if (conformance.isConcrete() &&
           conformance.getConcrete()->getType()->hasArchetype()) {
         auto concreteConformance = conformance.getConcrete();
-        if (concreteConformance->getKind()
-              == ProtocolConformanceKind::Inherited &&
-            conformance.getConcrete()->getType()->is<ArchetypeType>()) {
-          inheritedInterfaceType =
-            concreteConformance->getType()->mapTypeOutOfContext();
-          concreteConformance =
-            cast<InheritedProtocolConformance>(concreteConformance)
-              ->getInheritedConformance();
-        }
 
         // Map the conformance.
-        // FIXME: It would be so much easier and efficient if we had
-        // ProtocolConformance::mapTypesOutOfContext().
         auto interfaceType =
           concreteConformance->getType()->mapTypeOutOfContext();
 
-        conformance = *tc.conformsToProtocol(
-                         interfaceType,
-                         conformance.getRequirement(),
-                         this->conformance->getDeclContext(),
-                         (ConformanceCheckFlags::SuppressDependencyTracking|
-                          ConformanceCheckFlags::SkipConditionalRequirements));
+        concreteConformance = concreteConformance->subst(
+            interfaceType,
+            [](SubstitutableType *type) -> Type {
+              if (auto *archetypeType = type->getAs<ArchetypeType>())
+                return archetypeType->getInterfaceType();
+              return type;
+            },
+            MakeAbstractConformanceForGenericType());
 
-        // Reinstate inherited conformance.
-        if (inheritedInterfaceType) {
-          conformance =
-            ProtocolConformanceRef(
-              tc.Context.getInheritedConformance(inheritedInterfaceType,
-                                                 conformance.getConcrete()));
-        }
+        conformance = ProtocolConformanceRef(concreteConformance);
       }
 
       writer(conformance);
@@ -3384,7 +3363,7 @@
 
       return false;
     }
-  } listener(TC, Conformance, writer);
+  } listener(Conformance, writer);
 
   auto result = TC.checkGenericArguments(
       DC, Loc, Loc,
diff --git a/stdlib/public/core/Flatten.swift b/stdlib/public/core/Flatten.swift
index 09b217d..092cae2 100644
--- a/stdlib/public/core/Flatten.swift
+++ b/stdlib/public/core/Flatten.swift
@@ -85,6 +85,8 @@
   }
 }
 
+extension FlattenSequence.Iterator: Sequence { }
+
 extension FlattenSequence: Sequence {
   /// Returns an iterator over the elements of this sequence.
   ///
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index 4ce7b5c..0d02022 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -3592,10 +3592,12 @@
   /// to find an absolute value. In addition, because `abs(_:)` always returns
   /// a value of the same type, even in a generic context, using the function
   /// instead of the `magnitude` property is encouraged.
-  @_transparent
   public var magnitude: U${Self} {
-    let base = U${Self}(_value)
-    return self < (0 as ${Self}) ? ~base + 1 : base
+    @inline(__always)
+    get {
+      let base = U${Self}(_value)
+      return self < (0 as ${Self}) ? ~base + 1 : base
+    }
   }
 % end
 
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index 06d19bf..eb21519 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -951,7 +951,7 @@
     case bar
   }
 
-  // expected-error@+2 {{binary operator '*' cannot be applied to operands of type 'Int' and 'Float'}} {{35-41=}} {{42-43=}}
+  // expected-error@+2 {{binary operator '*' cannot be applied to operands of type 'Int' and 'Float'}} {{35-35=Int(}} {{42-42=)}}
   // expected-note@+1 {{expected an argument list of type '(Int, Int)'}}
   let _: Int = Foo.bar.rawValue * Float(0)
 
diff --git a/test/Constraints/optional.swift b/test/Constraints/optional.swift
index 2d0b03b..fc16857 100644
--- a/test/Constraints/optional.swift
+++ b/test/Constraints/optional.swift
@@ -272,3 +272,23 @@
 func rdar37508855(_ e1: X?, _ e2: X?) -> [X] {
   return [e1, e2].filter { $0 == nil }.map { $0! }
 }
+
+func se0213() {
+  struct Q: ExpressibleByStringLiteral {
+    typealias StringLiteralType =  String
+
+    var foo: String
+
+    init?(_ possibleQ: StringLiteralType) {
+      return nil
+    }
+
+    init(stringLiteral str: StringLiteralType) {
+      self.foo = str
+    }
+  }
+
+  _ = Q("why")?.foo // Ok
+  _ = Q("who")!.foo // Ok
+  _ = Q?("how") // Ok
+}
diff --git a/test/SILOptimizer/diagnostic_constant_propagation-swift4.swift b/test/SILOptimizer/diagnostic_constant_propagation-swift4.swift
index 83390c2..adeac2e 100644
--- a/test/SILOptimizer/diagnostic_constant_propagation-swift4.swift
+++ b/test/SILOptimizer/diagnostic_constant_propagation-swift4.swift
@@ -4,6 +4,5 @@
 // These are specific to Swift 4.
 
 func testArithmeticOverflowSwift4() {
-  var _ = Int8(126) + (1 + 1)  //  FIXME: Should expect an integer overflow
-    // error but none happens now (see <rdar://problem/39120081>)
+  var _ = Int8(126) + (1 + 1) // expected-error {{arithmetic operation '126 + 2' (on type 'Int8') results in an overflow}}
 }
diff --git a/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift b/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift
index 7081100..7c2f6f8 100644
--- a/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift
+++ b/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift
@@ -109,8 +109,5 @@
   let e2: Float80 =  18_446_744_073_709_551_617 // expected-warning {{'18446744073709551617' is not exactly representable as 'Float80'; it becomes '18446744073709551616'}}
   _blackHole(e2)
 
-  // No warnings are emitted for conversion through explicit constructor calls.
-  // Note that the error here is because of an implicit conversion of the input
-  // literal to 'Int'.
-  _blackHole(Float80(18_446_744_073_709_551_617)) // expected-error {{integer literal '18446744073709551617' overflows when stored into 'Int'}}
+  _blackHole(Float80(18_446_744_073_709_551_617)) // Ok
 }
diff --git a/test/SILOptimizer/diagnostic_constant_propagation_int_arch32.swift b/test/SILOptimizer/diagnostic_constant_propagation_int_arch32.swift
index 41fd7ed..a4ef070 100644
--- a/test/SILOptimizer/diagnostic_constant_propagation_int_arch32.swift
+++ b/test/SILOptimizer/diagnostic_constant_propagation_int_arch32.swift
@@ -234,8 +234,5 @@
 }
 
 func testIntToFloatConversion() {
-  // No warnings are emitted for conversion through explicit constructor calls.
-  // Note that the error here is because of an implicit conversion of the input
-  // literal to 'Int', which is 32 bits in arch32.
-  _blackHole(Double(9_007_199_254_740_993)) // expected-error {{integer literal '9007199254740993' overflows when stored into 'Int'}}
+  _blackHole(Double(9_007_199_254_740_993)) // Ok
 }
diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift
index b7122d5..9099fc8 100644
--- a/test/expr/expressions.swift
+++ b/test/expr/expressions.swift
@@ -910,3 +910,10 @@
   let obj = C();
   _ = obj[#column] // Ok.
 }
+
+// rdar://problem/23672697 - No way to express literal integers larger than Int without using type ascription
+let _: Int64 = 0xFFF_FFFF_FFFF_FFFF
+let _: Int64 = Int64(0xFFF_FFFF_FFFF_FFFF)
+let _: Int64 = 0xFFF_FFFF_FFFF_FFFF as Int64
+let _ = Int64(0xFFF_FFFF_FFFF_FFFF)
+let _ = 0xFFF_FFFF_FFFF_FFFF as Int64
diff --git a/validation-test/Sema/type_checker_perf/slow/rdar18699199.swift.gyb b/validation-test/Sema/type_checker_perf/fast/rdar18699199.swift.gyb
similarity index 69%
rename from validation-test/Sema/type_checker_perf/slow/rdar18699199.swift.gyb
rename to validation-test/Sema/type_checker_perf/fast/rdar18699199.swift.gyb
index a3108cc..7b950c4 100644
--- a/validation-test/Sema/type_checker_perf/slow/rdar18699199.swift.gyb
+++ b/validation-test/Sema/type_checker_perf/fast/rdar18699199.swift.gyb
@@ -1,4 +1,4 @@
-// RUN: %scale-test --invert-result --begin 1 --end 5 --step 1 --select incrementScopeCounter %s
+// RUN: %scale-test --begin 1 --end 10 --step 1 --select incrementScopeCounter %s
 // REQUIRES: OS=macosx
 // REQUIRES: asserts
 public enum E
diff --git a/validation-test/compiler_crashers_2_fixed/0165-sr8240.swift b/validation-test/compiler_crashers_2_fixed/0165-sr8240.swift
new file mode 100644
index 0000000..5b175c3
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0165-sr8240.swift
@@ -0,0 +1,14 @@
+// RUN: %target-typecheck-verify-swift
+
+struct Box<Representation> {
+    let value: Representation
+}
+enum Repr {}
+extension Repr {
+    typealias RawEnum = ()
+}
+extension Box where Representation == Repr {
+    init(rawEnumValue: Representation.RawEnum) {
+        fatalError()
+    }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0166-sr8240-2.swift b/validation-test/compiler_crashers_2_fixed/0166-sr8240-2.swift
new file mode 100644
index 0000000..0723703
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0166-sr8240-2.swift
@@ -0,0 +1,15 @@
+// RUN: %target-typecheck-verify-swift
+
+struct Box<Representation, T> {
+    let value: Representation
+}
+enum Repr {}
+extension Repr {
+    typealias RawEnum = ()
+}
+extension Box where Representation == Repr, T == Representation.RawEnum {
+    init(rawEnumValue: Representation.RawEnum) {
+        let _: Int.Type = T.self // expected-error {{cannot convert value of type '().Type' to specified type 'Int.Type'}}
+        fatalError()
+    }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0168-rdar40164371.swift b/validation-test/compiler_crashers_2_fixed/0168-rdar40164371.swift
new file mode 100644
index 0000000..8ab7754
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0168-rdar40164371.swift
@@ -0,0 +1,44 @@
+// RUN: %target-swift-frontend -emit-sil %s
+
+protocol X1 {
+  associatedtype X3 : X4
+}
+
+protocol X4 {
+  associatedtype X15
+}
+
+protocol X7 { }
+
+protocol X9 : X7 {
+  associatedtype X10 : X7
+}
+
+struct X12 : X9 {
+  typealias X10 = X12
+}
+
+struct X13<I1 : X7> : X9 {
+  typealias X10 = X13<I1>
+}
+
+struct X14<G : X4> : X4 where G.X15 : X9 {
+  typealias X15 = X13<G.X15.X10>
+}
+
+struct X17<A : X4> : X1 where A.X15 == X12 {
+  typealias X3 = X14<A>
+}
+
+struct X18 : X4 {
+  typealias X15 = X12
+}
+
+@_transparent
+func callee<T>(_: T) where T : X1 {
+  let _: T.X3.X15? = nil
+}
+
+func caller(b: X17<X18>) {
+  callee(b)
+}
diff --git a/validation-test/compiler_crashers/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift b/validation-test/compiler_crashers_fixed/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
similarity index 87%
rename from validation-test/compiler_crashers/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
rename to validation-test/compiler_crashers_fixed/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
index ece7287..dd3f37e 100644
--- a/validation-test/compiler_crashers/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
+++ b/validation-test/compiler_crashers_fixed/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
@@ -5,5 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol P{class a{protocol a:P{func a:a.a{}typealias a
diff --git a/validation-test/stdlib/Collection/FlattenCollection.swift.gyb b/validation-test/stdlib/Collection/FlattenCollection.swift.gyb
index 26849a5..e4d7833 100644
--- a/validation-test/stdlib/Collection/FlattenCollection.swift.gyb
+++ b/validation-test/stdlib/Collection/FlattenCollection.swift.gyb
@@ -66,10 +66,15 @@
   do {
     let expected = ["apple", "orange", "banana", "grapefruit", "lychee"]
     let base = [["apple", "orange"], ["banana", "grapefruit"], ["lychee"]]
+    let flattened = Minimal${traversal}${kind}(elements: base).joined()
     check${traversal}${kind}(
       expected,
       Minimal${traversal}${kind}(elements: base).joined(),
       sameValue: { $0 == $1 })
+    checkSequence(
+      expected,
+      flattened.makeIterator(),
+      sameValue: { $0 == $1 })
   }
 }
 % end