Merge pull request #13926 from xedin/rdar-26060144

[Runtime/ABI] Replace `emitTypeFieldAccessor` with a single runtime method
diff --git a/include/swift/Driver/Compilation.h b/include/swift/Driver/Compilation.h
index c2a5513..96112d7 100644
--- a/include/swift/Driver/Compilation.h
+++ b/include/swift/Driver/Compilation.h
@@ -161,6 +161,9 @@
   /// redundant work.
   bool EnableBatchMode;
 
+  /// Provides a randomization seed to batch-mode partitioning, for debugging.
+  unsigned BatchSeed;
+
   /// True if temporary files should not be deleted.
   bool SaveTemps;
 
@@ -203,6 +206,7 @@
               unsigned NumberOfParallelCommands = 1,
               bool EnableIncrementalBuild = false,
               bool EnableBatchMode = false,
+              unsigned BatchSeed = 0,
               bool SkipTaskExecution = false,
               bool SaveTemps = false,
               bool ShowDriverTimeCompilation = false,
diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h
index dab4b8c..e957a40 100644
--- a/include/swift/Driver/Driver.h
+++ b/include/swift/Driver/Driver.h
@@ -156,6 +156,9 @@
   /// Indicates whether the driver should check that the input files exist.
   bool CheckInputFilesExist = true;
 
+  /// Provides a randomization seed to batch-mode partitioning, for debugging.
+  unsigned DriverBatchSeed = 0;
+
 public:
   Driver(StringRef DriverExecutable, StringRef Name,
          ArrayRef<const char *> Args, DiagnosticEngine &Diags);
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index d1c1030..0f2d9df 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -98,6 +98,9 @@
   HelpText<"Show every step in the lifecycle of driver jobs">;
 def driver_use_filelists : Flag<["-"], "driver-use-filelists">,
   InternalDebugOpt, HelpText<"Pass input files as filelists whenever possible">;
+def driver_batch_seed : Separate<["-"], "driver-batch-seed">,
+  InternalDebugOpt,
+  HelpText<"Use the given seed value to randomize batch-mode partitions">;
 
 def driver_always_rebuild_dependents :
   Flag<["-"], "driver-always-rebuild-dependents">, InternalDebugOpt,
diff --git a/include/swift/SILOptimizer/Utils/Local.h b/include/swift/SILOptimizer/Utils/Local.h
index d6ebd5c..9ef601c 100644
--- a/include/swift/SILOptimizer/Utils/Local.h
+++ b/include/swift/SILOptimizer/Utils/Local.h
@@ -161,8 +161,6 @@
 bool tryCheckedCastBrJumpThreading(SILFunction *Fn, DominanceInfo *DT,
                           SmallVectorImpl<SILBasicBlock *> &BlocksForWorklist);
 
-void recalcDomTreeForCCBOpt(DominanceInfo *DT, SILFunction &F);
-
 /// A structure containing callbacks that are called when an instruction is
 /// removed or added.
 struct InstModCallbacks {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 17e9664..b9aa54a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -5471,7 +5471,11 @@
   // always delegating. This occurs if the struct type is not fixed layout,
   // and the constructor is either inlinable or defined in another module.
   if (Kind == BodyInitKind::None && isa<StructDecl>(NTD)) {
-    if (NTD->isFormallyResilient() &&
+    // Note: This is specifically not using isFormallyResilient. We relax this
+    // rule for structs in non-resilient modules so that they can have inlinable
+    // constructors, as long as those constructors don't reference private
+    // declarations.
+    if (NTD->isResilient() &&
         getResilienceExpansion() == ResilienceExpansion::Minimal) {
       Kind = BodyInitKind::Delegating;
 
diff --git a/lib/Basic/PartsOfSpeech.def b/lib/Basic/PartsOfSpeech.def
index 05326b7..a134ab9 100644
--- a/lib/Basic/PartsOfSpeech.def
+++ b/lib/Basic/PartsOfSpeech.def
@@ -370,7 +370,6 @@
 VERB(hand)
 VERB(handle)
 VERB(hang)
-VERB(hang)
 VERB(happen)
 VERB(harass)
 VERB(harm)
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 57c2a15..f091fee 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -4511,15 +4511,15 @@
     }
 
     Decl *VisitObjCInterfaceDecl(const clang::ObjCInterfaceDecl *decl) {
-      auto createRootClass = [=](Identifier name,
-                                 DeclContext *dc = nullptr) -> ClassDecl * {
+      auto createFakeRootClass = [=](Identifier name,
+                                     DeclContext *dc = nullptr) -> ClassDecl * {
         if (!dc) {
           dc = Impl.getClangModuleForDecl(decl->getCanonicalDecl(),
                                           /*allowForwardDeclaration=*/true);
         }
 
         auto result = Impl.createDeclWithClangNode<ClassDecl>(decl,
-                                                        AccessLevel::Open,
+                                                        AccessLevel::Public,
                                                         SourceLoc(), name,
                                                         SourceLoc(), None,
                                                         nullptr, dc);
@@ -4547,7 +4547,7 @@
         const ClassDecl *nsObjectDecl =
           nsObjectTy->getClassOrBoundGenericClass();
 
-        auto result = createRootClass(Impl.SwiftContext.Id_Protocol,
+        auto result = createFakeRootClass(Impl.SwiftContext.Id_Protocol,
                                       nsObjectDecl->getDeclContext());
         result->setForeignClassKind(ClassDecl::ForeignKind::RuntimeOnly);
         return result;
@@ -4579,7 +4579,7 @@
 
         if (Impl.ImportForwardDeclarations) {
           // Fake it by making an unavailable opaque @objc root class.
-          auto result = createRootClass(name);
+          auto result = createFakeRootClass(name);
           result->setImplicit();
           auto attr = AvailableAttr::createPlatformAgnostic(Impl.SwiftContext,
               "This Objective-C class has only been forward-declared; "
@@ -4602,13 +4602,16 @@
       if (declaredNative && nativeDecl)
         return nativeDecl;
 
+      auto access = AccessLevel::Open;
+      if (decl->hasAttr<clang::ObjCSubclassingRestrictedAttr>() &&
+          Impl.SwiftContext.isSwiftVersionAtLeast(5)) {
+        access = AccessLevel::Public;
+      }
+
       // Create the class declaration and record it.
-      auto result = Impl.createDeclWithClangNode<ClassDecl>(decl,
-                                AccessLevel::Open,
-                                Impl.importSourceLoc(decl->getLocStart()),
-                                name,
-                                Impl.importSourceLoc(decl->getLocation()),
-                                None, nullptr, dc);
+      auto result = Impl.createDeclWithClangNode<ClassDecl>(
+          decl, access, Impl.importSourceLoc(decl->getLocStart()), name,
+          Impl.importSourceLoc(decl->getLocation()), None, nullptr, dc);
 
       // Import generic arguments, if any.
       if (auto gpImportResult = importObjCGenericParams(decl, dc)) {
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 7360d18..f43a17a 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -42,6 +42,10 @@
 
 #include "CompilationRecord.h"
 
+// Batch-mode has a sub-mode for testing that randomizes batch partitions,
+// by user-provided seed. That is the only thing randomized here.
+#include <random>
+
 using namespace swift;
 using namespace swift::sys;
 using namespace swift::driver;
@@ -97,6 +101,7 @@
                          unsigned NumberOfParallelCommands,
                          bool EnableIncrementalBuild,
                          bool EnableBatchMode,
+                         unsigned BatchSeed,
                          bool SkipTaskExecution,
                          bool SaveTemps,
                          bool ShowDriverTimeCompilation,
@@ -112,6 +117,7 @@
     SkipTaskExecution(SkipTaskExecution),
     EnableIncrementalBuild(EnableIncrementalBuild),
     EnableBatchMode(EnableBatchMode),
+    BatchSeed(BatchSeed),
     SaveTemps(SaveTemps),
     ShowDriverTimeCompilation(ShowDriverTimeCompilation),
     Stats(std::move(StatsReporter)) {
@@ -120,7 +126,8 @@
 static bool writeFilelistIfNecessary(const Job *job, DiagnosticEngine &diags);
 
 using CommandSet = llvm::SmallPtrSet<const Job *, 16>;
-
+using CommandSetVector = llvm::SetVector<const Job*>;
+using BatchPartition = std::vector<std::vector<const Job*>>;
 
 using InputInfoMap = llvm::SmallMapVector<const llvm::opt::Arg *,
                                           CompileJobAction::InputInfo, 16>;
@@ -140,7 +147,7 @@
     /// A temporary buffer to hold commands that were scheduled but haven't been
     /// added to the Task Queue yet, because we might try batching them together
     /// first.
-    CommandSet PendingExecution;
+    CommandSetVector PendingExecution;
 
     /// Set of synthetic BatchJobs that serve to cluster subsets of jobs waiting
     /// in PendingExecution. Also used to identify (then unpack) BatchJobs back
@@ -680,7 +687,8 @@
 
     /// Insert all jobs in \p Cmds (of descriptive name \p Kind) to the \c
     /// TaskQueue, and clear \p Cmds.
-    void transferJobsToTaskQueue(CommandSet &Cmds, StringRef Kind) {
+    template <typename Container>
+    void transferJobsToTaskQueue(Container &Cmds, StringRef Kind) {
       for (const Job *Cmd : Cmds) {
         if (Comp.ShowJobLifecycle)
           llvm::outs() << "Adding " << Kind
@@ -694,8 +702,8 @@
     /// Partition the jobs in \c PendingExecution into those that are \p
     /// Batchable and those that are \p NonBatchable, clearing \p
     /// PendingExecution.
-    void getPendingBatchableJobs(CommandSet &Batchable,
-                                 CommandSet &NonBatchable) {
+    void getPendingBatchableJobs(CommandSetVector &Batchable,
+                                 CommandSetVector &NonBatchable) {
       for (const Job *Cmd : PendingExecution) {
         if (Comp.getToolChain().jobIsBatchable(Comp, Cmd)) {
           if (Comp.ShowJobLifecycle)
@@ -710,49 +718,83 @@
       PendingExecution.clear();
     }
 
-    /// If \p CurrentBatch is nonempty, construct a new \c BatchJob from its
+    /// If \p Batch is nonempty, construct a new \c BatchJob from its
     /// contents by calling \p ToolChain::constructBatchJob, then insert the
-    /// new \c BatchJob into \p Batches and clear \p CurrentBatch.
+    /// new \c BatchJob into \p Batches.
     void
-    formBatchJobFromCurrentBatch(CommandSet &Batches,
-                                 llvm::SetVector<const Job *> &CurrentBatch) {
-      if (CurrentBatch.empty())
+    formBatchJobFromPartitionBatch(std::vector<const Job *> &Batches,
+                                   std::vector<const Job *> const &Batch) {
+      if (Batch.empty())
         return;
       if (Comp.ShowJobLifecycle)
         llvm::outs() << "Forming batch job from "
-                     << CurrentBatch.size() << " constituents\n";
+                     << Batch.size() << " constituents\n";
       auto const &TC = Comp.getToolChain();
-      auto J = TC.constructBatchJob(CurrentBatch.getArrayRef(), Comp);
+      auto J = TC.constructBatchJob(Batch, Comp);
       if (J)
-        Batches.insert(Comp.addJob(std::move(J)));
-      CurrentBatch.clear();
+        Batches.push_back(Comp.addJob(std::move(J)));
     }
 
-    /// Return true iff \p Cmd can be expanded by \p CurrentBatch, meaning
-    /// that \p CurrentBatch is smaller than \p TargetBatchSize and \p Cmd
-    /// is batch-combinable with the equivalence class of \p CurrentBatch
-    /// (as represented by element 0 of \p CurrentBatch).
-    bool canExpandBatch(const Job *Cmd,
-                        llvm::SetVector<const Job *> &CurrentBatch,
-                        size_t TargetBatchSize) {
-      auto const &TC = Comp.getToolChain();
-      return (CurrentBatch.empty() ||
-              (TC.jobsAreBatchCombinable(Comp, Cmd, CurrentBatch[0]) &&
-               CurrentBatch.size() < TargetBatchSize));
+    /// Inspect current batch \p i of the \p Partition currently being built
+    /// and, if that batch is "full" (in the sense of holding an evenly-divided
+    /// portion of NumJobs) then advance \p i to the next batch index in the
+    /// partition.
+    void maybeAdvanceToNextPartition(size_t &i,
+                                     BatchPartition const &Partition,
+                                     size_t NumJobs) {
+      assert(i < Partition.size());
+      size_t Remainder = NumJobs % Partition.size();
+      size_t TargetSize = NumJobs / Partition.size();
+      // Spread remainder evenly across partitions by adding 1 to the target
+      // size of the first Remainder of them.
+      if (i < Remainder)
+        TargetSize++;
+      if (Partition[i].size() >= TargetSize)
+        ++i;
+      assert(i < Partition.size());
     }
 
-    /// If \p CurrentBatch can't be expanded with \p Cmd, form a new \c BatchJob
-    /// from \p CurrentBatch, add it to \p Batches, and reset\p CurrentBatch;
-    /// then in either case, insert \p Cmd into \p CurrentBatch.
-    void expandBatch(const Job *Cmd,
-                     CommandSet &Batches,
-                     llvm::SetVector<const Job *> &CurrentBatch,
-                     size_t TargetBatchSize) {
-      if (!canExpandBatch(Cmd, CurrentBatch, TargetBatchSize)) {
-        formBatchJobFromCurrentBatch(Batches, CurrentBatch);
+    /// Shuffle \p Batchable if -driver-batch-seed is nonzero.
+    void maybeShuffleBatchable(std::vector<const Job *> &Batchable) {
+      if (Comp.BatchSeed != 0) {
+        std::minstd_rand gen(Comp.BatchSeed);
+        std::shuffle(Batchable.begin(), Batchable.end(), gen);
       }
-      llvm::outs() << "Adding to batch: " << LogJob(Cmd) << "\n";
-      CurrentBatch.insert(Cmd);
+    }
+
+    /// Create \c NumberOfParallelCommands batches and assign each job to a
+    /// batch either filling each partition in order or, if seeded with a
+    /// nonzero value, pseudo-randomly (but determinstically and nearly-evenly).
+    void partitionIntoBatches(std::vector<const Job *> Batchable,
+                              BatchPartition &Partition) {
+      if (Comp.ShowJobLifecycle) {
+        llvm::outs() << "Found " << Batchable.size() << " batchable jobs\n";
+        llvm::outs() << "Forming into " << Partition.size() << " batches\n";
+      }
+
+      assert(Partition.size() > 0);
+      maybeShuffleBatchable(Batchable);
+
+      size_t i = 0;
+      auto const &TC = Comp.getToolChain();
+      for (const Job *Cmd : Batchable) {
+        maybeAdvanceToNextPartition(i, Partition, Batchable.size());
+        std::vector<const Job*> &P = Partition[i];
+        if (P.empty() || TC.jobsAreBatchCombinable(Comp, P[0], Cmd)) {
+          if (Comp.ShowJobLifecycle)
+            llvm::outs() << "Adding " << LogJob(Cmd)
+                         << " to batch " << i << '\n';
+          P.push_back(Cmd);
+        } else {
+          // Strange but theoretically possible that we have a batchable job
+          // that's not combinable with others; tack a new batch on for it.
+          if (Comp.ShowJobLifecycle)
+            llvm::outs() << "Adding " << LogJob(Cmd)
+                         << " to new batch " << Partition.size() << '\n';
+          Partition.push_back(std::vector<const Job*>());
+          Partition.back().push_back(Cmd);
+        }
+      }
     }
 
     /// Select jobs that are batch-combinable from \c PendingExecution, combine
@@ -768,25 +810,18 @@
         return;
       }
 
-      // Partition the pending jobs.
-      CommandSet Batchable, NonBatchable, Batches;
+      // Split the batchable from non-batchable pending jobs.
+      CommandSetVector Batchable, NonBatchable;
       getPendingBatchableJobs(Batchable, NonBatchable);
-      size_t TargetBatchSize = Batchable.size() / Comp.NumberOfParallelCommands;
 
-      if (Comp.ShowJobLifecycle) {
-        llvm::outs() << "Found " << Batchable.size() << " batchable jobs\n";
-        llvm::outs() << "Aiming for batch size " << TargetBatchSize << '\n';
-      }
+      // Partition the batchable jobs into sets.
+      BatchPartition Partition(Comp.NumberOfParallelCommands);
+      partitionIntoBatches(Batchable.takeVector(), Partition);
 
-      // Batch the batchable jobs.
-      llvm::SetVector<const Job *> CurrentBatch;
-      for (const Job *Cmd : Batchable) {
-        expandBatch(Cmd, Batches, CurrentBatch, TargetBatchSize);
-      }
-
-      // Form a residual incomplete batch if any jobs remain.
-      if (!CurrentBatch.empty()) {
-        formBatchJobFromCurrentBatch(Batches, CurrentBatch);
+      // Construct a BatchJob from each batch in the partition.
+      std::vector<const Job *> Batches;
+      for (auto const &Batch : Partition) {
+        formBatchJobFromPartitionBatch(Batches, Batch);
       }
 
       // Save batches so we can locate and decompose them on task-exit.
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index e3f7545..a567d8a 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -522,6 +522,12 @@
     ArgList->hasArg(options::OPT_driver_show_incremental);
   bool ShowJobLifecycle =
     ArgList->hasArg(options::OPT_driver_show_job_lifecycle);
+  if (const Arg *A = ArgList->getLastArg(options::OPT_driver_batch_seed)) {
+    if (StringRef(A->getValue()).getAsInteger(10, DriverBatchSeed)) {
+      Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
+                     A->getAsString(*ArgList), A->getValue());
+    }
+  }
 
   bool Incremental = ArgList->hasArg(options::OPT_incremental);
   if (ArgList->hasArg(options::OPT_whole_module_optimization)) {
@@ -684,6 +690,7 @@
                                                  NumberOfParallelCommands,
                                                  Incremental,
                                                  BatchMode,
+                                                 DriverBatchSeed,
                                                  DriverSkipExecution,
                                                  SaveTemps,
                                                  ShowDriverTimeCompilation,
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index bd191de..c53f052 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -244,36 +244,44 @@
   // from a JobAction that itself has InputActions sources, then we collect
   // those up. Otherwise it's more correct to talk about our inputs as the
   // outputs of our input-jobs.
-  SmallVector<std::string, 4> Inputs;
+  SmallVector<StringRef, 4> Inputs;
+  SmallVector<StringRef, 4> Outputs = getOutput().getPrimaryOutputFilenames();
 
   for (const Action *A : getSource().getInputs())
     if (const auto *IA = dyn_cast<InputAction>(A))
       Inputs.push_back(IA->getInputArg().getValue());
 
   for (const Job *J : getInputs())
-    for (const std::string &f : J->getOutput().getPrimaryOutputFilenames())
+    for (StringRef f : J->getOutput().getPrimaryOutputFilenames())
       Inputs.push_back(f);
 
   size_t limit = 3;
-  size_t actual = Inputs.size();
-  if (actual > limit) {
+  size_t actual_in = Inputs.size();
+  size_t actual_out = Outputs.size();
+  if (actual_in > limit) {
     Inputs.erase(Inputs.begin() + limit, Inputs.end());
   }
+  if (actual_out > limit) {
+    Outputs.erase(Outputs.begin() + limit, Outputs.end());
+  }
 
   os << "{" << getSource().getClassName() << ": ";
-  interleave(getOutput().getPrimaryOutputFilenames(),
+  interleave(Outputs,
              [&](const std::string &Arg) {
                os << llvm::sys::path::filename(Arg);
              },
              [&] { os << ' '; });
+  if (actual_out > limit) {
+    os << " ... " << (actual_out-limit) << " more";
+  }
   os << " <= ";
   interleave(Inputs,
              [&](const std::string &Arg) {
                os << llvm::sys::path::filename(Arg);
              },
              [&] { os << ' '; });
-  if (actual > limit) {
-    os << " ... " << (actual-limit) << " more";
+  if (actual_in > limit) {
+    os << " ... " << (actual_in-limit) << " more";
   }
   os << "}";
 }
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index e0b28f2..4484168 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -544,10 +544,11 @@
 
   public:
     /// \brief Build a reference to the given declaration.
-    Expr *buildDeclRef(ValueDecl *decl, DeclNameLoc loc, Type openedType,
+    Expr *buildDeclRef(OverloadChoice choice, DeclNameLoc loc, Type openedType,
                        ConstraintLocatorBuilder locator, bool implicit,
                        FunctionRefKind functionRefKind,
                        AccessSemantics semantics) {
+      auto *decl = choice.getDecl();
       // Determine the declaration selected for this overloaded reference.
       auto &ctx = cs.getASTContext();
       
@@ -612,7 +613,7 @@
                 if (auto fnConv = dyn_cast<FunctionConversionExpr>(refExpr))
                   refExpr = fnConv->getSubExpr();
 
-                return forceUnwrapIfExpected(refExpr, decl, locator);
+                return forceUnwrapIfExpected(refExpr, choice, locator);
               }
             }
           }
@@ -623,7 +624,7 @@
           TypeExpr::createImplicitHack(loc.getBaseNameLoc(), baseTy, ctx);
         cs.cacheExprTypes(base);
 
-        return buildMemberRef(base, openedType, SourceLoc(), decl, loc,
+        return buildMemberRef(base, openedType, SourceLoc(), choice, loc,
                               openedFnType->getResult(), locator, locator,
                               implicit, functionRefKind, semantics,
                               /*isDynamic=*/false);
@@ -659,7 +660,7 @@
                               loc, implicit, semantics, type);
       cs.cacheType(declRefExpr);
       declRefExpr->setFunctionRefKind(functionRefKind);
-      return forceUnwrapIfExpected(declRefExpr, decl, locator);
+      return forceUnwrapIfExpected(declRefExpr, choice, locator);
     }
 
     /// Describes an opened existential that has not yet been closed.
@@ -899,11 +900,12 @@
 
     /// \brief Build a new member reference with the given base and member.
     Expr *buildMemberRef(Expr *base, Type openedFullType, SourceLoc dotLoc,
-                         ValueDecl *member, DeclNameLoc memberLoc,
+                         OverloadChoice choice, DeclNameLoc memberLoc,
                          Type openedType, ConstraintLocatorBuilder locator,
                          ConstraintLocatorBuilder memberLocator, bool Implicit,
                          FunctionRefKind functionRefKind,
                          AccessSemantics semantics, bool isDynamic) {
+      ValueDecl *member = choice.getDecl();
       auto &tc = cs.getTypeChecker();
       auto &context = tc.Context;
 
@@ -949,7 +951,7 @@
         ref->setFunctionRefKind(functionRefKind);
         auto *DSBI = cs.cacheType(new (context) DotSyntaxBaseIgnoredExpr(
             base, dotLoc, ref, cs.getType(ref)));
-        return forceUnwrapIfExpected(DSBI, member, memberLocator);
+        return forceUnwrapIfExpected(DSBI, choice, memberLocator);
       }
 
       // The formal type of the 'self' value for the member's declaration.
@@ -1088,8 +1090,9 @@
         // We also need to handle the implicitly unwrap of the result
         // of the called function if that's the type checking solution
         // we ended up with.
-        return forceUnwrapIfExpected(ref, member, memberLocator,
-                                     member->getAttrs().hasAttribute<OptionalAttr>());
+        return forceUnwrapIfExpected(
+            ref, choice, memberLocator,
+            member->getAttrs().hasAttribute<OptionalAttr>());
       }
 
       // For types and properties, build member references.
@@ -1115,7 +1118,7 @@
         cs.setType(memberRefExpr, simplifyType(openedType));
         Expr *result = memberRefExpr;
         closeExistential(result, locator);
-        return forceUnwrapIfExpected(result, member, memberLocator);
+        return forceUnwrapIfExpected(result, choice, memberLocator);
       }
       
       // Handle all other references.
@@ -1135,7 +1138,7 @@
       ApplyExpr *apply;
       if (isa<ConstructorDecl>(member)) {
         // FIXME: Provide type annotation.
-        ref = forceUnwrapIfExpected(ref, member, memberLocator);
+        ref = forceUnwrapIfExpected(ref, choice, memberLocator);
         apply = new (context) ConstructorRefCallExpr(ref, base);
       } else if (!baseIsInstance && member->isInstanceMember()) {
         // Reference to an unbound instance method.
@@ -1144,11 +1147,11 @@
                                                               cs.getType(ref));
         cs.cacheType(result);
         closeExistential(result, locator, /*force=*/openedExistential);
-        return forceUnwrapIfExpected(result, member, memberLocator);
+        return forceUnwrapIfExpected(result, choice, memberLocator);
       } else {
         assert((!baseIsInstance || member->isInstanceMember()) &&
                "can't call a static method on an instance");
-        ref = forceUnwrapIfExpected(ref, member, memberLocator);
+        ref = forceUnwrapIfExpected(ref, choice, memberLocator);
         apply = new (context) DotSyntaxCallExpr(ref, dotLoc, base);
         if (Implicit) {
           apply->setImplicit();
@@ -1449,10 +1452,10 @@
         if (selected->choice.getKind() ==
             OverloadChoiceKind::DynamicMemberLookup)
           locatorKind = ConstraintLocator::Member;
-        
-        newSubscript = forceUnwrapIfExpected(
-            newSubscript, selected->choice.getDecl(),
-            locator.withPathElement(locatorKind));
+
+        newSubscript =
+            forceUnwrapIfExpected(newSubscript, selected->choice,
+                                  locator.withPathElement(locatorKind));
       }
 
       return newSubscript;
@@ -2471,8 +2474,9 @@
       }
     }
 
-    bool shouldForceUnwrapResult(Decl *decl, ConstraintLocatorBuilder locator) {
-      if (!decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+    bool shouldForceUnwrapResult(OverloadChoice choice,
+                                 ConstraintLocatorBuilder locator) {
+      if (!choice.isImplicitlyUnwrappedValueOrReturnValue())
         return false;
 
       auto *choiceLocator = cs.getConstraintLocator(locator.withPathElement(
@@ -2481,10 +2485,10 @@
       return solution.getDisjunctionChoice(choiceLocator);
     }
 
-    Expr *forceUnwrapIfExpected(Expr *expr, Decl *decl,
+    Expr *forceUnwrapIfExpected(Expr *expr, OverloadChoice choice,
                                 ConstraintLocatorBuilder locator,
-                                bool forForcedOptional =false) {
-      if (!shouldForceUnwrapResult(decl, locator))
+                                bool forForcedOptional = false) {
+      if (!shouldForceUnwrapResult(choice, locator))
         return expr;
 
       // Force the expression if required for the solution.
@@ -2503,12 +2507,9 @@
         cs.setType(expr, varDecl->getType());
         return expr;
       }
-      
-      auto choice = selected->choice;
-      auto decl = choice.getDecl();
 
-      return buildDeclRef(decl, expr->getNameLoc(), selected->openedFullType,
-                          locator, expr->isImplicit(),
+      return buildDeclRef(selected->choice, expr->getNameLoc(),
+                          selected->openedFullType, locator, expr->isImplicit(),
                           expr->getFunctionRefKind(),
                           expr->getAccessSemantics());
     }
@@ -2539,9 +2540,8 @@
       auto locator = cs.getConstraintLocator(expr);
       auto selected = getOverloadChoice(locator);
       auto choice = selected.choice;
-      auto decl = choice.getDecl();
 
-      return buildDeclRef(decl, expr->getNameLoc(), selected.openedFullType,
+      return buildDeclRef(choice, expr->getNameLoc(), selected.openedFullType,
                           locator, expr->isImplicit(),
                           choice.getFunctionRefKind(),
                           AccessSemantics::Ordinary);
@@ -2566,7 +2566,7 @@
         = selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
       return buildMemberRef(
           expr->getBase(), selected.openedFullType, expr->getDotLoc(),
-          selected.choice.getDecl(), expr->getNameLoc(), selected.openedType,
+          selected.choice, expr->getNameLoc(), selected.openedType,
           cs.getConstraintLocator(expr), memberLocator, expr->isImplicit(),
           selected.choice.getFunctionRefKind(), expr->getAccessSemantics(),
           isDynamic);
@@ -2594,7 +2594,6 @@
       auto memberLocator = cs.getConstraintLocator(
                              expr, ConstraintLocator::UnresolvedMember);
       auto selected = getOverloadChoice(memberLocator);
-      auto member = selected.choice.getDecl();
       
       // If the member came by optional unwrapping, then unwrap the base type.
       if (selected.choice.getKind()
@@ -2614,7 +2613,7 @@
       bool isDynamic
         = selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
       auto result = buildMemberRef(
-          base, selected.openedFullType, expr->getDotLoc(), member,
+          base, selected.openedFullType, expr->getDotLoc(), selected.choice,
           expr->getNameLoc(), selected.openedType,
           cs.getConstraintLocator(expr), memberLocator, expr->isImplicit(),
           selected.choice.getFunctionRefKind(), AccessSemantics::Ordinary,
@@ -2651,9 +2650,10 @@
     Expr *applyCtorRefExpr(Expr *expr, Expr *base, SourceLoc dotLoc,
                            DeclNameLoc nameLoc, bool implicit,
                            ConstraintLocator *ctorLocator,
-                           ConstructorDecl *ctor,
-                           FunctionRefKind functionRefKind,
-                           Type openedType) {
+                           OverloadChoice choice,
+                           FunctionRefKind functionRefKind, Type openedType) {
+
+      auto *ctor = cast<ConstructorDecl>(choice.getDecl());
 
       // If the member is a constructor, verify that it can be legally
       // referenced from this base.
@@ -2665,7 +2665,7 @@
       // constructor.
       if (cs.getType(base)->is<AnyMetatypeType>()) {
         return buildMemberRef(
-            base, openedType, dotLoc, ctor, nameLoc, cs.getType(expr),
+            base, openedType, dotLoc, choice, nameLoc, cs.getType(expr),
             ConstraintLocatorBuilder(cs.getConstraintLocator(expr)),
             ctorLocator, implicit, functionRefKind, AccessSemantics::Ordinary,
             /*isDynamic=*/false);
@@ -2731,10 +2731,9 @@
                            ConstraintLocator::ConstructorMember);
       if (auto selected = getOverloadChoiceIfAvailable(ctorLocator)) {
         auto choice = selected->choice;
-        auto *ctor = cast<ConstructorDecl>(choice.getDecl());
-        return applyCtorRefExpr(expr, base, dotLoc, nameLoc, implicit,
-                                ctorLocator, ctor, choice.getFunctionRefKind(),
-                                selected->openedFullType);
+        return applyCtorRefExpr(
+            expr, base, dotLoc, nameLoc, implicit, ctorLocator, choice,
+            choice.getFunctionRefKind(), selected->openedFullType);
       }
 
       // Determine the declaration selected for this overloaded reference.
@@ -2783,11 +2782,11 @@
       case OverloadChoiceKind::DeclViaDynamic: {
         bool isDynamic
           = selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
-        return buildMemberRef(
-            base, selected.openedFullType, dotLoc, selected.choice.getDecl(),
-            nameLoc, selected.openedType, cs.getConstraintLocator(expr),
-            memberLocator, implicit, selected.choice.getFunctionRefKind(),
-            AccessSemantics::Ordinary, isDynamic);
+        return buildMemberRef(base, selected.openedFullType, dotLoc,
+                              selected.choice, nameLoc, selected.openedType,
+                              cs.getConstraintLocator(expr), memberLocator,
+                              implicit, selected.choice.getFunctionRefKind(),
+                              AccessSemantics::Ordinary, isDynamic);
       }
 
       case OverloadChoiceKind::TupleIndex: {
@@ -4370,7 +4369,7 @@
           baseTy = component.getComponentType();
           resolvedComponents.push_back(component);
 
-          if (shouldForceUnwrapResult(property, locator)) {
+          if (shouldForceUnwrapResult(foundDecl->choice, locator)) {
             auto objectTy = getObjectType(baseTy);
             auto loc = origComponent.getLoc();
             component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
@@ -4451,7 +4450,7 @@
           baseTy = component.getComponentType();
           resolvedComponents.push_back(component);
 
-          if (shouldForceUnwrapResult(subscript, locator)) {
+          if (shouldForceUnwrapResult(foundDecl->choice, locator)) {
             auto objectTy = getObjectType(baseTy);
             auto loc = origComponent.getLoc();
             component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
@@ -7469,17 +7468,16 @@
 
   // We have the constructor.
   auto choice = selected->choice;
-  auto decl = choice.getDecl();
   
   // Consider the constructor decl reference expr 'implicit', but the
   // constructor call expr itself has the apply's 'implicitness'.
   bool isDynamic = choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
-  Expr *declRef =
-      buildMemberRef(fn, selected->openedFullType,
-                     /*dotLoc=*/SourceLoc(), decl, DeclNameLoc(fn->getEndLoc()),
-                     selected->openedType, locator, ctorLocator,
-                     /*Implicit=*/true, choice.getFunctionRefKind(),
-                     AccessSemantics::Ordinary, isDynamic);
+  Expr *declRef = buildMemberRef(fn, selected->openedFullType,
+                                 /*dotLoc=*/SourceLoc(), choice,
+                                 DeclNameLoc(fn->getEndLoc()),
+                                 selected->openedType, locator, ctorLocator,
+                                 /*Implicit=*/true, choice.getFunctionRefKind(),
+                                 AccessSemantics::Ordinary, isDynamic);
   if (!declRef)
     return nullptr;
   declRef->setImplicit(apply->isImplicit());
@@ -8173,8 +8171,10 @@
   ExprRewriter rewriter(cs, solution,
                         /*suppressDiagnostics=*/false);
 
+  auto choice =
+      OverloadChoice(openedFullType, witness, FunctionRefKind::SingleApply);
   auto memberRef = rewriter.buildMemberRef(
-      base, openedFullType, base->getStartLoc(), witness,
+      base, openedFullType, base->getStartLoc(), choice,
       DeclNameLoc(base->getEndLoc()), openedType, dotLocator, dotLocator,
       /*Implicit=*/true, FunctionRefKind::SingleApply,
       AccessSemantics::Ordinary,
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index 7a0e1e7..62cfdfc 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -1957,6 +1957,23 @@
 }
 
 bool OverloadChoice::isImplicitlyUnwrappedValueOrReturnValue() const {
-  return isDecl() &&
-         getDecl()->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
+  if (!isDecl())
+    return false;
+
+  auto *decl = getDecl();
+  if (!decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+    return false;
+
+  auto itfType = decl->getInterfaceType();
+  if (!itfType->getAs<AnyFunctionType>())
+    return true;
+
+  switch (getFunctionRefKind()) {
+  case FunctionRefKind::Unapplied:
+  case FunctionRefKind::Compound:
+    return false;
+  case FunctionRefKind::SingleApply:
+  case FunctionRefKind::DoubleApply:
+    return true;
+  }
 }
diff --git a/lib/Sema/OverloadChoice.h b/lib/Sema/OverloadChoice.h
index 1752343..4e4afac 100644
--- a/lib/Sema/OverloadChoice.h
+++ b/lib/Sema/OverloadChoice.h
@@ -190,6 +190,7 @@
     result.BaseAndDeclKind.setPointer(base);
     result.DeclOrKind = value;
     result.DynamicNameAndFRK.setPointer(name);
+    result.DynamicNameAndFRK.setInt(FunctionRefKind::SingleApply);
     return result;
   }
 
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index cca4735..fc1e097 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -2276,14 +2276,10 @@
 
   // If we entered an initializer context, contextualize any
   // auto-closures we might have created.
-  if (initContext) {
+  if (initContext && !hadError) {
     // Check safety of error-handling in the declaration, too.
-    if (!hadError) {
-      checkInitializerErrorHandling(initContext, init);
-    }
-
-    if (!hadError)
-      (void)contextualizeInitializer(initContext, init);
+    checkInitializerErrorHandling(initContext, init);
+    (void)contextualizeInitializer(initContext, init);
   }
 
   if (hadError) {
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index d9fb64b..06a1213 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -1620,9 +1620,12 @@
     }
 
     // An inlinable constructor in a class must always be delegating,
-    // unless the class is formally '@_fixed_layout'.
-    if (!isDelegating &&
-        ClassD->isFormallyResilient() &&
+    // unless the class is '@_fixed_layout'.
+    // Note: This is specifically not using isFormallyResilient. We relax this
+    // rule for classes in non-resilient modules so that they can have inlinable
+    // constructors, as long as those constructors don't reference private
+    // declarations.
+    if (!isDelegating && ClassD->isResilient() &&
         ctor->getResilienceExpansion() == ResilienceExpansion::Minimal) {
       diagnose(ctor, diag::class_designated_init_inlineable_resilient,
                ClassD->getDeclaredInterfaceType(),
diff --git a/stdlib/public/core/Policy.swift b/stdlib/public/core/Policy.swift
index 8128f8c..ce5db62 100644
--- a/stdlib/public/core/Policy.swift
+++ b/stdlib/public/core/Policy.swift
@@ -474,39 +474,44 @@
   static var allZeros: Self { get }
 }
 
-/// Calculates the union of bits sets in the two arguments and stores the result
-/// in the first argument.
-///
-/// - Parameters:
-///   - lhs: A value to update with the union of bits set in the two arguments.
-///   - rhs: Another value.
-@_inlineable // FIXME(sil-serialize-all)
-public func |= <T : _BitwiseOperations>(lhs: inout T, rhs: T) {
-  lhs = lhs | rhs
-}
+extension _BitwiseOperations {
+  /// Calculates the union of bits sets in the two arguments and stores the result
+  /// in the first argument.
+  ///
+  /// - Parameters:
+  ///   - lhs: A value to update with the union of bits set in the two arguments.
+  ///   - rhs: Another value.
+  @_inlineable // FIXME(sil-serialize-all)
+  @available(swift, obsoleted: 4.1)
+  public static func |= (lhs: inout Self, rhs: Self) {
+    lhs = lhs | rhs
+  }
 
-/// Calculates the intersections of bits sets in the two arguments and stores
-/// the result in the first argument.
-///
-/// - Parameters:
-///   - lhs: A value to update with the intersections of bits set in the two
-///     arguments.
-///   - rhs: Another value.
-@_inlineable // FIXME(sil-serialize-all)
-public func &= <T : _BitwiseOperations>(lhs: inout T, rhs: T) {
-  lhs = lhs & rhs
-}
+  /// Calculates the intersections of bits sets in the two arguments and stores
+  /// the result in the first argument.
+  ///
+  /// - Parameters:
+  ///   - lhs: A value to update with the intersections of bits set in the two
+  ///     arguments.
+  ///   - rhs: Another value.
+  @_inlineable // FIXME(sil-serialize-all)
+  @available(swift, obsoleted: 4.1)
+  public static func &= (lhs: inout Self, rhs: Self) {
+    lhs = lhs & rhs
+  }
 
-/// Calculates the bits that are set in exactly one of the two arguments and
-/// stores the result in the first argument.
-///
-/// - Parameters:
-///   - lhs: A value to update with the bits that are set in exactly one of the
-///     two arguments.
-///   - rhs: Another value.
-@_inlineable // FIXME(sil-serialize-all)
-public func ^= <T : _BitwiseOperations>(lhs: inout T, rhs: T) {
-  lhs = lhs ^ rhs
+  /// Calculates the bits that are set in exactly one of the two arguments and
+  /// stores the result in the first argument.
+  ///
+  /// - Parameters:
+  ///   - lhs: A value to update with the bits that are set in exactly one of the
+  ///     two arguments.
+  ///   - rhs: Another value.
+  @_inlineable // FIXME(sil-serialize-all)
+  @available(swift, obsoleted: 4.1)
+  public static func ^= (lhs: inout Self, rhs: Self) {
+    lhs = lhs ^ rhs
+  }
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/ClangImporter/Inputs/attr-objc_subclassing_restricted.h b/test/ClangImporter/Inputs/attr-objc_subclassing_restricted.h
new file mode 100644
index 0000000..acdd65b
--- /dev/null
+++ b/test/ClangImporter/Inputs/attr-objc_subclassing_restricted.h
@@ -0,0 +1,6 @@
+// This file is meant to be used with the mock SDK.
+#import <Foundation.h>
+
+__attribute__((objc_subclassing_restricted))
+@interface Restricted: NSObject
+@end
diff --git a/test/ClangImporter/attr-objc_subclassing_restricted.swift b/test/ClangImporter/attr-objc_subclassing_restricted.swift
new file mode 100644
index 0000000..dd9b4ac
--- /dev/null
+++ b/test/ClangImporter/attr-objc_subclassing_restricted.swift
@@ -0,0 +1,9 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -import-objc-header %S/Inputs/attr-objc_subclassing_restricted.h %s -swift-version 5 -verify
+
+// No errors in Swift 3 and 4 modes.
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -import-objc-header %S/Inputs/attr-objc_subclassing_restricted.h %s -swift-version 4
+
+// REQUIRES: objc_interop
+
+class Sub: Restricted { // expected-error {{cannot inherit from non-open class 'Restricted' outside of its defining module}}
+}
diff --git a/test/Constraints/iuo.swift b/test/Constraints/iuo.swift
index b483b4f..a4b0731 100644
--- a/test/Constraints/iuo.swift
+++ b/test/Constraints/iuo.swift
@@ -167,3 +167,14 @@
   let _: (Bool) -> T? = id(T.iuoResultStatic as (Bool) -> T?)
   let _: T! = id(T.iuoResultStatic(true))
 }
+
+class rdar37241550 {
+  public init(blah: Float) { fatalError() }
+  public convenience init() { fatalError() }
+  public convenience init!(with void: ()) { fatalError() }
+
+  static func f(_ fn: () -> rdar37241550) {}
+  static func test() {
+    f(rdar37241550.init) // no error, the failable init is not applicable
+  }
+}
diff --git a/test/Driver/batch_mode.swift b/test/Driver/batch_mode.swift
new file mode 100644
index 0000000..2bbf0ab
--- /dev/null
+++ b/test/Driver/batch_mode.swift
@@ -0,0 +1,64 @@
+// RUN: %empty-directory(%t)
+// RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/file-04.swift %t/file-05.swift
+// RUN: touch %t/file-06.swift %t/file-07.swift %t/file-08.swift %t/file-09.swift %t/file-10.swift
+// RUN: touch %t/file-11.swift %t/file-12.swift %t/file-13.swift %t/file-14.swift %t/file-15.swift
+// RUN: touch %t/file-16.swift %t/file-17.swift %t/file-18.swift %t/file-19.swift %t/file-20.swift
+// RUN: touch %t/file-21.swift %t/file-22.swift %t/file-23.swift %t/file-24.swift %t/file-25.swift
+// RUN: touch %t/file-26.swift %t/file-27.swift %t/file-28.swift %t/file-29.swift %t/file-30.swift
+//
+// RUN: %swiftc_driver -enable-batch-mode -driver-show-job-lifecycle -driver-skip-execution -j 4 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/file-04.swift %t/file-05.swift %t/file-06.swift %t/file-07.swift %t/file-08.swift %t/file-09.swift %t/file-10.swift %t/file-11.swift %t/file-12.swift %t/file-13.swift %t/file-14.swift %t/file-15.swift %t/file-16.swift %t/file-17.swift %t/file-18.swift %t/file-19.swift %t/file-20.swift %t/file-21.swift %t/file-22.swift %t/file-23.swift %t/file-24.swift %t/file-25.swift %t/file-26.swift %t/file-27.swift %t/file-28.swift %t/file-29.swift %t/file-30.swift | %FileCheck %s -check-prefix=SEED0
+//
+// RUN: %swiftc_driver -enable-batch-mode -driver-show-job-lifecycle -driver-skip-execution -j 4 -driver-batch-seed 1 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/file-04.swift %t/file-05.swift %t/file-06.swift %t/file-07.swift %t/file-08.swift %t/file-09.swift %t/file-10.swift %t/file-11.swift %t/file-12.swift %t/file-13.swift %t/file-14.swift %t/file-15.swift %t/file-16.swift %t/file-17.swift %t/file-18.swift %t/file-19.swift %t/file-20.swift %t/file-21.swift %t/file-22.swift %t/file-23.swift %t/file-24.swift %t/file-25.swift %t/file-26.swift %t/file-27.swift %t/file-28.swift %t/file-29.swift %t/file-30.swift | %FileCheck %s -check-prefix=SEED1
+//
+// RUN: %swiftc_driver -enable-batch-mode -driver-show-job-lifecycle -driver-skip-execution -j 4 -driver-batch-seed 2 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/file-04.swift %t/file-05.swift %t/file-06.swift %t/file-07.swift %t/file-08.swift %t/file-09.swift %t/file-10.swift %t/file-11.swift %t/file-12.swift %t/file-13.swift %t/file-14.swift %t/file-15.swift %t/file-16.swift %t/file-17.swift %t/file-18.swift %t/file-19.swift %t/file-20.swift %t/file-21.swift %t/file-22.swift %t/file-23.swift %t/file-24.swift %t/file-25.swift %t/file-26.swift %t/file-27.swift %t/file-28.swift %t/file-29.swift %t/file-30.swift | %FileCheck %s -check-prefix=SEED2
+//
+// 30 files / 4 batches => 2 batches of 8 jobs + 2 batches of 7 jobs
+//
+// SEED0: Found 30 batchable jobs
+// SEED0: Forming into 4 batches
+// SEED0: Adding {compile: {{file-01-.*}} <= file-01.swift} to batch 0
+// SEED0: Adding {compile: {{file-02-.*}} <= file-02.swift} to batch 0
+// SEED0: Adding {compile: {{file-09-.*}} <= file-09.swift} to batch 1
+// SEED0: Adding {compile: {{file-10-.*}} <= file-10.swift} to batch 1
+// SEED0: Adding {compile: {{file-19-.*}} <= file-19.swift} to batch 2
+// SEED0: Adding {compile: {{file-20-.*}} <= file-20.swift} to batch 2
+// SEED0: Adding {compile: {{file-29-.*}} <= file-29.swift} to batch 3
+// SEED0: Adding {compile: {{file-30-.*}} <= file-30.swift} to batch 3
+// SEED0: Forming batch job from 8 constituents
+// SEED0: Forming batch job from 8 constituents
+// SEED0: Forming batch job from 7 constituents
+// SEED0: Forming batch job from 7 constituents
+// SEED0: Adding batch job to task queue: {compile: file-01{{.*}} file-02{{.*}} file-03{{.*}} ... 5 more <= file-01.swift file-02.swift file-03.swift ... 5 more}
+// SEED0: Adding batch job to task queue: {compile: file-09{{.*}} file-10{{.*}} file-11{{.*}} ... 5 more <= file-09.swift file-10.swift file-11.swift ... 5 more}
+// SEED0: Adding batch job to task queue: {compile: file-17{{.*}} file-18{{.*}} file-19{{.*}} ... 4 more <= file-17.swift file-18.swift file-19.swift ... 4 more}
+// SEED0: Adding batch job to task queue: {compile: file-24{{.*}} file-25{{.*}} file-26{{.*}} ... 4 more <= file-24.swift file-25.swift file-26.swift ... 4 more}
+//
+// SEED1: Found 30 batchable jobs
+// SEED1: Forming into 4 batches
+// SEED1: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 0
+// SEED1: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 1
+// SEED1: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 2
+// SEED1: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 3
+// SEED1: Forming batch job from 8 constituents
+// SEED1: Forming batch job from 8 constituents
+// SEED1: Forming batch job from 7 constituents
+// SEED1: Forming batch job from 7 constituents
+// SEED1-NOT: Adding batch job to task queue: {compile: file-01{{.*}} file-02{{.*}} file-03{{.*}} ... 5 more <= file-01.swift file-02.swift file-03.swift ... 5 more }
+// SEED1: Added to TaskQueue: {compile: {{.*}} <= {{file-[0-3][2-9].swift .*}}}
+// SEED1: Added to TaskQueue: {compile: {{.*}} <= {{.*}}}
+// SEED1: Added to TaskQueue: {compile: {{.*}} <= {{.*}}}
+//
+// SEED2: Found 30 batchable jobs
+// SEED2: Forming into 4 batches
+// SEED2: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 0
+// SEED2: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 1
+// SEED2: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 2
+// SEED2: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 3
+// SEED2: Forming batch job from 8 constituents
+// SEED2: Forming batch job from 8 constituents
+// SEED2: Forming batch job from 7 constituents
+// SEED2: Forming batch job from 7 constituents
+// SEED2-NOT: Adding batch job to task queue: {compile: file-01{{.*}} file-02{{.*}} file-03{{.*}} ... 5 more <= file-01.swift file-02.swift file-03.swift ... 5 more }
+// SEED2: Added to TaskQueue: {compile: {{.*}} <= {{file-[0-3][2-9].swift .*}}}
+// SEED2: Added to TaskQueue: {compile: {{.*}} <= {{.*}}}
+// SEED2: Added to TaskQueue: {compile: {{.*}} <= {{.*}}}
diff --git a/test/decl/init/resilience-cross-module.swift b/test/decl/init/resilience-cross-module.swift
new file mode 100644
index 0000000..e547759
--- /dev/null
+++ b/test/decl/init/resilience-cross-module.swift
@@ -0,0 +1,38 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../../Inputs/resilient_protocol.swift
+
+// RUN: %target-swift-frontend -typecheck -swift-version 4 -verify -I %t %s
+// RUN: %target-swift-frontend -typecheck -swift-version 4 -verify -enable-resilience -I %t %s
+
+// RUN: %target-swift-frontend -typecheck -swift-version 5 -verify -I %t %s
+// RUN: %target-swift-frontend -typecheck -swift-version 5 -verify -enable-resilience -I %t %s
+
+import resilient_struct
+import resilient_protocol
+
+// Size is not @_fixed_layout, so we cannot define a new designated initializer
+extension Size {
+  init(ww: Int, hh: Int) {
+    self.w = ww
+    self.h = hh // expected-error {{'let' property 'h' may not be initialized directly; use "self.init(...)" or "self = ..." instead}}
+  }
+
+  // This is OK
+  init(www: Int, hhh: Int) {
+    self.init(w: www, h: hhh)
+  }
+
+  // This is OK
+  init(other: Size) {
+    self = other
+  }
+}
+
+// Protocol extension initializers are OK too
+extension OtherResilientProtocol {
+  public init(other: Self) {
+    self = other
+  }
+}
diff --git a/test/decl/init/resilience.swift b/test/decl/init/resilience.swift
index 0133982..fba6e6d 100644
--- a/test/decl/init/resilience.swift
+++ b/test/decl/init/resilience.swift
@@ -1,34 +1,9 @@
-// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -typecheck -swift-version 4 -verify -enable-resilience %s -DRESILIENT
+// RUN: %target-swift-frontend -typecheck -swift-version 5 -verify -enable-resilience %s -DRESILIENT
 
-// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../../Inputs/resilient_struct.swift
-// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../../Inputs/resilient_protocol.swift
-
-// RUN: %target-swift-frontend -typecheck -swift-version 4 -verify -I %t %s
-// RUN: %target-swift-frontend -typecheck -swift-version 4 -verify -enable-resilience -I %t %s
-
-// RUN: %target-swift-frontend -typecheck -swift-version 5 -verify -I %t %s
-// RUN: %target-swift-frontend -typecheck -swift-version 5 -verify -enable-resilience -I %t %s
-
-import resilient_struct
-import resilient_protocol
-
-// Size is not @_fixed_layout, so we cannot define a new designated initializer
-extension Size {
-  init(ww: Int, hh: Int) {
-    self.w = ww
-    self.h = hh // expected-error {{'let' property 'h' may not be initialized directly; use "self.init(...)" or "self = ..." instead}}
-  }
-
-  // This is OK
-  init(www: Int, hhh: Int) {
-    self.init(w: www, h: hhh)
-  }
-
-  // This is OK
-  init(other: Size) {
-    self = other
-  }
-}
+// There should be no errors when run without resilience enabled.
+// RUN: %target-swift-frontend -typecheck -swift-version 4 %s
+// RUN: %target-swift-frontend -typecheck -swift-version 5 %s
 
 // Animal is not @_fixed_layout, so we cannot define an @_inlineable
 // designated initializer
@@ -86,10 +61,3 @@
     self.init()
   }
 }
-
-// Protocol extension initializers are OK too
-extension OtherResilientProtocol {
-  public init(other: Self) {
-    self = other
-  }
-}
diff --git a/test/stdlib/BinaryIntegerRequirements.swift b/test/stdlib/BinaryIntegerRequirements.swift
new file mode 100644
index 0000000..f3c8a25
--- /dev/null
+++ b/test/stdlib/BinaryIntegerRequirements.swift
@@ -0,0 +1,61 @@
+// RUN: %swift -swift-version 4 -typecheck -verify %s
+
+struct MyInt: FixedWidthInteger { // expected-error {{type 'MyInt' does not conform to protocol 'BinaryInteger'}}
+  typealias IntegerLiteralType = Int
+  static let isSigned = false
+  init(integerLiteral value: Int) { fatalError() }
+  init(_truncatingBits bits: UInt) { fatalError() }
+  init<T : BinaryFloatingPoint>(_ source: T) { fatalError() }
+  init?<T : BinaryFloatingPoint>(exactly source: T) { fatalError() }
+  init<T : BinaryInteger>(_ source: T) { fatalError() }
+  init?<T : BinaryInteger>(exactly source: T) { fatalError() }
+  init<T : BinaryInteger>(truncatingIfNeeded source: T) { fatalError() }
+  init<T : BinaryInteger>(clamping source: T) { fatalError() }
+
+  let words = [UInt]()
+  let _lowWord: UInt = 0
+  static var bitWidth: Int { fatalError() }
+  var trailingZeroBitCount: Int { fatalError() }
+
+  static func /=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
+  static func /(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
+  static func %=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
+  static func %(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
+  static func +=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
+  static func +(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
+  static func -=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
+  static func -(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
+  static func *=(_ lhs: inout MyInt, _ rhs: MyInt) { fatalError() }
+  static func *(_ lhs: MyInt, _ rhs: MyInt) -> MyInt { fatalError() }
+
+  static func ==(_ lhs: MyInt, _ rhs: MyInt) -> Bool { fatalError() }
+  static func <(_ lhs: MyInt, _ rhs: MyInt) -> Bool { fatalError() }
+
+  static prefix func ~ (_ x: MyInt) -> MyInt { fatalError() }
+
+  static func >><RHS: BinaryInteger>(_ lhs: MyInt, _ rhs: RHS) -> MyInt { fatalError() }
+
+  static func >>=<RHS: BinaryInteger>(_ lhs: inout MyInt, _ rhs: RHS) { fatalError() } 
+  static func <<<RHS: BinaryInteger>(_ lhs: MyInt, _ rhs: RHS) -> MyInt { fatalError() }
+  static func <<=<RHS: BinaryInteger>(_ lhs: inout MyInt, _ rhs: RHS) { fatalError() }
+
+  func quotientAndRemainder(dividingBy rhs: MyInt) -> (quotient: MyInt, remainder: MyInt) { fatalError() }
+  func signum() -> MyInt { fatalError() }
+
+  var hashValue: Int { fatalError() }
+  var byteSwapped: MyInt { fatalError() }
+  static var max: MyInt { fatalError() }
+  static var min: MyInt { fatalError() }
+  func addingReportingOverflow(_ rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
+  func subtractingReportingOverflow(_ rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
+  func multipliedReportingOverflow(by rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
+  func dividedReportingOverflow(by rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
+  func remainderReportingOverflow(dividingBy rhs: MyInt) -> (partialValue: MyInt, overflow: Bool) { fatalError() }
+  func multipliedFullWidth(by other: MyInt) -> (high: MyInt, low: Magnitude) { fatalError() }
+  func dividingFullWidth(_ dividend: (high: MyInt, low: Magnitude)) -> (quotient: MyInt, remainder: MyInt) { fatalError() }
+
+  var nonzeroBitCount: Int { fatalError() }
+  var leadingZeroBitCount: Int { fatalError() }
+
+  var magnitude: UInt { fatalError() }
+}