Merge pull request #12797 from anemet/opt-remark-demangle

diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT
index b6244ec..1309040 100644
--- a/CODE_OWNERS.TXT
+++ b/CODE_OWNERS.TXT
@@ -4,49 +4,85 @@
 what goes in or not.
 
 The list is sorted by surname and formatted to allow easy grepping and
-beautification by scripts.  The fields are: name (N), email (E), web-address
-(W), description (D).
+beautification by scripts.  The fields are: name (N), email (E),
+GitHub account (G), description (D).
 
 N: Ben Cohen
 E: ben_cohen@apple.com
+G: airspeedswift
 D: Swift standard library
 
+N: Brian Croom
+E: bcroom@apple.com
+G: briancroom
+D: XCTest overlay
+
 N: Erik Eckstein
 E: eeckstein@apple.com
+G: eeckstein
 D: SILOptimizer
 
 N: Xi Ge
 E: xi_ge@apple.com
+G: nkcsgexi
 D: Markup, Migrator, lib/Syntax
 
 N: Doug Gregor
 E: dgregor@apple.com
+G: DougGregor
 D: AST, Basic, Parse, Sema
 
 N: Joe Groff
 E: jgroff@apple.com
+G: jckarter
 D: SIL, SILGen, everything in Swift not covered by someone else
 
 N: Argyrios Kyrzidis
 E: kyrtzidis@apple.com
-D: IDE, SourceKit, swift-ide-test
+G: akyrtzi
+D: IDE, Index, SourceKit, swift-ide-test
 
 N: Luke Larson
 E: llarson@apple.com
+G: lplarson
 D: Swift Benchmark Suite
 
 N: John McCall
 E: rjmccall@apple.com
+G: rjmccall
 D: Demangler, IRGen, Runtime
 
+N: Max Moiseev
+E: moiseev@apple.com
+G: moiseev
+D: Apple contact for non-corelibs overlays
+
+N: Tony Parker
+E: anthony.parker@apple.com
+G: parkera
+D: Foundation overlay
+
 N: Slava Pestov
 E: spestov@apple.com
+G: slavapestov
 D: Reflection, SwiftRemoteMirror
 
+N: Adrian Prantl
+E: aprantl@apple.com
+G: adrian-prantl
+D: Debug info
+
 N: Jordan Rose
 E: jordan_rose@apple.com
-D: ClangImporter, Serialization, (Objective-)C printer, Driver
+G: jrose-apple
+D: ClangImporter, Serialization, PrintAsObjC, Driver, Frontend
+
+N: Daniel Steffen
+E: dsteffen@apple.com
+G: das
+D: Dispatch overlay
 
 N: Anna Zaks
 E: ganna@apple.com
-D: SIL diagnostics passes
+G: AnnaZaks
+D: SIL diagnostics passes, sanitizers
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 91e5cdb..5dd2ae9 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -719,7 +719,7 @@
   # On platforms that use ELF binaries we add markers for metadata sections in
   # the shared libraries using these object files.  This wouldn't be necessary
   # if the link was done by the swift binary: rdar://problem/19007002
-  if(SWIFTLIB_TARGET_LIBRARY AND
+  if(SWIFTLIB_SINGLE_TARGET_LIBRARY AND
      "${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF")
     if("${libkind}" STREQUAL "SHARED")
       set(arch_subdir "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}")
@@ -874,7 +874,8 @@
 
   # The section metadata objects are generated sources, and we need to tell CMake
   # not to expect to find them prior to their generation.
-  if("${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF")
+  if(SWIFTLIB_SINGLE_TARGET_LIBRARY AND
+     "${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF")
     if("${libkind}" STREQUAL "SHARED")
       set_source_files_properties(${SWIFT_SECTIONS_OBJECT_BEGIN} PROPERTIES GENERATED 1)
       set_source_files_properties(${SWIFT_SECTIONS_OBJECT_END} PROPERTIES GENERATED 1)
diff --git a/docs/SIL.rst b/docs/SIL.rst
index a6753b4..fdcbde9 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -582,6 +582,43 @@
     importer only imports non-native methods and types as ``throws``
     when it is possible to do this automatically.
 
+Coroutine Types
+```````````````
+
+A coroutine is a function which can suspend itself and return control to
+its caller without terminating the function.  That is, it does not need to
+obey a strict stack discipline.
+
+SIL supports two kinds of coroutine: ``@yield_many`` and ``@yield_once``.
+Either of these attributes may be written before a function type to
+indicate that it is a coroutine type.
+
+A coroutine type may declare any number of *yielded values*, which is to
+say, values which are provided to the caller at a yield point.  Yielded
+values are written in the result list of a function type, prefixed by
+the ``@yields`` attribute.  A yielded value may have a convention attribute,
+taken from the set of parameter attributes and interpreted as if the yield
+site were calling back to the calling function.
+
+Currently, a coroutine may not have normal results.
+
+Coroutine functions may be used in many of the same ways as normal
+function values.  However, they cannot be called with the standard
+``apply`` or ``try_apply`` instructions.
+
+Coroutines may contain the special ``yield`` and ``unwind`` instructions.
+
+A ``@yield_many`` coroutine may yield as many times as it desires.
+A ``@yield_once`` coroutine may yield exactly once before returning,
+although it may also ``throw`` before reaching that point.
+
+This coroutine representation is well-suited to coroutines whose control
+flow is tightly integrated with their callers and which intend to pass
+information back and forth.  This matches the needs of generalized
+accessor and generator features in Swift.  It is not a particularly good
+match for ``async``/``await``-style features; a simpler representation
+would probably do fine for that.
+
 Properties of Types
 ```````````````````
 
@@ -4698,6 +4735,10 @@
 resumes at the normal destination, and the value of the basic block argument
 will be the operand of this ``return`` instruction.
 
+If the current function is a ``yield_once`` coroutine, there must not be
+a path from the entry block to a ``return`` which does not pass through
+a ``yield`` instruction. This rule does not apply in the ``raw`` SIL stage.
+
 ``return`` does not retain or release its operand or any other values.
 
 A function must not contain more than one ``return`` instruction.
@@ -4713,7 +4754,7 @@
 
 Exits the current function and returns control to the calling
 function. The current function must have an error result, and so the
-function must have been invoked with a ``try_apply` instruction.
+function must have been invoked with a ``try_apply`` instruction.
 Control will resume in the error destination of that instruction, and
 the basic block argument will be the operand of the ``throw``.
 
@@ -4721,6 +4762,50 @@
 
 A function must not contain more than one ``throw`` instruction.
 
+yield
+`````
+::
+
+  sil-terminator ::= 'yield' sil-yield-values
+                       ',' 'resume' sil-identifier
+                       ',' 'unwind' sil-identifier
+  sil-yield-values ::= sil-operand
+  sil-yield-values ::= '(' (sil-operand (',' sil-operand)*)? ')'
+
+Temporarily suspends the current function and provides the given
+values to the calling function. The current function must be a coroutine,
+and the yield values must match the yield types of the coroutine.
+If the calling function resumes the coroutine normally, control passes to
+the ``resume`` destination. If the calling function aborts the coroutine,
+control passes to the ``unwind`` destination.
+
+The ``resume`` and ``unwind`` destination blocks must be uniquely
+referenced by the ``yield`` instruction.  This prevents them from becoming
+critical edges.
+
+In a ``yield_once`` coroutine, there must not be a control flow path leading
+from the ``resume`` edge to another ``yield`` instruction in this function.
+This rule does not apply in the ``raw`` SIL stage.
+
+There must not be a control flow path leading from the ``unwind`` edge to
+a ``return`` instruction, to a ``throw`` instruction, or to any block
+reachable from the entry block via a path that does not pass through
+an ``unwind`` edge. That is, the blocks reachable from ``unwind`` edges
+must jointly form a disjoint subfunction of the coroutine.
+
+unwind
+``````
+::
+
+  sil-terminator ::= 'unwind'
+
+Exits the current function and returns control to the calling function,
+completing an unwind from a ``yield``. The current function must be a
+coroutine.
+
+``unwind`` is only permitted in blocks reachable from the ``unwind`` edges
+of ``yield`` instructions.
+
 br
 ``
 ::
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index c7629da..d9fc118 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -60,6 +60,9 @@
 TYPE_ATTR(objc_metatype)
 TYPE_ATTR(opened)
 TYPE_ATTR(pseudogeneric)
+TYPE_ATTR(yields)
+TYPE_ATTR(yield_once)
+TYPE_ATTR(yield_many)
 
 // SIL metatype attributes.
 TYPE_ATTR(thin)
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index a832920..e64b60b 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3183,6 +3183,8 @@
       "SIL function types cannot have labeled inputs", ())
 ERROR(sil_function_output_label,PointsToFirstBadToken,
       "SIL function types cannot have labeled results", ())
+ERROR(sil_non_coro_yields,PointsToFirstBadToken,
+      "non-coroutine SIL function types cannot have @yield results", ())
 ERROR(sil_function_repeat_convention,PointsToFirstBadToken,
       "repeated %select{parameter|result|callee}0 convention attribute",
       (unsigned))
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index 9e8b509..35f9411 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -802,6 +802,16 @@
   /// Determine whether the two given types are in the same equivalence class.
   bool areInSameEquivalenceClass(Type type1, Type type2);
 
+  /// Verify the correctness of the given generic signature.
+  ///
+  /// This routine will test that the given generic signature is both minimal
+  /// and canonical, emitting errors if it is not.
+  static void verifyGenericSignature(ASTContext &context,
+                                     GenericSignature *sig);
+
+  /// Verify all of the generic sigantures in the given module.
+  static void verifyGenericSignaturesInModule(ModuleDecl *module);
+
   /// \brief Dump all of the requirements, both specified and inferred.
   LLVM_ATTRIBUTE_DEPRECATED(
       void dump(),
diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h
index 377b7e2..4e99b99 100644
--- a/include/swift/AST/Module.h
+++ b/include/swift/AST/Module.h
@@ -1173,6 +1173,15 @@
 
   virtual bool isSystemModule() const { return false; }
 
+  /// Retrieve the set of generic signatures stored within this module.
+  ///
+  /// \returns \c true if this module file supports retrieving all of the
+  /// generic signatures, \c false otherwise.
+  virtual bool getAllGenericSignatures(
+                 SmallVectorImpl<GenericSignature*> &genericSignatures) {
+    return false;
+  }
+
   static bool classof(const FileUnit *file) {
     return file->getKind() == FileUnitKind::SerializedAST ||
            file->getKind() == FileUnitKind::ClangModule;
diff --git a/include/swift/AST/PrettyStackTrace.h b/include/swift/AST/PrettyStackTrace.h
index 96894b1..9715dd32 100644
--- a/include/swift/AST/PrettyStackTrace.h
+++ b/include/swift/AST/PrettyStackTrace.h
@@ -26,6 +26,7 @@
   class ASTContext;
   class Decl;
   class Expr;
+  class GenericSignature;
   class Pattern;
   class Stmt;
   class TypeRepr;
@@ -129,6 +130,24 @@
   virtual void print(llvm::raw_ostream &OS) const;
 };
 
+class PrettyStackTraceGenericSignature : public llvm::PrettyStackTraceEntry {
+  const char *Action;
+  GenericSignature *GenericSig;
+  Optional<unsigned> Requirement;
+
+public:
+  PrettyStackTraceGenericSignature(const char *action,
+                                   GenericSignature *genericSig,
+                                   Optional<unsigned> requirement = None)
+    : Action(action), GenericSig(genericSig), Requirement(requirement) { }
+
+  void setRequirement(Optional<unsigned> requirement) {
+    Requirement = requirement;
+  }
+
+  void print(llvm::raw_ostream &out) const override;
+};
+
 } // end namespace swift
 
 #endif
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 10ca863..5663a15 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -319,8 +319,9 @@
     unsigned ExtInfo : 16;
     unsigned CalleeConvention : 3;
     unsigned HasErrorResult : 1;
+    unsigned CoroutineKind : 2;
   };
-  enum { NumSILFunctionTypeBits = NumTypeBaseBits + 16+5 };
+  enum { NumSILFunctionTypeBits = NumTypeBaseBits + 16 + 6 };
   static_assert(NumSILFunctionTypeBits <= 32, "fits in an unsigned");
 
   struct AnyMetatypeTypeBitfields {
@@ -3175,6 +3176,42 @@
     return !(*this == rhs);
   }
 };
+
+using YieldConvention = ParameterConvention;
+
+/// The type and convention of a value yielded from a yield-once or
+/// yield-many coroutine.
+class SILYieldInfo : public SILParameterInfo {
+public:
+  SILYieldInfo() {}
+  SILYieldInfo(CanType type, YieldConvention conv)
+    : SILParameterInfo(type, conv) {
+  }
+
+  SILYieldInfo getWithType(CanType type) const {
+    return SILYieldInfo(type, getConvention());
+  }
+
+  template<typename F>
+  SILYieldInfo map(const F &fn) const {
+    return getWithType(fn(getType()));
+  }
+};
+
+/// SILCoroutineKind - What kind of coroutine is this SILFunction?
+enum class SILCoroutineKind : uint8_t {
+  /// This function is not a coroutine.  It may have arbitrary normal
+  /// results and may not have yield results.
+  None,
+
+  /// This function is a yield-once coroutine (used by e.g. accessors).
+  /// It must not have normal results and may have arbitrary yield results.
+  YieldOnce,
+
+  /// This function is a yield-many coroutine (used by e.g. generators).
+  /// It must not have normal results and may have arbitrary yield results.
+  YieldMany,
+};
   
 class SILFunctionType;
 typedef CanTypeWrapper<SILFunctionType> CanSILFunctionType;
@@ -3334,16 +3371,20 @@
 
 private:
   unsigned NumParameters;
-  unsigned NumResults : 16;               // Not including the ErrorResult.
-  unsigned NumIndirectFormalResults : 16; // Subset of NumResults.
+
+  // These are *normal* results if this is not a coroutine and *yield* results
+  // otherwise.
+  unsigned NumAnyResults : 16;         // Not including the ErrorResult.
+  unsigned NumAnyIndirectFormalResults : 16; // Subset of NumAnyResults.
 
   // The layout of a SILFunctionType in memory is:
   //   SILFunctionType
   //   SILParameterInfo[NumParameters]
-  //   SILResultInfo[NumResults]
-  //   SILResultInfo?                 // if hasErrorResult()
-  //   CanType?                       // if NumResults > 1, formal result cache
-  //   CanType?                       // if NumResults > 1, all result cache
+  //   SILResultInfo[isCoroutine() ? 0 : NumAnyResults]
+  //   SILYieldInfo[isCoroutine() ? NumAnyResults : 0]
+  //   SILResultInfo?    // if hasErrorResult()
+  //   CanType?          // if !isCoro && NumAnyResults > 1, formal result cache
+  //   CanType?          // if !isCoro && NumAnyResults > 1, all result cache
 
   CanGenericSignature GenericSig;
   Optional<ProtocolConformanceRef> WitnessMethodConformance;
@@ -3354,48 +3395,74 @@
 
   MutableArrayRef<SILResultInfo> getMutableResults() {
     auto *ptr = reinterpret_cast<SILResultInfo *>(getMutableParameters().end());
-    return MutableArrayRef<SILResultInfo>(ptr, getNumResults());
+    return {ptr, getNumResults()};
   }
 
-  SILResultInfo *getEndOfNormalResults() { return getMutableResults().end(); }
+  MutableArrayRef<SILYieldInfo> getMutableYields() {
+    auto *ptr = reinterpret_cast<SILYieldInfo *>(getMutableParameters().end());
+    return {ptr, getNumYields()};
+  }
+
+  /// Return a pointer past the end of the formal results, whether they
+  /// are yield-results or normal results.
+  void *getEndOfFormalResults() {
+    return isCoroutine() ? static_cast<void*>(getMutableYields().end())
+                         : static_cast<void*>(getMutableResults().end());
+  }
 
   SILResultInfo &getMutableErrorResult() {
     assert(hasErrorResult());
-    return *getEndOfNormalResults();
+    return *reinterpret_cast<SILResultInfo*>(getEndOfFormalResults());
   }
 
-  bool hasResultCache() const { return NumResults > 1; }
+  /// Return a pointer past the end of all of the results, including the
+  /// error result if one is present.
+  void *getEndOfAllResults() {
+    void *end = getEndOfFormalResults();
+    if (hasErrorResult())
+      end = reinterpret_cast<char*>(end) + sizeof(SILResultInfo);
+    return end;
+  }
+
+  /// Do we have slots for caches of the normal-result tuple type?
+  bool hasResultCache() const {
+    return NumAnyResults > 1 && !isCoroutine();
+  }
 
   CanType &getMutableFormalResultsCache() const {
     assert(hasResultCache());
-    auto *ptr = const_cast<SILFunctionType *>(this)->getEndOfNormalResults()
-                + size_t(hasErrorResult());
+    auto *ptr = const_cast<SILFunctionType *>(this)->getEndOfAllResults();
     return *reinterpret_cast<CanType*>(ptr);
   }
 
   CanType &getMutableAllResultsCache() const {
     assert(hasResultCache());
-    auto *ptr = const_cast<SILFunctionType *>(this)->getEndOfNormalResults()
-                + size_t(hasErrorResult());
+    auto *ptr = const_cast<SILFunctionType *>(this)->getEndOfAllResults();
     return *(reinterpret_cast<CanType *>(ptr) + 1);
   }
 
-  SILFunctionType(
-      GenericSignature *genericSig, ExtInfo ext,
-      ParameterConvention calleeConvention, ArrayRef<SILParameterInfo> params,
-      ArrayRef<SILResultInfo> normalResults,
-      Optional<SILResultInfo> errorResult, const ASTContext &ctx,
-      RecursiveTypeProperties properties,
-      Optional<ProtocolConformanceRef> witnessMethodConformance = None);
+  SILFunctionType(GenericSignature *genericSig, ExtInfo ext,
+                  SILCoroutineKind coroutineKind,
+                  ParameterConvention calleeConvention,
+                  ArrayRef<SILParameterInfo> params,
+                  ArrayRef<SILYieldInfo> yieldResults,
+                  ArrayRef<SILResultInfo> normalResults,
+                  Optional<SILResultInfo> errorResult,
+                  const ASTContext &ctx,
+                  RecursiveTypeProperties properties,
+                  Optional<ProtocolConformanceRef> witnessMethodConformance);
 
 public:
-  static CanSILFunctionType
-  get(GenericSignature *genericSig, ExtInfo ext,
-      ParameterConvention calleeConvention,
-      ArrayRef<SILParameterInfo> interfaceParams,
-      ArrayRef<SILResultInfo> interfaceResults,
-      Optional<SILResultInfo> interfaceErrorResult, const ASTContext &ctx,
-      Optional<ProtocolConformanceRef> witnessMethodConformance = None);
+  static CanSILFunctionType get(GenericSignature *genericSig,
+                                ExtInfo ext,
+                                SILCoroutineKind coroutineKind,
+                                ParameterConvention calleeConvention,
+                                ArrayRef<SILParameterInfo> interfaceParams,
+                                ArrayRef<SILYieldInfo> interfaceYields,
+                                ArrayRef<SILResultInfo> interfaceResults,
+                                Optional<SILResultInfo> interfaceErrorResult,
+                                const ASTContext &ctx,
+              Optional<ProtocolConformanceRef> witnessMethodConformance = None);
 
   /// Given that this function type uses a C-language convention, return its
   /// formal semantic result type.
@@ -3423,12 +3490,26 @@
     return getCalleeConvention() == ParameterConvention::Direct_Guaranteed;
   }
 
+  /// Is this some kind of coroutine?
+  bool isCoroutine() const {
+    return getCoroutineKind() != SILCoroutineKind::None;
+  }
+  SILCoroutineKind getCoroutineKind() const {
+    return SILCoroutineKind(SILFunctionTypeBits.CoroutineKind);
+  }
+
+  /// Return the array of all the yields.
+  ArrayRef<SILYieldInfo> getYields() const {
+    return const_cast<SILFunctionType *>(this)->getMutableYields();
+  }
+  unsigned getNumYields() const { return isCoroutine() ? NumAnyResults : 0; }
+
   /// Return the array of all result information. This may contain inter-mingled
   /// direct and indirect results.
   ArrayRef<SILResultInfo> getResults() const {
     return const_cast<SILFunctionType *>(this)->getMutableResults();
   }
-  unsigned getNumResults() const { return NumResults; }
+  unsigned getNumResults() const { return isCoroutine() ? 0 : NumAnyResults; }
 
   /// Given that this function type has exactly one result, return it.
   /// This is a common situation when working with a function with a known
@@ -3458,14 +3539,14 @@
   // indirect property, not the SIL indirect property, should be consulted to
   // determine whether function reabstraction is necessary.
   unsigned getNumIndirectFormalResults() const {
-    return NumIndirectFormalResults;
+    return isCoroutine() ? 0 : NumAnyIndirectFormalResults;
   }
   /// Does this function have any formally indirect results?
   bool hasIndirectFormalResults() const {
     return getNumIndirectFormalResults() != 0;
   }
   unsigned getNumDirectFormalResults() const {
-    return NumResults - NumIndirectFormalResults;
+    return isCoroutine() ? 0 : NumAnyResults - NumAnyIndirectFormalResults;
   }
 
   struct IndirectFormalResultFilter {
@@ -3607,15 +3688,18 @@
                                       LookupConformanceFn conformances);
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getGenericSignature(), getExtInfo(), getCalleeConvention(),
-            getParameters(), getResults(), getOptionalErrorResult());
+    Profile(ID, getGenericSignature(), getExtInfo(), getCoroutineKind(),
+            getCalleeConvention(), getParameters(), getYields(),
+            getResults(), getOptionalErrorResult());
   }
   static void Profile(llvm::FoldingSetNodeID &ID,
                       GenericSignature *genericSig,
                       ExtInfo info,
+                      SILCoroutineKind coroutineKind,
                       ParameterConvention calleeConvention,
                       ArrayRef<SILParameterInfo> params,
-                      ArrayRef<SILResultInfo> result,
+                      ArrayRef<SILYieldInfo> yields,
+                      ArrayRef<SILResultInfo> results,
                       Optional<SILResultInfo> errorResult);
 
   // Implement isa/cast/dyncast/etc.
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index 76e6733..db3c8f6 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -296,6 +296,9 @@
   /// too complex.
   unsigned SolverExpressionTimeThreshold = 0;
 
+  /// The module for which we should verify all of the generic signatures.
+  std::string VerifyGenericSignaturesInModule;
+
   enum ActionType {
     NoneAction, ///< No specific action
     Parse, ///< Parse only
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 018ec22..159dbcd 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -76,6 +76,9 @@
   HelpText<"Like -verify, but updates the original source file">;
 def verify_ignore_unknown: Flag<["-"], "verify-ignore-unknown">,
   HelpText<"Allow diagnostics for '<unknown>' location in verify mode">;
+def verify_generic_signatures : Separate<["-"], "verify-generic-signatures">,
+  MetaVarName<"<module-name>">,
+  HelpText<"Verify the generic signatures in the given module">;
 
 def show_diagnostics_after_fatal : Flag<["-"], "show-diagnostics-after-fatal">,
   HelpText<"Keep emitting subsequent diagnostics after a fatal error">;
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 0fa561a..7fd371f 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -58,6 +58,7 @@
     class SyntaxParsingContext;
     struct RawSyntaxInfo;
     struct RawTokenSyntax;
+    enum class SyntaxKind;
   }// end of syntax namespace
 
   /// Different contexts in which BraceItemList are parsed.
@@ -416,12 +417,7 @@
     BacktrackingScope(Parser &P)
       : P(P), PP(P.getParserPosition()), DT(P.Diags) {}
 
-    ~BacktrackingScope() {
-      if (Backtrack) {
-        P.backtrackToPosition(PP);
-        DT.abort();
-      }
-    }
+    ~BacktrackingScope();
 
     void cancelBacktrack() {
       Backtrack = false;
@@ -674,6 +670,7 @@
   /// \brief Parse a comma separated list of some elements.
   ParserStatus parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
                          bool AllowSepAfterLast, Diag<> ErrorDiag,
+                         syntax::SyntaxKind Kind,
                          std::function<ParserStatus()> callback);
 
   void consumeTopLevelDecl(ParserPosition BeginParserPosition,
@@ -1247,7 +1244,8 @@
                                       SourceLoc &inLoc);
 
   Expr *parseExprAnonClosureArg();
-  ParserResult<Expr> parseExprList(tok LeftTok, tok RightTok);
+  ParserResult<Expr> parseExprList(tok LeftTok, tok RightTok,
+                                   syntax::SyntaxKind Kind);
 
   /// Parse an expression list, keeping all of the pieces separated.
   ParserStatus parseExprList(tok leftTok, tok rightTok,
@@ -1258,7 +1256,8 @@
                              SmallVectorImpl<Identifier> &exprLabels,
                              SmallVectorImpl<SourceLoc> &exprLabelLocs,
                              SourceLoc &rightLoc,
-                             Expr *&trailingClosure);
+                             Expr *&trailingClosure,
+                             syntax::SyntaxKind Kind);
 
   ParserResult<Expr> parseTrailingClosure(SourceRange calleeRange);
 
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index 920c1d2..fd459d9 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -66,7 +66,7 @@
 
   unsigned getSizeOfHeapObject() {
     // This must match sizeof(HeapObject) for the target.
-    return sizeof(StoredPointer) + 8;
+    return sizeof(StoredPointer) * 2;
   }
 
   void dumpAllSections(std::ostream &OS) {
@@ -483,9 +483,8 @@
     case MetadataSourceKind::ClosureBinding: {
       unsigned Index = cast<ClosureBindingMetadataSource>(MS)->getIndex();
 
-      // Skip the context's isa pointer (4 or 8 bytes) and reference counts
-      // (4 bytes each regardless of platform word size). This is just
-      // sizeof(HeapObject) in the target.
+      // Skip the context's HeapObject header
+      // (one word each for isa pointer and reference counts).
       //
       // Metadata and conformance tables are stored consecutively after
       // the heap object header, in the 'necessary bindings' area.
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 09e8629..2e1f4c5 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -1617,6 +1617,18 @@
         new (getModule()) ThrowInst(getSILDebugLocation(Loc), errorValue));
   }
 
+  UnwindInst *createUnwind(SILLocation loc) {
+    return insertTerminator(
+        new (getModule()) UnwindInst(getSILDebugLocation(loc)));
+  }
+
+  YieldInst *createYield(SILLocation loc, ArrayRef<SILValue> yieldedValues,
+                         SILBasicBlock *resumeBB, SILBasicBlock *unwindBB) {
+    return insertTerminator(
+        YieldInst::create(getSILDebugLocation(loc), yieldedValues,
+                          resumeBB, unwindBB, getFunction()));
+  }
+
   CondBranchInst *
   createCondBranch(SILLocation Loc, SILValue Cond, SILBasicBlock *Target1,
                    SILBasicBlock *Target2,
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 833719b..c4345ed 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -2118,6 +2118,27 @@
 
 template<typename ImplClass>
 void
+SILCloner<ImplClass>::visitUnwindInst(UnwindInst *Inst) {
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  doPostProcess(Inst,
+    getBuilder().createUnwind(getOpLocation(Inst->getLoc())));
+}
+
+template<typename ImplClass>
+void
+SILCloner<ImplClass>::visitYieldInst(YieldInst *Inst) {
+  auto Values = getOpValueArray<8>(Inst->getYieldedValues());
+  auto ResumeBB = getOpBasicBlock(Inst->getResumeBB());
+  auto UnwindBB = getOpBasicBlock(Inst->getUnwindBB());
+
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  doPostProcess(Inst,
+    getBuilder().createYield(getOpLocation(Inst->getLoc()), Values,
+                             ResumeBB, UnwindBB));
+}
+
+template<typename ImplClass>
+void
 SILCloner<ImplClass>::visitBranchInst(BranchInst *Inst) {
   auto Args = getOpValueArray<8>(Inst->getArgs());
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h
index 4f95c8a..b1bc7be 100644
--- a/include/swift/SIL/SILDeclRef.h
+++ b/include/swift/SIL/SILDeclRef.h
@@ -66,8 +66,6 @@
 /// True if the entry point is natively foreign.
 bool requiresForeignToNativeThunk(ValueDecl *vd);
 
-unsigned getNaturalUncurryLevel(ValueDecl *vd);
-
 enum ForDefinition_t : bool {
   NotForDefinition = false,
   ForDefinition = true
@@ -304,7 +302,7 @@
   void print(llvm::raw_ostream &os) const;
   void dump() const;
 
-  unsigned getUncurryLevel() const;
+  unsigned getParameterListCount() const;
 
   ResilienceExpansion getResilienceExpansion() const {
     return ResilienceExpansion(Expansion);
diff --git a/include/swift/SIL/SILFunctionConventions.h b/include/swift/SIL/SILFunctionConventions.h
index 558541e..d26e981 100644
--- a/include/swift/SIL/SILFunctionConventions.h
+++ b/include/swift/SIL/SILFunctionConventions.h
@@ -45,10 +45,14 @@
 
   static bool isIndirectSILParam(SILParameterInfo param, bool loweredAddresses);
 
+  static bool isIndirectSILYield(SILYieldInfo yield, bool loweredAddresses);
+
   static bool isIndirectSILResult(SILResultInfo result, bool loweredAddresses);
 
   static SILType getSILParamType(SILParameterInfo param, bool loweredAddresses);
 
+  static SILType getSILYieldType(SILYieldInfo yield, bool loweredAddresses);
+
   static SILType getSILResultType(SILResultInfo param, bool loweredAddresses);
 
 public:
@@ -77,6 +81,10 @@
     return isIndirectSILParam(param, loweredAddresses);
   }
 
+  bool isSILIndirect(SILYieldInfo yield) const {
+    return isIndirectSILYield(yield, loweredAddresses);
+  }
+
   bool isSILIndirect(SILResultInfo result) const {
     return isIndirectSILResult(result, loweredAddresses);
   }
@@ -85,6 +93,10 @@
     return getSILParamType(param, loweredAddresses);
   }
 
+  SILType getSILType(SILYieldInfo yield) const {
+    return getSILYieldType(yield, loweredAddresses);
+  }
+
   SILType getSILType(SILResultInfo result) const {
     return getSILResultType(result, loweredAddresses);
   }
@@ -115,6 +127,10 @@
     return silConv.isSILIndirect(param);
   }
 
+  bool isSILIndirect(SILYieldInfo yield) const {
+    return silConv.isSILIndirect(yield);
+  }
+
   bool isSILIndirect(SILResultInfo result) const {
     return silConv.isSILIndirect(result);
   }
@@ -123,6 +139,10 @@
     return silConv.getSILType(param);
   }
 
+  SILType getSILType(SILYieldInfo yield) const {
+    return silConv.getSILType(yield);
+  }
+
   SILType getSILType(SILResultInfo result) const {
     return silConv.getSILType(result);
   }
@@ -279,6 +299,28 @@
   }
 
   //===--------------------------------------------------------------------===//
+  // SIL yield types.
+  //===--------------------------------------------------------------------===//
+
+  unsigned getNumYields() const { return funcTy->getNumYields(); }
+
+  ArrayRef<SILYieldInfo> getYields() const {
+    return funcTy->getYields();
+  }
+
+  using SILYieldTypeIter =
+      llvm::mapped_iterator<const SILYieldInfo *, SILParameterTypeFunc>;
+  using SILYieldTypeRange = IteratorRange<SILYieldTypeIter>;
+
+  SILYieldTypeRange getYieldSILTypes() const {
+    return makeIteratorRange(
+        SILYieldTypeIter(funcTy->getYields().begin(),
+                         SILParameterTypeFunc(silConv)),
+        SILYieldTypeIter(funcTy->getYields().end(),
+                         SILParameterTypeFunc(silConv)));
+  }
+
+  //===--------------------------------------------------------------------===//
   // SILArgument API, including indirect results and parameters.
   //
   // The argument indices below relate to full applies in which the caller and
@@ -363,6 +405,11 @@
   llvm_unreachable("covered switch isn't covered?!");
 }
 
+inline bool SILModuleConventions::isIndirectSILYield(SILYieldInfo yield,
+                                                     bool loweredAddresses) {
+  return isIndirectSILParam(yield, loweredAddresses);
+}
+
 inline bool SILModuleConventions::isIndirectSILResult(SILResultInfo result,
                                                       bool loweredAddresses) {
   switch (result.getConvention()) {
@@ -386,6 +433,11 @@
              : SILType::getPrimitiveObjectType(param.getType());
 }
 
+inline SILType SILModuleConventions::getSILYieldType(SILYieldInfo yield,
+                                                     bool loweredAddresses) {
+  return getSILParamType(yield, loweredAddresses);
+}
+
 inline SILType SILModuleConventions::getSILResultType(SILResultInfo result,
                                                       bool loweredAddresses) {
   return SILModuleConventions::isIndirectSILResult(result, loweredAddresses)
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 1ed4bcb..a7c5364 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -6242,6 +6242,84 @@
   }
 };
 
+/// UnwindInst - Continue unwinding out of this function.  Currently this is
+/// only used in coroutines as the eventual terminator of the unwind edge
+/// out of a 'yield'.
+class UnwindInst
+  : public InstructionBase<SILInstructionKind::UnwindInst,
+                           TermInst> {
+  friend SILBuilder;
+
+  UnwindInst(SILDebugLocation loc)
+    : InstructionBase(loc) {}
+
+public:
+  SuccessorListTy getSuccessors() {
+    // No successors.
+    return SuccessorListTy();
+  }
+
+  ArrayRef<Operand> getAllOperands() const { return {}; }
+  MutableArrayRef<Operand> getAllOperands() { return {}; }
+};
+
+/// YieldInst - Yield control temporarily to the caller of this coroutine.
+///
+/// This is a terminator because the caller can abort the coroutine,
+/// e.g. if an error is thrown and an unwind is provoked.
+class YieldInst
+  : public InstructionBase<SILInstructionKind::YieldInst,
+                           TermInst> {
+  friend SILBuilder;
+
+  SILSuccessor DestBBs[2];
+
+  TailAllocatedOperandList<0> Operands;
+
+  YieldInst(SILDebugLocation loc, ArrayRef<SILValue> yieldedValues,
+            SILBasicBlock *normalBB, SILBasicBlock *unwindBB);
+
+  static YieldInst *create(SILDebugLocation loc,
+                           ArrayRef<SILValue> yieldedValues,
+                           SILBasicBlock *normalBB, SILBasicBlock *unwindBB,
+                           SILFunction &F);
+
+public:
+  /// Return the normal resume destination of the yield, which is where the
+  /// coroutine resumes when the caller is ready to continue normally.
+  ///
+  /// This must be the unique predecessor edge of the given block.
+  ///
+  /// Control flow along every path from this block must either loop or
+  /// eventually terminate in a 'return', 'throw', or 'unreachable'
+  /// instruction.  In a yield_many coroutine, control is permitted to
+  /// first reach a 'yield' instruction; this is prohibited in a
+  /// yield_once coroutine.
+  SILBasicBlock *getResumeBB() const { return DestBBs[0]; }
+
+  /// Return the 'unwind' destination of the yield, which is where the
+  /// coroutine resumes when the caller is unconditionally aborting the
+  /// coroutine.
+  ///
+  /// This must be the unique predecessor edge of the given block.
+  ///
+  /// Control flow along every path from this block must either loop or
+  /// eventually terminate in an 'unwind' or 'unreachable' instruction.
+  /// It is not permitted to reach a 'yield' instruction.
+  SILBasicBlock *getUnwindBB() const { return DestBBs[1]; }
+
+  OperandValueArrayRef getYieldedValues() const {
+    return Operands.asValueArray();
+  }
+
+  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
+  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
+
+  SuccessorListTy getSuccessors() {
+    return DestBBs;
+  }
+};
+
 /// BranchInst - An unconditional branch.
 class BranchInst
     : public InstructionBase<SILInstructionKind::BranchInst,
diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def
index 78a6318..6afe2fe 100644
--- a/include/swift/SIL/SILNodes.def
+++ b/include/swift/SIL/SILNodes.def
@@ -498,6 +498,10 @@
              TermInst, None, DoesNotRelease)
   TERMINATOR(ThrowInst, throw,
              TermInst, None, DoesNotRelease)
+  TERMINATOR(YieldInst, yield,
+             TermInst, MayHaveSideEffects, MayRelease)
+  TERMINATOR(UnwindInst, unwind,
+             TermInst, None, DoesNotRelease)
   TERMINATOR(TryApplyInst, try_apply,
              TermInst, MayHaveSideEffects, MayRelease)
   TERMINATOR(BranchInst, br,
diff --git a/include/swift/SILOptimizer/Utils/SCCVisitor.h b/include/swift/SILOptimizer/Utils/SCCVisitor.h
index c0f2b4f..9ea03d2 100644
--- a/include/swift/SILOptimizer/Utils/SCCVisitor.h
+++ b/include/swift/SILOptimizer/Utils/SCCVisitor.h
@@ -133,8 +133,14 @@
     case TermKind::ReturnInst:
     case TermKind::SwitchValueInst:
     case TermKind::ThrowInst:
+    case TermKind::UnwindInst:
       llvm_unreachable("Did not expect terminator that does not have args!");
 
+    case TermKind::YieldInst:
+      for (auto &O : cast<YieldInst>(Term)->getAllOperands())
+        Operands.push_back(O.get());
+      return;
+
     case TermKind::TryApplyInst:
       for (auto &O : cast<TryApplyInst>(Term)->getAllOperands())
         Operands.push_back(O.get());
diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def
index 03f68a3..b772124 100644
--- a/include/swift/Serialization/DeclTypeRecordNodes.def
+++ b/include/swift/Serialization/DeclTypeRecordNodes.def
@@ -162,7 +162,7 @@
 TRAILING_INFO(GENERIC_PARAM)
 TRAILING_INFO(GENERIC_REQUIREMENT)
 TRAILING_INFO(LAYOUT_REQUIREMENT)
-OTHER(GENERIC_ENVIRONMENT, 244)
+OTHER(GENERIC_SIGNATURE, 244)
 OTHER(SIL_GENERIC_ENVIRONMENT, 245)
 
 OTHER(LOCAL_DISCRIMINATOR, 248)
diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h
index 8cc53e2..f701536 100644
--- a/include/swift/Serialization/ModuleFile.h
+++ b/include/swift/Serialization/ModuleFile.h
@@ -299,6 +299,9 @@
   /// Types referenced by this module.
   std::vector<Serialized<Type>> Types;
 
+  /// Generic signatures referenced by this module.
+  std::vector<Serialized<GenericSignature *>> GenericSignatures;
+
   /// Generic environments referenced by this module.
   std::vector<Serialized<GenericEnvironment *>> GenericEnvironments;
 
@@ -818,6 +821,9 @@
   /// is loaded instead.
   ModuleDecl *getModule(ArrayRef<Identifier> name);
 
+  /// Returns the generic signature for the given ID.
+  GenericSignature *getGenericSignature(serialization::GenericSignatureID ID);
+
   /// Returns the generic signature or environment for the given ID,
   /// deserializing it if needed.
   ///
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 746988f..bff02ca 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -54,7 +54,7 @@
 /// in source control, you should also update the comment to briefly
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
-const uint16_t VERSION_MINOR = 380; // Last change: IUO decl attribute
+const uint16_t VERSION_MINOR = 381; // Last change: generic signature
 
 using DeclIDField = BCFixed<31>;
 
@@ -77,6 +77,11 @@
 using NormalConformanceID = DeclID;
 using NormalConformanceIDField = DeclIDField;
 
+// GenericSignatureID must be the same as DeclID because it is stored in the
+// same way.
+using GenericSignatureID = DeclID;
+using GenericSignatureIDField = DeclIDField;
+
 // GenericEnvironmentID must be the same as DeclID because it is stored in the
 // same way.
 using GenericEnvironmentID = DeclID;
@@ -156,6 +161,15 @@
 
 // These IDs must \em not be renumbered or reordered without incrementing
 // VERSION_MAJOR.
+enum class SILCoroutineKind : uint8_t {
+  None = 0,
+  YieldOnce = 1,
+  YieldMany = 2,
+};
+using SILCoroutineKindField = BCFixed<2>;
+
+// These IDs must \em not be renumbered or reordered without incrementing
+// VERSION_MAJOR.
 enum OperatorKind : uint8_t {
   Infix = 0,
   Prefix,
@@ -729,25 +743,25 @@
     TypeIDField,         // output
     FunctionTypeRepresentationField, // representation
     BCFixed<1>,          // throws?
-    BCArray<TypeIDField> // generic parameters
-                         // followed by requirements
+    GenericSignatureIDField // generic signture
   >;
 
   using SILFunctionTypeLayout = BCRecordLayout<
     SIL_FUNCTION_TYPE,
+    SILCoroutineKindField, // coroutine kind
     ParameterConventionField, // callee convention
     SILFunctionTypeRepresentationField, // representation
     BCFixed<1>,            // pseudogeneric?
     BCFixed<1>,            // noescape?
     BCFixed<1>,            // error result?
     BCFixed<30>,           // number of parameters
+    BCFixed<30>,           // number of yields
     BCFixed<30>,           // number of results
+    GenericSignatureIDField, // generic signature
     BCArray<TypeIDField>   // parameter types/conventions, alternating
                            // followed by result types/conventions, alternating
                            // followed by error result type/convention
-                           // followed by generic parameter types
     // Optionally a protocol conformance (for witness_methods)
-    // Trailed by its generic requirements, if any.
   >;
   
   using SILBlockStorageTypeLayout = BCRecordLayout<
@@ -757,10 +771,9 @@
 
   using SILLayoutLayout = BCRecordLayout<
     SIL_LAYOUT,
+    GenericSignatureIDField,    // generic signature
     BCFixed<31>,                // number of fields
     BCArray<TypeIDWithBitField> // field types with mutability
-                                // followed by generic parameters
-                                // trailed by generic requirements, if any
   >;
 
   using SILBoxTypeLayout = BCRecordLayout<
@@ -1154,9 +1167,9 @@
     DeclIDField // Typealias
   >;
 
-  using GenericEnvironmentLayout = BCRecordLayout<
-    GENERIC_ENVIRONMENT,
-    BCArray<TypeIDField>         // sugared interface types
+  using GenericSignatureLayout = BCRecordLayout<
+    GENERIC_SIGNATURE,
+    BCArray<TypeIDField>         // generic parameter types
   >;
 
   using SILGenericEnvironmentLayout = BCRecordLayout<
@@ -1271,8 +1284,8 @@
   using XRefExtensionPathPieceLayout = BCRecordLayout<
     XREF_EXTENSION_PATH_PIECE,
     ModuleIDField,       // module ID
-    BCArray<TypeIDField> // for a constrained extension, the type parameters
-    // for a constrained extension, requirements follow
+    GenericSignatureIDField  // for a constrained extension,
+                             // the generic signature
   >;
 
   using XRefOperatorOrAccessorPathPieceLayout = BCRecordLayout<
@@ -1524,7 +1537,8 @@
     NESTED_TYPE_DECLS,
     DECL_MEMBER_NAMES,
 
-    LastRecordKind = DECL_MEMBER_NAMES,
+    GENERIC_SIGNATURE_OFFSETS,
+    LastRecordKind = GENERIC_SIGNATURE_OFFSETS,
   };
   
   constexpr const unsigned RecordIDFieldWidth = 5;
diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h
index 0978e16..13db711 100644
--- a/include/swift/Serialization/SerializedModuleLoader.h
+++ b/include/swift/Serialization/SerializedModuleLoader.h
@@ -195,6 +195,10 @@
 
   virtual const clang::Module *getUnderlyingClangModule() const override;
 
+  virtual bool getAllGenericSignatures(
+                   SmallVectorImpl<GenericSignature*> &genericSignatures)
+                override;
+
   static bool classof(const FileUnit *file) {
     return file->getKind() == FileUnitKind::SerializedAST;
   }
diff --git a/include/swift/Syntax/SyntaxFactory.h.gyb b/include/swift/Syntax/SyntaxFactory.h.gyb
index 26f4879..08f8372 100644
--- a/include/swift/Syntax/SyntaxFactory.h.gyb
+++ b/include/swift/Syntax/SyntaxFactory.h.gyb
@@ -56,6 +56,9 @@
 
   static SyntaxKind getUnknownKind(SyntaxKind Kind);
 
+  static Syntax
+  makeBlankCollectionSyntax(SyntaxKind Kind);
+
 % for node in SYNTAX_NODES:
 %   if node.children:
 %     child_params = []
diff --git a/include/swift/Syntax/SyntaxParsingContext.h b/include/swift/Syntax/SyntaxParsingContext.h
index 002f9b0..372ab45 100644
--- a/include/swift/Syntax/SyntaxParsingContext.h
+++ b/include/swift/Syntax/SyntaxParsingContext.h
@@ -37,6 +37,12 @@
   /// Start and end location of this syntax node.
   SourceRange SyntaxRange;
 
+  /// This location must be valid if this node is an implicit node, e.g.
+  /// an empty statement list collection.
+  /// This location indicates the implicit node should appear before the token
+  /// on the location.
+  SourceLoc BeforeLoc;
+
   /// The raw node.
   RC<RawSyntax> RawNode;
   RawSyntaxInfo(RC<RawSyntax> RawNode): RawNode(RawNode) {}
@@ -57,6 +63,10 @@
     return RC<RawSyntaxNode>(cast<RawSyntaxNode>(RawNode));
   }
   void brigeWithContext(SyntaxContextKind Kind);
+  void setBeforeLoc(SourceLoc Loc) {
+    assert(isImplicit());
+    BeforeLoc = Loc;
+  }
 };
 
 enum class SyntaxParsingContextKind: uint8_t {
@@ -75,16 +85,11 @@
   ContextInfo &ContextData;
   const Token &Tok;
 
-  // Add a token syntax at the given source location to the context; this
-  // token node can be used to build more complex syntax nodes in later call
-  // back.
-  virtual void addTokenSyntax(SourceLoc Loc) = 0;
-
   // Get the context kind.
   virtual SyntaxParsingContextKind getKind() = 0;
 
   // Create a syntax node of the given kind.
-  virtual void makeNode(SyntaxKind Kind) = 0;
+  virtual void makeNode(SyntaxKind Kind, SourceLoc LastTokLoc) = 0;
   virtual ~SyntaxParsingContext();
 
   // Disable the building of syntax tree in the current context.
@@ -100,8 +105,7 @@
   SyntaxParsingContextRoot(SourceFile &File, unsigned BufferID, Token &Tok):
     SyntaxParsingContext(File, BufferID, Tok), File(File) {}
   ~SyntaxParsingContextRoot();
-  void addTokenSyntax(SourceLoc Loc) override {};
-  void makeNode(SyntaxKind Kind) override {};
+  void makeNode(SyntaxKind Kind, SourceLoc LastTokLoc) override {};
   SyntaxParsingContextKind getKind() override {
     return SyntaxParsingContextKind::Root;
   };
@@ -130,8 +134,7 @@
                              None, KnownSyntax) {};
 
   ~SyntaxParsingContextChild();
-  void makeNode(SyntaxKind Kind) override;
-  void addTokenSyntax(SourceLoc Loc) override;
+  void makeNode(SyntaxKind Kind, SourceLoc LastTokLoc) override;
   SyntaxParsingContext* getParent() { return Parent; }
   SyntaxParsingContextRoot &getRoot();
   SyntaxParsingContextKind getKind() override {
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 314321f..e57bd64 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3787,16 +3787,22 @@
 void SILFunctionType::Profile(llvm::FoldingSetNodeID &id,
                               GenericSignature *genericParams,
                               ExtInfo info,
+                              SILCoroutineKind coroutineKind,
                               ParameterConvention calleeConvention,
                               ArrayRef<SILParameterInfo> params,
+                              ArrayRef<SILYieldInfo> yields,
                               ArrayRef<SILResultInfo> results,
                               Optional<SILResultInfo> errorResult) {
   id.AddPointer(genericParams);
   id.AddInteger(info.getFuncAttrKey());
+  id.AddInteger(unsigned(coroutineKind));
   id.AddInteger(unsigned(calleeConvention));
   id.AddInteger(params.size());
   for (auto param : params)
     param.profile(id);
+  id.AddInteger(yields.size());
+  for (auto yield : yields)
+    yield.profile(id);
   id.AddInteger(results.size());
   for (auto result : results)
     result.profile(id);
@@ -3806,32 +3812,47 @@
   if (errorResult) errorResult->profile(id);
 }
 
-SILFunctionType::SILFunctionType(
-    GenericSignature *genericSig, ExtInfo ext,
-    ParameterConvention calleeConvention, ArrayRef<SILParameterInfo> params,
-    ArrayRef<SILResultInfo> normalResults, Optional<SILResultInfo> errorResult,
-    const ASTContext &ctx, RecursiveTypeProperties properties,
-    Optional<ProtocolConformanceRef> witnessMethodConformance)
-    : TypeBase(TypeKind::SILFunction, &ctx, properties), GenericSig(genericSig),
+SILFunctionType::SILFunctionType(GenericSignature *genericSig, ExtInfo ext,
+                                 SILCoroutineKind coroutineKind,
+                                 ParameterConvention calleeConvention,
+                                 ArrayRef<SILParameterInfo> params,
+                                 ArrayRef<SILYieldInfo> yields,
+                                 ArrayRef<SILResultInfo> normalResults,
+                                 Optional<SILResultInfo> errorResult,
+                                 const ASTContext &ctx,
+                                 RecursiveTypeProperties properties,
+                      Optional<ProtocolConformanceRef> witnessMethodConformance)
+    : TypeBase(TypeKind::SILFunction, &ctx, properties),
+      GenericSig(genericSig),
       WitnessMethodConformance(witnessMethodConformance) {
 
   SILFunctionTypeBits.HasErrorResult = errorResult.hasValue();
   SILFunctionTypeBits.ExtInfo = ext.Bits;
+  SILFunctionTypeBits.CoroutineKind = unsigned(coroutineKind);
   NumParameters = params.size();
-  NumResults = normalResults.size();
-  NumIndirectFormalResults =
+  if (coroutineKind == SILCoroutineKind::None) {
+    assert(yields.empty());
+    NumAnyResults = normalResults.size();
+    NumAnyIndirectFormalResults =
       std::count_if(normalResults.begin(), normalResults.end(),
                     [](const SILResultInfo &resultInfo) {
                       return resultInfo.isFormalIndirect();
                     });
+    memcpy(getMutableResults().data(), normalResults.data(),
+           normalResults.size() * sizeof(SILResultInfo));
+  } else {
+    assert(normalResults.empty());    
+    NumAnyResults = yields.size();
+    NumAnyIndirectFormalResults = 0; // unused
+    memcpy(getMutableYields().data(), yields.data(),
+           yields.size() * sizeof(SILYieldInfo));
+  }
 
   assert(!isIndirectFormalParameter(calleeConvention));
   SILFunctionTypeBits.CalleeConvention = unsigned(calleeConvention);
 
   memcpy(getMutableParameters().data(), params.data(),
          params.size() * sizeof(SILParameterInfo));
-  memcpy(getMutableResults().data(), normalResults.data(),
-         normalResults.size() * sizeof(SILResultInfo));
   if (errorResult)
     getMutableErrorResult() = *errorResult;
 
@@ -3868,6 +3889,13 @@
       assert(!result.getType()->hasArchetype()
              && "interface type of result should not contain context archetypes");
     }
+    for (auto yield : getYields()) {
+      (void)yield;
+      assert(!yield.getType()->hasError()
+             && "interface type of yield should not contain error types");
+      assert(!yield.getType()->hasArchetype()
+             && "interface type of yield should not contain context archetypes");
+    }
     if (hasErrorResult()) {
       assert(!getErrorResult().getType()->hasError()
              && "interface type of result should not contain error types");
@@ -3892,14 +3920,22 @@
   return CanSILBlockStorageType(storageTy);
 }
 
-CanSILFunctionType SILFunctionType::get(
-    GenericSignature *genericSig, ExtInfo ext, ParameterConvention callee,
-    ArrayRef<SILParameterInfo> params, ArrayRef<SILResultInfo> normalResults,
-    Optional<SILResultInfo> errorResult, const ASTContext &ctx,
-    Optional<ProtocolConformanceRef> witnessMethodConformance) {
+CanSILFunctionType SILFunctionType::get(GenericSignature *genericSig,
+                                        ExtInfo ext,
+                                        SILCoroutineKind coroutineKind,
+                                        ParameterConvention callee,
+                                        ArrayRef<SILParameterInfo> params,
+                                        ArrayRef<SILYieldInfo> yields,
+                                        ArrayRef<SILResultInfo> normalResults,
+                                        Optional<SILResultInfo> errorResult,
+                                        const ASTContext &ctx,
+                    Optional<ProtocolConformanceRef> witnessMethodConformance) {
+  assert(coroutineKind == SILCoroutineKind::None || normalResults.empty());
+  assert(coroutineKind != SILCoroutineKind::None || yields.empty());
+
   llvm::FoldingSetNodeID id;
-  SILFunctionType::Profile(id, genericSig, ext, callee, params, normalResults,
-                           errorResult);
+  SILFunctionType::Profile(id, genericSig, ext, coroutineKind, callee,
+                           params, yields, normalResults, errorResult);
 
   // Do we already have this generic function type?
   void *insertPos;
@@ -3912,6 +3948,7 @@
   // Allocate storage for the object.
   size_t bytes = sizeof(SILFunctionType)
                  + sizeof(SILParameterInfo) * params.size()
+                 + sizeof(SILYieldInfo) * yields.size()
                  + sizeof(SILResultInfo) * normalResults.size()
                  + (errorResult ? sizeof(SILResultInfo) : 0)
                  + (normalResults.size() > 1 ? sizeof(CanType) * 2 : 0);
@@ -3922,6 +3959,8 @@
                 "revisit this if you add new recursive type properties");
   for (auto &param : params)
     properties |= param.getType()->getRecursiveProperties();
+  for (auto &yield : yields)
+    properties |= yield.getType()->getRecursiveProperties();
   for (auto &result : normalResults)
     properties |= result.getType()->getRecursiveProperties();
   if (errorResult)
@@ -3934,9 +3973,10 @@
     properties.removeHasDependentMember();
   }
 
-  auto fnType = new (mem)
-      SILFunctionType(genericSig, ext, callee, params, normalResults,
-                      errorResult, ctx, properties, witnessMethodConformance);
+  auto fnType =
+      new (mem) SILFunctionType(genericSig, ext, coroutineKind, callee,
+                                params, yields, normalResults, errorResult,
+                                ctx, properties, witnessMethodConformance);
   ctx.Impl.SILFunctionTypes.InsertNode(fnType, insertPos);
   return CanSILFunctionType(fnType);
 }
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 6a8cebf..6cad624 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -3630,6 +3630,20 @@
     Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
   }
 
+  void printSILCoroutineKind(SILCoroutineKind kind) {
+    switch (kind) {
+    case SILCoroutineKind::None:
+      return;
+    case SILCoroutineKind::YieldOnce:
+      Printer << "@yield_once ";
+      return;
+    case SILCoroutineKind::YieldMany:
+      Printer << "@yield_many ";
+      return;
+    }
+    llvm_unreachable("bad convention");
+  }
+
   void printCalleeConvention(ParameterConvention conv) {
     switch (conv) {
     case ParameterConvention::Direct_Unowned:
@@ -3651,6 +3665,7 @@
   }
 
   void visitSILFunctionType(SILFunctionType *T) {
+    printSILCoroutineKind(T->getCoroutineKind());
     printFunctionExtInfo(T->getExtInfo(),
                          T->getWitnessMethodConformanceOrNone());
     printCalleeConvention(T->getCalleeConvention());
@@ -3669,11 +3684,19 @@
     }
     Printer << ") -> ";
 
-    unsigned totalResults = T->getNumResults() + unsigned(T->hasErrorResult());
+    unsigned totalResults =
+      T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
 
     if (totalResults != 1) Printer << "(";
 
     first = true;
+
+    for (auto yield : T->getYields()) {
+      Printer.printSeparator(first, ", ");
+      Printer << "@yields ";
+      yield.print(Printer, Options);
+    }
+
     for (auto result : T->getResults()) {
       Printer.printSeparator(first, ", ");
       result.print(Printer, Options);
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 2b31ca1..4279839 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -20,6 +20,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/STLExtras.h"
 #include <functional>
@@ -174,6 +175,18 @@
   return getCanonicalSignature() == this;
 }
 
+#ifndef NDEBUG
+/// Determine the canonical ordering of requirements.
+static unsigned getRequirementKindOrder(RequirementKind kind) {
+  switch (kind) {
+  case RequirementKind::Conformance: return 2;
+  case RequirementKind::Superclass: return 0;
+  case RequirementKind::SameType: return 3;
+  case RequirementKind::Layout: return 1;
+  }
+}
+#endif
+
 CanGenericSignature GenericSignature::getCanonical(
                                         ArrayRef<GenericTypeParamType *> params,
                                         ArrayRef<Requirement> requirements) {
@@ -197,8 +210,105 @@
           Requirement(reqt.getKind(), reqt.getFirstType()->getCanonicalType(),
                       reqt.getLayoutConstraint()));
   }
+
   auto canSig = get(canonicalParams, canonicalRequirements,
                     /*isKnownCanonical=*/true);
+
+#ifndef NDEBUG
+  PrettyStackTraceGenericSignature debugStack("canonicalizing", canSig);
+
+  // Check that the signature is canonical.
+  for (unsigned idx : indices(canonicalRequirements)) {
+    debugStack.setRequirement(idx);
+
+    const auto &reqt = canonicalRequirements[idx];
+
+    // Left-hand side must be canonical in its context.
+    // Check canonicalization of requirement itself.
+    switch (reqt.getKind()) {
+    case RequirementKind::Superclass:
+      assert(canSig->isCanonicalTypeInContext(reqt.getFirstType()) &&
+             "Left-hand side is not canonical");
+      assert(canSig->isCanonicalTypeInContext(reqt.getSecondType()) &&
+             "Superclass type isn't canonical in its own context");
+      break;
+
+    case RequirementKind::Layout:
+      assert(canSig->isCanonicalTypeInContext(reqt.getFirstType()) &&
+             "Left-hand side is not canonical");
+      break;
+
+    case RequirementKind::SameType:
+      assert(reqt.getFirstType()->isTypeParameter() &&
+             "Left-hand side must be a type parameter");
+      if (reqt.getSecondType()->isTypeParameter()) {
+        assert(compareDependentTypes(reqt.getFirstType(), reqt.getSecondType())
+                 < 0 &&
+               "Out-of-order type parameters in same-type constraint");
+      } else {
+        assert(canSig->isCanonicalTypeInContext(reqt.getSecondType()) &&
+               "Concrete same-type isn't canonical in its own context");
+      }
+      break;
+
+    case RequirementKind::Conformance:
+      assert(reqt.getFirstType()->isTypeParameter() &&
+             "Left-hand side must be a type parameter");
+      assert(isa<ProtocolType>(reqt.getSecondType().getPointer()) &&
+             "Right-hand side of conformance isn't a protocol type");
+      break;
+    }
+
+    // From here on, we're only interested in requirements beyond the first.
+    if (idx == 0) continue;
+
+    // Make sure that the left-hand sides are in nondecreasing order.
+    const auto &prevReqt = canonicalRequirements[idx-1];
+    int compareLHS =
+      compareDependentTypes(prevReqt.getFirstType(), reqt.getFirstType());
+    assert(compareLHS <= 0 && "Out-of-order left-hand sides");
+
+    // If we have two same-type requirements where the left-hand sides differ
+    // but fall into the same equivalence class, we can check the form.
+    if (compareLHS < 0 && reqt.getKind() == RequirementKind::SameType &&
+        prevReqt.getKind() == RequirementKind::SameType &&
+        canSig->areSameTypeParameterInContext(prevReqt.getFirstType(),
+                                              reqt.getFirstType())) {
+      // If it's a it's a type parameter, make sure the equivalence class is
+      // wired together sanely.
+      if (prevReqt.getSecondType()->isTypeParameter()) {
+        assert(prevReqt.getSecondType()->isEqual(reqt.getFirstType()) &&
+               "same-type constraints within an equiv. class are out-of-order");
+      } else {
+        // Otherwise, the concrete types must match up.
+        assert(prevReqt.getSecondType()->isEqual(reqt.getSecondType()) &&
+               "inconsistent concrete same-type constraints in equiv. class");
+      }
+    }
+
+    // From here on, we only care about cases where the previous and current
+    // requirements have the same left-hand side.
+    if (compareLHS != 0) continue;
+
+    // Check ordering of requirement kinds.
+    assert((getRequirementKindOrder(prevReqt.getKind()) <=
+            getRequirementKindOrder(reqt.getKind())) &&
+           "Requirements for a given kind are out-of-order");
+
+    // From here on, we only care about the same requirement kind.
+    if (prevReqt.getKind() != reqt.getKind()) continue;
+
+    assert(reqt.getKind() == RequirementKind::Conformance &&
+           "Only conformance requirements can have multiples");
+
+    auto prevProto =
+      prevReqt.getSecondType()->castTo<ProtocolType>()->getDecl();
+    auto proto = reqt.getSecondType()->castTo<ProtocolType>()->getDecl();
+    assert(ProtocolType::compareProtocols(&prevProto, &proto) < 0 &&
+           "Out-of-order conformance requirements");
+  }
+#endif
+
   return CanGenericSignature(canSig);
 }
 
@@ -621,14 +731,12 @@
                              type1,
                              ArchetypeResolutionKind::CompleteWellFormed);
   assert(equivClass1 && "not a valid dependent type of this signature?");
-  assert(!equivClass1->concreteType);
 
   auto equivClass2 =
     builder.resolveEquivalenceClass(
                              type2,
                              ArchetypeResolutionKind::CompleteWellFormed);
   assert(equivClass2 && "not a valid dependent type of this signature?");
-  assert(!equivClass2->concreteType);
 
   return equivClass1 == equivClass2;
 }
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 4aada77..f0d7135 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -25,6 +25,7 @@
 #include "swift/AST/LazyResolver.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/ParameterList.h"
+#include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeMatcher.h"
 #include "swift/AST/TypeRepr.h"
@@ -2954,36 +2955,30 @@
 
 /// Resolve any unresolved dependent member types using the given builder.
 static Type resolveDependentMemberTypes(GenericSignatureBuilder &builder,
-                                        Type type,
-                                        ArchetypeResolutionKind kind) {
+                                        Type type) {
   if (!type->hasTypeParameter()) return type;
 
-  return type.transformRec([&builder,kind](TypeBase *type) -> Optional<Type> {
-    if (auto depTy = dyn_cast<DependentMemberType>(type)) {
-      if (depTy->getAssocType()) return None;
+  return type.transformRec([&builder](TypeBase *type) -> Optional<Type> {
+    if (!type->isTypeParameter())
+      return None;
 
-      Type newBase =
-        resolveDependentMemberTypes(builder, depTy->getBase(), kind);
-      if (newBase->is<ErrorType>())
-        return ErrorType::get(depTy);
+    // Map the type parameter to an equivalence class.
+    auto equivClass =
+      builder.resolveEquivalenceClass(Type(type),
+                                      ArchetypeResolutionKind::WellFormed);
+    if (!equivClass)
+      return ErrorType::get(Type(type));
 
-      auto parentEquivClass = builder.resolveEquivalenceClass(newBase, kind);
-      if (!parentEquivClass)
-        return ErrorType::get(depTy);
+    // If there is a concrete type in this equivalence class, use that.
+    if (equivClass->concreteType) {
+      // .. unless it's recursive.
+      if (equivClass->recursiveConcreteType)
+        return ErrorType::get(Type(type));
 
-      auto memberType =
-        parentEquivClass->lookupNestedType(builder, depTy->getName());
-      if (!memberType)
-        return ErrorType::get(depTy);
-
-      if (auto assocType = dyn_cast<AssociatedTypeDecl>(memberType))
-        return Type(DependentMemberType::get(newBase, assocType));
-
-      // FIXME: Need to substitute here.
-      return Type(type);
+      return resolveDependentMemberTypes(builder, equivClass->concreteType);
     }
 
-    return None;
+    return equivClass->getAnchor(builder, builder.getGenericParams());
   });
 }
 
@@ -3094,9 +3089,7 @@
   // FIXME: Generic typealiases contradict the assumption above.
   // If there is a type parameter somewhere in this type, resolve it.
   if (type->hasTypeParameter()) {
-    Type resolved =
-    resolveDependentMemberTypes(*this, type,
-                                ArchetypeResolutionKind::WellFormed);
+    Type resolved = resolveDependentMemberTypes(*this, type);
     if (resolved->hasError() && !type->hasError())
       return ResolvedType::forUnresolved(nullptr);
 
@@ -5951,10 +5944,9 @@
     diag::redundant_same_type_to_concrete,
     diag::same_type_redundancy_here);
 
-  // Resolve any this-far-unresolved dependent types.
+  // Resolve any thus-far-unresolved dependent types.
   equivClass->concreteType =
-    resolveDependentMemberTypes(*this, equivClass->concreteType,
-                                ArchetypeResolutionKind::CompleteWellFormed);
+    resolveDependentMemberTypes(*this, equivClass->concreteType);
 }
 
 void GenericSignatureBuilder::checkSuperclassConstraints(
@@ -5996,8 +5988,7 @@
 
   // Resolve any this-far-unresolved dependent types.
   equivClass->superclass =
-    resolveDependentMemberTypes(*this, equivClass->superclass,
-                                ArchetypeResolutionKind::CompleteWellFormed);
+    resolveDependentMemberTypes(*this, equivClass->superclass);
 
   // If we have a concrete type, check it.
   // FIXME: Substitute into the concrete type.
@@ -6374,7 +6365,7 @@
   // over-minimizing.
   if (allowBuilderToMove && !Impl->HadAnyError &&
       !Impl->HadAnyRedundantConstraints) {
-    // Register this generic signature builer as the canonical builder for the
+    // Register this generic signature builder as the canonical builder for the
     // given signature.
     Context.registerGenericSignatureBuilder(sig, std::move(*this));
   }
@@ -6412,3 +6403,77 @@
            /*allowBuilderToMove=*/false);
 }
 
+#pragma mark Generic signature verification
+
+void GenericSignatureBuilder::verifyGenericSignature(ASTContext &context,
+                                                     GenericSignature *sig) {
+  llvm::errs() << "Validating generic signature: ";
+  sig->print(llvm::errs());
+  llvm::errs() << "\n";
+
+  // Try removing each requirement in turn.
+  auto genericParams = sig->getGenericParams();
+  auto requirements = sig->getRequirements();
+  for (unsigned victimIndex : indices(requirements)) {
+    PrettyStackTraceGenericSignature debugStack("verifying", sig, victimIndex);
+
+    // Form a new generic signature builder.
+    GenericSignatureBuilder builder(context);
+
+    // Add the generic parameters.
+    for (auto gp : genericParams)
+      builder.addGenericParameter(gp);
+
+    // Add the requirements *except* the victim.
+    auto source = FloatingRequirementSource::forAbstract();
+    for (unsigned i : indices(requirements)) {
+      if (i != victimIndex)
+        builder.addRequirement(requirements[i], source, nullptr);
+    }
+
+    // Finalize the generic signature. If there were any errors, we formed
+    // an invalid signature, so just continue.
+    if (builder.Impl->HadAnyError) continue;
+
+    // Form a generic signature from the result.
+    auto newSig =
+      std::move(builder).computeGenericSignature(
+                                      SourceLoc(),
+                                      /*allowConcreteGenericParams=*/true,
+                                      /*allowBuilderToMove=*/true);
+
+    // Check whether the removed requirement
+    assert(!newSig->isRequirementSatisfied(requirements[victimIndex]) &&
+           "Generic signature is not minimal");
+
+    // Canonicalize the signature to check that it is canonical.
+    (void)newSig->getCanonicalSignature();
+  }
+}
+
+void GenericSignatureBuilder::verifyGenericSignaturesInModule(
+                                                        ModuleDecl *module) {
+  LoadedFile *loadedFile = nullptr;
+  for (auto fileUnit : module->getFiles()) {
+    loadedFile = dyn_cast<LoadedFile>(fileUnit);
+    if (loadedFile) break;
+  }
+
+  if (!loadedFile) return;
+
+  // Check all of the (canonical) generic signatures.
+  SmallVector<GenericSignature *, 8> allGenericSignatures;
+  SmallPtrSet<CanGenericSignature, 4> knownGenericSignatures;
+  (void)loadedFile->getAllGenericSignatures(allGenericSignatures);
+  ASTContext &context = module->getASTContext();
+  for (auto genericSig : allGenericSignatures) {
+    // Check whether this is the first time we've checked this (canonical)
+    // signature.
+    auto canGenericSig = genericSig->getCanonicalSignature();
+    if (!knownGenericSignatures.insert(canGenericSig).second) continue;
+
+    verifyGenericSignature(context, canGenericSig);
+  }
+}
+
+
diff --git a/lib/AST/PrettyStackTrace.cpp b/lib/AST/PrettyStackTrace.cpp
index 26a1fb5..649baea 100644
--- a/lib/AST/PrettyStackTrace.cpp
+++ b/lib/AST/PrettyStackTrace.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/Expr.h"
+#include "swift/AST/GenericSignature.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/Pattern.h"
 #include "swift/AST/Stmt.h"
@@ -214,3 +215,12 @@
   out << "While " << Action << " starting at ";
   printSourceLocDescription(out, Loc, Context);
 }
+
+void PrettyStackTraceGenericSignature::print(llvm::raw_ostream &out) const {
+  out << "While " << Action << " generic signature ";
+  GenericSig->print(out);
+  if (Requirement) {
+    out << " in requirement #" << *Requirement;
+  }
+  out << '\n';
+}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index d1291d5..1a15a3f 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -18,6 +18,7 @@
 #include "ForeignRepresentationInfo.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ExistentialLayout.h"
+#include "swift/AST/GenericSignatureBuilder.h"
 #include "swift/AST/TypeVisitor.h"
 #include "swift/AST/TypeWalker.h"
 #include "swift/AST/Decl.h"
@@ -3089,15 +3090,110 @@
                               getAssocType(), getName(), None);
 }
 
+static Type substGenericFunctionType(GenericFunctionType *genericFnType,
+                                     TypeSubstitutionFn substitutions,
+                                     LookupConformanceFn lookupConformances,
+                                     SubstOptions options) {
+  // Substitute into the function type (without generic signature).
+  auto *bareFnType = FunctionType::get(genericFnType->getInput(),
+                                       genericFnType->getResult(),
+                                       genericFnType->getExtInfo());
+  Type result =
+    Type(bareFnType).subst(substitutions, lookupConformances, options);
+  if (!result || result->is<ErrorType>()) return result;
+
+  auto *fnType = result->castTo<FunctionType>();
+  // Substitute generic parameters.
+  bool anySemanticChanges = false;
+  SmallVector<GenericTypeParamType *, 4> genericParams;
+  for (auto param : genericFnType->getGenericParams()) {
+    Type paramTy =
+      Type(param).subst(substitutions, lookupConformances, options);
+    if (!paramTy)
+      return Type();
+
+    if (auto newParam = paramTy->getAs<GenericTypeParamType>()) {
+      if (!newParam->isEqual(param))
+        anySemanticChanges = true;
+
+      genericParams.push_back(newParam);
+    } else {
+      anySemanticChanges = true;
+    }
+  }
+
+  // If no generic parameters remain, this is a non-generic function type.
+  if (genericParams.empty())
+    return result;
+
+  // Transform requirements.
+  SmallVector<Requirement, 4> requirements;
+  for (const auto &req : genericFnType->getRequirements()) {
+    // Substitute into the requirement.
+    auto substReqt = req.subst(substitutions, lookupConformances, options);
+    if (!substReqt) {
+      anySemanticChanges = true;
+      continue;
+    }
+
+    // Did anything change?
+    if (!anySemanticChanges &&
+        (!req.getFirstType()->isEqual(substReqt->getFirstType()) ||
+         (req.getKind() != RequirementKind::Layout &&
+          !req.getSecondType()->isEqual(substReqt->getSecondType())))) {
+      anySemanticChanges = true;
+    }
+
+    // Skip any erroneous requirements.
+    if (substReqt->getFirstType()->hasError() ||
+        (substReqt->getKind() != RequirementKind::Layout &&
+         substReqt->getSecondType()->hasError()))
+      continue;
+
+    requirements.push_back(*substReqt);
+  }
+
+  GenericSignature *genericSig = nullptr;
+  if (anySemanticChanges) {
+    // If there were semantic changes, we need to build a new generic
+    // signature.
+    GenericSignatureBuilder builder(genericFnType->getASTContext());
+
+    // Add the generic parameters to the builder.
+    for (auto gp : genericParams)
+      builder.addGenericParameter(gp);
+
+    // Add the requirements to the builder.
+    auto source =
+      GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
+    for (const auto &req : requirements)
+      builder.addRequirement(req, source, /*inferForModule=*/nullptr);
+
+    // Form the generic signature.
+    genericSig = std::move(builder).computeGenericSignature(SourceLoc());
+  } else {
+    // Use the mapped generic signature.
+    genericSig = GenericSignature::get(genericParams, requirements);
+  }
+
+  // Produce the new generic function type.
+  return GenericFunctionType::get(genericSig, fnType->getInput(),
+                                  fnType->getResult(), fnType->getExtInfo());
+}
+
 static Type substType(Type derivedType,
                       TypeSubstitutionFn substitutions,
                       LookupConformanceFn lookupConformances,
                       SubstOptions options) {
+  // Handle substitutions into generic function types.
+  if (auto genericFnType = derivedType->getAs<GenericFunctionType>()) {
+    return substGenericFunctionType(genericFnType, substitutions,
+                                    lookupConformances, options);
+  }
 
   // FIXME: Change getTypeOfMember() to not pass GenericFunctionType here
   if (!derivedType->hasArchetype() &&
-      !derivedType->hasTypeParameter() &&
-      !derivedType->is<GenericFunctionType>())
+      !derivedType->hasTypeParameter())
     return derivedType;
 
   return derivedType.transformRec([&](TypeBase *type) -> Optional<Type> {
@@ -3409,6 +3505,7 @@
 
   assert(memberType);
 
+  // Perform the substitution.
   auto substitutions = getMemberSubstitutionMap(module, member);
   return memberType.subst(substitutions, SubstFlags::UseErrorType);
 }
@@ -3463,6 +3560,20 @@
   return false;
 }
 
+static bool transformSILYield(
+                            SILYieldInfo &yield, bool &changed,
+                            llvm::function_ref<Optional<Type>(TypeBase *)> fn) {
+  Type transType = yield.getType().transformRec(fn);
+  if (!transType) return true;
+
+  CanType canTransType = transType->getCanonicalType();
+  if (canTransType != yield.getType()) {
+    changed = true;
+    yield = yield.getWithType(canTransType);
+  }
+  return false;
+}
+
 static bool transformSILParameter(
                             SILParameterInfo &param, bool &changed,
                             llvm::function_ref<Optional<Type>(TypeBase *)> fn) {
@@ -3568,6 +3679,12 @@
       transInterfaceParams.push_back(param);
     }
 
+    SmallVector<SILYieldInfo, 8> transInterfaceYields;
+    for (SILYieldInfo yield : fnTy->getYields()) {
+      if (transformSILYield(yield, changed, fn)) return Type();
+      transInterfaceYields.push_back(yield);
+    }
+
     SmallVector<SILResultInfo, 8> transInterfaceResults;
     for (SILResultInfo result : fnTy->getResults()) {
       if (transformSILResult(result, changed, fn)) return Type();
@@ -3583,10 +3700,15 @@
 
     if (!changed) return *this;
 
-    return SILFunctionType::get(fnTy->getGenericSignature(), fnTy->getExtInfo(),
+    return SILFunctionType::get(fnTy->getGenericSignature(),
+                                fnTy->getExtInfo(),
+                                fnTy->getCoroutineKind(),
                                 fnTy->getCalleeConvention(),
-                                transInterfaceParams, transInterfaceResults,
-                                transErrorResult, Ptr->getASTContext(),
+                                transInterfaceParams,
+                                transInterfaceYields,
+                                transInterfaceResults,
+                                transErrorResult,
+                                Ptr->getASTContext(),
                                 fnTy->getWitnessMethodConformanceOrNone());
   }
 
@@ -3777,6 +3899,7 @@
     return DependentMemberType::get(dependentBase, dependent->getName());
   }
 
+  case TypeKind::GenericFunction:
   case TypeKind::Function: {
     auto function = cast<AnyFunctionType>(base);
     auto inputTy = function->getInput().transformRec(fn);
@@ -3786,131 +3909,33 @@
     if (!resultTy)
       return Type();
 
-    if (inputTy.getPointer() == function->getInput().getPointer() &&
-        resultTy.getPointer() == function->getResult().getPointer())
-      return *this;
+    bool isUnchanged =
+        inputTy.getPointer() == function->getInput().getPointer() &&
+        resultTy.getPointer() == function->getResult().getPointer();
+
+    if (auto genericFnType = dyn_cast<GenericFunctionType>(base)) {
+
+#ifndef NDEBUG
+      // Check that generic parameters won't be trasnformed.
+      // Transform generic parameters.
+      for (auto param : genericFnType->getGenericParams()) {
+        assert(Type(param).transformRec(fn).getPointer() == param &&
+               "GenericFunctionType transform() changes type parameter");
+      }
+#endif
+      if (isUnchanged) return *this;
+      
+      auto genericSig = genericFnType->getGenericSignature();
+      return GenericFunctionType::get(genericSig, inputTy, resultTy,
+                                      function->getExtInfo());
+    }
+
+    if (isUnchanged) return *this;
 
     return FunctionType::get(inputTy, resultTy,
                              function->getExtInfo());
   }
 
-  case TypeKind::GenericFunction: {
-    GenericFunctionType *function = cast<GenericFunctionType>(base);
-    bool anyChanges = false;
-
-    // Transform generic parameters.
-    SmallVector<GenericTypeParamType *, 4> genericParams;
-    for (auto param : function->getGenericParams()) {
-      Type paramTy = Type(param).transformRec(fn);
-      if (!paramTy)
-        return Type();
-
-      if (auto newParam = paramTy->getAs<GenericTypeParamType>()) {
-        if (newParam != param)
-          anyChanges = true;
-
-        genericParams.push_back(newParam);
-      } else {
-        anyChanges = true;
-      }
-    }
-
-    // Transform requirements.
-    SmallVector<Requirement, 4> requirements;
-    for (const auto &req : function->getRequirements()) {
-      auto firstType = req.getFirstType().transformRec(fn);
-      if (!firstType)
-        return Type();
-
-      if (firstType.getPointer() != req.getFirstType().getPointer())
-        anyChanges = true;
-
-      if (req.getKind() == RequirementKind::Layout) {
-        if (!firstType->isTypeParameter())
-          continue;
-
-        requirements.push_back(Requirement(req.getKind(), firstType,
-                                           req.getLayoutConstraint()));
-        continue;
-      }
-
-      Type secondType = req.getSecondType();
-      if (secondType) {
-        secondType = secondType.transformRec(fn);
-        if (!secondType)
-          return Type();
-
-        if (secondType.getPointer() != req.getSecondType().getPointer())
-          anyChanges = true;
-      }
-
-      if (!firstType->isTypeParameter()) {
-        if (!secondType || !secondType->isTypeParameter())
-          continue;
-        std::swap(firstType, secondType);
-      }
-
-      requirements.push_back(Requirement(req.getKind(), firstType,
-                                         secondType));
-    }
-    
-    // Transform input type.
-    auto inputTy = function->getInput().transformRec(fn);
-    if (!inputTy)
-      return Type();
-
-    // Transform result type.
-    auto resultTy = function->getResult().transformRec(fn);
-    if (!resultTy)
-      return Type();
-
-    // Check whether anything changed.
-    if (!anyChanges &&
-        inputTy.getPointer() == function->getInput().getPointer() &&
-        resultTy.getPointer() == function->getResult().getPointer())
-      return *this;
-
-    // If no generic parameters remain, this is a non-generic function type.
-    if (genericParams.empty()) {
-      return FunctionType::get(inputTy, resultTy, function->getExtInfo());
-    }
-
-    // Sort/unique the generic parameters by depth/index.
-    using llvm::array_pod_sort;
-    array_pod_sort(genericParams.begin(), genericParams.end(),
-                   [](GenericTypeParamType * const * gpp1,
-                      GenericTypeParamType * const * gpp2) {
-                     auto gp1 = *gpp1;
-                     auto gp2 = *gpp2;
-
-                     if (gp1->getDepth() < gp2->getDepth())
-                       return -1;
-
-                     if (gp1->getDepth() > gp2->getDepth())
-                       return 1;
-
-                     if (gp1->getIndex() < gp2->getIndex())
-                       return -1;
-
-                     if (gp1->getIndex() > gp2->getIndex())
-                       return 1;
-
-                     return 0;
-                   });
-    genericParams.erase(std::unique(genericParams.begin(), genericParams.end(),
-                                    [](GenericTypeParamType *gp1,
-                                       GenericTypeParamType *gp2) {
-                                      return gp1->getDepth() == gp2->getDepth()
-                                          && gp1->getIndex() == gp2->getIndex();
-                                    }),
-                        genericParams.end());
-
-    // Produce the new generic function type.
-    auto sig = GenericSignature::get(genericParams, requirements);
-    return GenericFunctionType::get(sig, inputTy, resultTy,
-                                    function->getExtInfo());
-  }
-
   case TypeKind::ArraySlice: {
     auto slice = cast<ArraySliceType>(base);
     auto baseTy = slice->getBaseType().transformRec(fn);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 8d88e15..9700939 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -229,6 +229,10 @@
 
   Opts.ParseStdlib |= Args.hasArg(OPT_parse_stdlib);
 
+  if (const Arg *A = Args.getLastArg(OPT_verify_generic_signatures)) {
+    Opts.VerifyGenericSignaturesInModule = A->getValue();
+  }
+
   // Determine what the user has asked the frontend to do.
   FrontendOptions::ActionType &Action = Opts.RequestedAction;
   if (const Arg *A = Args.getLastArg(OPT_modes_Group)) {
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index fba8441..4682fc5 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -30,6 +30,7 @@
 #include "swift/AST/ASTScope.h"
 #include "swift/AST/DiagnosticsFrontend.h"
 #include "swift/AST/DiagnosticsSema.h"
+#include "swift/AST/GenericSignatureBuilder.h"
 #include "swift/AST/IRGenOptions.h"
 #include "swift/AST/ASTMangler.h"
 #include "swift/AST/LegacyASTTransformer.h"
@@ -630,6 +631,14 @@
 
   ASTContext &Context = Instance.getASTContext();
 
+
+  auto verifyGenericSignaturesInModule =
+    Invocation.getFrontendOptions().VerifyGenericSignaturesInModule;
+  if (!verifyGenericSignaturesInModule.empty()) {
+    if (auto module = Context.getModuleByName(verifyGenericSignaturesInModule))
+      GenericSignatureBuilder::verifyGenericSignaturesInModule(module);
+  }
+
   if (Invocation.getMigratorOptions().shouldRunMigrator()) {
     migrator::updateCodeAndEmitRemap(&Instance, Invocation);
   }
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 5e5e9b2..74e2f0e 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3138,11 +3138,10 @@
   metaclass = llvm::ConstantExpr::getBitCast(metaclass, TypeMetadataPtrTy);
 
   // Get a reference count of two.
-  auto *strongRefCountInit = llvm::ConstantInt::get(
-      Int32Ty,
-      InlineRefCountBits(0 /*unowned ref count*/, 2 /*strong ref count*/)
+  auto *refCountInit = llvm::ConstantInt::get(
+      IntPtrTy,
+      InlineRefCountBits(1 /* "extra" strong ref count*/, 1 /* unowned count */)
           .getBitsValue());
-  auto *unownedRefCountInit = llvm::ConstantInt::get(Int32Ty, 0);
 
   auto *count = llvm::ConstantInt::get(Int32Ty, utf8.size());
   // Capacity is length plus one because of the implicitly added '\0'
@@ -3150,9 +3149,8 @@
   auto *capacity = llvm::ConstantInt::get(Int32Ty, utf8.size() + 1);
   auto *flags = llvm::ConstantInt::get(Int8Ty, 0);
 
-  // FIXME: Big endian-ness.
   llvm::Constant *heapObjectHeaderFields[] = {
-      metaclass, strongRefCountInit, unownedRefCountInit
+      metaclass, refCountInit
   };
 
   auto *initRefCountStruct = llvm::ConstantStruct::get(
@@ -3216,11 +3214,10 @@
   metaclass = llvm::ConstantExpr::getBitCast(metaclass, TypeMetadataPtrTy);
 
   // Get a reference count of two.
-  auto *strongRefCountInit = llvm::ConstantInt::get(
-      Int32Ty,
-      InlineRefCountBits(0 /*unowned ref count*/, 2 /*strong ref count*/)
+  auto *refCountInit = llvm::ConstantInt::get(
+      IntPtrTy,
+      InlineRefCountBits(1 /* "extra" strong ref count*/, 1 /* unowned count */)
           .getBitsValue());
-  auto *unownedRefCountInit = llvm::ConstantInt::get(Int32Ty, 0);
 
   auto *count = llvm::ConstantInt::get(Int32Ty, utf16Length);
   auto *capacity = llvm::ConstantInt::get(Int32Ty, utf16Length + 1);
@@ -3228,7 +3225,7 @@
   auto *padding = llvm::ConstantInt::get(Int8Ty, 0);
 
   llvm::Constant *heapObjectHeaderFields[] = {
-      metaclass, strongRefCountInit, unownedRefCountInit
+      metaclass, refCountInit
   };
 
   auto *initRefCountStruct = llvm::ConstantStruct::get(
diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp
index 9e7b6ed..4a0cabf 100644
--- a/lib/IRGen/GenExistential.cpp
+++ b/lib/IRGen/GenExistential.cpp
@@ -2128,7 +2128,7 @@
 
         //  Size = ((sizeof(HeapObject) + align) & ~align) + size
         auto *heapHeaderSize = llvm::ConstantInt::get(
-            IGF.IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
+            IGF.IGM.SizeTy, IGM.RefCountedStructSize.getValue());
         size = Builder.CreateAdd(
             Builder.CreateAnd(Builder.CreateAdd(heapHeaderSize, alignmentMask),
                               Builder.CreateNot(alignmentMask)),
@@ -2222,7 +2222,7 @@
 
           //  StartOffset = ((sizeof(HeapObject) + align) & ~align)
           auto *heapHeaderSize = llvm::ConstantInt::get(
-              IGF.IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
+              IGF.IGM.SizeTy, IGM.RefCountedStructSize.getValue());
           auto *startOffset = Builder.CreateAnd(
               Builder.CreateAdd(heapHeaderSize, alignmentMask),
               Builder.CreateNot(alignmentMask));
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index 198f9cc..b025fe7 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -700,11 +700,6 @@
   fields.add(emitMetadataGenerator(rootTy));
   fields.add(emitMetadataGenerator(valueTy));
   
-  // TODO: 32-bit heap object header still has an extra word
-  if (SizeTy == Int32Ty) {
-    fields.addInt32(0);
-  }
-  
 #ifndef NDEBUG
   auto endOfObjectHeader = fields.getNextOffsetFromGlobal();
   unsigned expectedObjectHeaderSize;
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 4797745..5b4c114 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -2594,8 +2594,10 @@
   auto generics = ncGenerics->getCanonicalSignature();
   CanSILFunctionType fnType = [&]() -> CanSILFunctionType {
     return SILFunctionType::get(generics, SILFunctionType::ExtInfo(),
+                                SILCoroutineKind::None,
                                 /*callee*/ ParameterConvention::Direct_Unowned,
-                                /*params*/ {}, /*results*/ {}, /*error*/ None,
+                                /*params*/ {}, /*yields*/ {},
+                                /*results*/ {}, /*error*/ None,
                                 IGM.Context);
   }();
 
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index 348ceb8..fe7ac34 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -242,8 +242,8 @@
         buffer.getAlignment());
     auto *boxStart = IGF.Builder.CreateLoad(boxAddress);
     auto *alignmentMask = type.getAlignmentMask(IGF, T);
-    auto *heapHeaderSize =
-        llvm::ConstantInt::get(IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
+    auto *heapHeaderSize = llvm::ConstantInt::get(
+        IGM.SizeTy, IGM.RefCountedStructSize.getValue());
     auto *startOffset =
         Builder.CreateAnd(Builder.CreateAdd(heapHeaderSize, alignmentMask),
                           Builder.CreateNot(alignmentMask));
@@ -820,7 +820,7 @@
         IGF.Builder.CreateStore(ptr, dest);
         auto *alignmentMask = fixedTI.getStaticAlignmentMask(IGM);
         auto *heapHeaderSize = llvm::ConstantInt::get(
-            IGM.SizeTy, getHeapHeaderSize(IGM).getValue());
+            IGM.SizeTy, IGM.RefCountedStructSize.getValue());
         auto *startOffset = IGF.Builder.CreateAnd(
             IGF.Builder.CreateAdd(heapHeaderSize, alignmentMask),
             IGF.Builder.CreateNot(alignmentMask));
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index b931047..27b1531 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -264,8 +264,11 @@
   });
   FullBoxMetadataPtrTy = FullBoxMetadataStructTy->getPointerTo(DefaultAS);
 
-  llvm::Type *refCountedElts[] = {TypeMetadataPtrTy, Int32Ty, Int32Ty};
+  // This must match struct HeapObject in the runtime.
+  llvm::Type *refCountedElts[] = {TypeMetadataPtrTy, IntPtrTy};
   RefCountedStructTy->setBody(refCountedElts);
+  RefCountedStructSize =
+    Size(DataLayout.getStructLayout(RefCountedStructTy)->getSizeInBytes());
 
   PtrSize = Size(DataLayout.getPointerSize(DefaultAS));
 
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index b242a31..ca960d6 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -446,6 +446,7 @@
     llvm::PointerType *WitnessTablePtrTy;
   };
   llvm::StructType *RefCountedStructTy;/// %swift.refcounted = type { ... }
+  Size RefCountedStructSize;     /// sizeof(%swift.refcounted)
   llvm::PointerType *RefCountedPtrTy;  /// %swift.refcounted*
   llvm::PointerType *WeakReferencePtrTy;/// %swift.weak_reference*
   llvm::PointerType *UnownedReferencePtrTy;/// %swift.unowned_reference*
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 6656db0..c5a5524 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -1024,6 +1024,8 @@
   void visitCondBranchInst(CondBranchInst *i);
   void visitReturnInst(ReturnInst *i);
   void visitThrowInst(ThrowInst *i);
+  void visitUnwindInst(UnwindInst *i);
+  void visitYieldInst(YieldInst *i);
   void visitSwitchValueInst(SwitchValueInst *i);
   void visitSwitchEnumInst(SwitchEnumInst *i);
   void visitSwitchEnumAddrInst(SwitchEnumAddrInst *i);
@@ -2470,6 +2472,20 @@
   }
 }
 
+void IRGenSILFunction::visitUnwindInst(swift::UnwindInst *i) {
+  IGM.unimplemented(i->getLoc().getSourceLoc(),
+                    "unwind instruction");
+  Builder.CreateUnreachable();
+  Builder.emitBlock(createBasicBlock("unwind"));
+}
+
+void IRGenSILFunction::visitYieldInst(swift::YieldInst *i) {
+  IGM.unimplemented(i->getLoc().getSourceLoc(),
+                    "yield instruction");
+  Builder.CreateUnreachable();
+  Builder.emitBlock(createBasicBlock("yield"));
+}
+
 static llvm::BasicBlock *emitBBMapForSwitchValue(
         IRGenSILFunction &IGF,
         SmallVectorImpl<std::pair<SILValue, llvm::BasicBlock*>> &dests,
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 31069ff..80c2e9b 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -73,47 +73,60 @@
   return true;
 }
 
-static bool modResultType(GenericEnvironment *genEnv,
-                          CanSILFunctionType loweredTy,
-                          irgen::IRGenModule &Mod);
+static bool shouldTransformResults(GenericEnvironment *env,
+                                   CanSILFunctionType fnType,
+                                   irgen::IRGenModule &IGM);
 
-static bool containsLargeLoadable(GenericEnvironment *GenericEnv,
-                                  ArrayRef<SILParameterInfo> params,
-                                  irgen::IRGenModule &Mod) {
-  for (SILParameterInfo param : params) {
-    SILType storageType = param.getSILStorageType();
-    CanType currCanType = storageType.getSwiftRValueType();
-    if (SILFunctionType *currSILFunctionType =
-            dyn_cast<SILFunctionType>(currCanType.getPointer())) {
-      if (containsLargeLoadable(GenericEnv,
-                                currSILFunctionType->getParameters(), Mod) ||
-          modResultType(GenericEnv, CanSILFunctionType(currSILFunctionType),
-                        Mod)) {
-        return true;
-      }
-    } else {
-      switch (param.getConvention()) {
-      case ParameterConvention::Indirect_In_Guaranteed:
-      case ParameterConvention::Indirect_Inout:
-      case ParameterConvention::Indirect_InoutAliasable:
-      case ParameterConvention::Indirect_In: {
-        continue;
-      }
-      default:
-        break;
-      }
-      if (isLargeLoadableType(GenericEnv, storageType, Mod)) {
-        return true;
-      }
-    }
+static bool shouldTransformFunctionType(GenericEnvironment *env,
+                                        CanSILFunctionType fnType,
+                                        irgen::IRGenModule &IGM);
+
+static bool shouldTransformParameter(GenericEnvironment *env,
+                                     SILParameterInfo param,
+                                     irgen::IRGenModule &IGM) {
+  SILType storageType = param.getSILStorageType();
+
+  // FIXME: only function types and not recursively-transformable types?
+  if (auto fnType = storageType.getAs<SILFunctionType>())
+    return shouldTransformFunctionType(env, fnType, IGM);
+
+  switch (param.getConvention()) {
+  case ParameterConvention::Indirect_In_Guaranteed:
+  case ParameterConvention::Indirect_Inout:
+  case ParameterConvention::Indirect_InoutAliasable:
+  case ParameterConvention::Indirect_In:
+    return false;
+  default:
+    return isLargeLoadableType(env, storageType, IGM);
   }
+}
+
+static bool shouldTransformFunctionType(GenericEnvironment *env,
+                                        CanSILFunctionType fnType,
+                                        irgen::IRGenModule &IGM) {
+  if (shouldTransformResults(env, fnType, IGM))
+    return true;
+
+  for (auto param : fnType->getParameters()) {
+    if (shouldTransformParameter(env, param, IGM))
+      return true;
+  }
+
+  for (auto yield : fnType->getYields()) {
+    if (shouldTransformParameter(env, yield, IGM))
+      return true;
+  }
+
   return false;
 }
 
 // Forward declarations - functions depend on each other
 static SmallVector<SILParameterInfo, 4>
-getNewArgTys(GenericEnvironment *GenericEnv,
-             SILFunctionType *currSILFunctionType, irgen::IRGenModule &Mod);
+getNewParameters(GenericEnvironment *env, CanSILFunctionType fnType,
+                 irgen::IRGenModule &IGM);
+static SmallVector<SILYieldInfo, 2>
+getNewYields(GenericEnvironment *env, CanSILFunctionType fnType,
+             irgen::IRGenModule &IGM);
 static SILType getNewSILType(GenericEnvironment *GenericEnv,
                              SILType storageType, irgen::IRGenModule &Mod);
 
@@ -135,11 +148,11 @@
 
 static SmallVector<SILResultInfo, 2>
 getNewResults(GenericEnvironment *GenericEnv,
-              SILFunctionType *currSILFunctionType, irgen::IRGenModule &Mod) {
+              CanSILFunctionType fnType, irgen::IRGenModule &Mod) {
   // Get new SIL Function results - same as old results UNLESS:
   // 1) Function type results might have a different signature
   // 2) Large loadables are replaced by @out version
-  auto origResults = currSILFunctionType->getResults();
+  auto origResults = fnType->getResults();
   SmallVector<SILResultInfo, 2> newResults;
   for (auto result : origResults) {
     SILType currResultTy = result.getSILStorageType();
@@ -152,8 +165,7 @@
                               result.getConvention());
       newResults.push_back(newResult);
     } else if ((newSILType != currResultTy) &&
-               modResultType(GenericEnv,
-                             CanSILFunctionType(currSILFunctionType), Mod)) {
+               shouldTransformResults(GenericEnv, fnType, Mod)) {
       // Case (2) Above
       SILResultInfo newSILResultInfo(newSILType.getSwiftRValueType(),
                                      ResultConvention::Indirect);
@@ -165,39 +177,28 @@
   return newResults;
 }
 
-static SILFunctionType *
-getNewSILFunctionTypePtr(GenericEnvironment *GenericEnv,
-                         SILFunctionType *currSILFunctionType,
-                         irgen::IRGenModule &Mod) {
-  if (!modifiableFunction(CanSILFunctionType(currSILFunctionType))) {
-    return currSILFunctionType;
+static CanSILFunctionType
+getNewSILFunctionType(GenericEnvironment *env,
+                      CanSILFunctionType fnType,
+                      irgen::IRGenModule &IGM) {
+  if (!modifiableFunction(fnType)) {
+    return fnType;
   }
-  SmallVector<SILParameterInfo, 4> newArgTys =
-      getNewArgTys(GenericEnv, currSILFunctionType, Mod);
-  SILFunctionType *newSILFunctionType = SILFunctionType::get(
-      currSILFunctionType->getGenericSignature(),
-      currSILFunctionType->getExtInfo(),
-      currSILFunctionType->getCalleeConvention(), newArgTys,
-      getNewResults(GenericEnv, currSILFunctionType, Mod),
-      currSILFunctionType->getOptionalErrorResult(),
-      currSILFunctionType->getASTContext(),
-      currSILFunctionType->getWitnessMethodConformanceOrNone());
-  return newSILFunctionType;
-}
-
-static SILType getNewSILFunctionType(GenericEnvironment *GenericEnv,
-                                     SILFunctionType *currSILFunctionType,
-                                     irgen::IRGenModule &Mod) {
-  if (!modifiableFunction(CanSILFunctionType(currSILFunctionType))) {
-    SILType newSILType = SILType::getPrimitiveObjectType(
-        currSILFunctionType->getCanonicalType());
-    return newSILType;
-  }
-  SILFunctionType *newSILFunctionType =
-      getNewSILFunctionTypePtr(GenericEnv, currSILFunctionType, Mod);
-  SILType newSILType =
-      SILType::getPrimitiveObjectType(newSILFunctionType->getCanonicalType());
-  return newSILType;
+  auto newParams = getNewParameters(env, fnType, IGM);
+  auto newYields = getNewYields(env, fnType, IGM);
+  auto newResults = getNewResults(env, fnType, IGM);
+  auto newFnType = SILFunctionType::get(
+      fnType->getGenericSignature(),
+      fnType->getExtInfo(),
+      fnType->getCoroutineKind(),
+      fnType->getCalleeConvention(),
+      newParams,
+      newYields,
+      newResults,
+      fnType->getOptionalErrorResult(),
+      fnType->getASTContext(),
+      fnType->getWitnessMethodConformanceOrNone());
+  return newFnType;
 }
 
 // Get the function type or the optional function type
@@ -223,35 +224,22 @@
                                           SILType storageType,
                                           irgen::IRGenModule &Mod) {
   SILType newSILType = storageType;
-  CanType currCanType = storageType.getSwiftRValueType();
-  OptionalTypeKind optKind;
-  if (auto optionalType = currCanType.getAnyOptionalObjectType(optKind)) {
-    assert(optKind != OptionalTypeKind::OTK_None &&
-           "Expected Real Optional Type");
-    if (auto *currSILFunctionType =
-            dyn_cast<SILFunctionType>(optionalType.getPointer())) {
-      if (containsLargeLoadable(GenericEnv,
-                                currSILFunctionType->getParameters(), Mod) ||
-          modResultType(GenericEnv, CanSILFunctionType(currSILFunctionType),
-                        Mod)) {
+  if (auto objectType = storageType.getAnyOptionalObjectType()) {
+    if (auto fnType = objectType.getAs<SILFunctionType>()) {
+      if (shouldTransformFunctionType(GenericEnv, fnType, Mod)) {
+        auto newFnType = getNewSILFunctionType(GenericEnv, fnType, Mod);        
         newSILType =
-            getNewSILFunctionType(GenericEnv, currSILFunctionType, Mod);
-        currCanType = newSILType.getSwiftRValueType();
-        auto newType = OptionalType::get(optKind, currCanType);
-        CanType newCanType = newType->getCanonicalType();
-        newSILType = SILType::getPrimitiveObjectType(newCanType);
-        if (storageType.isAddress()) {
-          newSILType = newSILType.getAddressType();
-        }
+          SILType::getPrimitiveType(newFnType, storageType.getCategory());
+        newSILType = SILType::getOptionalType(newSILType);
       }
     }
   }
   return newSILType;
 }
 
-static bool modResultType(GenericEnvironment *genEnv,
-                          CanSILFunctionType loweredTy,
-                          irgen::IRGenModule &Mod) {
+static bool shouldTransformResults(GenericEnvironment *genEnv,
+                                   CanSILFunctionType loweredTy,
+                                   irgen::IRGenModule &Mod) {
   if (!modifiableFunction(loweredTy)) {
     return false;
   }
@@ -274,53 +262,55 @@
     genEnv = getGenericEnvironment(F->getModule(), loweredTy);
   }
 
-  return modResultType(genEnv, loweredTy, Mod);
+  return shouldTransformResults(genEnv, loweredTy, Mod);
+}
+
+static SILParameterInfo
+getNewParameter(GenericEnvironment *env, SILParameterInfo param,
+                irgen::IRGenModule &IGM) {
+  SILType storageType = param.getSILStorageType();
+  SILType newOptFuncType =
+      getNewOptionalFunctionType(env, storageType, IGM);
+  if (newOptFuncType != storageType) {
+    return param.getWithType(newOptFuncType.getSwiftRValueType());
+  }
+
+  if (auto paramFnType = storageType.getAs<SILFunctionType>()) {
+    if (shouldTransformFunctionType(env, paramFnType, IGM)) {
+      auto newFnType = getNewSILFunctionType(env, paramFnType, IGM);
+      return param.getWithType(newFnType);
+    } else {
+      return param;
+    }
+  } else if (isLargeLoadableType(env, storageType, IGM)) {
+    return  SILParameterInfo(storageType.getSwiftRValueType(),
+                             ParameterConvention::Indirect_In_Constant);
+  } else {
+    return param;
+  }
 }
 
 static SmallVector<SILParameterInfo, 4>
-getNewArgTys(GenericEnvironment *GenericEnv,
-             SILFunctionType *currSILFunctionType, irgen::IRGenModule &Mod) {
-  ArrayRef<SILParameterInfo> params = currSILFunctionType->getParameters();
-  SmallVector<SILParameterInfo, 4> newArgTys;
-  for (SILParameterInfo param : params) {
-    SILType storageType = param.getSILStorageType();
-    SILType newOptFuncType =
-        getNewOptionalFunctionType(GenericEnv, storageType, Mod);
-    if (newOptFuncType != storageType) {
-      auto newParam = SILParameterInfo(newOptFuncType.getSwiftRValueType(),
-                                       param.getConvention());
-      newArgTys.push_back(newParam);
-      continue;
-    }
-    CanType currCanType = storageType.getSwiftRValueType();
-    if (SILFunctionType *currSILFunctionType =
-            dyn_cast<SILFunctionType>(currCanType.getPointer())) {
-      if (containsLargeLoadable(GenericEnv,
-                                currSILFunctionType->getParameters(), Mod) ||
-          modResultType(GenericEnv, CanSILFunctionType(currSILFunctionType),
-                        Mod)) {
-        SILType newSILType =
-            getNewSILFunctionType(GenericEnv, currSILFunctionType, Mod);
-        if (storageType.isAddress()) {
-          newSILType = newSILType.getAddressType();
-        }
-        auto newParam = SILParameterInfo(newSILType.getSwiftRValueType(),
-                                         param.getConvention());
-        newArgTys.push_back(newParam);
-      } else {
-        newArgTys.push_back(param);
-      }
-    } else if (isLargeLoadableType(GenericEnv, storageType, Mod)) {
-      SILType addrType = storageType.getAddressType();
-      auto newParam =
-          SILParameterInfo(addrType.getSwiftRValueType(),
-                           ParameterConvention::Indirect_In_Constant);
-      newArgTys.push_back(newParam);
-    } else {
-      newArgTys.push_back(param);
-    }
+getNewParameters(GenericEnvironment *env, CanSILFunctionType fnType,
+                 irgen::IRGenModule &IGM) {
+  SmallVector<SILParameterInfo, 4> newParams;
+  for (SILParameterInfo param : fnType->getParameters()) {
+    auto newParam = getNewParameter(env, param, IGM);
+    newParams.push_back(newParam);
   }
-  return newArgTys;
+  return newParams;
+}
+
+static SmallVector<SILYieldInfo, 2>
+getNewYields(GenericEnvironment *env, CanSILFunctionType fnType,
+             irgen::IRGenModule &IGM) {
+  SmallVector<SILYieldInfo, 2> newYields;
+  for (auto oldYield : fnType->getYields()) {
+    auto newYieldAsParam = getNewParameter(env, oldYield, IGM);
+    newYields.push_back(SILYieldInfo(newYieldAsParam.getType(),
+                                     newYieldAsParam.getConvention()));
+  }
+  return newYields;
 }
 
 static SILType getNewSILType(GenericEnvironment *GenericEnv,
@@ -329,17 +319,11 @@
   if (newSILType != storageType) {
     return newSILType;
   }
-  CanType currCanType = storageType.getSwiftRValueType();
-  if (SILFunctionType *currSILFunctionType =
-          dyn_cast<SILFunctionType>(currCanType.getPointer())) {
-    if (containsLargeLoadable(GenericEnv, currSILFunctionType->getParameters(),
-                              Mod) ||
-        modResultType(GenericEnv, CanSILFunctionType(currSILFunctionType),
-                      Mod)) {
-      newSILType = getNewSILFunctionType(GenericEnv, currSILFunctionType, Mod);
-      if (storageType.isAddress()) {
-        newSILType = newSILType.getAddressType();
-      }
+  if (auto fnType = storageType.getAs<SILFunctionType>()) {
+    if (shouldTransformFunctionType(GenericEnv, fnType, Mod)) {
+      auto newFnType = getNewSILFunctionType(GenericEnv, fnType, Mod);
+      newSILType = SILType::getPrimitiveType(newFnType,
+                                             storageType.getCategory());
     }
   } else if (isLargeLoadableType(GenericEnv, storageType, Mod)) {
     newSILType = storageType.getAddressType();
@@ -584,14 +568,14 @@
     return;
   }
   // Check callee - need new generic env:
-  SILFunctionType *origSILFunctionType = applySite.getSubstCalleeType();
+  CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
   GenericEnvironment *genEnvCallee = nullptr;
   if (origSILFunctionType->isPolymorphic()) {
     genEnvCallee = getGenericEnvironment(
         applySite.getModule(), CanSILFunctionType(origSILFunctionType));
   }
-  SILFunctionType *newSILFunctionType =
-      getNewSILFunctionTypePtr(genEnvCallee, origSILFunctionType, pass.Mod);
+  auto newSILFunctionType =
+      getNewSILFunctionType(genEnvCallee, origSILFunctionType, pass.Mod);
   if (origSILFunctionType != newSILFunctionType) {
     pass.applies.push_back(applySite.getInstruction());
   }
@@ -617,27 +601,19 @@
     return;
   }
   SILType currSILType = instr->getType();
-  CanType currCanType = currSILType.getSwiftRValueType();
-  SILFunctionType *currSILFunctionType =
-      dyn_cast<SILFunctionType>(currCanType.getPointer());
-  if (!currSILFunctionType) {
-    llvm_unreachable("unsupported type");
-  }
+  auto fnType = currSILType.castTo<SILFunctionType>();
+
   GenericEnvironment *genEnv = nullptr;
-  if (currSILFunctionType->isPolymorphic()) {
-    genEnv = getGenericEnvironment(instr->getModule(),
-                                   CanSILFunctionType(currSILFunctionType));
+  if (fnType->isPolymorphic()) {
+    genEnv = getGenericEnvironment(instr->getModule(), fnType);
   }
   Lowering::GenericContextScope GenericScope(
-      instr->getModule().Types, currSILFunctionType->getGenericSignature());
-  if (containsLargeLoadable(genEnv, currSILFunctionType->getParameters(),
-                            pass.Mod) ||
-      modResultType(genEnv, CanSILFunctionType(currSILFunctionType),
-                    pass.Mod)) {
+      instr->getModule().Types, fnType->getGenericSignature());
+  if (shouldTransformFunctionType(genEnv, fnType, pass.Mod)) {
     pass.methodInstsToMod.push_back(instr);
     return;
   }
-  if (newResultsDiffer(genEnv, currSILFunctionType->getResults(), pass.Mod)) {
+  if (newResultsDiffer(genEnv, fnType->getResults(), pass.Mod)) {
     pass.methodInstsToMod.push_back(instr);
   }
 }
@@ -763,8 +739,8 @@
     if (!genEnv && canFuncType->isPolymorphic()) {
       genEnv = getGenericEnvironment(instr->getModule(), canFuncType);
     }
-    SILFunctionType *newSILFunctionType =
-        getNewSILFunctionTypePtr(genEnv, funcType, pass.Mod);
+    auto newSILFunctionType =
+        getNewSILFunctionType(genEnv, funcType, pass.Mod);
     if (funcType != newSILFunctionType) {
       pass.tupleInstsToMod.push_back(instr);
     }
@@ -1255,23 +1231,22 @@
       if (!modifiableApply(applySite, pass.Mod)) {
         continue;
       }
-      SILFunctionType *origSILFunctionType = applySite.getSubstCalleeType();
-      auto canSILFunctionType = CanSILFunctionType(origSILFunctionType);
+      CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
       Lowering::GenericContextScope GenericScope(
-          silModue.Types, canSILFunctionType->getGenericSignature());
+          silModue.Types, origSILFunctionType->getGenericSignature());
       GenericEnvironment *genEnv = nullptr;
       if (origSILFunctionType->isPolymorphic()) {
-        genEnv = getGenericEnvironment(silModue, canSILFunctionType);
+        genEnv = getGenericEnvironment(silModue, origSILFunctionType);
       }
-      if (!modResultType(genEnv, canSILFunctionType, pass.Mod)) {
+      if (!shouldTransformResults(genEnv, origSILFunctionType, pass.Mod)) {
         continue;
       }
-      auto singleResult = canSILFunctionType->getSingleResult();
+      auto singleResult = origSILFunctionType->getSingleResult();
       auto resultStorageType = singleResult.getSILStorageType();
       if (!isLargeLoadableType(genEnv, resultStorageType, pass.Mod)) {
         // Make sure it is a function type
         auto canType = resultStorageType.getSwiftRValueType();
-        if (!dyn_cast<SILFunctionType>(canType.getPointer())) {
+        if (!isa<SILFunctionType>(canType)) {
           // Check if it is an optional funciton type
           OptionalTypeKind optKind;
           auto optionalType = canType.getAnyOptionalObjectType(optKind);
@@ -1607,19 +1582,16 @@
 }
 
 static void castTupleInstr(SingleValueInstruction *instr, IRGenModule &Mod) {
-  SILType currSILType = instr->getType().getObjectType();
-  CanType currCanType = currSILType.getSwiftRValueType();
-  SILFunctionType *funcType = dyn_cast<SILFunctionType>(currCanType);
-  assert(funcType && "Expected SILFunctionType as tuple's return");
-  CanSILFunctionType canFuncType = CanSILFunctionType(funcType);
+  SILType currSILType = instr->getType();
+  auto funcType = currSILType.castTo<SILFunctionType>();
   GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment();
-  if (!genEnv && canFuncType->isPolymorphic()) {
-    genEnv = getGenericEnvironment(instr->getModule(), canFuncType);
+  if (!genEnv && funcType->isPolymorphic()) {
+    genEnv = getGenericEnvironment(instr->getModule(), funcType);
   }
-  SILType newSILType = getNewSILFunctionType(genEnv, funcType, Mod);
-  if (currSILType.isAddress()) {
-    newSILType = newSILType.getAddressType();
-  }
+  auto newFnType = getNewSILFunctionType(genEnv, funcType, Mod);
+  SILType newSILType =
+    SILType::getPrimitiveType(newFnType, currSILType.getCategory());
+
   auto II = instr->getIterator();
   ++II;
   SILBuilder castBuilder(II);
@@ -1993,16 +1965,14 @@
 
   for (MethodInst *instr : pass.methodInstsToMod) {
     SILType currSILType = instr->getType();
-    CanType currCanType = currSILType.getSwiftRValueType();
-    SILFunctionType *currSILFunctionType =
-        dyn_cast<SILFunctionType>(currCanType.getPointer());
+    auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
     GenericEnvironment *genEnvForMethod = nullptr;
     if (currSILFunctionType->isPolymorphic()) {
       genEnvForMethod = getGenericEnvironment(
           instr->getModule(), CanSILFunctionType(currSILFunctionType));
     }
-    SILType newSILType =
-        getNewSILFunctionType(genEnvForMethod, currSILFunctionType, pass.Mod);
+    SILType newSILType = SILType::getPrimitiveObjectType(
+        getNewSILFunctionType(genEnvForMethod, currSILFunctionType, pass.Mod));
     auto member = instr->getMember();
     auto loc = instr->getLoc();
     SILBuilder methodBuilder(instr);
@@ -2104,7 +2074,9 @@
                                    origResultInfo.getConvention());
     auto NewTy = SILFunctionType::get(
         loweredTy->getGenericSignature(), loweredTy->getExtInfo(),
+        loweredTy->getCoroutineKind(),
         loweredTy->getCalleeConvention(), loweredTy->getParameters(),
+        loweredTy->getYields(),
         newSILResultInfo, loweredTy->getOptionalErrorResult(),
         F->getModule().getASTContext(),
         loweredTy->getWitnessMethodConformanceOrNone());
@@ -2131,10 +2103,8 @@
     if (!genEnv && loweredTy->isPolymorphic()) {
       genEnv = getGenericEnvironment(F->getModule(), loweredTy);
     }
-    if (containsLargeLoadable(
-            genEnv, F->getLoweredFunctionType()->getParameters(), *currIRMod) ||
-        modResultType(genEnv, CanSILFunctionType(F->getLoweredFunctionType()),
-                      *currIRMod)) {
+    if (shouldTransformFunctionType(genEnv, F->getLoweredFunctionType(),
+                                    *currIRMod)) {
       modFuncs.insert(F);
     }
     return;
@@ -2178,16 +2148,15 @@
 getOperandTypeWithCastIfNecessary(SILInstruction *containingInstr, SILValue op,
                                   IRGenModule &Mod, SILBuilder &builder) {
   SILType currSILType = op->getType();
-  CanType currCanType = currSILType.getSwiftRValueType();
-  SILFunctionType *funcType = dyn_cast<SILFunctionType>(currCanType);
-  if (funcType) {
+  if (auto funcType = currSILType.getAs<SILFunctionType>()) {
     CanSILFunctionType canFuncType = CanSILFunctionType(funcType);
     GenericEnvironment *genEnv =
         containingInstr->getFunction()->getGenericEnvironment();
     if (!genEnv && canFuncType->isPolymorphic()) {
       genEnv = getGenericEnvironment(containingInstr->getModule(), canFuncType);
     }
-    SILType newSILType = getNewSILFunctionType(genEnv, funcType, Mod);
+    auto newFnType = getNewSILFunctionType(genEnv, funcType, Mod);
+    SILType newSILType = SILType::getPrimitiveObjectType(newFnType);
     if (currSILType.isAddress()) {
       newSILType = newSILType.getAddressType(); // we need address for loads
       if (newSILType != currSILType) {
@@ -2242,7 +2211,7 @@
       callee = applySite.getCallee();
     }
   }
-  SILFunctionType *origSILFunctionType = applySite.getSubstCalleeType();
+  CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
   auto origCanType = CanSILFunctionType(origSILFunctionType);
   Lowering::GenericContextScope GenericScope(
       getModule()->Types, origCanType->getGenericSignature());
@@ -2251,8 +2220,8 @@
     genEnv = getGenericEnvironment(applyInst->getModule(),
                                    CanSILFunctionType(origSILFunctionType));
   }
-  SILFunctionType *newSILFunctionType =
-      getNewSILFunctionTypePtr(genEnv, origSILFunctionType, *currIRMod);
+  CanSILFunctionType newSILFunctionType =
+      getNewSILFunctionType(genEnv, origSILFunctionType, *currIRMod);
   CanSILFunctionType newCanSILFuncType(newSILFunctionType);
   SILFunctionConventions newSILFunctionConventions(newCanSILFuncType,
                                                    *getModule());
@@ -2432,23 +2401,19 @@
     if (auto *thinToPointer = dyn_cast<ThinFunctionToPointerInst>(convInstr)) {
       currSILType = thinToPointer->getOperand()->getType();
     }
-    CanType currCanType = currSILType.getSwiftRValueType();
-    SILFunctionType *currSILFunctionType =
-        dyn_cast<SILFunctionType>(currCanType.getPointer());
+    auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
     Lowering::GenericContextScope GenericScope(
         getModule()->Types,
-        CanSILFunctionType(currSILFunctionType)->getGenericSignature());
-    if (!currSILFunctionType) {
-      llvm_unreachable("unsupported type");
-    }
+        currSILFunctionType->getGenericSignature());
     GenericEnvironment *genEnv =
         convInstr->getFunction()->getGenericEnvironment();
     auto loweredTy = convInstr->getFunction()->getLoweredFunctionType();
     if (!genEnv && loweredTy->isPolymorphic()) {
       genEnv = getGenericEnvironment(convInstr->getModule(), loweredTy);
     }
-    SILType newType =
+    CanSILFunctionType newFnType =
         getNewSILFunctionType(genEnv, currSILFunctionType, *currIRMod);
+    SILType newType = SILType::getPrimitiveObjectType(newFnType);
     SILBuilder convBuilder(convInstr);
     SingleValueInstruction *newInstr = nullptr;
     switch (convInstr->getKind()) {
@@ -2511,7 +2476,6 @@
 void LoadableByAddress::updateLoweredTypes(SILFunction *F) {
   IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
   CanSILFunctionType funcType = F->getLoweredFunctionType();
-  auto *currSILFunctionType = dyn_cast<SILFunctionType>(funcType.getPointer());
   Lowering::GenericContextScope GenericScope(getModule()->Types,
                                              funcType->getGenericSignature());
   GenericEnvironment *genEnv = F->getGenericEnvironment();
@@ -2519,10 +2483,8 @@
   if (!genEnv && loweredTy->isPolymorphic()) {
     genEnv = getGenericEnvironment(F->getModule(), loweredTy);
   }
-  auto *newFuncTy =
-      getNewSILFunctionTypePtr(genEnv, currSILFunctionType, *currIRMod);
-
-  F->rewriteLoweredTypeUnsafe(CanSILFunctionType(newFuncTy));
+  auto newFuncTy = getNewSILFunctionType(genEnv, funcType, *currIRMod);
+  F->rewriteLoweredTypeUnsafe(newFuncTy);
 }
 
 /// The entry point to this function transformation.
diff --git a/lib/IRGen/StructLayout.cpp b/lib/IRGen/StructLayout.cpp
index e27403f..003caf3 100644
--- a/lib/IRGen/StructLayout.cpp
+++ b/lib/IRGen/StructLayout.cpp
@@ -38,11 +38,6 @@
   llvm_unreachable("bad layout kind!");
 }
 
-/// Return the size of the standard heap header.
-Size irgen::getHeapHeaderSize(IRGenModule &IGM) {
-  return IGM.getPointerSize() + Size(8);
-}
-
 /// Perform structure layout on the given types.
 StructLayout::StructLayout(IRGenModule &IGM, CanType astTy,
                            LayoutKind layoutKind,
@@ -184,7 +179,7 @@
 
 void StructLayoutBuilder::addHeapHeader() {
   assert(StructFields.empty() && "adding heap header at a non-zero offset");
-  CurSize = getHeapHeaderSize(IGM);
+  CurSize = IGM.RefCountedStructSize;
   CurAlignment = IGM.getPointerAlignment();
   StructFields.push_back(IGM.RefCountedStructTy);
 }
diff --git a/lib/IRGen/StructLayout.h b/lib/IRGen/StructLayout.h
index 70c1531..84128b8 100644
--- a/lib/IRGen/StructLayout.h
+++ b/lib/IRGen/StructLayout.h
@@ -395,8 +395,6 @@
                      const llvm::Twine &name = "") const;
 };
 
-Size getHeapHeaderSize(IRGenModule &IGM);
-
 /// Different policies for accessing a physical field.
 enum class FieldAccess : uint8_t {
   /// Instance variable offsets are constant.
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index d3a64cc..37bcfe2 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -473,7 +473,6 @@
     Tok.setKind(tok::oper_prefix);
     LLVM_FALLTHROUGH;
   case tok::oper_prefix:
-    SyntaxContext->addTokenSyntax(Tok.getLoc());
     Operator = parseExprOperator();
     break;
   case tok::oper_binary_spaced:
@@ -867,7 +866,8 @@
                                         lSquareLoc, indexArgs, indexArgLabels,
                                         indexArgLabelLocs,
                                         rSquareLoc,
-                                        trailingClosure);
+                                        trailingClosure,
+                                        SyntaxKind::Unknown);
     if (status.hasCodeCompletion())
       return makeParserCodeCompletionResult<Expr>();
     if (status.isError())
@@ -1216,7 +1216,8 @@
       ParserStatus status = parseExprList(
           tok::l_square, tok::r_square,
           /*isPostfix=*/true, isExprBasic, lSquareLoc, indexArgs,
-          indexArgLabels, indexArgLabelLocs, rSquareLoc, trailingClosure);
+          indexArgLabels, indexArgLabelLocs, rSquareLoc, trailingClosure,
+          SyntaxKind::Unknown);
       if (status.hasCodeCompletion())
         return makeParserCodeCompletionResult<Expr>();
       if (status.isError() || Result.isNull())
@@ -1389,8 +1390,7 @@
   case tok::integer_literal: {
     StringRef Text = copyAndStripUnderscores(Context, Tok.getText());
     SourceLoc Loc = consumeToken(tok::integer_literal);
-    SyntaxContext->addTokenSyntax(Loc);
-    SyntaxContext->makeNode(SyntaxKind::IntegerLiteralExpr);
+    SyntaxContext->makeNode(SyntaxKind::IntegerLiteralExpr, Loc);
     Result = makeParserResult(new (Context) IntegerLiteralExpr(Text, Loc,
                                                            /*Implicit=*/false));
     break;
@@ -1398,8 +1398,7 @@
   case tok::floating_literal: {
     StringRef Text = copyAndStripUnderscores(Context, Tok.getText());
     SourceLoc Loc = consumeToken(tok::floating_literal);
-    SyntaxContext->addTokenSyntax(Loc);
-    SyntaxContext->makeNode(SyntaxKind::FloatLiteralExpr);
+    SyntaxContext->makeNode(SyntaxKind::FloatLiteralExpr, Loc);
     Result = makeParserResult(new (Context) FloatLiteralExpr(Text, Loc,
                                                            /*Implicit=*/false));
     break;
@@ -1608,7 +1607,8 @@
                                           lParenLoc, args, argLabels,
                                           argLabelLocs,
                                           rParenLoc,
-                                          trailingClosure);
+                                          trailingClosure,
+                                          SyntaxKind::FunctionCallArgumentList);
       if (status.isError())
         return nullptr;
 
@@ -1657,7 +1657,8 @@
   }
 
   case tok::l_paren:
-    Result = parseExprList(tok::l_paren, tok::r_paren);
+    Result = parseExprList(tok::l_paren, tok::r_paren,
+                           SyntaxKind::FunctionCallArgumentList);
     break;
 
   case tok::l_square:
@@ -1805,8 +1806,7 @@
   Token EntireTok = Tok;
 
   // Create a syntax node for string literal.
-  SyntaxContext->addTokenSyntax(Tok.getLoc());
-  SyntaxContext->makeNode(SyntaxKind::StringLiteralExpr);
+  SyntaxContext->makeNode(SyntaxKind::StringLiteralExpr, Tok.getLoc());
   SyntaxParsingContextChild LocalContext(SyntaxContext,
                                          SyntaxContextKind::Expr);
 
@@ -1883,7 +1883,8 @@
       assert(Tok.is(tok::l_paren));
       TokReceiver->registerTokenKindChange(Tok.getLoc(),
                                            tok::string_interpolation_anchor);
-      ParserResult<Expr> E = parseExprList(tok::l_paren, tok::r_paren);
+      ParserResult<Expr> E = parseExprList(tok::l_paren, tok::r_paren,
+                                           SyntaxKind::Unknown);
       Status |= E;
       if (E.isNonNull()) {
         Exprs.push_back(E.get());
@@ -1995,6 +1996,11 @@
   SourceLoc lparenLoc = consumeToken(tok::l_paren);
   SourceLoc rparenLoc;
   while (true) {
+    SyntaxParsingContextChild DisabledContext(SyntaxContext,
+                                              SyntaxContextKind::Expr);
+    // The following code may backtrack; so we disable the syntax tree creation
+    // in this scope.
+    DisabledContext.disable();
     // Terminate at ')'.
     if (Tok.is(tok::r_paren)) {
       rparenLoc = consumeToken(tok::r_paren);
@@ -2752,7 +2758,8 @@
 ///   expr-paren-element:
 ///     (identifier ':')? expr
 ///
-ParserResult<Expr> Parser::parseExprList(tok leftTok, tok rightTok) {
+ParserResult<Expr>
+Parser::parseExprList(tok leftTok, tok rightTok, SyntaxKind Kind) {
   SmallVector<Expr*, 8> subExprs;
   SmallVector<Identifier, 8> subExprNames;
   SmallVector<SourceLoc, 8> subExprNameLocs;
@@ -2766,7 +2773,8 @@
                                       subExprNames,
                                       subExprNameLocs,
                                       rightLoc,
-                                      trailingClosure);
+                                      trailingClosure,
+                                      Kind);
 
   // A tuple with a single, unlabeled element is just parentheses.
   if (subExprs.size() == 1 &&
@@ -2801,7 +2809,8 @@
                                    SmallVectorImpl<Identifier> &exprLabels,
                                    SmallVectorImpl<SourceLoc> &exprLabelLocs,
                                    SourceLoc &rightLoc,
-                                   Expr *&trailingClosure) {
+                                   Expr *&trailingClosure,
+                                   SyntaxKind Kind) {
   trailingClosure = nullptr;
 
   StructureMarkerRAII ParsingExprList(*this, Tok);
@@ -2812,6 +2821,7 @@
                                   rightTok == tok::r_paren
                                     ? diag::expected_rparen_expr_list
                                     : diag::expected_rsquare_expr_list,
+                                  Kind,
                                   [&] () -> ParserStatus {
     Identifier FieldName;
     SourceLoc FieldNameLoc;
@@ -2823,6 +2833,8 @@
     ParserStatus Status;
     Expr *SubExpr = nullptr;
     if (Tok.isBinaryOperator() && peekToken().isAny(rightTok, tok::comma)) {
+      SyntaxParsingContextChild operatorContext(SyntaxContext,
+                                                SyntaxContextKind::Expr);
       SourceLoc Loc;
       Identifier OperName;
       if (parseAnyIdentifier(OperName, Loc, diag::expected_operator_ref)) {
@@ -2963,7 +2975,8 @@
                                       lParenLoc, args, argLabels,
                                       argLabelLocs,
                                       rParenLoc,
-                                      trailingClosure);
+                                      trailingClosure,
+                                      SyntaxKind::FunctionCallArgumentList);
   if (status.hasCodeCompletion())
     return makeParserCodeCompletionResult<Expr>();
   if (status.isError())
@@ -3055,7 +3068,8 @@
                                       lParenLoc, args, argLabels,
                                       argLabelLocs,
                                       rParenLoc,
-                                      trailingClosure);
+                                      trailingClosure,
+                                      SyntaxKind::FunctionCallArgumentList);
 
   // Form the call.
   auto Result = makeParserResult(status | fn, 
@@ -3151,6 +3165,7 @@
   Status |= parseList(tok::r_square, LSquareLoc, RSquareLoc,
                       /*AllowSepAfterLast=*/true,
                       diag::expected_rsquare_array_expr,
+                      SyntaxKind::Unknown,
                       [&] () -> ParserStatus
   {
     ParserResult<Expr> Element
@@ -3199,7 +3214,9 @@
   Status |=
       parseList(tok::r_square, LSquareLoc, RSquareLoc,
                 /*AllowSepAfterLast=*/true,
-                diag::expected_rsquare_array_expr, [&]() -> ParserStatus {
+                diag::expected_rsquare_array_expr,
+                SyntaxKind::Unknown,
+                [&]() -> ParserStatus {
     // Parse the next key.
     ParserResult<Expr> Key;
     if (FirstPair) {
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 09c2496..352e927 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -19,10 +19,15 @@
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/Initializer.h"
 #include "swift/Basic/StringExtras.h"
+#include "swift/Syntax/SyntaxFactory.h"
+#include "swift/Syntax/TokenSyntax.h"
+#include "swift/Syntax/SyntaxParsingContext.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/SaveAndRestore.h"
+
 using namespace swift;
+using namespace swift::syntax;
 
 /// \brief Determine the kind of a default argument given a parsed
 /// expression that has not yet been type-checked.
@@ -162,6 +167,7 @@
   return parseList(tok::r_paren, leftParenLoc, rightParenLoc,
                       /*AllowSepAfterLast=*/false,
                       diag::expected_rparen_parameter,
+                      SyntaxKind::Unknown,
                       [&]() -> ParserStatus {
     ParsedParameter param;
     ParserStatus status;
@@ -795,7 +801,8 @@
                                             /*isExprBasic=*/false,
                                             lParenLoc, args, argLabels,
                                             argLabelLocs, rParenLoc,
-                                            trailingClosure);
+                                            trailingClosure,
+                                            SyntaxKind::Unknown);
         if (status.isSuccess()) {
           backtrack.cancelBacktrack();
           
@@ -947,6 +954,7 @@
     parseList(tok::r_paren, LPLoc, RPLoc,
               /*AllowSepAfterLast=*/false,
               diag::expected_rparen_tuple_pattern_list,
+              SyntaxKind::Unknown,
               [&] () -> ParserStatus {
     // Parse the pattern tuple element.
     ParserStatus EltStatus;
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index aa7059c..5a91fae 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -592,17 +592,14 @@
   }
   SyntaxParsingContextChild LocalContext(SyntaxContext, SyntaxKind::CodeBlock);
   SourceLoc LBLoc = consumeToken(tok::l_brace);
-  LocalContext.addTokenSyntax(LBLoc);
 
   SmallVector<ASTNode, 16> Entries;
   SourceLoc RBLoc;
 
   ParserStatus Status = parseBraceItems(Entries, BraceItemListKind::Brace,
                                         BraceItemListKind::Brace);
-  if (!parseMatchingToken(tok::r_brace, RBLoc,
-                          diag::expected_rbrace_in_brace_stmt, LBLoc)) {
-    LocalContext.addTokenSyntax(RBLoc);
-  }
+  parseMatchingToken(tok::r_brace, RBLoc,
+                     diag::expected_rbrace_in_brace_stmt, LBLoc);
 
   return makeParserResult(Status,
                           BraceStmt::create(Context, LBLoc, Entries, RBLoc));
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index bf66864..9ff7c0f 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -19,6 +19,9 @@
 #include "swift/AST/TypeLoc.h"
 #include "swift/Parse/Lexer.h"
 #include "swift/Parse/CodeCompletionCallbacks.h"
+#include "swift/Syntax/SyntaxFactory.h"
+#include "swift/Syntax/TokenSyntax.h"
+#include "swift/Syntax/SyntaxParsingContext.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
@@ -26,6 +29,7 @@
 #include "llvm/Support/SaveAndRestore.h"
 
 using namespace swift;
+using namespace swift::syntax;
 
 TypeRepr *Parser::applyAttributeToType(TypeRepr *ty,
                                        const TypeAttributes &attrs,
@@ -794,6 +798,7 @@
   ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
                                   /*AllowSepAfterLast=*/false,
                                   diag::expected_rparen_tuple_type_list,
+                                  SyntaxKind::Unknown,
                                   [&] () -> ParserStatus {
     TupleTypeReprElement element;
 
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index a5d5c6d..aa9444d 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -35,6 +35,7 @@
 #include "llvm/ADT/Twine.h"
 
 using namespace swift;
+using namespace swift::syntax;
 
 void DelayedParsingCallbacks::anchor() { }
 void SILParserTUStateBase::anchor() { }
@@ -127,6 +128,14 @@
 }
 } // unnamed namespace
 
+
+swift::Parser::BacktrackingScope::~BacktrackingScope() {
+  if (Backtrack) {
+    P.backtrackToPosition(PP);
+    DT.abort();
+  }
+}
+
 void swift::performDelayedParsing(
     DeclContext *DC, PersistentParserState &PersistentState,
     CodeCompletionCallbacksFactory *CodeCompletionFactory) {
@@ -438,8 +447,8 @@
     TokReceiver(SF.shouldKeepSyntaxInfo() ?
                 new TokenRecorder(SF) :
                 new ConsumeTokenReceiver()),
-    SyntaxContext(new syntax::SyntaxParsingContextRoot(SF, L->getBufferID(), Tok)) {
-
+    SyntaxContext(new syntax::SyntaxParsingContextRoot(SF, L->getBufferID(),
+                                                       Tok)) {
   State = PersistentState;
   if (!State) {
     OwnedState.reset(new PersistentParserState());
@@ -819,10 +828,15 @@
 
 ParserStatus
 Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
-                  bool AllowSepAfterLast, Diag<> ErrorDiag,
+                  bool AllowSepAfterLast, Diag<> ErrorDiag, SyntaxKind Kind,
                   std::function<ParserStatus()> callback) {
+  std::unique_ptr<SyntaxParsingContext> pListContext;
+  if (Kind == SyntaxKind::FunctionCallArgumentList) {
+    pListContext.reset(new SyntaxParsingContextChild(SyntaxContext, Kind));
+  }
 
   if (Tok.is(RightK)) {
+    pListContext.reset();
     RightLoc = consumeToken(RightK);
     return makeParserSuccess();
   }
@@ -835,6 +849,11 @@
       consumeToken();
     }
     SourceLoc StartLoc = Tok.getLoc();
+    std::unique_ptr<SyntaxParsingContext> pElementContext;
+    if (Kind == SyntaxKind::FunctionCallArgumentList) {
+      pElementContext.reset(new SyntaxParsingContextChild(SyntaxContext,
+                                            SyntaxKind::FunctionCallArgument));
+    }
     Status |= callback();
     if (Tok.is(RightK))
       break;
@@ -878,6 +897,7 @@
     Status.setIsParseError();
   }
 
+  pListContext.reset();
   if (Status.isError()) {
     // If we've already got errors, don't emit missing RightK diagnostics.
     RightLoc = Tok.is(RightK) ? consumeToken() : PreviousLoc;
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index cc7166e..8fd9a96 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -28,10 +28,13 @@
 #include "swift/SIL/SILModule.h"
 #include "swift/SIL/SILUndef.h"
 #include "swift/SIL/TypeLowering.h"
+#include "swift/Syntax/SyntaxKind.h"
 #include "swift/Subsystems.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/SaveAndRestore.h"
+
 using namespace swift;
+using namespace swift::syntax;
 
 //===----------------------------------------------------------------------===//
 // SILParserState implementation
@@ -1236,7 +1239,7 @@
   if (!P.consumeIf(tok::sil_exclamation)) {
     // Construct SILDeclRef.
     Result = SILDeclRef(VD, Kind, expansion, /*isCurried=*/false, IsObjC);
-    if (uncurryLevel < Result.getUncurryLevel())
+    if (uncurryLevel < Result.getParameterListCount() - 1)
       Result = Result.asCurried();
     return false;
   }
@@ -1327,7 +1330,7 @@
 
   // Construct SILDeclRef.
   Result = SILDeclRef(VD, Kind, expansion, /*isCurried=*/false, IsObjC);
-  if (uncurryLevel < Result.getUncurryLevel())
+  if (uncurryLevel < Result.getParameterListCount() - 1)
     Result = Result.asCurried();
   return false;
 }
@@ -1462,6 +1465,7 @@
     if (P.parseList(tok::r_paren, LParenLoc, RParenLoc,
                     /*AllowSepAfterLast=*/false,
                     diag::sil_basicblock_arg_rparen,
+                    SyntaxKind::Unknown,
                     [&]() -> ParserStatus {
                       SILValue Arg;
                       SourceLoc ArgLoc;
@@ -3735,6 +3739,51 @@
     ResultVal = B.createThrow(InstLoc, Val);
     break;
   }
+  case SILInstructionKind::UnwindInst: {
+    if (parseSILDebugLocation(InstLoc, B))
+      return true;
+    ResultVal = B.createUnwind(InstLoc);
+    break;
+  }
+  case SILInstructionKind::YieldInst: {
+    SmallVector<SILValue, 6> values;
+
+    // Parse a parenthesized (unless length-1), comma-separated list
+    // of yielded values.
+    if (P.consumeIf(tok::l_paren)) {
+      do {
+        if (parseTypedValueRef(Val, B))
+          return true;
+        values.push_back(Val);
+      } while (P.consumeIf(tok::comma));
+
+      if (P.parseToken(tok::r_paren, diag::expected_tok_in_sil_instr, ")"))
+        return true;
+
+    } else {
+      if (parseTypedValueRef(Val, B))
+        return true;
+      values.push_back(Val);
+    }
+
+    Identifier resumeName, unwindName;
+    SourceLoc resumeLoc, unwindLoc;
+    if (P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
+        parseVerbatim("resume") ||
+        parseSILIdentifier(resumeName, resumeLoc,
+                           diag::expected_sil_block_name) ||
+        P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
+        parseVerbatim("unwind") ||
+        parseSILIdentifier(unwindName, unwindLoc,
+                           diag::expected_sil_block_name) ||
+        parseSILDebugLocation(InstLoc, B))
+      return true;
+
+    auto resumeBB = getBBForReference(resumeName, resumeLoc);
+    auto unwindBB = getBBForReference(unwindName, unwindLoc);
+    ResultVal = B.createYield(InstLoc, values, resumeBB, unwindBB);
+    break;
+  }
   case SILInstructionKind::BranchInst: {
     Identifier BBName;
     SourceLoc NameLoc;
diff --git a/lib/SIL/SILArgument.cpp b/lib/SIL/SILArgument.cpp
index dfd1686..87ed4af 100644
--- a/lib/SIL/SILArgument.cpp
+++ b/lib/SIL/SILArgument.cpp
@@ -73,12 +73,14 @@
   case TermKind::UnreachableInst:
   case TermKind::ReturnInst:
   case TermKind::ThrowInst:
+  case TermKind::UnwindInst:
     llvm_unreachable("Have terminator that implies no successors?!");
   case TermKind::TryApplyInst:
   case TermKind::SwitchValueInst:
   case TermKind::SwitchEnumAddrInst:
   case TermKind::CheckedCastAddrBranchInst:
   case TermKind::DynamicMethodBranchInst:
+  case TermKind::YieldInst:
     return SILValue();
   case TermKind::BranchInst:
     return cast<const BranchInst>(TI)->getArg(Index);
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index 06d7bff..aa65f47 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -79,8 +79,10 @@
   }
 
   auto appliedFnType = SILFunctionType::get(nullptr, extInfo,
+                                            FTI->getCoroutineKind(),
                                             calleeConvention,
                                             newParams,
+                                            FTI->getYields(),
                                             results,
                                             FTI->getOptionalErrorResult(),
                                             M.getASTContext());
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index 1acb152..65dda5d 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -227,29 +227,6 @@
   return false;
 }
 
-static unsigned getFuncNaturalUncurryLevel(AnyFunctionRef AFR) {
-  assert(AFR.getParameterLists().size() >= 1 && "no arguments for func?!");
-  return AFR.getParameterLists().size() - 1;
-}
-
-unsigned swift::getNaturalUncurryLevel(ValueDecl *vd) {
-  if (auto *func = dyn_cast<FuncDecl>(vd)) {
-    return getFuncNaturalUncurryLevel(func);
-  } else if (isa<ConstructorDecl>(vd)) {
-    return 1;
-  } else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
-    return ed->hasAssociatedValues() ? 1 : 0;
-  } else if (isa<DestructorDecl>(vd)) {
-    return 0;
-  } else if (isa<ClassDecl>(vd)) {
-    return 1;
-  } else if (isa<VarDecl>(vd)) {
-    return 0;
-  } else {
-    llvm_unreachable("Unhandled ValueDecl for SILDeclRef");
-  }
-}
-
 SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind,
                        ResilienceExpansion expansion,
                        bool isCurried, bool isForeign)
@@ -888,12 +865,23 @@
   llvm_unreachable("Unhandled access level in switch.");
 }
 
-unsigned SILDeclRef::getUncurryLevel() const {
-  if (isCurried)
-    return 0;
-  if (!hasDecl())
-    return getFuncNaturalUncurryLevel(*getAnyFunctionRef());
-  if (kind == Kind::DefaultArgGenerator)
-    return 0;
-  return getNaturalUncurryLevel(getDecl());
+unsigned SILDeclRef::getParameterListCount() const {
+  if (isCurried || !hasDecl() || kind == Kind::DefaultArgGenerator)
+    return 1;
+
+  auto *vd = getDecl();
+
+  if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) {
+    return func->getParameterLists().size();
+  } else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
+    return ed->hasAssociatedValues() ? 2 : 1;
+  } else if (isa<DestructorDecl>(vd)) {
+    return 1;
+  } else if (isa<ClassDecl>(vd)) {
+    return 2;
+  } else if (isa<VarDecl>(vd)) {
+    return 1;
+  } else {
+    llvm_unreachable("Unhandled ValueDecl for SILDeclRef");
+  }
 }
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 29c2e2e..81f745e 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -196,10 +196,13 @@
       type->getWitnessMethodConformanceOrNone() == witnessMethodConformance)
     return type;
 
-  return SILFunctionType::get(type->getGenericSignature(), extInfo, callee,
-                              type->getParameters(), type->getResults(),
+  return SILFunctionType::get(type->getGenericSignature(),
+                              extInfo, type->getCoroutineKind(), callee,
+                              type->getParameters(), type->getYields(),
+                              type->getResults(),
                               type->getOptionalErrorResult(),
-                              type->getASTContext(), witnessMethodConformance);
+                              type->getASTContext(),
+                              witnessMethodConformance);
 }
 
 namespace {
@@ -960,7 +963,8 @@
     .withIsPseudogeneric(pseudogeneric)
     .withNoEscape(extInfo.isNoEscape());
   
-  return SILFunctionType::get(genericSig, silExtInfo, calleeConvention, inputs,
+  return SILFunctionType::get(genericSig, silExtInfo, SILCoroutineKind::None,
+                              calleeConvention, inputs, /*yields*/ {},
                               results, errorResult, M.getASTContext(),
                               witnessMethodConformance);
 }
@@ -1777,7 +1781,7 @@
     return false;
 
   // Must be a type member.
-  if (constant.getUncurryLevel() != 1)
+  if (constant.getParameterListCount() != 2)
     return false;
 
   // Must be imported from a function.
@@ -2235,6 +2239,12 @@
         substParams.push_back(subst(origParam));
       }
 
+      SmallVector<SILYieldInfo, 8> substYields;
+      substYields.reserve(origType->getYields().size());
+      for (auto &origYield : origType->getYields()) {
+        substYields.push_back(subst(origYield));
+      }
+
       Optional<ProtocolConformanceRef> witnessMethodConformance;
       if (auto conformance = origType->getWitnessMethodConformanceOrNone()) {
         assert(origType->getExtInfo().hasSelfParam());
@@ -2253,8 +2263,9 @@
       }
 
       return SILFunctionType::get(nullptr, origType->getExtInfo(),
+                                  origType->getCoroutineKind(),
                                   origType->getCalleeConvention(), substParams,
-                                  substResults, substErrorResult,
+                                  substYields, substResults, substErrorResult,
                                   getASTContext(), witnessMethodConformance);
     }
 
@@ -2267,6 +2278,10 @@
       return SILResultInfo(visit(orig.getType()), orig.getConvention());
     }
 
+    SILYieldInfo subst(SILYieldInfo orig) {
+      return SILYieldInfo(visit(orig.getType()), orig.getConvention());
+    }
+
     SILParameterInfo subst(SILParameterInfo orig) {
       return SILParameterInfo(visit(orig.getType()), orig.getConvention());
     }
@@ -2486,7 +2501,7 @@
 TypeConverter::LoweredFormalTypes
 TypeConverter::getLoweredFormalTypes(SILDeclRef constant,
                                      CanAnyFunctionType fnType) {
-  unsigned uncurryLevel = constant.getUncurryLevel();
+  unsigned uncurryLevel = constant.getParameterListCount() - 1;
   auto extInfo = fnType->getExtInfo();
 
   // Form an abstraction pattern for bridging purposes.
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 2af36c2..d7ea5dd 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -1056,15 +1056,33 @@
   case TermKind::CheckedCastAddrBranchInst:
   case TermKind::UnreachableInst:
   case TermKind::TryApplyInst:
+  case TermKind::YieldInst:
     return false;
   case TermKind::ReturnInst:
   case TermKind::ThrowInst:
+  case TermKind::UnwindInst:
     return true;
   }
 
   llvm_unreachable("Unhandled TermKind in switch.");
 }
 
+YieldInst::YieldInst(SILDebugLocation loc, ArrayRef<SILValue> yieldedValues,
+                     SILBasicBlock *normalBB, SILBasicBlock *unwindBB)
+  : InstructionBase(loc),
+    DestBBs{{this, normalBB}, {this, unwindBB}},
+    Operands(this, yieldedValues) {}
+
+YieldInst *YieldInst::create(SILDebugLocation loc,
+                             ArrayRef<SILValue> yieldedValues,
+                             SILBasicBlock *normalBB, SILBasicBlock *unwindBB,
+                             SILFunction &F) {
+  void *buffer = F.getModule().allocateInst(sizeof(YieldInst) +
+                        decltype(Operands)::getExtraSize(yieldedValues.size()),
+                                            alignof(YieldInst));
+  return ::new (buffer) YieldInst(loc, yieldedValues, normalBB, unwindBB);
+}
+
 BranchInst::BranchInst(SILDebugLocation Loc, SILBasicBlock *DestBB,
                        ArrayRef<SILValue> Args)
     : InstructionBase(Loc), DestBB(this, DestBB),
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index 8372dce..ecade1b 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -448,6 +448,7 @@
 NO_OPERAND_INST(StrongRetainUnowned)
 NO_OPERAND_INST(UnownedRetain)
 NO_OPERAND_INST(Unreachable)
+NO_OPERAND_INST(Unwind)
 #undef NO_OPERAND_INST
 
 /// Instructions whose arguments are always compatible with one convention.
@@ -1109,6 +1110,35 @@
 }
 
 OwnershipUseCheckerResult
+OwnershipCompatibilityUseChecker::visitYieldInst(YieldInst *I) {
+  // Indirect return arguments are address types.
+  if (isAddressOrTrivialType())
+    return {compatibleWithOwnership(ValueOwnershipKind::Trivial),
+            UseLifetimeConstraint::MustBeLive};
+
+  auto fnType = I->getFunction()->getLoweredFunctionType();
+  auto yieldInfo = fnType->getYields()[getOperandIndex()];
+  switch (yieldInfo.getConvention()) {
+  case ParameterConvention::Indirect_In:
+  case ParameterConvention::Direct_Owned:
+    return visitApplyParameter(ValueOwnershipKind::Owned,
+                               UseLifetimeConstraint::MustBeInvalidated);
+  case ParameterConvention::Indirect_In_Constant:
+  case ParameterConvention::Direct_Unowned:
+    // We accept unowned, owned, and guaranteed in unowned positions.
+    return {true, UseLifetimeConstraint::MustBeLive};
+  case ParameterConvention::Indirect_In_Guaranteed:
+  case ParameterConvention::Direct_Guaranteed:
+    return visitApplyParameter(ValueOwnershipKind::Guaranteed,
+                               UseLifetimeConstraint::MustBeLive);
+  // The following conventions should take address types.
+  case ParameterConvention::Indirect_Inout:
+  case ParameterConvention::Indirect_InoutAliasable:
+    llvm_unreachable("Unexpected non-trivial parameter convention.");
+  }
+}
+
+OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitAssignInst(AssignInst *I) {
   if (getValue() == I->getSrc()) {
     if (isAddressOrTrivialType()) {
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index a4dacb1..541c479 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -351,7 +351,7 @@
     break;
   }
 
-  auto uncurryLevel = getUncurryLevel();
+  auto uncurryLevel = getParameterListCount() - 1;
   if (uncurryLevel != 0)
     OS << (isDot ? '.' : '!')  << uncurryLevel;
 
@@ -1854,6 +1854,21 @@
     *this << getIDAndType(TI->getOperand());
   }
 
+  void visitUnwindInst(UnwindInst *UI) {
+    // no operands
+  }
+
+  void visitYieldInst(YieldInst *YI) {
+    auto values = YI->getYieldedValues();
+    if (values.size() != 1) *this << '(';
+    interleave(values,
+               [&](SILValue value) { *this << getIDAndType(value); },
+               [&] { *this << ", "; });
+    if (values.size() != 1) *this << ')';
+    *this << ", resume " << Ctx.getID(YI->getResumeBB())
+          << ", unwind " << Ctx.getID(YI->getUnwindBB());
+  }
+
   void visitSwitchValueInst(SwitchValueInst *SII) {
     *this << getIDAndType(SII->getOperand());
     for (unsigned i = 0, e = SII->getNumCases(); i < e; ++i) {
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 7252575..f3630bf 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -941,6 +941,9 @@
               "apply instruction cannot call function with error result");
     }
 
+    require(!calleeConv.funcTy->isCoroutine(),
+            "cannot call coroutine with normal apply");
+
     // Check that if the apply is of a noreturn callee, make sure that an
     // unreachable is the next instruction.
     if (AI->getModule().getStage() == SILStage::Raw ||
@@ -955,6 +958,9 @@
 
     SILFunctionConventions calleeConv(AI->getSubstCalleeType(), F.getModule());
 
+    require(!calleeConv.funcTy->isCoroutine(),
+            "cannot call coroutine with normal apply");
+
     auto normalBB = AI->getNormalBB();
     require(normalBB->args_size() == 1,
             "normal destination of try_apply must take one argument");
@@ -2164,6 +2170,8 @@
     auto constantInfo = F.getModule().Types.getConstantInfo(method);
     auto methodTy = constantInfo.SILFnType;
 
+    assert(!methodTy->isCoroutine());
+
     // Map interface types to archetypes.
     if (auto *env = constantInfo.GenericEnv) {
       auto subs = env->getForwardingSubstitutions();
@@ -2196,8 +2204,10 @@
 
     auto fnTy = SILFunctionType::get(nullptr,
                                      methodTy->getExtInfo(),
+                                     methodTy->getCoroutineKind(),
                                      methodTy->getCalleeConvention(),
                                      dynParams,
+                                     methodTy->getYields(),
                                      dynResults,
                                      methodTy->getOptionalErrorResult(),
                                      F.getASTContext());
@@ -3309,6 +3319,35 @@
             "throw operand type does not match error result type of function");
   }
   
+  void checkUnwindInst(UnwindInst *UI) {
+    require(F.getLoweredFunctionType()->isCoroutine(),
+            "unwind in non-coroutine function");
+  }
+
+  void checkYieldInst(YieldInst *YI) {
+    CanSILFunctionType fnType = F.getLoweredFunctionType();
+    require(fnType->isCoroutine(),
+            "yield in non-coroutine function");
+
+    auto yieldedValues = YI->getYieldedValues();
+    auto yieldInfos = fnType->getYields();
+    require(yieldedValues.size() == yieldInfos.size(),
+            "wrong number of yielded values for function");
+    for (auto i : indices(yieldedValues)) {
+      SILType yieldType =
+        F.mapTypeIntoContext(fnConv.getSILType(yieldInfos[i]));
+      require(yieldedValues[i]->getType() == yieldType,
+              "yielded value does not match yield type of coroutine");
+    }
+
+    // We require the resume and unwind destinations to be unique in order
+    // to prevent either edge from becoming critical.
+    require(YI->getResumeBB()->getSinglePredecessorBlock(),
+            "resume dest of 'yield' must be uniquely used");
+    require(YI->getUnwindBB()->getSinglePredecessorBlock(),
+            "unwind dest of 'yield' must be uniquely used");
+  }
+
   void checkSelectEnumCases(SelectEnumInstBase *I) {
     EnumDecl *eDecl = I->getEnumOperand()->getType().getEnumOrBoundGenericEnum();
     require(eDecl, "select_enum operand must be an enum");
@@ -4147,9 +4186,18 @@
   /// - accesses must be uniquely ended
   /// - flow-sensitive states must be equivalent on all paths into a block
   void verifyFlowSensitiveRules(SILFunction *F) {
+    enum CFGState {
+      /// No special rules are in play.
+      Normal,
+      /// We've followed the resume edge of a yield in a yield_once coroutine.
+      YieldOnceResume,
+      /// We've followed the unwind edge of a yield.
+      YieldUnwind
+    };
     struct BBState {
       std::vector<SingleValueInstruction*> Stack;
       std::set<BeginAccessInst*> Accesses;
+      CFGState CFG = Normal;
     };
 
     // Do a breath-first search through the basic blocks.
@@ -4195,6 +4243,29 @@
                     "return with stack allocs that haven't been deallocated");
             require(state.Accesses.empty(),
                     "return with accesses that haven't been ended");
+
+            if (isa<UnwindInst>(term)) {
+              require(state.CFG == YieldUnwind,
+                      "encountered 'unwind' when not on unwind path");
+            } else {
+              require(state.CFG != YieldUnwind,
+                      "encountered 'return' or 'throw' when on unwind path");
+              if (isa<ReturnInst>(term) &&
+                  F->getLoweredFunctionType()->getCoroutineKind() ==
+                    SILCoroutineKind::YieldOnce &&
+                  F->getModule().getStage() != SILStage::Raw) {
+                require(state.CFG == YieldOnceResume,
+                        "encountered 'return' before yielding a value in "
+                        "yield_once coroutine");
+              }
+            }
+          }
+
+          if (isa<YieldInst>(term)) {
+            require(state.CFG != YieldOnceResume,
+                    "encountered multiple 'yield's along single path");
+            require(state.CFG == Normal,
+                    "encountered 'yield' on abnormal CFG path");
           }
 
           auto successors = term->getSuccessors();
@@ -4215,9 +4286,30 @@
             // worklist and continue.
             if (insertResult.second) {
               Worklist.push_back(succBB);
+
+              // If we're following a 'yield', update the CFG state:
+              if (isa<YieldInst>(term)) {
+                // Enforce that the unwind logic is segregated in all stages.
+                if (i == 1) {
+                  insertResult.first->second.CFG = YieldUnwind;
+
+                // We check the yield_once rule in the mandatory analyses,
+                // so we can't assert it yet in the raw stage.
+                } else if (F->getLoweredFunctionType()->getCoroutineKind()
+                             == SILCoroutineKind::YieldOnce && 
+                           F->getModule().getStage() != SILStage::Raw) {
+                  insertResult.first->second.CFG = YieldOnceResume;
+                }
+              }
+
               continue;
             }
 
+            // This rule is checked elsewhere, but we'd want to assert it
+            // here anyway.
+            require(!isa<YieldInst>(term),
+                    "successor of 'yield' should not be encountered twice");
+
             // Check that the stack height is consistent coming from all entry
             // points into this BB. We only care about consistency if there is
             // a possible return from this function along the path starting at
@@ -4233,6 +4325,8 @@
                     "inconsistent stack heights entering basic block");
             require(state.Accesses == foundState.Accesses || isUnreachable(),
                     "inconsistent access sets entering basic block");
+            require(state.CFG == foundState.CFG,
+                    "inconsistent coroutine states entering basic block");
           }
         }
       }
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index da1b89c..9cfd5e6 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -2107,9 +2107,9 @@
   if (genericSig && genericSig->areAllParamsConcrete())
     genericSig = nullptr;
 
-  return SILFunctionType::get(genericSig, extInfo,
+  return SILFunctionType::get(genericSig, extInfo, SILCoroutineKind::None,
                               /*callee*/ ParameterConvention::Direct_Unowned,
-                              params, results, None, ctx,
+                              params, {}, results, None, ctx,
                               witnessMethodConformance);
 }
 
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index bb4e271..d182a49 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -432,8 +432,9 @@
   };
 
   CanSILFunctionType topLevelType = SILFunctionType::get(nullptr, extInfo,
+                                   SILCoroutineKind::None,
                                    ParameterConvention::Direct_Unowned,
-                                   params,
+                                   params, /*yields*/ {},
                                    SILResultInfo(Int32Ty,
                                                  ResultConvention::Unowned),
                                    None,
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 71395d6..d269ad8 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -64,16 +64,6 @@
   llvm_unreachable("bad representation");
 }
 
-static CanType getDynamicMethodSelfType(SILGenFunction &SGF,
-                                        const ArgumentSource &proto,
-                                        ValueDecl *member) {
-  if (member->isInstanceMember()) {
-    return SGF.getASTContext().getAnyObjectType();
-  } else {
-    return proto.getSILSubstType(SGF).getSwiftRValueType();
-  }
-}
-
 /// Return the formal type for the partial-apply result type of a
 /// dynamic method invocation.
 static CanFunctionType
@@ -113,37 +103,6 @@
   return fnType;
 }
 
-/// Replace the 'self' parameter in the given type.
-static CanSILFunctionType
-replaceSelfTypeForDynamicLookup(ASTContext &ctx,
-                                CanSILFunctionType fnType,
-                                CanType newSelfType,
-                                SILDeclRef methodName) {
-  auto oldParams = fnType->getParameters();
-  SmallVector<SILParameterInfo, 4> newParams;
-  newParams.append(oldParams.begin(), oldParams.end() - 1);
-  newParams.push_back({newSelfType, oldParams.back().getConvention()});
-
-  // If the method returns Self, substitute AnyObject for the result type.
-  SmallVector<SILResultInfo, 4> newResults;
-  newResults.append(fnType->getResults().begin(), fnType->getResults().end());
-  if (auto fnDecl = dyn_cast<FuncDecl>(methodName.getDecl())) {
-    if (fnDecl->hasDynamicSelf()) {
-      auto anyObjectTy = ctx.getAnyObjectType();
-      for (auto &result : newResults) {
-        auto newResultTy
-          = result.getType()->replaceCovariantResultType(anyObjectTy, 0);
-        result = result.getWithType(newResultTy->getCanonicalType());
-      }
-    }
-  }
-
-  return SILFunctionType::get(nullptr, fnType->getExtInfo(),
-                              fnType->getCalleeConvention(), newParams,
-                              newResults, fnType->getOptionalErrorResult(), ctx,
-                              fnType->getWitnessMethodConformanceOrNone());
-}
-
 /// Retrieve the type to use for a method found via dynamic lookup.
 static CanSILFunctionType
 getDynamicMethodLoweredType(SILGenFunction &SGF, SILValue v,
@@ -161,7 +120,7 @@
 
   auto methodTy = SGF.SGM.M.Types
     .getUncachedSILFunctionTypeForConstant(methodName, objcFormalTy);
-  return replaceSelfTypeForDynamicLookup(ctx, methodTy, selfTy, methodName);
+  return methodTy;
 }
 
 /// Check if we can perform a dynamic dispatch on a super method call.
@@ -398,13 +357,11 @@
   }
   static Callee forDynamic(SILGenFunction &SGF, ArgumentSource &&arg,
                            SILDeclRef c, const SubstitutionList &constantSubs,
-                           CanAnyFunctionType partialSubstFormalType,
+                           CanAnyFunctionType substFormalType,
                            SubstitutionList subs, SILLocation l) {
     auto &ci = SGF.getConstantInfo(c);
     AbstractionPattern origFormalType = ci.FormalPattern;
 
-    auto selfType = getDynamicMethodSelfType(SGF, arg, c.getDecl());
-
     // Replace the original self type with the partially-applied subst type.
     auto origFormalFnType = cast<AnyFunctionType>(origFormalType.getType());
     if (auto genericFnType = dyn_cast<GenericFunctionType>(origFormalFnType)) {
@@ -418,16 +375,8 @@
         cast<FunctionType>(genericFnType->substGenericArgs(constantSubs)
                                         ->getCanonicalType());
     }
-    origFormalFnType = CanFunctionType::get(selfType,
-                                            origFormalFnType.getResult(),
-                                            origFormalFnType->getExtInfo());
     origFormalType.rewriteType(CanGenericSignature(), origFormalFnType);
 
-    // Add the self type clause to the partially-applied subst type.
-    auto substFormalType = CanFunctionType::get(selfType,
-                                                partialSubstFormalType,
-                                                origFormalFnType->getExtInfo());
-
     return Callee(Kind::DynamicMethod, SGF, std::move(arg), c, origFormalType,
                   substFormalType, subs, l);
   }
@@ -457,10 +406,10 @@
     return SubstFormalInterfaceType;
   }
 
-  unsigned getNaturalUncurryLevel() const {
+  unsigned getParameterListCount() const {
     switch (kind) {
     case Kind::IndirectValue:
-      return 0;
+      return 1;
 
     case Kind::StandaloneFunction:
     case Kind::EnumElement:
@@ -468,7 +417,7 @@
     case Kind::SuperMethod:
     case Kind::WitnessMethod:
     case Kind::DynamicMethod:
-      return Constant.getUncurryLevel();
+      return Constant.getParameterListCount();
     }
 
     llvm_unreachable("Unhandled Kind in switch.");
@@ -498,21 +447,52 @@
     return result;
   }
 
-  ManagedValue getFnValueAtUncurryLevel(SILGenFunction &SGF,
-                                        unsigned level) const & {
+  SILDeclRef getCurriedConstant(bool isCurried) const {
+    if (isCurried) {
+      auto constant = Constant.asCurried();
+
+      // If we're currying a direct reference to a class-dispatched method,
+      // make sure we emit the right set of thunks.
+      if (kind == Kind::StandaloneFunction) {
+        if (auto func = Constant.getAbstractFunctionDecl()) {
+          if (getMethodDispatch(func) == MethodDispatch::Class) {
+            return constant.asDirectReference(true);
+          }
+        }
+      }
+
+      return constant;
+    }
+
+    return Constant;
+  }
+
+  SILType getDynamicMethodType(SILModule &M) const {
+    // Lower the substituted type from the AST, which should have any generic
+    // parameters in the original signature erased to their upper bounds.
+    auto substFormalType = getSubstFormalType();
+    auto objcFormalType = substFormalType.withExtInfo(
+      substFormalType->getExtInfo().withSILRepresentation(
+        SILFunctionTypeRepresentation::ObjCMethod));
+    auto fnType = M.Types.getUncachedSILFunctionTypeForConstant(
+        Constant, objcFormalType);
+
+    return SILType::getPrimitiveObjectType(fnType);
+  }
+
+  ManagedValue getFnValue(SILGenFunction &SGF, bool isCurried) const & {
     Optional<SILDeclRef> constant = None;
 
     if (!Constant) {
-      assert(level == 0 && "can't curry indirect function");
+      assert(!isCurried && "can't curry indirect function");
     } else {
-      unsigned uncurryLevel = Constant.getUncurryLevel();
-      assert(level <= uncurryLevel &&
-             "uncurrying past natural uncurry level of standalone function");
-      if (level < uncurryLevel) {
-        assert(level == 0);
-        constant = Constant.asCurried();
-      } else {
-        constant = Constant;
+      constant = getCurriedConstant(isCurried);
+
+      // If the call is curried, emit a direct call to the curry thunk.
+      if (constant->isCurried) {
+        auto constantInfo = SGF.getConstantInfo(*constant);
+        SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
+        return ManagedValue::forUnmanaged(ref);
       }
     }
 
@@ -522,36 +502,13 @@
       return IndirectValue;
 
     case Kind::StandaloneFunction: {
-      // If we're currying a direct reference to a class-dispatched method,
-      // make sure we emit the right set of thunks.
-      if (constant->isCurried && Constant.hasDecl())
-        if (auto func = Constant.getAbstractFunctionDecl())
-          if (getMethodDispatch(func) == MethodDispatch::Class)
-            constant = constant->asDirectReference(true);
-
       auto constantInfo = SGF.getConstantInfo(*constant);
       SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
       return ManagedValue::forUnmanaged(ref);
     }
-    case Kind::EnumElement: {
-      auto constantInfo = SGF.getConstantInfo(*constant);
-
-      // We should not end up here if the enum constructor call is fully
-      // applied.
-      assert(constant->isCurried);
-
-      SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
-      return ManagedValue::forUnmanaged(ref);
-    }
+    case Kind::EnumElement:
+      llvm_unreachable("Should have been curried");
     case Kind::ClassMethod: {
-      auto constantInfo = SGF.getConstantInfo(*constant);
-
-      // If the call is curried, emit a direct call to the curry thunk.
-      if (constant->isCurried) {
-        SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
-        return ManagedValue::forUnmanaged(ref);
-      }
-
       auto methodTy = SGF.SGM.Types.getConstantOverrideType(*constant);
 
       // Otherwise, do the dynamic dispatch inline.
@@ -594,15 +551,8 @@
     case Kind::WitnessMethod: {
       auto constantInfo = SGF.getConstantInfo(*constant);
 
-      // If the call is curried, emit a direct call to the curry thunk.
-      if (constant->isCurried) {
-        SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
-        return ManagedValue::forUnmanaged(ref);
-      }
-
-      auto proto = Constant.getDecl()
-                       ->getDeclContext()
-                       ->getAsProtocolOrProtocolExtensionContext();
+      auto proto = cast<ProtocolDecl>(
+        Constant.getDecl()->getDeclContext());
       auto lookupType = getSubstFormalType()
                             .getInput()
                             ->getRValueInstanceType()
@@ -612,52 +562,34 @@
           Loc, lookupType, ProtocolConformanceRef(proto), *constant,
           constantInfo.getSILType(), constant->isForeign);
       return ManagedValue::forUnmanaged(fn);
-      ;
     }
     case Kind::DynamicMethod: {
-      assert(!constant->isCurried);
       assert(constant->isForeign);
-
-      // Lower the substituted type from the AST, which should have any generic
-      // parameters in the original signature erased to their upper bounds.
-      auto substFormalType = getSubstFormalType();
-      auto objcFormalType = substFormalType.withExtInfo(
-          substFormalType->getExtInfo().withSILRepresentation(
-              SILFunctionTypeRepresentation::ObjCMethod));
-      auto fnType = SGF.SGM.M.Types.getUncachedSILFunctionTypeForConstant(
-          *constant, objcFormalType);
-
-      auto closureType = replaceSelfTypeForDynamicLookup(
-          SGF.getASTContext(), fnType,
-          SelfValue.getValue().getSILSubstType(SGF).getSwiftRValueType(),
-          Constant);
+      auto closureType = getDynamicMethodType(SGF.SGM.M);
 
       Scope S(SGF, Loc);
       ManagedValue self =
           SelfValue.getValue().borrow(SGF).getAsSingleValue(SGF);
       SILValue fn = SGF.B.createObjCMethod(
           Loc, self.getValue(), *constant,
-          SILType::getPrimitiveObjectType(closureType));
+          closureType);
       return ManagedValue::forUnmanaged(fn);
     }
     }
   }
 
-  CalleeTypeInfo getTypeInfoAtUncurryLevel(SILGenFunction &SGF,
-                                           unsigned level) const & {
+  CalleeTypeInfo getTypeInfo(SILGenFunction &SGF, bool isCurried) const & {
     Optional<SILDeclRef> constant = None;
 
     if (!Constant) {
-      assert(level == 0 && "can't curry indirect function");
+      assert(!isCurried && "can't curry indirect function");
     } else {
-      unsigned uncurryLevel = Constant.getUncurryLevel();
-      assert(level <= uncurryLevel &&
-             "uncurrying past natural uncurry level of standalone function");
-      if (level < uncurryLevel) {
-        assert(level == 0);
-        constant = Constant.asCurried();
-      } else {
-        constant = Constant;
+      constant = getCurriedConstant(isCurried);
+
+      // If the call is curried, emit a direct call to the curry thunk.
+      if (constant->isCurried) {
+        auto constantInfo = SGF.getConstantInfo(*constant);
+        return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
       }
     }
 
@@ -667,38 +599,16 @@
       return createCalleeTypeInfo(SGF, constant, IndirectValue.getType());
 
     case Kind::StandaloneFunction: {
-      // If we're currying a direct reference to a class-dispatched method,
-      // make sure we emit the right set of thunks.
-      if (constant->isCurried && Constant.hasDecl())
-        if (auto func = Constant.getAbstractFunctionDecl())
-          if (getMethodDispatch(func) == MethodDispatch::Class)
-            constant = constant->asDirectReference(true);
-
       auto constantInfo = SGF.getConstantInfo(*constant);
       return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
-      ;
     }
-    case Kind::EnumElement: {
-      auto constantInfo = SGF.getConstantInfo(*constant);
-
-      // We should not end up here if the enum constructor call is fully
-      // applied.
-      assert(constant->isCurried);
-      return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
-    }
+    case Kind::EnumElement:
+      llvm_unreachable("Should have been curried");
     case Kind::ClassMethod: {
-      // If the call is curried, emit a direct call to the curry thunk.
-      if (constant->isCurried) {
-        auto constantInfo = SGF.getConstantInfo(*constant);
-        return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
-      }
-
-      // Otherwise, grab the override info.
       auto constantInfo = SGF.SGM.Types.getConstantOverrideInfo(*constant);
       return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
     }
     case Kind::SuperMethod: {
-      assert(!constant->isCurried);
       auto base = SGF.SGM.Types.getOverriddenVTableEntry(*constant);
       auto constantInfo =
           SGF.SGM.Types.getConstantOverrideInfo(*constant, base);
@@ -709,23 +619,7 @@
       return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
     }
     case Kind::DynamicMethod: {
-      assert(!constant->isCurried);
-
-      // Lower the substituted type from the AST, which should have any generic
-      // parameters in the original signature erased to their upper bounds.
-      auto substFormalType = getSubstFormalType();
-      auto objcFormalType = substFormalType.withExtInfo(
-          substFormalType->getExtInfo().withSILRepresentation(
-              SILFunctionTypeRepresentation::ObjCMethod));
-      auto fnType = SGF.SGM.M.Types.getUncachedSILFunctionTypeForConstant(
-          *constant, objcFormalType);
-
-      auto closureType = replaceSelfTypeForDynamicLookup(
-          SGF.getASTContext(), fnType,
-          SelfValue.getValue().getSILSubstType(SGF).getSwiftRValueType(),
-          Constant);
-
-      SILType formalType = SILType::getPrimitiveObjectType(closureType);
+      auto formalType = getDynamicMethodType(SGF.SGM.M);
       return createCalleeTypeInfo(SGF, constant, formalType);
     }
     }
@@ -743,11 +637,7 @@
   /// lowering, such as a builtin, or return null if there is no specialized
   /// emitter.
   Optional<SpecializedEmitter>
-  getSpecializedEmitter(SILGenModule &SGM, unsigned uncurryLevel) const {
-    // Currently we have no curried known functions.
-    if (uncurryLevel != 0)
-      return None;
-
+  getSpecializedEmitter(SILGenModule &SGM) const {
     switch (kind) {
     case Kind::StandaloneFunction: {
       return SpecializedEmitter::forDecl(SGM, Constant);
@@ -1515,6 +1405,10 @@
       auto substFormalType =
         cast<FunctionType>(dynamicMemberRef->getType()->getCanonicalType()
                                             .getAnyOptionalObjectType());
+      substFormalType = CanFunctionType::get(
+        dynamicMemberRef->getBase()->getType()->getCanonicalType(),
+        substFormalType, AnyFunctionType::ExtInfo());
+
       setCallee(Callee::forDynamic(SGF, baseArgSource.delayedBorrow(SGF),
                                    member, memberRef.getSubstitutions(),
                                    substFormalType, {}, e));
@@ -3957,8 +3851,7 @@
     std::vector<CallSite> extraSites;
     Callee callee;
     FormalEvaluationScope initialWritebackScope;
-    unsigned uncurries;
-    bool applied;
+    unsigned expectedSiteCount;
     bool assumedPlusZeroSelf;
 
   public:
@@ -3968,17 +3861,14 @@
                  bool assumedPlusZeroSelf = false)
         : SGF(SGF), callee(std::move(callee)),
           initialWritebackScope(std::move(writebackScope)),
-          uncurries(callee.getNaturalUncurryLevel() + 1), applied(false),
+          expectedSiteCount(callee.getParameterListCount()),
           assumedPlusZeroSelf(assumedPlusZeroSelf) {}
 
     /// Add a level of function application by passing in its possibly
     /// unevaluated arguments and their formal type.
     void addCallSite(CallSite &&site) {
-      assert(!applied && "already applied!");
-
       // Append to the main argument list if we have uncurry levels remaining.
-      if (uncurries > 0) {
-        --uncurries;
+      if (uncurriedSites.size() < expectedSiteCount) {
         uncurriedSites.push_back(std::move(site));
         return;
       }
@@ -4009,30 +3899,21 @@
 
     /// Is this a fully-applied enum element constructor call?
     bool isEnumElementConstructor() {
-      return (callee.kind == Callee::Kind::EnumElement && uncurries == 0);
+      return (callee.kind == Callee::Kind::EnumElement &&
+              uncurriedSites.size() == expectedSiteCount);
     }
 
     /// True if this is a completely unapplied super method call
-    bool isPartiallyAppliedSuperMethod(unsigned uncurryLevel) {
+    bool isPartiallyAppliedSuperMethod() {
       return (callee.kind == Callee::Kind::SuperMethod &&
-              uncurryLevel == 0);
+              uncurriedSites.size() == 1);
     }
 
     RValue apply(SGFContext C = SGFContext()) {
       initialWritebackScope.verify();
 
-      assert(!applied && "already applied!");
-
-      applied = true;
-
-      // Get the callee value at the needed uncurry level, uncurrying as
-      // much as possible. If the number of calls is less than the natural
-      // uncurry level, the callee emission might create a curry thunk.
-      unsigned uncurryLevel = callee.getNaturalUncurryLevel() - uncurries;
-
       // Emit the first level of call.
-      FirstLevelApplicationResult firstLevelResult =
-          applyFirstLevelCallee(uncurryLevel, C);
+      auto firstLevelResult = applyFirstLevelCallee(C);
 
       // End of the initial writeback scope.
       initialWritebackScope.verify();
@@ -4061,17 +3942,8 @@
           firstLevelResult.foreignSelf, C, formalTypeThrows);
     }
 
-    ~CallEmission() { assert(applied && "never applied!"); }
-
     // Movable, but not copyable.
-    CallEmission(CallEmission &&e)
-        : SGF(e.SGF), uncurriedSites(std::move(e.uncurriedSites)),
-          extraSites(std::move(e.extraSites)), callee(std::move(e.callee)),
-          initialWritebackScope(std::move(e.initialWritebackScope)),
-          uncurries(e.uncurries), applied(e.applied),
-          assumedPlusZeroSelf(e.assumedPlusZeroSelf) {
-      e.applied = true;
-    }
+    CallEmission(CallEmission &&e) = default;
 
   private:
     CallEmission(const CallEmission &) = delete;
@@ -4130,19 +4002,17 @@
 
     FirstLevelApplicationResult
     applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
-                            unsigned uncurryLevel, SGFContext C);
+                            SGFContext C);
 
     FirstLevelApplicationResult
-    applyPartiallyAppliedSuperMethod(unsigned uncurryLevel, SGFContext C);
+    applyPartiallyAppliedSuperMethod(SGFContext C);
 
     FirstLevelApplicationResult
-    applyEnumElementConstructor(unsigned uncurryLevel, SGFContext C);
+    applyEnumElementConstructor(SGFContext C);
 
-    FirstLevelApplicationResult applyNormalCall(unsigned uncurryLevel,
-                                                SGFContext C);
+    FirstLevelApplicationResult applyNormalCall(SGFContext C);
 
-    FirstLevelApplicationResult applyFirstLevelCallee(unsigned uncurryLevel,
-                                                      SGFContext C);
+    FirstLevelApplicationResult applyFirstLevelCallee(SGFContext C);
 
     RValue applyRemainingCallSites(RValue &&result,
                                    AbstractionPattern origFormalType,
@@ -4165,25 +4035,27 @@
 }
 
 CallEmission::FirstLevelApplicationResult
-CallEmission::applyFirstLevelCallee(unsigned uncurryLevel, SGFContext C) {
+CallEmission::applyFirstLevelCallee(SGFContext C) {
   // Check for a specialized emitter.
-  if (auto emitter = callee.getSpecializedEmitter(SGF.SGM, uncurryLevel)) {
-    return applySpecializedEmitter(emitter.getValue(), uncurryLevel, C);
+  if (uncurriedSites.size() == expectedSiteCount) {
+    if (auto emitter = callee.getSpecializedEmitter(SGF.SGM)) {
+      return applySpecializedEmitter(emitter.getValue(), C);
+    }
   }
 
-  if (isPartiallyAppliedSuperMethod(uncurryLevel)) {
-    return applyPartiallyAppliedSuperMethod(uncurryLevel, C);
+  if (isPartiallyAppliedSuperMethod()) {
+    return applyPartiallyAppliedSuperMethod(C);
   }
 
   if (isEnumElementConstructor()) {
-    return applyEnumElementConstructor(uncurryLevel, C);
+    return applyEnumElementConstructor(C);
   }
 
-  return applyNormalCall(uncurryLevel, C);
+  return applyNormalCall(C);
 }
 
 CallEmission::FirstLevelApplicationResult
-CallEmission::applyNormalCall(unsigned uncurryLevel, SGFContext C) {
+CallEmission::applyNormalCall(SGFContext C) {
   FirstLevelApplicationResult firstLevelResult;
 
   // We use the context emit-into initialization only for the
@@ -4193,16 +4065,16 @@
   firstLevelResult.formalType = callee.getSubstFormalType();
   auto origFormalType = callee.getOrigFormalType();
 
+  bool isCurried = (uncurriedSites.size() < callee.getParameterListCount());
+
   // Get the callee type information.
-  CalleeTypeInfo calleeTypeInfo =
-      callee.getTypeInfoAtUncurryLevel(SGF, uncurryLevel);
-  ManagedValue mv = callee.getFnValueAtUncurryLevel(SGF, uncurryLevel);
+  auto calleeTypeInfo = callee.getTypeInfo(SGF, isCurried);
+  auto mv = callee.getFnValue(SGF, isCurried);
 
   // In C language modes, substitute the type of the AbstractionPattern
   // so that we won't see type parameters down when we try to form bridging
   // conversions.
-  CanSILFunctionType calleeFnTy = mv.getType().castTo<SILFunctionType>();
-  if (calleeFnTy->getLanguage() == SILFunctionLanguage::C) {
+  if (calleeTypeInfo.substFnType->getLanguage() == SILFunctionLanguage::C) {
     if (auto genericFnType =
           dyn_cast<GenericFunctionType>(origFormalType.getType())) {
       auto fnType = genericFnType->substGenericArgs(callee.getSubstitutions());
@@ -4255,7 +4127,7 @@
 }
 
 CallEmission::FirstLevelApplicationResult
-CallEmission::applyEnumElementConstructor(unsigned uncurryLevel, SGFContext C) {
+CallEmission::applyEnumElementConstructor(SGFContext C) {
   FirstLevelApplicationResult firstLevelResult;
   assert(!assumedPlusZeroSelf);
   SGFContext uncurriedContext = (extraSites.empty() ? C : SGFContext());
@@ -4310,10 +4182,8 @@
 }
 
 CallEmission::FirstLevelApplicationResult
-CallEmission::applyPartiallyAppliedSuperMethod(unsigned uncurryLevel,
-                                               SGFContext C) {
+CallEmission::applyPartiallyAppliedSuperMethod(SGFContext C) {
   FirstLevelApplicationResult firstLevelResult;
-  assert(uncurryLevel == 0);
 
   // We want to emit the arguments as fully-substituted values
   // because that's what the partially applied super method expects;
@@ -4393,7 +4263,7 @@
 
 CallEmission::FirstLevelApplicationResult
 CallEmission::applySpecializedEmitter(SpecializedEmitter &specializedEmitter,
-                                      unsigned uncurryLevel, SGFContext C) {
+                                      SGFContext C) {
   FirstLevelApplicationResult firstLevelResult;
 
   // We use the context emit-into initialization only for the
@@ -4402,8 +4272,6 @@
 
   ManagedValue mv;
 
-  assert(uncurryLevel == 0);
-
   // Get the callee type information. We want to emit the arguments as
   // fully-substituted values because that's what the specialized emitters
   // expect.
@@ -4686,8 +4554,8 @@
   auto origFormalType = callee.getOrigFormalType();
   auto substFormalType = callee.getSubstFormalType();
 
-  CalleeTypeInfo calleeTypeInfo = callee.getTypeInfoAtUncurryLevel(*this, 0);
-  ManagedValue mv = callee.getFnValueAtUncurryLevel(*this, 0);
+  auto calleeTypeInfo = callee.getTypeInfo(*this, /*isCurried=*/false);
+  auto mv = callee.getFnValue(*this, /*isCurried=*/false);
 
   assert(!calleeTypeInfo.foreignError);
   assert(!calleeTypeInfo.foreignSelf.isImportAsMember());
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index f3a4cc2..c48ce35 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -498,6 +498,8 @@
   auto blockInterfaceTy = cast<SILFunctionType>(
     F.mapTypeOutOfContext(loweredBlockTy)->getCanonicalType());
 
+  assert(!blockInterfaceTy->isCoroutine());
+
   auto storageTy = SILBlockStorageType::get(loweredFuncTy);
   auto storageInterfaceTy = SILBlockStorageType::get(fnInterfaceTy);
 
@@ -535,8 +537,9 @@
   }
 
   auto invokeTy = SILFunctionType::get(
-      genericSig, extInfo, ParameterConvention::Direct_Unowned, params,
-      blockInterfaceTy->getResults(),
+      genericSig, extInfo, SILCoroutineKind::None,
+      ParameterConvention::Direct_Unowned, params, 
+      /*yields*/ {}, blockInterfaceTy->getResults(),
       blockInterfaceTy->getOptionalErrorResult(), getASTContext());
 
   // Create the invoke function. Borrow the mangling scheme from reabstraction
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index f782af6..d08ad65 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -857,8 +857,10 @@
     
     initConstantTy = SILFunctionType::get(initConstantTy->getGenericSignature(),
                                           initConstantTy->getExtInfo(),
+                                          SILCoroutineKind::None,
                                           ParameterConvention::Direct_Unowned,
                                           param,
+                                          /*yields*/ {},
                                           result,
                                           // TODO: throwing initializer?
                                           None,
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 0528044..a0f3f0e 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -1042,8 +1042,11 @@
   // If the referenced decl isn't a VarDecl, it should be a constant of some
   // sort.
   SILDeclRef silDeclRef(decl);
-  if (silDeclRef.getUncurryLevel() > 0)
+  if (silDeclRef.getParameterListCount() == 2) {
+    // Unqualified reference to an instance method from a static context,
+    // without applying 'self'.
     silDeclRef = silDeclRef.asCurried();
+  }
 
   ManagedValue result = emitClosureValue(loc, silDeclRef, refType,
                                          declRef.getSubstitutions());
@@ -3029,8 +3032,9 @@
     SILFunctionType::ExtInfo(SILFunctionType::Representation::Thin,
                              /*pseudogeneric*/ false,
                              /*noescape*/ false),
+    SILCoroutineKind::None,
     ParameterConvention::Direct_Unowned,
-    params, result, None, SGF.getASTContext());
+    params, {}, result, None, SGF.getASTContext());
   
   // Find the function and see if we already created it.
   SmallVector<CanType, 2> interfaceSubs;
@@ -3149,8 +3153,9 @@
     SILFunctionType::ExtInfo(SILFunctionType::Representation::Thin,
                              /*pseudogeneric*/ false,
                              /*noescape*/ false),
+    SILCoroutineKind::None,
     ParameterConvention::Direct_Unowned,
-    params, {}, None, SGF.getASTContext());
+    params, {}, {}, None, SGF.getASTContext());
   
   // Mangle the name of the thunk to see if we already created it.
   SmallString<64> nameBuf;
@@ -3317,8 +3322,9 @@
       SILFunctionType::ExtInfo(SILFunctionType::Representation::Thin,
                                /*pseudogeneric*/ false,
                                /*noescape*/ false),
+    SILCoroutineKind::None,
       ParameterConvention::Direct_Unowned,
-      params, results, None, C);
+      params, /*yields*/ {}, results, None, C);
     
     // Mangle the name of the thunk to see if we already created it.
     SmallString<64> nameBuf;
@@ -3483,8 +3489,9 @@
       SILFunctionType::ExtInfo(SILFunctionType::Representation::Thin,
                                /*pseudogeneric*/ false,
                                /*noescape*/ false),
+      SILCoroutineKind::None,
       ParameterConvention::Direct_Unowned,
-      params, results, None, C);
+      params, /*yields*/ {}, results, None, C);
     
     // Mangle the name of the thunk to see if we already created it.
     SmallString<64> nameBuf;
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index 8844bc6..f579dcc 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -475,9 +475,11 @@
                   SILFunctionType::ExtInfo()
                     .withRepresentation(SILFunctionType::Representation::
                                         CFunctionPointer),
+                  SILCoroutineKind::None,
                   ParameterConvention::Direct_Unowned,
                   SILParameterInfo(anyObjectMetaTy,
                                    ParameterConvention::Direct_Unowned),
+                  /*yields*/ {},
                   SILResultInfo(OptNSStringTy,
                                 ResultConvention::Autoreleased),
                   /*error result*/ None,
@@ -577,8 +579,10 @@
                     // Should be C calling convention, but NSApplicationMain
                     // has an overlay to fix the type of argv.
                     .withRepresentation(SILFunctionType::Representation::Thin),
+                  SILCoroutineKind::None,
                   ParameterConvention::Direct_Unowned,
                   argTypes,
+                  /*yields*/ {},
                   SILResultInfo(argc->getType().getSwiftRValueType(),
                                 ResultConvention::Unowned),
                   /*error result*/ None,
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 4cd88e0..33dc4ec 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -2837,6 +2837,15 @@
                        param.getConvention()));
   }
 
+  SmallVector<SILYieldInfo, 4> interfaceYields;
+  for (auto &yield : expectedType->getYields()) {
+    auto yieldIfaceTy = GenericEnvironment::mapTypeOutOfContext(
+        genericEnv, yield.getType());
+    auto interfaceYield =
+      yield.getWithType(yieldIfaceTy->getCanonicalType(genericSig));
+    interfaceYields.push_back(interfaceYield);
+  }
+
   SmallVector<SILResultInfo, 4> interfaceResults;
   for (auto &result : expectedType->getResults()) {
     auto resultIfaceTy = GenericEnvironment::mapTypeOutOfContext(
@@ -2858,9 +2867,10 @@
   
   // The type of the thunk function.
   return SILFunctionType::get(genericSig, extInfo,
+                              expectedType->getCoroutineKind(),
                               ParameterConvention::Direct_Unowned,
-                              interfaceParams, interfaceResults,
-                              interfaceErrorResult,
+                              interfaceParams, interfaceYields,
+                              interfaceResults, interfaceErrorResult,
                               getASTContext());
 }
 
diff --git a/lib/SILOptimizer/ARC/ARCRegionState.cpp b/lib/SILOptimizer/ARC/ARCRegionState.cpp
index e4c2eed..f776571 100644
--- a/lib/SILOptimizer/ARC/ARCRegionState.cpp
+++ b/lib/SILOptimizer/ARC/ARCRegionState.cpp
@@ -170,6 +170,8 @@
   // against the operand or can use the value in some way.
   case TermKind::ThrowInst:
   case TermKind::ReturnInst:
+  case TermKind::UnwindInst:
+  case TermKind::YieldInst:
   case TermKind::TryApplyInst:
   case TermKind::SwitchValueInst:
   case TermKind::SwitchEnumInst:
diff --git a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp
index bf3d1ae..50ae744 100644
--- a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp
+++ b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp
@@ -211,6 +211,8 @@
   // against the operand or can use the value in some way.
   case TermKind::ThrowInst:
   case TermKind::ReturnInst:
+  case TermKind::UnwindInst:
+  case TermKind::YieldInst:
   case TermKind::TryApplyInst:
   case TermKind::SwitchValueInst:
   case TermKind::SwitchEnumInst:
diff --git a/lib/SILOptimizer/Analysis/CFG.cpp b/lib/SILOptimizer/Analysis/CFG.cpp
index ef1b825..e0e84de 100644
--- a/lib/SILOptimizer/Analysis/CFG.cpp
+++ b/lib/SILOptimizer/Analysis/CFG.cpp
@@ -34,6 +34,11 @@
   case TermKind::UnreachableInst:
   case TermKind::ReturnInst:
   case TermKind::ThrowInst:
+  case TermKind::UnwindInst:
+    return false;
+  // yield and try_apply are special because they can do arbitrary,
+  // potentially-process-terminating things.
+  case TermKind::YieldInst:
   case TermKind::TryApplyInst:
     return false;
   }
diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp
index 49b1c64..ddaacb2 100644
--- a/lib/SILOptimizer/IPO/CapturePromotion.cpp
+++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp
@@ -416,7 +416,8 @@
   // Create the thin function type for the cloned closure.
   auto ClonedTy = SILFunctionType::get(
       OrigFTI->getGenericSignature(), OrigFTI->getExtInfo(),
-      OrigFTI->getCalleeConvention(), ClonedInterfaceArgTys,
+      OrigFTI->getCoroutineKind(), OrigFTI->getCalleeConvention(),
+      ClonedInterfaceArgTys, OrigFTI->getYields(),
       OrigFTI->getResults(), OrigFTI->getOptionalErrorResult(),
       M.getASTContext(), OrigFTI->getWitnessMethodConformanceOrNone());
 
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 73c0ff0..c21f9c9 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -614,8 +614,9 @@
 
   auto ClonedTy = SILFunctionType::get(
       ClosureUserFunTy->getGenericSignature(), ExtInfo,
+      ClosureUserFunTy->getCoroutineKind(),
       ClosureUserFunTy->getCalleeConvention(), NewParameterInfoList,
-      ClosureUserFunTy->getResults(),
+      ClosureUserFunTy->getYields(), ClosureUserFunTy->getResults(),
       ClosureUserFunTy->getOptionalErrorResult(), M.getASTContext());
 
   // We make this function bare so we don't have to worry about decls in the
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 7de21a7..4d3581c 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -260,7 +260,8 @@
   SILFunctionType::ExtInfo EInfo;
   EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin);
   auto LoweredType = SILFunctionType::get(nullptr, EInfo,
-      ParameterConvention::Direct_Owned, { }, Results, None,
+      SILCoroutineKind::None, ParameterConvention::Direct_Owned,
+      /*params*/ {}, /*yields*/ {}, Results, None,
       Store->getModule().getASTContext());
   auto *GetterF = Store->getModule().getOrCreateFunction(
       Store->getLoc(),
@@ -514,7 +515,8 @@
   SILFunctionType::ExtInfo EInfo;
   EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin);
   auto LoweredType = SILFunctionType::get(nullptr, EInfo,
-      ParameterConvention::Direct_Owned, { }, Results, None,
+      SILCoroutineKind::None, ParameterConvention::Direct_Owned,
+      /*params*/ {}, /*yields*/ {}, Results, None,
       InitF->getASTContext());
   auto *GetterF = InitF->getModule().getOrCreateFunction(
       InitF->getLocation(),
diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
index b92c698..996215f 100644
--- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
+++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
@@ -629,7 +629,8 @@
   // the parameters promoted.
   auto ClonedTy = SILFunctionType::get(
       OrigFTI->getGenericSignature(), OrigFTI->getExtInfo(),
-      OrigFTI->getCalleeConvention(), ClonedInterfaceArgTys,
+      OrigFTI->getCoroutineKind(), OrigFTI->getCalleeConvention(),
+      ClonedInterfaceArgTys, OrigFTI->getYields(),
       OrigFTI->getResults(), OrigFTI->getOptionalErrorResult(),
       M.getASTContext(), OrigFTI->getWitnessMethodConformanceOrNone());
 
diff --git a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
index 6d0e0df..5e1bca0 100644
--- a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
+++ b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
@@ -291,6 +291,8 @@
   switch (Term->getTermKind()) {
   case TermKind::ReturnInst:
   case TermKind::ThrowInst:
+  case TermKind::UnwindInst:
+  case TermKind::YieldInst:
 
   case TermKind::UnreachableInst:
   case TermKind::SwitchValueInst:
@@ -381,6 +383,7 @@
   switch (cast<TermInst>(I)->getTermKind()) {
   case TermKind::BranchInst:
   case TermKind::UnreachableInst:
+  case TermKind::UnwindInst:
     return;
 
   case TermKind::ReturnInst:
@@ -396,6 +399,7 @@
 
   case TermKind::TryApplyInst:
   case TermKind::SwitchValueInst:
+  case TermKind::YieldInst:
     for (auto &O : I->getAllOperands())
       markValueLive(O.get());
     return;
diff --git a/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
index c3304da..f43224d 100644
--- a/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
+++ b/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
@@ -577,6 +577,12 @@
     InterfaceResults.push_back(InterfaceResult);
   }
 
+  llvm::SmallVector<SILYieldInfo, 8> InterfaceYields;
+  for (SILYieldInfo InterfaceYield : FTy->getYields()) {
+    // For now, don't touch the yield types.
+    InterfaceYields.push_back(InterfaceYield);
+  }
+
   bool UsesGenerics = false;
   if (HasGenericSignature) {
     // Not all of the generic type parameters are used by the function
@@ -630,9 +636,9 @@
       UsesGenerics ? FTy->getGenericSignature() : nullptr;
 
   return SILFunctionType::get(
-      GenericSig, ExtInfo, FTy->getCalleeConvention(), InterfaceParams,
-      InterfaceResults, InterfaceErrorResult, F->getModule().getASTContext(),
-      witnessMethodConformance);
+      GenericSig, ExtInfo, FTy->getCoroutineKind(), FTy->getCalleeConvention(),
+      InterfaceParams, InterfaceYields, InterfaceResults, InterfaceErrorResult,
+      F->getModule().getASTContext(), witnessMethodConformance);
 }
 
 void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp
index 76741f7..47cc57e 100644
--- a/lib/SILOptimizer/Transforms/Outliner.cpp
+++ b/lib/SILOptimizer/Transforms/Outliner.cpp
@@ -290,7 +290,8 @@
       SILFunctionType::ExtInfo(SILFunctionType::Representation::Thin,
                                /*pseudogeneric*/ false, /*noescape*/ false);
   auto FunctionType = SILFunctionType::get(
-      nullptr, ExtInfo, ParameterConvention::Direct_Unowned, Parameters,
+      nullptr, ExtInfo, SILCoroutineKind::None,
+      ParameterConvention::Direct_Unowned, Parameters, /*yields*/ {},
       Results, None, M.getASTContext());
   return FunctionType;
 }
@@ -1197,7 +1198,8 @@
         SILResultInfo(BridgedReturn.getReturnType(), ResultConvention::Owned));
   }
   auto FunctionType = SILFunctionType::get(
-      nullptr, ExtInfo, ParameterConvention::Direct_Unowned, Parameters,
+      nullptr, ExtInfo, SILCoroutineKind::None,
+      ParameterConvention::Direct_Unowned, Parameters, {},
       Results, None, M.getASTContext());
   return FunctionType;
 }
diff --git a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
index fe6da5e..145a57b 100644
--- a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
+++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
@@ -2302,6 +2302,8 @@
     case TermKind::ThrowInst:
     case TermKind::DynamicMethodBranchInst:
     case TermKind::ReturnInst:
+    case TermKind::UnwindInst:
+    case TermKind::YieldInst:
       break;
     }
     // If the block has a cond_fail, try to move it to the predecessors.
diff --git a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
index 3d6da3c..4219ac2 100644
--- a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
+++ b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
@@ -84,7 +84,8 @@
         nullptr, SILFunctionType::ExtInfo(SILFunctionType::Representation::Thin,
                                           false /*isPseudoGeneric*/,
                                           false /*noescape*/),
-        ParameterConvention::Direct_Unowned, ArrayRef<SILParameterInfo>(),
+        SILCoroutineKind::None, ParameterConvention::Direct_Unowned,
+        ArrayRef<SILParameterInfo>(), ArrayRef<SILYieldInfo>(),
         ResultInfoArray, None, getFunction()->getModule().getASTContext());
 
     SILFunction *F = getFunction()->getModule().getOrCreateSharedFunction(
diff --git a/lib/SILOptimizer/Utils/CFG.cpp b/lib/SILOptimizer/Utils/CFG.cpp
index 452e58d..9f419ba 100644
--- a/lib/SILOptimizer/Utils/CFG.cpp
+++ b/lib/SILOptimizer/Utils/CFG.cpp
@@ -307,9 +307,25 @@
     return;
   }
 
+  case TermKind::YieldInst: {
+    auto *YI = cast<YieldInst>(T);
+    assert((EdgeIdx == 0 || EdgeIdx == 1) && "Invalid edge index");
+    auto *resumeBB = !EdgeIdx ? NewDest : YI->getResumeBB();
+    auto *unwindBB = EdgeIdx ? NewDest : YI->getUnwindBB();
+    SmallVector<SILValue, 4> yieldedValues;
+    for (auto value : YI->getYieldedValues())
+      yieldedValues.push_back(value);
+
+    B.createYield(YI->getLoc(), yieldedValues, resumeBB, unwindBB);
+
+    YI->eraseFromParent();
+    return;
+  }
+
   case TermKind::ReturnInst:
   case TermKind::ThrowInst:
   case TermKind::UnreachableInst:
+  case TermKind::UnwindInst:
     llvm_unreachable("Branch target cannot be changed for this terminator instruction!");
   }
   llvm_unreachable("Not yet implemented!");
@@ -469,6 +485,8 @@
   case TermKind::ThrowInst:
   case TermKind::TryApplyInst:
   case TermKind::UnreachableInst:
+  case TermKind::UnwindInst:
+  case TermKind::YieldInst:
     llvm_unreachable("Branch target cannot be replaced for this terminator instruction!");
   }
   llvm_unreachable("Not yet implemented!");
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index e7dfb6f..eb69a59 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -721,8 +721,10 @@
 
   // Use the new specialized generic signature.
   auto NewFnTy = SILFunctionType::get(
-      CanSpecializedGenericSig, FnTy->getExtInfo(), FnTy->getCalleeConvention(),
-      FnTy->getParameters(), FnTy->getResults(), FnTy->getOptionalErrorResult(),
+      CanSpecializedGenericSig, FnTy->getExtInfo(),
+      FnTy->getCoroutineKind(), FnTy->getCalleeConvention(),
+      FnTy->getParameters(), FnTy->getYields(),
+      FnTy->getResults(), FnTy->getOptionalErrorResult(),
       M.getASTContext(), FnTy->getWitnessMethodConformanceOrNone());
 
   // This is an interface type. It should not have any archetypes.
@@ -735,6 +737,7 @@
 CanSILFunctionType ReabstractionInfo::
 createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const {
   llvm::SmallVector<SILResultInfo, 8> SpecializedResults;
+  llvm::SmallVector<SILYieldInfo, 8> SpecializedYields;
   llvm::SmallVector<SILParameterInfo, 8> SpecializedParams;
 
   unsigned IndirectResultIdx = 0;
@@ -769,9 +772,15 @@
       SpecializedParams.push_back(PI);
     }
   }
+  for (SILYieldInfo YI : SubstFTy->getYields()) {
+    // For now, always just use the original, substituted parameter info.
+    SpecializedYields.push_back(YI);
+  }
   return SILFunctionType::get(
-      SubstFTy->getGenericSignature(), SubstFTy->getExtInfo(),
-      SubstFTy->getCalleeConvention(), SpecializedParams, SpecializedResults,
+      SubstFTy->getGenericSignature(),
+      SubstFTy->getExtInfo(), SubstFTy->getCoroutineKind(),
+      SubstFTy->getCalleeConvention(),
+      SpecializedParams, SpecializedYields, SpecializedResults,
       SubstFTy->getOptionalErrorResult(), M.getASTContext(),
       SubstFTy->getWitnessMethodConformanceOrNone());
 }
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index 96c67bb..1fdf29d 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -338,6 +338,8 @@
   case SILInstructionKind::UnreachableInst:
   case SILInstructionKind::ReturnInst:
   case SILInstructionKind::ThrowInst:
+  case SILInstructionKind::UnwindInst:
+  case SILInstructionKind::YieldInst:
     return InlineCost::Free;
 
   case SILInstructionKind::ApplyInst:
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index ca96300..2c4fded 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -7527,6 +7527,16 @@
                                                         DC);
     if (!useAs && !useAsBang)
       return false;
+    
+    // If we're performing pattern matching, "as" means something completely different...
+    if (auto binOpExpr = dyn_cast<BinaryExpr>(expr)) {
+      auto overloadedFn = dyn_cast<OverloadedDeclRefExpr>(binOpExpr->getFn());
+      if (overloadedFn && overloadedFn->getDecls().size() > 0) {
+        ValueDecl *decl0 = overloadedFn->getDecls()[0];
+        if (decl0->getBaseName() == decl0->getASTContext().Id_MatchOperator)
+          return false;
+      }
+    }
 
     bool needsParensInside = exprNeedsParensBeforeAddingAs(TC, DC, affected);
     bool needsParensOutside = exprNeedsParensAfterAddingAs(TC, DC, affected,
diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp
index 9a42ad4..3025c13 100644
--- a/lib/Sema/TypeCheckAvailability.cpp
+++ b/lib/Sema/TypeCheckAvailability.cpp
@@ -1499,6 +1499,27 @@
                                   IsUnavailable);
 }
 
+bool TypeChecker::isInsideCompatibleUnavailableDeclaration(
+    SourceRange ReferenceRange, const DeclContext *ReferenceDC,
+    const AvailableAttr *attr) {
+  if (!attr->isUnconditionallyUnavailable()) {
+    return false;
+  }
+  PlatformKind platform = attr->Platform;
+  if (platform == PlatformKind::none) {
+    return false;
+  }
+
+  auto IsUnavailable = [platform](const Decl *D) {
+    auto EnclosingUnavailable =
+        D->getAttrs().getUnavailable(D->getASTContext());
+    return EnclosingUnavailable && EnclosingUnavailable->Platform == platform;
+  };
+
+  return someEnclosingDeclMatches(ReferenceRange, ReferenceDC, *this,
+                                  IsUnavailable);
+}
+
 bool TypeChecker::isInsideDeprecatedDeclaration(SourceRange ReferenceRange,
                                                 const DeclContext *ReferenceDC){
   auto IsDeprecated = [](const Decl *D) {
@@ -2093,6 +2114,14 @@
     return false;
   }
 
+  // Calling unavailable code from within code with the same
+  // unavailability is OK -- the eventual caller can't call the
+  // enclosing code in the same situations it wouldn't be able to
+  // call this code.
+  if (isInsideCompatibleUnavailableDeclaration(R, DC, Attr)) {
+    return false;
+  }
+
   SourceLoc Loc = R.Start;
   auto Name = D->getFullName();
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index f53508b..0cdbf53 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2348,25 +2348,14 @@
   // Replace generic type parameters and associated types with their
   // witnesses, when we have them.
   auto selfTy = conformance->getProtocol()->getSelfInterfaceType();
-  type = type.transform([&](Type type) -> Type {
-    // If a dependent member refers to an associated type, replace it.
-    if (auto member = type->getAs<DependentMemberType>()) {
-      if (member->getBase()->isEqual(selfTy)) {
-        // FIXME: Could handle inherited conformances here.
-        if (conformance->hasTypeWitness(member->getAssocType()))
-          return conformance->getTypeWitness(member->getAssocType(), nullptr);
-      }
-    }
+  return type.subst([&](SubstitutableType *dependentType) {
+                      if (dependentType->isEqual(selfTy))
+                        return conformance->getType();
 
-    // Replace 'Self' with the conforming type.
-    if (type->isEqual(selfTy))
-      return conformance->getType();
-
-    return type;
-  });
-
-  //
-  return type;
+                      return Type(dependentType);
+                    },
+                    LookUpConformanceInModule(module),
+                    SubstFlags::UseErrorType);
 }
 
 /// \brief Retrieve the kind of requirement described by the given declaration,
@@ -6356,6 +6345,24 @@
   return false;
 }
 
+/// Determine whether this is an unlabeled initializer or subscript.
+static bool isUnlabeledInitializerOrSubscript(ValueDecl *value) {
+  ParameterList *paramList = nullptr;
+  if (auto constructor = dyn_cast<ConstructorDecl>(value))
+    paramList = constructor->getParameterList(1);
+  else if (auto subscript = dyn_cast<SubscriptDecl>(value))
+    paramList = subscript->getIndices();
+  else
+    return false;
+
+  for (auto param : *paramList) {
+    if (!param->getArgumentName().empty()) return false;
+  }
+
+  return true;
+}
+
+/// Determine whether this declaration is an initializer
 /// Determine whether we should warn about the given witness being a close
 /// match for the given optional requirement.
 static bool shouldWarnAboutPotentialWitness(
@@ -6390,6 +6397,12 @@
       if (!attr->isImplicit()) return false;
   }
 
+  // Don't warn if the requirement or witness is an initializer or subscript
+  // with no argument labels.
+  if (isUnlabeledInitializerOrSubscript(req) ||
+      isUnlabeledInitializerOrSubscript(witness))
+    return false;
+
   // If the score is relatively high, don't warn: this is probably
   // unrelated.  Allow about one typo for every four properly-typed
   // characters, which prevents completely-wacky suggestions in many
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 9cd8bd7..9aa42f8 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -1702,17 +1702,25 @@
                                 TypeResolutionOptions options,
                                 FunctionType::ExtInfo extInfo
                                   = FunctionType::ExtInfo());
-    Type resolveSILFunctionType(
-        FunctionTypeRepr *repr, TypeResolutionOptions options,
-        SILFunctionType::ExtInfo extInfo = SILFunctionType::ExtInfo(),
-        ParameterConvention calleeConvention = DefaultParameterConvention,
-        TypeRepr *witnessmethodProtocol = nullptr);
+    Type resolveSILFunctionType(FunctionTypeRepr *repr,
+                                TypeResolutionOptions options,
+                                SILCoroutineKind coroutineKind
+                                  = SILCoroutineKind::None,
+                                SILFunctionType::ExtInfo extInfo
+                                  = SILFunctionType::ExtInfo(),
+                                ParameterConvention calleeConvention
+                                  = DefaultParameterConvention,
+                                TypeRepr *witnessmethodProtocol = nullptr);
     SILParameterInfo resolveSILParameter(TypeRepr *repr,
                                          TypeResolutionOptions options);
+    SILYieldInfo resolveSILYield(TypeAttributes &remainingAttrs,
+                                 TypeRepr *repr, TypeResolutionOptions options);
     bool resolveSILResults(TypeRepr *repr, TypeResolutionOptions options,
+                           SmallVectorImpl<SILYieldInfo> &yields,
                            SmallVectorImpl<SILResultInfo> &results,
                            Optional<SILResultInfo> &errorResult);
     bool resolveSingleSILResult(TypeRepr *repr, TypeResolutionOptions options,
+                                SmallVectorImpl<SILYieldInfo> &yields,
                                 SmallVectorImpl<SILResultInfo> &results,
                                 Optional<SILResultInfo> &errorResult);
     Type resolveSpecifierTypeRepr(SpecifierTypeRepr *repr,
@@ -1970,7 +1978,7 @@
   static const TypeAttrKind FunctionAttrs[] = {
     TAK_convention, TAK_noreturn, TAK_pseudogeneric,
     TAK_callee_owned, TAK_callee_guaranteed, TAK_noescape, TAK_autoclosure,
-    TAK_escaping
+    TAK_escaping, TAK_yield_once, TAK_yield_many
   };
 
   auto checkUnsupportedAttr = [&](TypeAttrKind attr) {
@@ -2018,6 +2026,13 @@
     SILFunctionType::Representation rep;
     TypeRepr *witnessMethodProtocol = nullptr;
 
+    auto coroutineKind = SILCoroutineKind::None;
+    if (attrs.has(TAK_yield_once)) {
+      coroutineKind = SILCoroutineKind::YieldOnce;
+    } else if (attrs.has(TAK_yield_many)) {
+      coroutineKind = SILCoroutineKind::YieldMany;
+    }
+
     auto calleeConvention = ParameterConvention::Direct_Unowned;
     if (attrs.has(TAK_callee_owned)) {
       if (attrs.has(TAK_callee_guaranteed)) {
@@ -2065,7 +2080,8 @@
     SILFunctionType::ExtInfo extInfo(rep, attrs.has(TAK_pseudogeneric),
                                      attrs.has(TAK_noescape));
 
-    ty = resolveSILFunctionType(fnRepr, options, extInfo, calleeConvention,
+    ty = resolveSILFunctionType(fnRepr, options, coroutineKind,
+                                extInfo, calleeConvention,
                                 witnessMethodProtocol);
     if (!ty || ty->hasError()) return ty;
   } else if (hasFunctionAttr) {
@@ -2257,6 +2273,11 @@
   options -= TR_ImmediateFunctionInput;
   options -= TR_FunctionInput;
   options -= TR_TypeAliasUnderlyingType;
+  // FIXME: Until we remove the IUO type from the type system, we
+  // need to continue to parse IUOs in SIL tests so that we can
+  // match the types we generate from the importer.
+  if (!options.contains(TR_SILMode))
+    options -= TR_AllowIUO;
 
   Type inputTy = resolveType(repr->getArgsTypeRepr(),
                              options | TR_ImmediateFunctionInput);
@@ -2424,6 +2445,7 @@
 
 Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
                                           TypeResolutionOptions options,
+                                          SILCoroutineKind coroutineKind,
                                           SILFunctionType::ExtInfo extInfo,
                                           ParameterConvention callee,
                                           TypeRepr *witnessMethodProtocol) {
@@ -2436,6 +2458,7 @@
   // Resolve parameter and result types using the function's generic
   // environment.
   SmallVector<SILParameterInfo, 4> params;
+  SmallVector<SILYieldInfo, 4> yields;
   SmallVector<SILResultInfo, 4> results;
   Optional<SILResultInfo> errorResult;
   {
@@ -2484,10 +2507,17 @@
 
     {
       // FIXME: Deal with unsatisfied dependencies.
-      if (resolveSILResults(repr->getResultTypeRepr(), options,
+      if (resolveSILResults(repr->getResultTypeRepr(), options, yields,
                             results, errorResult)) {
         hasError = true;
       }
+
+      // Diagnose non-coroutines that declare yields.
+      if (coroutineKind == SILCoroutineKind::None && !yields.empty()) {
+        TC.diagnose(repr->getResultTypeRepr()->getLoc(),
+                    diag::sil_non_coro_yields);
+        hasError = true;
+      }
     }
   } // restore generic type resolver
 
@@ -2498,6 +2528,7 @@
   // FIXME: Remap the parsed context types to interface types.
   CanGenericSignature genericSig;
   SmallVector<SILParameterInfo, 4> interfaceParams;
+  SmallVector<SILYieldInfo, 4> interfaceYields;
   SmallVector<SILResultInfo, 4> interfaceResults;
   Optional<SILResultInfo> interfaceErrorResult;
   if (auto *genericEnv = repr->getGenericEnvironment()) {
@@ -2508,6 +2539,11 @@
           param.getType())->getCanonicalType();
       interfaceParams.push_back(param.getWithType(transParamType));
     }
+    for (auto &yield : yields) {
+      auto transYieldType = genericEnv->mapTypeOutOfContext(
+          yield.getType())->getCanonicalType();
+      interfaceYields.push_back(yield.getWithType(transYieldType));
+    }
     for (auto &result : results) {
       auto transResultType = genericEnv->mapTypeOutOfContext(
           result.getType())->getCanonicalType();
@@ -2522,6 +2558,7 @@
     }
   } else {
     interfaceParams = params;
+    interfaceYields = yields;
     interfaceResults = results;
     interfaceErrorResult = errorResult;
   }
@@ -2552,9 +2589,20 @@
            "found witness_method without matching conformance");
   }
 
-  return SILFunctionType::get(genericSig, extInfo, callee, interfaceParams,
-                              interfaceResults, interfaceErrorResult, Context,
-                              witnessMethodConformance);
+  return SILFunctionType::get(genericSig, extInfo, coroutineKind,
+                              callee,
+                              interfaceParams, interfaceYields,
+                              interfaceResults, interfaceErrorResult,
+                              Context, witnessMethodConformance);
+}
+
+SILYieldInfo TypeResolver::resolveSILYield(TypeAttributes &attrs,
+                                           TypeRepr *repr,
+                                           TypeResolutionOptions options) {
+  AttributedTypeRepr attrRepr(attrs, repr);
+  SILParameterInfo paramInfo =
+    resolveSILParameter(&attrRepr, options | TR_ImmediateFunctionInput);
+  return SILYieldInfo(paramInfo.getType(), paramInfo.getConvention());
 }
 
 SILParameterInfo TypeResolver::resolveSILParameter(
@@ -2568,6 +2616,7 @@
 
   if (auto attrRepr = dyn_cast<AttributedTypeRepr>(repr)) {
     auto attrs = attrRepr->getAttrs();
+
     auto checkFor = [&](TypeAttrKind tak, ParameterConvention attrConv) {
       if (!attrs.has(tak)) return;
       if (convention != DefaultParameterConvention) {
@@ -2610,6 +2659,7 @@
 
 bool TypeResolver::resolveSingleSILResult(TypeRepr *repr,
                                           TypeResolutionOptions options,
+                                          SmallVectorImpl<SILYieldInfo> &yields,
                               SmallVectorImpl<SILResultInfo> &ordinaryResults,
                                        Optional<SILResultInfo> &errorResult) {
   Type type;
@@ -2620,6 +2670,19 @@
     // Copy the attributes out; we're going to destructively modify them.
     auto attrs = attrRepr->getAttrs();
 
+    // Recognize @yields.
+    if (attrs.has(TypeAttrKind::TAK_yields)) {
+      attrs.clearAttribute(TypeAttrKind::TAK_yields);
+
+      // The treatment from this point on is basically completely different.
+      auto yield = resolveSILYield(attrs, attrRepr->getTypeRepr(), options);
+      if (yield.getType()->hasError())
+        return true;
+
+      yields.push_back(yield);
+      return false;
+    }
+
     // Recognize @error.
     if (attrs.has(TypeAttrKind::TAK_error)) {
       attrs.clearAttribute(TypeAttrKind::TAK_error);
@@ -2687,6 +2750,7 @@
 
 bool TypeResolver::resolveSILResults(TypeRepr *repr,
                                      TypeResolutionOptions options,
+                                SmallVectorImpl<SILYieldInfo> &yields,
                                 SmallVectorImpl<SILResultInfo> &ordinaryResults,
                                 Optional<SILResultInfo> &errorResult) {
   if (auto tuple = dyn_cast<TupleTypeRepr>(repr)) {
@@ -2696,13 +2760,15 @@
         TC.diagnose(element.UnderscoreLoc, diag::sil_function_output_label);
     }
     for (auto elt : tuple->getElements()) {
-      if (resolveSingleSILResult(elt.Type, options, ordinaryResults, errorResult))
+      if (resolveSingleSILResult(elt.Type, options,
+                                 yields, ordinaryResults, errorResult))
         hadError = true;
     }
     return hadError;
   }
 
-  return resolveSingleSILResult(repr, options, ordinaryResults, errorResult);
+  return resolveSingleSILResult(repr, options,
+                                yields, ordinaryResults, errorResult);
 }
 
 Type TypeResolver::resolveSpecifierTypeRepr(SpecifierTypeRepr *repr,
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index bf862ae..db21218 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -2376,6 +2376,12 @@
   bool isInsideUnavailableDeclaration(SourceRange ReferenceRange,
                                       const DeclContext *DC);
 
+  /// Returns true if the reference or any of its parents is an
+  /// unconditional unavailable declaration for the same platform.
+  bool isInsideCompatibleUnavailableDeclaration(SourceRange ReferenceRange,
+                                                const DeclContext *DC,
+                                                const AvailableAttr *attr);
+
   /// Returns true if the reference is lexically contained in a declaration
   /// that is deprecated on all deployment targets.
   bool isInsideDeprecatedDeclaration(SourceRange ReferenceRange,
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 68890a2..b62babb 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -439,9 +439,11 @@
   unsigned kind = Cursor.readRecord(next.ID, scratch);
   switch (kind) {
   case decls_block::SIL_LAYOUT: {
+    GenericSignatureID rawGenericSig;
     unsigned numFields;
     ArrayRef<uint64_t> types;
-    decls_block::SILLayoutLayout::readRecord(scratch, numFields, types);
+    decls_block::SILLayoutLayout::readRecord(scratch, rawGenericSig,
+                                             numFields, types);
     
     SmallVector<SILField, 4> fields;
     for (auto fieldInfo : types.slice(0, numFields)) {
@@ -452,20 +454,10 @@
                  isMutable));
     }
     
-    SmallVector<GenericTypeParamType*, 4> genericParams;
-    for (auto typeId : types.slice(numFields)) {
-      auto type = getType(typeId)->castTo<GenericTypeParamType>();
-      genericParams.push_back(type);
-    }
-    
-    SmallVector<Requirement, 4> requirements;
-    readGenericRequirements(requirements, DeclTypeCursor);
-    CanGenericSignature sig;
-    if (!genericParams.empty() || !requirements.empty()) {
-      sig = GenericSignature::get(genericParams, requirements)
-        ->getCanonicalSignature();
-    }
-    return SILLayout::get(getContext(), sig, fields);
+    CanGenericSignature canSig;
+    if (auto sig = getGenericSignature(rawGenericSig))
+      canSig = sig->getCanonicalSignature();
+    return SILLayout::get(getContext(), canSig, fields);
   }
   default:
     error();
@@ -920,6 +912,68 @@
   }
 }
 
+GenericSignature *ModuleFile::getGenericSignature(
+                                      serialization::GenericSignatureID ID) {
+  using namespace decls_block;
+
+  // Zero is a sentinel for having no generic signature.
+  if (ID == 0) return nullptr;
+
+  assert(ID <= GenericSignatures.size() && "invalid GenericSignature ID");
+  auto &sigOrOffset = GenericSignatures[ID-1];
+
+  // If we've already deserialized this generic signature, return it.
+  if (sigOrOffset.isComplete()) {
+    return sigOrOffset.get();
+  }
+
+  // Read the generic signature.
+  BCOffsetRAII restoreOffset(DeclTypeCursor);
+  DeclTypeCursor.JumpToBit(sigOrOffset);
+  DeserializingEntityRAII deserializingEntity(*this);
+
+  // Read the parameter types.
+  SmallVector<GenericTypeParamType *, 4> paramTypes;
+  StringRef blobData;
+  SmallVector<uint64_t, 8> scratch;
+
+  auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
+  if (entry.Kind != llvm::BitstreamEntry::Record) {
+    error();
+    return nullptr;
+  }
+
+  unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch, &blobData);
+  if (recordID != GENERIC_SIGNATURE) {
+    error();
+    return nullptr;
+  }
+
+  ArrayRef<uint64_t> rawParamIDs;
+  GenericSignatureLayout::readRecord(scratch, rawParamIDs);
+
+  for (unsigned i = 0, n = rawParamIDs.size(); i != n; ++i) {
+    auto paramTy = getType(rawParamIDs[i])->castTo<GenericTypeParamType>();
+    paramTypes.push_back(paramTy);
+  }
+
+  // Read the generic requirements.
+  SmallVector<Requirement, 4> requirements;
+  readGenericRequirements(requirements, DeclTypeCursor);
+
+  // Construct the generic signature from the loaded parameters and
+  // requirements.
+  auto signature = GenericSignature::get(paramTypes, requirements);
+
+  // If we've already deserialized this generic signature, return it.
+  if (sigOrOffset.isComplete()) {
+    return sigOrOffset.get();
+  }
+
+  sigOrOffset = signature;
+  return signature;
+}
+
 llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
 ModuleFile::getGenericSignatureOrEnvironment(
                                          serialization::GenericEnvironmentID ID,
@@ -940,13 +994,21 @@
     return envOrOffset.get();
   }
 
-  // Read the generic environment.
-  BCOffsetRAII restoreOffset(DeclTypeCursor);
-  DeclTypeCursor.JumpToBit(envOrOffset);
-  DeserializingEntityRAII deserializingEntity(*this);
+  // Extract the bit offset or generic signature ID.
+  uint64_t bitOffset = envOrOffset;
+  GenericSignature *signature = nullptr;
+  if (bitOffset & 0x01) {
+    // We have a generic signature ID.
+    signature = getGenericSignature(bitOffset >> 1);
+  } else {
+    bitOffset = bitOffset >> 1;
 
-  SmallVector<GenericTypeParamType *, 4> paramTypes;
-  {
+    // Read the generic environment.
+    BCOffsetRAII restoreOffset(DeclTypeCursor);
+    DeclTypeCursor.JumpToBit(bitOffset);
+    DeserializingEntityRAII deserializingEntity(*this);
+
+    SmallVector<GenericTypeParamType *, 4> paramTypes;
     using namespace decls_block;
 
     StringRef blobData;
@@ -963,72 +1025,55 @@
       return result;
 
     unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch, &blobData);
-    switch (recordID) {
-    case GENERIC_ENVIRONMENT: {
-      lastRecordOffset.reset();
-
-      ArrayRef<uint64_t> rawParamIDs;
-      GenericEnvironmentLayout::readRecord(scratch, rawParamIDs);
-
-      for (unsigned i = 0, n = rawParamIDs.size(); i != n; ++i) {
-        auto paramTy = getType(rawParamIDs[i])->castTo<GenericTypeParamType>();
-        paramTypes.push_back(paramTy);
-      }
-      break;
-    }
-
-    case SIL_GENERIC_ENVIRONMENT: {
-      ArrayRef<uint64_t> rawParamIDs;
-      SILGenericEnvironmentLayout::readRecord(scratch, rawParamIDs);
-      lastRecordOffset.reset();
-
-      if (rawParamIDs.size() % 2 != 0) {
-        error();
-        return result;
-      }
-
-      for (unsigned i = 0, n = rawParamIDs.size(); i != n; i += 2) {
-        Identifier name = getIdentifier(rawParamIDs[i]);
-        auto paramTy = getType(rawParamIDs[i+1])->castTo<GenericTypeParamType>();
-
-        if (!name.empty()) {
-          auto paramDecl =
-            createDecl<GenericTypeParamDecl>(getAssociatedModule(),
-                                             name,
-                                             SourceLoc(),
-                                             paramTy->getDepth(),
-                                             paramTy->getIndex());
-          paramTy = paramDecl->getDeclaredInterfaceType()
-                     ->castTo<GenericTypeParamType>();
-        }
-
-        paramTypes.push_back(paramTy);
-      }
-      break;
-    }
-
-    default:
+    if (recordID != SIL_GENERIC_ENVIRONMENT) {
       error();
       return result;
     }
+
+    ArrayRef<uint64_t> rawParamIDs;
+    SILGenericEnvironmentLayout::readRecord(scratch, rawParamIDs);
+    lastRecordOffset.reset();
+
+    if (rawParamIDs.size() % 2 != 0) {
+      error();
+      return result;
+    }
+
+    for (unsigned i = 0, n = rawParamIDs.size(); i != n; i += 2) {
+      Identifier name = getIdentifier(rawParamIDs[i]);
+      auto paramTy = getType(rawParamIDs[i+1])->castTo<GenericTypeParamType>();
+
+      if (!name.empty()) {
+        auto paramDecl =
+          createDecl<GenericTypeParamDecl>(getAssociatedModule(),
+                                           name,
+                                           SourceLoc(),
+                                           paramTy->getDepth(),
+                                           paramTy->getIndex());
+        paramTy = paramDecl->getDeclaredInterfaceType()
+                   ->castTo<GenericTypeParamType>();
+      }
+
+      paramTypes.push_back(paramTy);
+    }
+
+    // If there are no parameters, the environment is empty.
+    if (paramTypes.empty()) {
+      if (wantEnvironment)
+        envOrOffset = nullptr;
+
+      return result;
+    }
+
+    // Read the generic requirements.
+    SmallVector<Requirement, 4> requirements;
+    readGenericRequirements(requirements, DeclTypeCursor);
+
+    // Construct the generic signature from the loaded parameters and
+    // requirements.
+    signature = GenericSignature::get(paramTypes, requirements);
   }
 
-  // If there are no parameters, the environment is empty.
-  if (paramTypes.empty()) {
-    if (wantEnvironment)
-      envOrOffset = nullptr;
-
-    return result;
-  }
-
-  // Read the generic requirements.
-  SmallVector<Requirement, 4> requirements;
-  readGenericRequirements(requirements, DeclTypeCursor);
-
-  // Construct the generic signature from the loaded parameters and
-  // requirements.
-  auto signature = GenericSignature::get(paramTypes, requirements);
-
   // If we only want the signature, return it now.
   if (!wantEnvironment) return signature;
 
@@ -1465,23 +1510,13 @@
 
     case XREF_EXTENSION_PATH_PIECE: {
       ModuleID ownerID;
-      ArrayRef<uint64_t> genericParamIDs;
-      XRefExtensionPathPieceLayout::readRecord(scratch, ownerID,
-                                               genericParamIDs);
+      GenericSignatureID rawGenericSig;
+      XRefExtensionPathPieceLayout::readRecord(scratch, ownerID, rawGenericSig);
       M = getModule(ownerID);
       pathTrace.addExtension(M);
 
       // Read the generic signature, if we have one.
-      if (!genericParamIDs.empty()) {
-        SmallVector<GenericTypeParamType *, 4> params;
-        SmallVector<Requirement, 5> requirements;
-        for (TypeID paramID : genericParamIDs) {
-          params.push_back(getType(paramID)->castTo<GenericTypeParamType>());
-        }
-        readGenericRequirements(requirements, DeclTypeCursor);
-
-        genericSig = GenericSignature::getCanonical(params, requirements);
-      }
+      genericSig = CanGenericSignature(getGenericSignature(rawGenericSig));
 
       continue;
     }
@@ -3771,6 +3806,26 @@
   }
 }
 
+/// Translate from the Serialization coroutine kind enum values to the AST
+/// strongly-typed enum.
+///
+/// The former is guaranteed to be stable, but may not reflect this version of
+/// the AST.
+static Optional<swift::SILCoroutineKind>
+getActualSILCoroutineKind(uint8_t rep) {
+  switch (rep) {
+#define CASE(KIND) \
+  case (uint8_t)serialization::SILCoroutineKind::KIND: \
+    return swift::SILCoroutineKind::KIND;
+  CASE(None)
+  CASE(YieldOnce)
+  CASE(YieldMany)
+#undef CASE
+  default:
+    return None;
+  }
+}
+
 /// Translate from the serialization Ownership enumerators, which are
 /// guaranteed to be stable, to the AST ones.
 static
@@ -4248,40 +4303,23 @@
     TypeID resultID;
     uint8_t rawRep;
     bool throws = false;
-    ArrayRef<uint64_t> genericParamIDs;
+    GenericSignatureID rawGenericSig;
 
     decls_block::GenericFunctionTypeLayout::readRecord(scratch,
                                                        inputID,
                                                        resultID,
                                                        rawRep,
                                                        throws,
-                                                       genericParamIDs);
+                                                       rawGenericSig);
     auto rep = getActualFunctionTypeRepresentation(rawRep);
     if (!rep.hasValue()) {
       error();
       return nullptr;
     }
 
-    // Read the generic parameters.
-    SmallVector<GenericTypeParamType *, 4> genericParams;
-    for (auto paramID : genericParamIDs) {
-      auto param = dyn_cast_or_null<GenericTypeParamType>(
-                     getType(paramID).getPointer());
-      if (!param) {
-        error();
-        break;
-      }
-
-      genericParams.push_back(param);
-    }
-    
-    // Read the generic requirements.
-    SmallVector<Requirement, 4> requirements;
-    readGenericRequirements(requirements, DeclTypeCursor);
+    auto sig = getGenericSignature(rawGenericSig);
     auto info = GenericFunctionType::ExtInfo(*rep, throws);
-
-    auto sig = GenericSignature::get(genericParams, requirements);
-
+    
     auto inputTy = getTypeChecked(inputID);
     if (!inputTy)
       return inputTy.takeError();
@@ -4354,23 +4392,29 @@
   }
       
   case decls_block::SIL_FUNCTION_TYPE: {
+    uint8_t rawCoroutineKind;
     uint8_t rawCalleeConvention;
     uint8_t rawRepresentation;
     bool pseudogeneric = false;
     bool noescape;
     bool hasErrorResult;
     unsigned numParams;
+    unsigned numYields;
     unsigned numResults;
+    GenericSignatureID rawGenericSig;
     ArrayRef<uint64_t> variableData;
 
     decls_block::SILFunctionTypeLayout::readRecord(scratch,
+                                             rawCoroutineKind,
                                              rawCalleeConvention,
                                              rawRepresentation,
                                              pseudogeneric,
                                              noescape,
                                              hasErrorResult,
                                              numParams,
+                                             numYields,
                                              numResults,
+                                             rawGenericSig,
                                              variableData);
 
     // Process the ExtInfo.
@@ -4382,6 +4426,13 @@
     }
     SILFunctionType::ExtInfo extInfo(*representation, pseudogeneric, noescape);
 
+    // Process the coroutine kind.
+    auto coroutineKind = getActualSILCoroutineKind(rawCoroutineKind);
+    if (!coroutineKind.hasValue()) {
+      error();
+      return nullptr;
+    }
+
     // Process the callee convention.
     auto calleeConvention = getActualParameterConvention(rawCalleeConvention);
     if (!calleeConvention.hasValue()) {
@@ -4397,6 +4448,14 @@
       return SILParameterInfo(type->getCanonicalType(), *convention);
     };
 
+    auto processYield = [&](TypeID typeID, uint64_t rawConvention)
+                                  -> Optional<SILYieldInfo> {
+      auto convention = getActualParameterConvention(rawConvention);
+      auto type = getType(typeID);
+      if (!convention || !type) return None;
+      return SILYieldInfo(type->getCanonicalType(), *convention);
+    };
+
     auto processResult = [&](TypeID typeID, uint64_t rawConvention)
                                -> Optional<SILResultInfo> {
       auto convention = getActualResultConvention(rawConvention);
@@ -4428,6 +4487,20 @@
       allParams.push_back(*param);
     }
 
+    // Process the yields.
+    SmallVector<SILYieldInfo, 8> allYields;
+    allYields.reserve(numYields);
+    for (unsigned i = 0; i != numYields; ++i) {
+      auto typeID = variableData[nextVariableDataIndex++];
+      auto rawConvention = variableData[nextVariableDataIndex++];
+      auto yield = processYield(typeID, rawConvention);
+      if (!yield) {
+        error();
+        return nullptr;
+      }
+      allYields.push_back(*yield);
+    }
+
     // Process the results.
     SmallVector<SILResultInfo, 8> allResults;
     allParams.reserve(numResults);
@@ -4454,30 +4527,19 @@
       }
     }
 
-    // Process the generic signature parameters.
-    SmallVector<GenericTypeParamType *, 8> genericParamTypes;
-    for (auto id : variableData.slice(nextVariableDataIndex)) {
-      genericParamTypes.push_back(
-                  cast<GenericTypeParamType>(getType(id)->getCanonicalType()));
-    }
-
     Optional<ProtocolConformanceRef> witnessMethodConformance;
     if (*representation == SILFunctionTypeRepresentation::WitnessMethod) {
       witnessMethodConformance = readConformance(DeclTypeCursor);
     }
 
-    // Read the generic requirements, if any.
-    SmallVector<Requirement, 4> requirements;
-    readGenericRequirements(requirements, DeclTypeCursor);
+    GenericSignature *genericSig = getGenericSignature(rawGenericSig);
 
-    GenericSignature *genericSig = nullptr;
-    if (!genericParamTypes.empty() || !requirements.empty())
-      genericSig = GenericSignature::get(genericParamTypes, requirements,
-                                         /*isKnownCanonical=*/true);
-
-    typeOrOffset = SILFunctionType::get(
-        genericSig, extInfo, calleeConvention.getValue(), allParams, allResults,
-        errorResult, ctx, witnessMethodConformance);
+    typeOrOffset = SILFunctionType::get(genericSig, extInfo,
+                                        coroutineKind.getValue(),
+                                        calleeConvention.getValue(),
+                                        allParams, allYields, allResults,
+                                        errorResult,
+                                        ctx, witnessMethodConformance);
     break;
   }
 
@@ -4891,21 +4953,7 @@
 
     // Requirement -> synthetic map.
     SmallVector<Substitution, 4> reqToSyntheticSubs;
-    if (unsigned numGenericParams = *rawIDIter++) {
-      // Generic parameters of the synthetic environment.
-      SmallVector<GenericTypeParamType *, 2> genericParams;
-      while (numGenericParams--) {
-        genericParams.push_back(
-          getType(*rawIDIter++)->castTo<GenericTypeParamType>());
-      }
-
-      // Generic requirements of the synthetic environment.
-      SmallVector<Requirement, 4> requirements;
-      readGenericRequirements(requirements, DeclTypeCursor);
-
-      // Form the generic signature for the synthetic environment.
-      syntheticSig = GenericSignature::get(genericParams, requirements);
-
+    if (auto syntheticSig = getGenericSignature(*rawIDIter++)) {
       // Create the synthetic environment.
       syntheticEnv = syntheticSig->createGenericEnvironment();
 
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index fcdcb48..b1e78e8 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -710,7 +710,7 @@
                   (SILDeclRef::Kind)ListOfValues[NextIdx+1],
                   (swift::ResilienceExpansion)ListOfValues[NextIdx+2],
                   /*isCurried=*/false, ListOfValues[NextIdx+4] > 0);
-  if (ListOfValues[NextIdx+3] < DRef.getUncurryLevel())
+  if (ListOfValues[NextIdx+3] < DRef.getParameterListCount() - 1)
     DRef = DRef.asCurried();
   NextIdx += 5;
   return DRef;
@@ -2112,6 +2112,27 @@
     ResultVal = Builder.createUnreachable(Loc);
     break;
   }
+  case SILInstructionKind::UnwindInst: {
+    ResultVal = Builder.createUnwind(Loc);
+    break;
+  }
+  case SILInstructionKind::YieldInst: {
+    SILBasicBlock *unwindBB = getBBForReference(Fn, ListOfValues.back());
+    ListOfValues = ListOfValues.drop_back();
+    SILBasicBlock *resumeBB = getBBForReference(Fn, ListOfValues.back());
+    ListOfValues = ListOfValues.drop_back();
+
+    SmallVector<SILValue, 4> yieldedValues;
+    for (unsigned I = 0, E = ListOfValues.size(); I < E; I += 3) {
+      auto valueTy = MF->getType(ListOfValues[I]);
+      auto valueCategory = (SILValueCategory) ListOfValues[I+1];
+      yieldedValues.push_back(
+        getLocalValue(ListOfValues[I+2], getSILType(valueTy, valueCategory)));
+    }
+
+    ResultVal = Builder.createYield(Loc, yieldedValues, resumeBB, unwindBB);
+    break;
+  }
   case SILInstructionKind::KeyPathInst: {
     unsigned nextValue = 0;
     SILType kpTy
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index 94c42c2..a9b83c7 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -16,6 +16,7 @@
 #include "swift/Subsystems.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTMangler.h"
+#include "swift/AST/GenericSignature.h"
 #include "swift/AST/ModuleLoader.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/USRGeneration.h"
@@ -842,6 +843,10 @@
         assert(blobData.empty());
         LocalDeclContexts.assign(scratch.begin(), scratch.end());
         break;
+      case index_block::GENERIC_SIGNATURE_OFFSETS:
+        assert(blobData.empty());
+        GenericSignatures.assign(scratch.begin(), scratch.end());
+        break;
       case index_block::GENERIC_ENVIRONMENT_OFFSETS:
         assert(blobData.empty());
         GenericEnvironments.assign(scratch.begin(), scratch.end());
@@ -2170,6 +2175,17 @@
   return File.Bits.HasEntryPoint;
 }
 
+bool SerializedASTFile::getAllGenericSignatures(
+                       SmallVectorImpl<GenericSignature*> &genericSignatures) {
+  genericSignatures.clear();
+  for (unsigned index : indices(File.GenericSignatures)) {
+    if (auto genericSig = File.getGenericSignature(index + 1))
+      genericSignatures.push_back(genericSig);
+  }
+
+  return true;
+}
+
 ClassDecl *SerializedASTFile::getMainClass() const {
   assert(hasEntryPoint());
   return cast_or_null<ClassDecl>(File.getDecl(File.Bits.EntryPointDeclID));
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 524bc75..9b0ec56 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -531,6 +531,19 @@
   return id;
 }
 
+GenericSignatureID Serializer::addGenericSignatureRef(
+                                                const GenericSignature *env) {
+  if (!env) return 0;
+
+  auto &id = GenericSignatureIDs[env];
+  if (id != 0)
+    return id;
+
+  id = ++LastGenericSignatureID;
+  GenericSignaturesToWrite.push(env);
+  return id;
+}
+
 GenericEnvironmentID Serializer::addGenericEnvironmentRef(
                                                 const GenericEnvironment *env) {
   if (!env) return 0;
@@ -759,10 +772,10 @@
   BLOCK_RECORD(index_block, OBJC_METHODS);
   BLOCK_RECORD(index_block, ENTRY_POINT);
   BLOCK_RECORD(index_block, LOCAL_DECL_CONTEXT_OFFSETS);
+  BLOCK_RECORD(index_block, GENERIC_SIGNATURE_OFFSETS);
   BLOCK_RECORD(index_block, GENERIC_ENVIRONMENT_OFFSETS);
   BLOCK_RECORD(index_block, DECL_CONTEXT_OFFSETS);
   BLOCK_RECORD(index_block, LOCAL_TYPE_DECLS);
-  BLOCK_RECORD(index_block, GENERIC_ENVIRONMENT_OFFSETS);
   BLOCK_RECORD(index_block, NORMAL_CONFORMANCE_OFFSETS);
   BLOCK_RECORD(index_block, SIL_LAYOUT_OFFSETS);
   BLOCK_RECORD(index_block, PRECEDENCE_GROUPS);
@@ -1349,6 +1362,31 @@
   return true;
 }
 
+void Serializer::writeGenericSignature(const GenericSignature *sig) {
+  using namespace decls_block;
+
+  // Record the offset of this generic environment.
+  auto id = GenericSignatureIDs[sig];
+  assert(id != 0 && "generic signature not referenced properly");
+  (void)id;
+
+  assert((id - 1) == GenericSignatureOffsets.size());
+  GenericSignatureOffsets.push_back(Out.GetCurrentBitNo());
+
+  assert(sig != nullptr);
+
+  // Record the generic parameters.
+  SmallVector<uint64_t, 4> rawParamIDs;
+  for (auto *paramTy : sig->getGenericParams()) {
+    rawParamIDs.push_back(addTypeRef(paramTy));
+  }
+
+  auto abbrCode = DeclTypeAbbrCodes[GenericSignatureLayout::Code];
+  GenericSignatureLayout::emitRecord(Out, ScratchRecord, abbrCode, rawParamIDs);
+
+  writeGenericRequirements(sig->getRequirements(), DeclTypeAbbrCodes);
+}
+
 void Serializer::writeGenericEnvironment(const GenericEnvironment *env) {
   using namespace decls_block;
 
@@ -1358,10 +1396,7 @@
   (void)id;
 
   assert((id - 1) == GenericEnvironmentOffsets.size());
-  GenericEnvironmentOffsets.push_back(Out.GetCurrentBitNo());
-
-  if (env == nullptr)
-    return;
+  assert(env != nullptr);
 
   // Determine whether we must use SIL mode, because one of the generic
   // parameters has a declaration with module context.
@@ -1375,33 +1410,36 @@
     }
   }
 
+  // If not in SIL mode, generic environments just contain a reference to
+  // the generic signature.
+  if (!SILMode) {
+    // Record the generic signature directly.
+    auto genericSigID = addGenericSignatureRef(env->getGenericSignature());
+    GenericEnvironmentOffsets.push_back((genericSigID << 1) | 0x01);
+    return;
+  }
+
+  // Record the current bit.
+  GenericEnvironmentOffsets.push_back((Out.GetCurrentBitNo() << 1));
+
   // Record the generic parameters.
   SmallVector<uint64_t, 4> rawParamIDs;
   for (auto *paramTy : env->getGenericParams()) {
     auto *decl = paramTy->getDecl();
 
     // In SIL mode, add the name and canonicalize the parameter type.
-    if (SILMode) {
-      if (decl)
-        rawParamIDs.push_back(addDeclBaseNameRef(decl->getName()));
-      else
-        rawParamIDs.push_back(addDeclBaseNameRef(Identifier()));
+    if (decl)
+      rawParamIDs.push_back(addDeclBaseNameRef(decl->getName()));
+    else
+      rawParamIDs.push_back(addDeclBaseNameRef(Identifier()));
 
-      paramTy = paramTy->getCanonicalType()->castTo<GenericTypeParamType>();
-    }
-
+    paramTy = paramTy->getCanonicalType()->castTo<GenericTypeParamType>();
     rawParamIDs.push_back(addTypeRef(paramTy));
   }
 
-  if (SILMode) {
-    auto envAbbrCode = DeclTypeAbbrCodes[SILGenericEnvironmentLayout::Code];
-    SILGenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode,
-                                            rawParamIDs);
-  } else {
-    auto envAbbrCode = DeclTypeAbbrCodes[GenericEnvironmentLayout::Code];
-    GenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode,
-                                         rawParamIDs);
-  }
+  auto envAbbrCode = DeclTypeAbbrCodes[SILGenericEnvironmentLayout::Code];
+  SILGenericEnvironmentLayout::emitRecord(Out, ScratchRecord, envAbbrCode,
+                                          rawParamIDs);
 
   writeGenericRequirements(env->getGenericSignature()->getRequirements(),
                            DeclTypeAbbrCodes);
@@ -1425,22 +1463,14 @@
     data.push_back(typeRef);
   }
   
-  // Save generic params.
-  if (auto sig = layout->getGenericSignature()) {
-    for (auto param : sig->getGenericParams()) {
-      data.push_back(addTypeRef(param));
-    }
-  }
-  
   unsigned abbrCode
     = DeclTypeAbbrCodes[SILLayoutLayout::Code];
 
-  SILLayoutLayout::emitRecord(Out, ScratchRecord, abbrCode,
-                              layout->getFields().size(),
-                              data);
-  // Emit requirements.
-  if (auto sig = layout->getGenericSignature())
-    writeGenericRequirements(sig->getRequirements(), DeclTypeAbbrCodes);
+  SILLayoutLayout::emitRecord(
+                        Out, ScratchRecord, abbrCode,
+                        addGenericSignatureRef(layout->getGenericSignature()),
+                        layout->getFields().size(),
+                        data);
 }
 
 void Serializer::writeNormalConformance(
@@ -1477,19 +1507,14 @@
       if (auto genericEnv = witness.requiresSubstitution() 
                               ? witness.getSyntheticEnvironment()
                               : nullptr) {
+        // Generic signature.
         auto *genericSig = genericEnv->getGenericSignature();
-
-        // Generic parameters.
-        data.push_back(genericSig->getGenericParams().size());
-        for (auto gp : genericSig->getGenericParams())
-          data.push_back(addTypeRef(gp));
+        data.push_back(addGenericSignatureRef(genericSig));
 
         auto reqToSyntheticSubs = witness.getRequirementToSyntheticSubs();
         data.push_back(reqToSyntheticSubs.size());
-
-        // Requirements come at the end.
       } else {
-        data.push_back(/*number of generic parameters*/0);
+        data.push_back(/*null generic signature*/0);
       }
 
       data.push_back(witness.getSubstitutions().size());
@@ -1531,12 +1556,6 @@
    if (auto genericEnv = witness.requiresSubstitution() 
                            ? witness.getSyntheticEnvironment()
                            : nullptr) {
-     auto *genericSig = genericEnv->getGenericSignature();
-
-     // Write the generic requirements of the synthetic environment.
-     writeGenericRequirements(genericSig->getRequirements(),
-                              DeclTypeAbbrCodes);
-
      // Write requirement-to-synthetic substitutions.
      writeSubstitutions(witness.getRequirementToSyntheticSubs(),
                         DeclTypeAbbrCodes,
@@ -1866,21 +1885,13 @@
     writeCrossReference(baseTy->getAnyNominal(), pathLen + 1);
 
     abbrCode = DeclTypeAbbrCodes[XRefExtensionPathPieceLayout::Code];
-    SmallVector<TypeID, 4> genericParams;
     CanGenericSignature genericSig(nullptr);
     if (ext->isConstrainedExtension()) {
       genericSig = ext->getGenericSignature()->getCanonicalSignature();
-      for (auto param : genericSig->getGenericParams())
-        genericParams.push_back(addTypeRef(param));
     }
     XRefExtensionPathPieceLayout::emitRecord(
         Out, ScratchRecord, abbrCode, addModuleRef(DC->getParentModule()),
-        genericParams);
-
-    if (genericSig) {
-      writeGenericRequirements(genericSig->getRequirements(),
-                               DeclTypeAbbrCodes);
-    }
+        addGenericSignatureRef(genericSig));
     break;
   }
 
@@ -3354,6 +3365,18 @@
   llvm_unreachable("bad calling convention");
 }
 
+/// Translate from the AST coroutine-kind enum to the Serialization enum
+/// values, which are guaranteed to be stable.
+static uint8_t getRawStableSILCoroutineKind(
+                                    swift::SILCoroutineKind kind) {
+  switch (kind) {
+  SIMPLE_CASE(SILCoroutineKind, None)
+  SIMPLE_CASE(SILCoroutineKind, YieldOnce)
+  SIMPLE_CASE(SILCoroutineKind, YieldMany)
+  }
+  llvm_unreachable("bad kind");
+}
+
 /// Translate from the AST ownership enum to the Serialization enum
 /// values, which are guaranteed to be stable.
 static uint8_t getRawStableOwnership(swift::Ownership ownership) {
@@ -3616,19 +3639,12 @@
   case TypeKind::GenericFunction: {
     auto fnTy = cast<GenericFunctionType>(ty.getPointer());
     unsigned abbrCode = DeclTypeAbbrCodes[GenericFunctionTypeLayout::Code];
-    SmallVector<TypeID, 4> genericParams;
-    for (auto param : fnTy->getGenericParams())
-      genericParams.push_back(addTypeRef(param));
     GenericFunctionTypeLayout::emitRecord(Out, ScratchRecord, abbrCode,
             addTypeRef(fnTy->getInput()),
             addTypeRef(fnTy->getResult()),
             getRawStableFunctionTypeRepresentation(fnTy->getRepresentation()),
             fnTy->throws(),
-            genericParams);
-
-    // Write requirements.
-    writeGenericRequirements(fnTy->getRequirements(),
-                             DeclTypeAbbrCodes);
+            addGenericSignatureRef(fnTy->getGenericSignature()));
     break;
   }
       
@@ -3674,6 +3690,11 @@
       unsigned conv = getRawStableParameterConvention(param.getConvention());
       variableData.push_back(TypeID(conv));
     }
+    for (auto yield : fnTy->getYields()) {
+      variableData.push_back(addTypeRef(yield.getType()));
+      unsigned conv = getRawStableParameterConvention(yield.getConvention());
+      variableData.push_back(TypeID(conv));
+    }
     for (auto result : fnTy->getResults()) {
       variableData.push_back(addTypeRef(result.getType()));
       unsigned conv = getRawStableResultConvention(result.getConvention());
@@ -3687,27 +3708,25 @@
     }
 
     auto sig = fnTy->getGenericSignature();
-    if (sig) {
-      for (auto param : sig->getGenericParams())
-        variableData.push_back(addTypeRef(param));
-    }
+
+    auto stableCoroutineKind = 
+      getRawStableSILCoroutineKind(fnTy->getCoroutineKind());
 
     auto stableCalleeConvention =
       getRawStableParameterConvention(fnTy->getCalleeConvention());
 
     unsigned abbrCode = DeclTypeAbbrCodes[SILFunctionTypeLayout::Code];
     SILFunctionTypeLayout::emitRecord(
-        Out, ScratchRecord, abbrCode, stableCalleeConvention,
+        Out, ScratchRecord, abbrCode,
+        stableCoroutineKind, stableCalleeConvention,
         stableRepresentation, fnTy->isPseudogeneric(), fnTy->isNoEscape(),
         fnTy->hasErrorResult(), fnTy->getParameters().size(),
-        fnTy->getNumResults(), variableData);
+        fnTy->getNumYields(), fnTy->getNumResults(),
+        addGenericSignatureRef(sig), variableData);
 
     if (auto conformance = fnTy->getWitnessMethodConformanceOrNone())
       writeConformance(*conformance, DeclTypeAbbrCodes);
 
-    if (sig)
-      writeGenericRequirements(sig->getRequirements(),
-                               DeclTypeAbbrCodes);
     break;
   }
       
@@ -3891,7 +3910,7 @@
   registerDeclTypeAbbr<GenericParamLayout>();
   registerDeclTypeAbbr<GenericRequirementLayout>();
   registerDeclTypeAbbr<LayoutRequirementLayout>();
-  registerDeclTypeAbbr<GenericEnvironmentLayout>();
+  registerDeclTypeAbbr<GenericSignatureLayout>();
   registerDeclTypeAbbr<SILGenericEnvironmentLayout>();
 
   registerDeclTypeAbbr<ForeignErrorConventionLayout>();
@@ -3951,6 +3970,12 @@
       writeDeclContext(next);
     }
 
+    while (!GenericSignaturesToWrite.empty()) {
+      auto next = GenericSignaturesToWrite.front();
+      GenericSignaturesToWrite.pop();
+      writeGenericSignature(next);
+    }
+
     while (!GenericEnvironmentsToWrite.empty()) {
       auto next = GenericEnvironmentsToWrite.front();
       GenericEnvironmentsToWrite.pop();
@@ -3972,6 +3997,7 @@
            !LocalDeclContextsToWrite.empty() ||
            !DeclContextsToWrite.empty() ||
            !SILLayoutsToWrite.empty() ||
+           !GenericSignaturesToWrite.empty() ||
            !GenericEnvironmentsToWrite.empty() ||
            !NormalConformancesToWrite.empty());
 }
@@ -4769,6 +4795,7 @@
     writeOffsets(Offsets, IdentifierOffsets);
     writeOffsets(Offsets, DeclContextOffsets);
     writeOffsets(Offsets, LocalDeclContextOffsets);
+    writeOffsets(Offsets, GenericSignatureOffsets);
     writeOffsets(Offsets, GenericEnvironmentOffsets);
     writeOffsets(Offsets, NormalConformanceOffsets);
     writeOffsets(Offsets, SILLayoutOffsets);
diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h
index 59a3eba..340f88a 100644
--- a/lib/Serialization/Serialization.h
+++ b/lib/Serialization/Serialization.h
@@ -100,6 +100,10 @@
   /// A map from local DeclContexts to their serialized IDs.
   llvm::DenseMap<const DeclContext*, DeclContextID> LocalDeclContextIDs;
 
+  /// A map from generic signatures to their serialized IDs.
+  llvm::DenseMap<const GenericSignature *, GenericSignatureID>
+    GenericSignatureIDs;
+
   /// A map from generic environments to their serialized IDs.
   llvm::DenseMap<const GenericEnvironment *, GenericEnvironmentID>
     GenericEnvironmentIDs;
@@ -167,6 +171,9 @@
   /// Local DeclContexts that need to be serialized.
   std::queue<const DeclContext*> LocalDeclContextsToWrite;
 
+  /// Generic signatures that need to be serialized.
+  std::queue<const GenericSignature *> GenericSignaturesToWrite;
+
   /// Generic environments that need to be serialized.
   std::queue<const GenericEnvironment*> GenericEnvironmentsToWrite;
 
@@ -202,6 +209,10 @@
   /// IdentifierID.
   std::vector<CharOffset> IdentifierOffsets;
 
+  /// The offset of each GenericSignature in the bitstream, indexed by
+  /// GenericSignatureID.
+  std::vector<BitOffset> GenericSignatureOffsets;
+
   /// The offset of each GenericEnvironment in the bitstream, indexed by
   /// GenericEnvironmentID.
   std::vector<BitOffset> GenericEnvironmentOffsets;
@@ -242,6 +253,10 @@
   uint32_t /*IdentifierID*/ LastIdentifierID =
       serialization::NUM_SPECIAL_IDS - 1;
 
+  /// The last assigned GenericSignatureID for generic signature from this
+  /// module.
+  uint32_t /*GenericSignatureID*/ LastGenericSignatureID = 0;
+
   /// The last assigned GenericEnvironmentID for generic environments from this
   /// module.
   uint32_t /*GenericEnvironmentID*/ LastGenericEnvironmentID = 0;
@@ -261,6 +276,8 @@
       return index_block::DECL_CONTEXT_OFFSETS;
     if (&values == &LocalDeclContextOffsets)
       return index_block::LOCAL_DECL_CONTEXT_OFFSETS;
+    if (&values == &GenericSignatureOffsets)
+      return index_block::GENERIC_SIGNATURE_OFFSETS;
     if (&values == &GenericEnvironmentOffsets)
       return index_block::GENERIC_ENVIRONMENT_OFFSETS;
     if (&values == &NormalConformanceOffsets)
@@ -354,6 +371,9 @@
   /// Writes the given type.
   void writeType(Type ty);
 
+  /// Writes a generic signature.
+  void writeGenericSignature(const GenericSignature *sig);
+
   /// Writes a generic environment.
   void writeGenericEnvironment(const GenericEnvironment *env);
 
@@ -436,6 +456,11 @@
   /// The DeclContext will be scheduled for serialization if necessary.
   DeclContextID addLocalDeclContextRef(const DeclContext *DC);
 
+  /// Records the use of the given generic signature.
+  ///
+  /// The GenericSignature will be scheduled for serialization if necessary.
+  GenericSignatureID addGenericSignatureRef(const GenericSignature *sig);
+
   /// Records the use of the given generic environment.
   ///
   /// The GenericEnvironment will be scheduled for serialization if necessary.
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index 237f38f..02317e9 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -482,7 +482,7 @@
   ListOfValues.push_back(S.addDeclRef(Ref.getDecl()));
   ListOfValues.push_back((unsigned)Ref.kind);
   ListOfValues.push_back((unsigned)Ref.getResilienceExpansion());
-  ListOfValues.push_back(Ref.getUncurryLevel());
+  ListOfValues.push_back(Ref.getParameterListCount() - 1);
   ListOfValues.push_back(Ref.isForeign);
 }
 
@@ -582,6 +582,7 @@
     // TODO: decide if we want to serialize those instructions.
     return;
       
+  case SILInstructionKind::UnwindInst:
   case SILInstructionKind::UnreachableInst: {
     unsigned abbrCode = SILAbbrCodes[SILInstNoOperandLayout::Code];
     SILInstNoOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
@@ -1124,6 +1125,21 @@
     writeOneOperandLayout(SI.getKind(), Attr, SI.getOperand(0));
     break;
   }
+  case SILInstructionKind::YieldInst: {
+    auto YI = cast<YieldInst>(&SI);
+    SmallVector<ValueID, 4> args;
+    for (auto arg: YI->getYieldedValues()) {
+      args.push_back(S.addTypeRef(arg->getType().getSwiftRValueType()));
+      args.push_back((unsigned)arg->getType().getCategory());
+      args.push_back(addValueRef(arg));
+    }
+    args.push_back(BasicBlockMap[YI->getResumeBB()]);
+    args.push_back(BasicBlockMap[YI->getUnwindBB()]);
+    SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
+        SILAbbrCodes[SILOneTypeValuesLayout::Code],
+        (unsigned)YI->getKind(), 0, 0, args);
+    break;
+  }
   case SILInstructionKind::FunctionRefInst: {
     // Use SILOneOperandLayout to specify the function type and the function
     // name (IdentifierID).
diff --git a/lib/Syntax/SyntaxFactory.cpp.gyb b/lib/Syntax/SyntaxFactory.cpp.gyb
index b534351..f57d2361 100644
--- a/lib/Syntax/SyntaxFactory.cpp.gyb
+++ b/lib/Syntax/SyntaxFactory.cpp.gyb
@@ -57,6 +57,18 @@
   return make<UnknownSyntax>(Raw);
 }
 
+Syntax SyntaxFactory::makeBlankCollectionSyntax(SyntaxKind Kind) {
+  switch(Kind) {
+% for node in SYNTAX_NODES:
+%   if node.is_syntax_collection():
+  case SyntaxKind::${node.syntax_kind}: return makeBlank${node.syntax_kind}();
+%   end
+% end
+  default: break;
+  }
+  llvm_unreachable("not collection kind.");
+}
+
 Optional<Syntax>
 SyntaxFactory::createSyntax(SyntaxKind Kind, llvm::ArrayRef<Syntax> Elements) {
   switch(Kind) {
diff --git a/lib/Syntax/SyntaxParsingContext.cpp b/lib/Syntax/SyntaxParsingContext.cpp
index eb8e495..04b50d9 100644
--- a/lib/Syntax/SyntaxParsingContext.cpp
+++ b/lib/Syntax/SyntaxParsingContext.cpp
@@ -56,19 +56,34 @@
   assert(StartLoc.isValid() == EndLoc.isValid());
   return SourceRange(StartLoc, EndLoc);
 }
+
+static RawSyntaxInfo createSyntaxAs(ArrayRef<RawSyntaxInfo> Parts,
+                                    SyntaxKind Kind) {
+  llvm::SmallVector<Syntax, 8> Scratch;
+  auto SyntaxParts = getSyntaxNodes(Parts, Scratch);
+
+  // Try to create the node of the given syntax.
+  Optional<Syntax> Result = SyntaxFactory::createSyntax(Kind, SyntaxParts);
+  if (!Result) {
+
+    // If unable to create, we should create an unknown node.
+    Result.emplace(makeUnknownSyntax(SyntaxFactory::getUnknownKind(Kind),
+                                     SyntaxParts));
+  }
+  return { getNodesRange(Parts), Result->getRaw() };
+}
 } // End of anonymous namespace
 
 struct SyntaxParsingContext::ContextInfo {
   bool Enabled;
 private:
   SourceLoc ContextStartLoc;
-  SourceLoc ContextEndLoc;
   std::vector<RawSyntaxInfo> PendingSyntax;
 
   // All tokens after the start of this context.
   ArrayRef<RawSyntaxInfo> Tokens;
 
-  ArrayRef<RawSyntaxInfo>::const_iterator findTokenAt(SourceLoc Loc) {
+  ArrayRef<RawSyntaxInfo>::const_iterator findTokenAt(SourceLoc Loc) const {
     for (auto It = Tokens.begin(); It != Tokens.end(); It ++) {
       assert(It->getStartLoc() == It->getEndLoc());
       if (It->getStartLoc() == Loc)
@@ -96,10 +111,13 @@
   }
 
   // Squash N syntax nodex from the back of the pending list into one.
-  void createFromBack(SyntaxKind Kind, unsigned N = 0);
-  std::vector<RawSyntaxInfo> collectAllSyntax();
+  void createFromBackTokens(SyntaxKind Kind, ArrayRef<RawSyntaxInfo> UsedTokens,
+                            unsigned N);
+  void createWhole(SyntaxKind Kind, ArrayRef<RawSyntaxInfo> NodesToUse);
+  std::vector<RawSyntaxInfo> collectAllSyntax(SourceLoc EndLoc);
   ArrayRef<RawSyntaxInfo> allTokens() const { return Tokens; }
-  ArrayRef<RawSyntaxInfo> getPendingSyntax() const { return PendingSyntax; };
+  ArrayRef<RawSyntaxInfo> getPendingSyntax() const { return PendingSyntax; }
+  SourceLoc getContextStartLoc() const { return ContextStartLoc; }
 
   void addPendingSyntax(RawSyntaxInfo Info) {
     assert(Info.isImplicit() || PendingSyntax.empty() ||
@@ -114,42 +132,65 @@
     Tokens = Tokens.slice(findTokenAt(Loc) - Tokens.begin());
   }
 
-  void setContextEnd(SourceLoc Loc) {
-    assert(ContextEndLoc.isInvalid());
-    ContextEndLoc = Loc;
-    Tokens = Tokens.take_front(findTokenAt(Loc) - Tokens.begin());
-  }
-
-  void promoteTokenAt(SourceLoc Loc) {
-    PendingSyntax.push_back(*findTokenAt(Loc));
+  ArrayRef<RawSyntaxInfo> dropTokenAt(SourceLoc Loc) const {
+    return Tokens.take_front(findTokenAt(Loc) - Tokens.begin());
   }
 
   // Check if the pending syntax is a token syntax in the given kind.
-  bool checkTokenFromBack(tok Kind, unsigned OffsetFromBack = 0) {
-    if (PendingSyntax.size() - 1 < OffsetFromBack)
+  bool checkTokenFromBack(tok Kind, ArrayRef<RawSyntaxInfo> UsedTokens,
+                          unsigned OffsetFromBack = 0) {
+    if (UsedTokens.size() - 1 < OffsetFromBack)
       return false;
-    auto Back = PendingSyntax[PendingSyntax.size() - 1 - OffsetFromBack].
+    auto Back = UsedTokens[UsedTokens.size() - 1 - OffsetFromBack].
       makeSyntax<Syntax>().getAs<TokenSyntax>();
     return Back.hasValue() && Back->getTokenKind() == Kind;
   }
 };
 
+static void addNodeToResults(std::vector<RawSyntaxInfo> &Results,
+                             std::vector<RawSyntaxInfo> &ImplicitNodes,
+                             RawSyntaxInfo Info) {
+  // Add implicit nodes before adding the explicit nodes they attach to.
+  assert(!Info.isImplicit());
+  auto StartSize = Results.size();
+
+  // Find all implicit nodes where the attach-to location is the start position
+  // of this non-implicit nodes.
+  Results.insert(Results.end(),
+                 std::find_if(ImplicitNodes.begin(), ImplicitNodes.end(),
+                   [&](const RawSyntaxInfo &Imp) {
+                     return Imp.BeforeLoc == Info.getStartLoc();
+                   }),
+                 ImplicitNodes.end());
+
+  // If any implicit nodes are inserted to results, we should clear the buffer
+  // to avoid re-inserting them.
+  if (StartSize != Results.size()) {
+    ImplicitNodes.clear();
+  }
+
+  // Add the non-implicit node.
+  Results.emplace_back(Info);
+}
+
 std::vector<RawSyntaxInfo>
-SyntaxParsingContext::ContextInfo::collectAllSyntax() {
+SyntaxParsingContext::ContextInfo::collectAllSyntax(SourceLoc EndLoc) {
   std::vector<RawSyntaxInfo> Results;
+  std::vector<RawSyntaxInfo> ImplicitNodes;
   auto CurSyntax = PendingSyntax.begin();
-  for (auto It = Tokens.begin(); It != Tokens.end();) {
+  for (auto It = Tokens.begin(); It->getStartLoc() != EndLoc;) {
     auto Tok = *It;
     if (CurSyntax == PendingSyntax.end()) {
       // If no remaining syntax nodes, add the token.
-      Results.emplace_back(Tok);
+      addNodeToResults(Results, ImplicitNodes, Tok);
       It ++;
     } else if (CurSyntax->isImplicit()) {
+      ImplicitNodes.emplace_back(*CurSyntax);
       // Skip implicit syntax node.
       CurSyntax ++;
     } else if (CurSyntax->getStartLoc() == Tok.getStartLoc()) {
       // Prefer syntax nodes to tokens.
-      Results.emplace_back(*CurSyntax);
+      addNodeToResults(Results, ImplicitNodes, *CurSyntax);
       while(It->getEndLoc() != CurSyntax->getEndLoc()) It++;
       assert(It < Tokens.end() && It->getEndLoc() == CurSyntax->getEndLoc());
       It ++;
@@ -159,7 +200,7 @@
       // started.
       assert(Tok.getStartLoc().getOpaquePointerValue() <
              CurSyntax->getStartLoc().getOpaquePointerValue());
-      Results.push_back(Tok);
+      addNodeToResults(Results, ImplicitNodes, Tok);
       It ++;
     }
   }
@@ -170,40 +211,30 @@
   return Results;
 }
 
-void
-SyntaxParsingContext::ContextInfo::createFromBack(SyntaxKind Kind, unsigned N) {
-  auto Size = PendingSyntax.size();
-  if (!N)
-    N = Size;
-  assert(Size >= N);
-  auto Parts = llvm::makeArrayRef(PendingSyntax).slice(Size - N);
-  llvm::SmallVector<Syntax, 8> Scratch;
-  auto SyntaxParts = getSyntaxNodes(Parts, Scratch);
+void SyntaxParsingContext::ContextInfo::
+createFromBackTokens(SyntaxKind Kind, ArrayRef<RawSyntaxInfo> UsedTokens,
+                     unsigned N) {
+  auto Size = UsedTokens.size();
+  assert(N && Size >= N);
+  auto Parts = llvm::makeArrayRef(UsedTokens).slice(Size - N);
+  addPendingSyntax(createSyntaxAs(Parts, Kind));
+}
 
-  // Try to create the node of the given syntax.
-  Optional<Syntax> Result = SyntaxFactory::createSyntax(Kind, SyntaxParts);
-  if (!Result) {
-
-    // If unable to create, we should create an unknown node.
-    Result.emplace(makeUnknownSyntax(SyntaxFactory::getUnknownKind(Kind),
-                                     SyntaxParts));
-  }
-  RawSyntaxInfo NewSyntaxNode(getNodesRange(Parts), Result->getRaw());
-
-  // Remove the building bricks and re-append the result.
-  for (unsigned I = 0; I < N; I ++)
-    PendingSyntax.pop_back();
-  addPendingSyntax(NewSyntaxNode);
-  assert(Size - N + 1 == PendingSyntax.size());
+void SyntaxParsingContext::ContextInfo::
+createWhole(SyntaxKind Kind, ArrayRef<RawSyntaxInfo> NodesToUse) {
+  auto Result = createSyntaxAs(NodesToUse, Kind);
+  PendingSyntax.clear();
+  addPendingSyntax(Result);
 }
 
 SyntaxParsingContext::
 SyntaxParsingContext(SourceFile &SF, unsigned BufferID, Token &Tok):
-  ContextData(*new ContextInfo(SF, BufferID)), Tok(Tok) {}
+  ContextData(*new ContextInfo(SF, BufferID)),
+    Tok(Tok) {}
 
 SyntaxParsingContext::SyntaxParsingContext(SyntaxParsingContext &Another):
   ContextData(*new ContextInfo(Another.ContextData.allTokens(),
-                               Another.ContextData.Enabled)), Tok(Another.Tok) {}
+    Another.ContextData.Enabled)), Tok(Another.Tok) {}
 
 SyntaxParsingContext::~SyntaxParsingContext() { delete &ContextData; }
 
@@ -250,15 +281,11 @@
     ContextData.setContextStart(Tok.getLoc());
 }
 
-
-void SyntaxParsingContextChild::addTokenSyntax(SourceLoc Loc) {
-  if (ContextData.Enabled)
-    ContextData.promoteTokenAt(Loc);
-}
-
-void SyntaxParsingContextChild::makeNode(SyntaxKind Kind) {
+void SyntaxParsingContextChild::makeNode(SyntaxKind Kind, SourceLoc LastTokLoc) {
   if (!ContextData.Enabled)
     return;
+  auto UsedTokens = ContextData.dropTokenAt(LastTokLoc);
+  UsedTokens = llvm::makeArrayRef(UsedTokens.data(), UsedTokens.size() + 1);
 
   // Create syntax nodes according to the given kind.
   switch (Kind) {
@@ -266,12 +293,12 @@
   case SyntaxKind::IntegerLiteralExpr: {
     // Integer may include the signs before the digits, so check if the sign
     // exists and create.
-    ContextData.createFromBack(Kind, ContextData.
-      checkTokenFromBack(tok::oper_prefix, 1) ? 2 : 1);
+    ContextData.createFromBackTokens(Kind, UsedTokens, ContextData.
+      checkTokenFromBack(tok::oper_prefix, UsedTokens, 1) ? 2 : 1);
     break;
   }
   case SyntaxKind::StringLiteralExpr: {
-    ContextData.createFromBack(Kind, 1);
+    ContextData.createFromBackTokens(Kind, UsedTokens, 1);
     break;
   }
 
@@ -282,17 +309,24 @@
 
 void SyntaxParsingContextChild::makeNodeWhole(SyntaxKind Kind) {
   assert(ContextData.Enabled);
+  auto EndLoc = Tok.getLoc();
+  auto AllNodes = ContextData.collectAllSyntax(EndLoc);
   switch (Kind) {
+  case SyntaxKind::FunctionCallArgument:
   case SyntaxKind::CodeBlock: {
-    ContextData.createFromBack(Kind);
+    ContextData.createWhole(Kind, AllNodes);
     break;
   }
-  case SyntaxKind::StmtList: {
-    if (ContextData.getPendingSyntax().empty()) {
-      // Create an empty statement list if no statement is in the context.
-      ContextData.addPendingSyntax({SyntaxFactory::makeBlankStmtList().getRaw()});
+  case SyntaxKind::StmtList:
+  case SyntaxKind::FunctionCallArgumentList: {
+    if (AllNodes.empty()) {
+      // Create an empty argument list if no arguments are in the context.
+      RawSyntaxInfo Empty(SyntaxFactory::
+                          makeBlankCollectionSyntax(Kind).getRaw());
+      Empty.setBeforeLoc(EndLoc);
+      ContextData.addPendingSyntax(Empty);
     } else {
-      ContextData.createFromBack(Kind);
+      ContextData.createWhole(Kind, AllNodes);
     }
     break;
   }
@@ -335,26 +369,22 @@
   if (!ContextData.Enabled)
     return;
 
-  // Set the end of the context.
-  ContextData.setContextEnd(Tok.getLoc());
+  SourceLoc EndLoc = Tok.getLoc();
   if (KnownSyntax) {
     // If the entire context should be created to a known syntax kind, create
     // all pending syntax nodes into that node.
     makeNodeWhole(*KnownSyntax);
     assert(ContextData.getPendingSyntax().size() == 1);
-    auto AllNodes = ContextData.collectAllSyntax();
-    assert(AllNodes.size() == 1);
-    Parent->ContextData.addPendingSyntax(AllNodes.front());
+    Parent->ContextData.addPendingSyntax(ContextData.getPendingSyntax().front());
     return;
   }
-  auto AllNodes = ContextData.collectAllSyntax();
+  auto AllNodes = ContextData.collectAllSyntax(EndLoc);
   RC<RawSyntax> FinalResult;
   if (AllNodes.empty())
     return;
 
   // Make sure we used all tokens.
-  assert(AllNodes.front().getStartLoc() == ContextData.allTokens().front().getStartLoc());
-  assert(AllNodes.back().getEndLoc() == ContextData.allTokens().back().getStartLoc());
+  assert(AllNodes.front().getStartLoc() == ContextData.getContextStartLoc());
 
   if (AllNodes.size() == 1) {
     // If we have only one syntax node remaining, we are done.
diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h
index 29b78b9..8c9ae82 100644
--- a/stdlib/public/SwiftShims/HeapObject.h
+++ b/stdlib/public/SwiftShims/HeapObject.h
@@ -16,8 +16,7 @@
 #include "System.h"
 
 #define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64 16
-// TODO: Should be 8
-#define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32 12
+#define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32 8
 
 #ifdef __cplusplus
 #include <type_traits>
@@ -39,12 +38,12 @@
   InlineRefCounts refCounts
 
 /// The Swift heap-object header.
+/// This must match RefCountedStructTy in IRGen.
 struct HeapObject {
   /// This is always a valid pointer to a metadata object.
   HeapMetadata const *metadata;
 
   SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;
-  // FIXME: allocate two words of metadata on 32-bit platforms
 
 #ifdef __cplusplus
   HeapObject() = default;
@@ -75,15 +74,8 @@
 static_assert(std::is_trivially_destructible<HeapObject>::value,
               "HeapObject must be trivially destructible");
 
-// FIXME: small header for 32-bit
-//static_assert(sizeof(HeapObject) == 2*sizeof(void*),
-//              "HeapObject must be two pointers long");
-//
-static_assert(sizeof(HeapObject) ==
-  (sizeof(void*) == 8 ? SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64 :
-   sizeof(void*) == 4 ? SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32 :
-   0 && "unexpected pointer size"),
-  "HeapObject must match ABI heap object header size");
+static_assert(sizeof(HeapObject) == 2*sizeof(void*),
+              "HeapObject must be two pointers long");
 
 static_assert(alignof(HeapObject) == alignof(void*),
               "HeapObject must be pointer-aligned");
diff --git a/stdlib/public/SwiftShims/RefCount.h b/stdlib/public/SwiftShims/RefCount.h
index 211de02..e1cd7aa 100644
--- a/stdlib/public/SwiftShims/RefCount.h
+++ b/stdlib/public/SwiftShims/RefCount.h
@@ -15,19 +15,17 @@
 #include "Visibility.h"
 #include "SwiftStdint.h"
 
+// This definition is a placeholder for importing into Swift.
+// It provides size and alignment but cannot be manipulated safely there.
+typedef struct {
+  __swift_uintptr_t refCounts SWIFT_ATTRIBUTE_UNAVAILABLE;
+} InlineRefCountsPlaceholder;
+
 #if !defined(__cplusplus)
 
-// These definitions are placeholders for importing into Swift.
-// They provide size and alignment but cannot be manipulated safely there.
+typedef InlineRefCountsPlaceholder InlineRefCounts;
 
-typedef struct {
-  _Alignas(__swift_uintptr_t) __swift_uint32_t refCounts1 SWIFT_ATTRIBUTE_UNAVAILABLE;
-  __swift_uint32_t refCounts2 SWIFT_ATTRIBUTE_UNAVAILABLE;
-} InlineRefCounts;
-
-// not __cplusplus
 #else
-// __cplusplus
 
 #include <type_traits>
 #include <atomic>
@@ -733,11 +731,6 @@
 template <typename RefCountBits>
 class RefCounts {
   std::atomic<RefCountBits> refCounts;
-#if __POINTER_WIDTH__ == 32
-  // FIXME: hack - something somewhere is assuming a 3-word header on 32-bit
-  // See also other fixmes marked "small header for 32-bit"
-  uintptr_t : 32;
-#endif
 
   // Out-of-line slow paths.
 
@@ -1572,15 +1565,11 @@
 #endif
 
 // These assertions apply to both the C and the C++ declarations.
-_Static_assert(_Alignof(InlineRefCounts) == _Alignof(__swift_uintptr_t),
-  "InlineRefCounts must be pointer-aligned");
-// FIXME: small header for 32-bit
-#if 0
+_Static_assert(sizeof(InlineRefCounts) == sizeof(InlineRefCountsPlaceholder),
+  "InlineRefCounts and InlineRefCountsPlaceholder must match");
 _Static_assert(sizeof(InlineRefCounts) == sizeof(__swift_uintptr_t),
   "InlineRefCounts must be pointer-sized");
-#else
-_Static_assert(sizeof(InlineRefCounts) == 2*sizeof(__swift_uint32_t),
-  "InlineRefCounts must be 8 bytes");
-#endif
+_Static_assert(_Alignof(InlineRefCounts) == _Alignof(__swift_uintptr_t),
+  "InlineRefCounts must be pointer-aligned");
 
 #endif
diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb
index c9eeeee..773e7fb 100644
--- a/stdlib/public/core/Arrays.swift.gyb
+++ b/stdlib/public/core/Arrays.swift.gyb
@@ -178,7 +178,7 @@
 /// can store any kind of elements---from integers to strings to classes.
 ///
 /// Swift makes it easy to create arrays in your code using an array literal:
-/// simply surround a comma separated list of values with square brackets.
+/// simply surround a comma-separated list of values with square brackets.
 /// Without any other information, Swift creates an array that includes the
 /// specified values, automatically inferring the array's `Element` type. For
 /// example:
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index 72e2592..2f06587 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -144,8 +144,13 @@
   return !(lhs == rhs)
 }
 
-/// Returns `true` iff `t0` is identical to `t1`; i.e. if they are both
-/// `nil` or they both represent the same type.
+/// Returns a Boolean value indicating whether two types are identical.
+///
+/// - Parameters:
+///   - t0: A type to compare.
+///   - t1: Another type to compare.
+/// - Returns: `true` if both `t0` and `t1` are `nil` or if they represent the
+///   same type; otherwise, `false`.
 @_inlineable
 public func == (t0: Any.Type?, t1: Any.Type?) -> Bool {
   switch (t0, t1) {
@@ -156,8 +161,13 @@
   }
 }
 
-/// Returns `false` iff `t0` is identical to `t1`; i.e. if they are both
-/// `nil` or they both represent the same type.
+/// Returns a Boolean value indicating whether two types are not identical.
+///
+/// - Parameters:
+///   - t0: A type to compare.
+///   - t1: Another type to compare.
+/// - Returns: `true` if one, but not both, of `t0` and `t1` are `nil`, or if
+///   they represent different types; otherwise, `false`.
 @_inlineable
 public func != (t0: Any.Type?, t1: Any.Type?) -> Bool {
   return !(t0 == t1)
diff --git a/stdlib/public/core/CTypes.swift b/stdlib/public/core/CTypes.swift
index 018b1da..0d3af0d 100644
--- a/stdlib/public/core/CTypes.swift
+++ b/stdlib/public/core/CTypes.swift
@@ -42,17 +42,19 @@
 /// The C 'int' type.
 public typealias CInt = Int32
 
-/// The C 'long' type.
 #if os(Windows) && arch(x86_64)
+/// The C 'long' type.
 public typealias CLong = Int32
 #else
+/// The C 'long' type.
 public typealias CLong = Int
 #endif
 
-/// The C 'long long' type.
 #if os(Windows) && arch(x86_64)
+/// The C 'long long' type.
 public typealias CLongLong = Int
 #else
+/// The C 'long long' type.
 public typealias CLongLong = Int64
 #endif
 
@@ -200,7 +202,7 @@
   }
 }
 
-/// The corresponding Swift type to `va_list` in imported C APIs.
+/// A wrapper around a C `va_list` pointer.
 @_fixed_layout
 public struct CVaListPointer {
   @_versioned // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/Codable.swift b/stdlib/public/core/Codable.swift
index 462c6cc..e7e2e05 100644
--- a/stdlib/public/core/Codable.swift
+++ b/stdlib/public/core/Codable.swift
@@ -1166,8 +1166,8 @@
 
 // An implementation of _KeyedDecodingContainerBase and _KeyedDecodingContainerBox are given at the bottom of this file.
 
-/// A concrete container that provides a view into an decoder's storage, making
-/// the encoded properties of an decodable type accessible by keys.
+/// A concrete container that provides a view into a decoder's storage, making
+/// the encoded properties of a decodable type accessible by keys.
 @_fixed_layout // FIXME(sil-serialize-all)
 public struct KeyedDecodingContainer<K : CodingKey> : KeyedDecodingContainerProtocol {
     public typealias Key = K
@@ -2307,7 +2307,8 @@
     mutating func encode<T : Encodable>(_ value: T) throws
 }
 
-/// A `SingleValueDecodingContainer` is a container which can support the storage and direct decoding of a single non-keyed value.
+/// A container that can support the storage and direct decoding of a single
+/// nonkeyed value.
 public protocol SingleValueDecodingContainer {
     /// The path of coding keys taken to get to this point in encoding.
     var codingPath: [CodingKey] { get }
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index 567c036..3861ca5 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -1503,8 +1503,9 @@
   public init?(exactly value: ${That}) {
     _value = Builtin.${sign}itofp_${ThatBuiltinName}_FPIEEE${bits}(value._value)
 
-%   if srcBits < SignificandBitCount:
-    if ${That}(self) != value {
+%   if srcBits >= SignificandBitCount:
+    guard let roundTrip = ${That}(exactly: self),
+      roundTrip == value else {
       return nil
     }
 %   end
diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift
index 020ff15..2f8a39d 100644
--- a/stdlib/public/core/KeyPath.swift
+++ b/stdlib/public/core/KeyPath.swift
@@ -1620,8 +1620,8 @@
 // on `Self` to prevent dynamically-typed methods from being inherited by
 // statically-typed key paths.
 
-/// This protocol is an implementation detail of key path expressions; do not
-/// use it directly.
+/// An implementation detail of key path expressions; do not use this protocol
+/// directly.
 @_show_in_interface
 public protocol _AppendKeyPath {}
 
diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift
index 1f41bd5..92f5b09 100644
--- a/stdlib/public/core/Mirror.swift
+++ b/stdlib/public/core/Mirror.swift
@@ -12,15 +12,31 @@
 // FIXME: ExistentialCollection needs to be supported before this will work
 // without the ObjC Runtime.
 
-/// Representation of the sub-structure and optional "display style"
-/// of any arbitrary subject instance.
+/// A representation of the substructure and display style of an instance of
+/// any type.
 ///
-/// Describes the parts---such as stored properties, collection
-/// elements, tuple elements, or the active enumeration case---that
-/// make up a particular instance.  May also supply a "display style"
-/// property that suggests how this structure might be rendered.
+/// A mirror describes the parts that make up a particular instance, such as
+/// the instance's stored properties, collection or tuple elements, or its
+/// active enumeration case. Mirrors also provide a "display style" property
+/// that suggests how this mirror might be rendered.
 ///
-/// Mirrors are used by playgrounds and the debugger.
+/// Playgrounds and the debugger use the `Mirror` type to display
+/// representations of values of any type. For example, when you pass an
+/// instance to the `dump(_:_:_:_:)` function, a mirror is used to render that
+/// instance's runtime contents.
+///
+///     struct Point {
+///         let x: Int, y: Int
+///     }
+///
+///     let p = Point(x: 21, y: 30)
+///     print(String(reflecting: p))
+///     // Prints "â–¿ Point
+///     //           - x: 21
+///     //           - y: 30"
+///
+/// To customize the mirror representation of a custom type, add conformance to
+/// the `CustomReflectable` protocol.
 @_fixed_layout // FIXME(sil-serialize-all)
 public struct Mirror {
   /// Representation of descendant classes that don't override
@@ -46,56 +62,58 @@
     case suppressed
   }
 
-  /// Representation of ancestor classes.
+  /// The representation to use for ancestor classes.
   ///
-  /// A `CustomReflectable` class can control how its mirror will
-  /// represent ancestor classes by initializing the mirror with a
-  /// `AncestorRepresentation`.  This setting has no effect on mirrors
+  /// A class that conforms to the `CustomReflectable` protocol can control how
+  /// its mirror represents ancestor classes by initializing the mirror
+  /// with an `AncestorRepresentation`. This setting has no effect on mirrors
   /// reflecting value type instances.
   public enum AncestorRepresentation {
 
-    /// Generate a default mirror for all ancestor classes.
+    /// Generates a default mirror for all ancestor classes.
     ///
-    /// This case is the default.
+    /// This case is the default when initializing a `Mirror` instance.
     ///
-    /// - Note: This option generates default mirrors even for
-    ///   ancestor classes that may implement `CustomReflectable`'s
-    ///   `customMirror` requirement.  To avoid dropping an ancestor class
-    ///   customization, an override of `customMirror` should pass
-    ///   `ancestorRepresentation: .Customized(super.customMirror)` when
-    ///   initializing its `Mirror`.
+    /// When you use this option, a subclass's mirror generates default mirrors
+    /// even for ancestor classes that conform to the `CustomReflectable`
+    /// protocol. To avoid dropping the customization provided by ancestor
+    /// classes, an override of `customMirror` should pass
+    /// `.customized({ super.customMirror })` as `ancestorRepresentation` when
+    /// initializing its mirror.
     case generated
 
-    /// Use the nearest ancestor's implementation of `customMirror` to
-    /// create a mirror for that ancestor.  Other classes derived from
-    /// such an ancestor are given a default mirror.
+    /// Uses the nearest ancestor's implementation of `customMirror` to create
+    /// a mirror for that ancestor.
     ///
-    /// The payload for this option should always be
-    /// "`{ super.customMirror }`":
+    /// Other classes derived from such an ancestor are given a default mirror.
+    /// The payload for this option should always be `{ super.customMirror }`:
     ///
     ///     var customMirror: Mirror {
-    ///       return Mirror(
-    ///         self,
-    ///         children: ["someProperty": self.someProperty],
-    ///         ancestorRepresentation: .Customized({ super.customMirror })) // <==
+    ///         return Mirror(
+    ///             self,
+    ///             children: ["someProperty": self.someProperty],
+    ///             ancestorRepresentation: .customized({ super.customMirror })) // <==
     ///     }
     case customized(() -> Mirror)
 
-    /// Suppress the representation of all ancestor classes.  The
-    /// resulting `Mirror`'s `superclassMirror` is `nil`.
+    /// Suppresses the representation of all ancestor classes.
+    ///
+    /// In a mirror created with this ancestor representation, the
+    /// `superclassMirror` property is `nil`.
     case suppressed
   }
 
-  /// Reflect upon the given `subject`.
+  /// Creates a mirror that reflects on the given instance.
   ///
-  /// If the dynamic type of `subject` conforms to `CustomReflectable`,
-  /// the resulting mirror is determined by its `customMirror` property.
+  /// If the dynamic type of `subject` conforms to `CustomReflectable`, the
+  /// resulting mirror is determined by its `customMirror` property.
   /// Otherwise, the result is generated by the language.
   ///
-  /// - Note: If the dynamic type of `subject` has value semantics,
-  ///   subsequent mutations of `subject` will not observable in
-  ///   `Mirror`.  In general, though, the observability of such
-  /// mutations is unspecified.
+  /// If the dynamic type of `subject` has value semantics, subsequent
+  /// mutations of `subject` will not observable in `Mirror`.  In general,
+  /// though, the observability of mutations is unspecified.
+  ///
+  /// - Parameter subject: The instance for which to create a mirror.
   @_inlineable // FIXME(sil-serialize-all)
   public init(reflecting subject: Any) {
     if case let customized as CustomReflectable = subject {
@@ -107,36 +125,33 @@
     }
   }
 
-  /// An element of the reflected instance's structure.  The optional
-  /// `label` may be used when appropriate, e.g. to represent the name
-  /// of a stored property or of an active `enum` case, and will be
-  /// used for lookup when `String`s are passed to the `descendant`
-  /// method.
+  /// An element of the reflected instance's structure.
+  ///
+  /// When the `label` component in not `nil`, it may represent the name of a
+  /// stored property or an active `enum` case. If you pass strings to the
+  /// `descendant(_:_:)` method, labels are used for lookup.
   public typealias Child = (label: String?, value: Any)
 
-  /// The type used to represent sub-structure.
+  /// The type used to represent substructure.
   ///
-  /// Depending on your needs, you may find it useful to "upgrade"
-  /// instances of this type to `AnyBidirectionalCollection` or
-  /// `AnyRandomAccessCollection`.  For example, to display the last
-  /// 20 children of a mirror if they can be accessed efficiently, you
-  /// might write:
+  /// When working with a mirror that reflects a bidirectional or random access
+  /// collection, you may find it useful to "upgrade" instances of this type
+  /// to `AnyBidirectionalCollection` or `AnyRandomAccessCollection`. For
+  /// example, to display the last twenty children of a mirror if they can be
+  /// accessed efficiently, you write the following code:
   ///
   ///     if let b = AnyBidirectionalCollection(someMirror.children) {
-  ///       var i = xs.index(b.endIndex, offsetBy: -20,
-  ///         limitedBy: b.startIndex) ?? b.startIndex
-  ///       while i != xs.endIndex {
-  ///          print(b[i])
-  ///          b.formIndex(after: &i)
-  ///       }
+  ///         for element in b.suffix(20) {
+  ///             print(element)
+  ///         }
   ///     }
   public typealias Children = AnyCollection<Child>
 
-  /// A suggestion of how a `Mirror`'s `subject` is to be interpreted.
+  /// A suggestion of how a mirror's subject is to be interpreted.
   ///
   /// Playgrounds and the debugger will show a representation similar
   /// to the one used for instances of the kind indicated by the
-  /// `DisplayStyle` case name when the `Mirror` is used for display.
+  /// `DisplayStyle` case name when the mirror is used for display.
   @_fixed_layout // FIXME(sil-serialize-all)
   public enum DisplayStyle {
     case `struct`, `class`, `enum`, tuple, optional, collection
@@ -200,26 +215,31 @@
     return Mirror._noSuperclassMirror
   }
   
-  /// Represent `subject` with structure described by `children`,
-  /// using an optional `displayStyle`.
+  /// Creates a mirror representing the given subject with a specified
+  /// structure.
   ///
-  /// If `subject` is not a class instance, `ancestorRepresentation`
-  /// is ignored.  Otherwise, `ancestorRepresentation` determines
+  /// You use this initializer from within your type's `customMirror`
+  /// implementation to create a customized mirror.
+  ///
+  /// If `subject` is a class instance, `ancestorRepresentation` determines
   /// whether ancestor classes will be represented and whether their
-  /// `customMirror` implementations will be used.  By default, a
-  /// representation is automatically generated and any `customMirror`
-  /// implementation is bypassed.  To prevent bypassing customized
-  /// ancestors, `customMirror` overrides should initialize the
-  /// `Mirror` with:
+  /// `customMirror` implementations will be used. By default, the
+  /// `customMirror` implementation of any ancestors is ignored. To prevent
+  /// bypassing customized ancestors, pass
+  /// `.customized({ super.customMirror })` as the `ancestorRepresentation`
+  /// parameter when implementing your type's `customMirror` property.
   ///
-  ///     ancestorRepresentation: .customized({ super.customMirror })
-  ///
-  /// - Note: The traversal protocol modeled by `children`'s indices
-  ///   (`ForwardIndex`, `BidirectionalIndex`, or
-  ///   `RandomAccessIndex`) is captured so that the resulting
-  /// `Mirror`'s `children` may be upgraded later.  See the failable
-  /// initializers of `AnyBidirectionalCollection` and
-  /// `AnyRandomAccessCollection` for details.
+  /// - Parameters:
+  ///   - subject: The instance to represent in the new mirror.
+  ///   - children: The structure to use for the mirror. The collection
+  ///     traversal modeled by `children` is captured so that the resulting
+  ///     mirror's children may be upgraded to a bidirectional or random
+  ///     access collection later. See the `children` property for details.
+  ///   - displayStyle: The preferred display style for the mirror when
+  ///     presented in the debugger or in a playground. The default is `nil`.
+  ///   - ancestorRepresentation: The means of generating the subject's
+  ///     ancestor representation. `ancestorRepresentation` is ignored if
+  ///     `subject` is not a class instance. The default is `.generated`.
   @_inlineable // FIXME(sil-serialize-all)
   public init<Subject, C : Collection>(
     _ subject: Subject,
@@ -239,36 +259,33 @@
       = subject is CustomLeafReflectable ? .suppressed : .generated
   }
 
-  /// Represent `subject` with child values given by
-  /// `unlabeledChildren`, using an optional `displayStyle`.  The
-  /// result's child labels will all be `nil`.
+  /// Creates a mirror representing the given subject with unlabeled children.
   ///
-  /// This initializer is especially useful for the mirrors of
-  /// collections, e.g.:
+  /// You use this initializer from within your type's `customMirror`
+  /// implementation to create a customized mirror, particularly for custom
+  /// types that are collections. The labels of the resulting mirror's
+  /// `children` collection are all `nil`.
   ///
-  ///     extension MyArray : CustomReflectable {
-  ///       var customMirror: Mirror {
-  ///         return Mirror(self, unlabeledChildren: self, displayStyle: .collection)
-  ///       }
-  ///     }
-  ///
-  /// If `subject` is not a class instance, `ancestorRepresentation`
-  /// is ignored.  Otherwise, `ancestorRepresentation` determines
+  /// If `subject` is a class instance, `ancestorRepresentation` determines
   /// whether ancestor classes will be represented and whether their
-  /// `customMirror` implementations will be used.  By default, a
-  /// representation is automatically generated and any `customMirror`
-  /// implementation is bypassed.  To prevent bypassing customized
-  /// ancestors, `customMirror` overrides should initialize the
-  /// `Mirror` with:
+  /// `customMirror` implementations will be used. By default, the
+  /// `customMirror` implementation of any ancestors is ignored. To prevent
+  /// bypassing customized ancestors, pass
+  /// `.customized({ super.customMirror })` as the `ancestorRepresentation`
+  /// parameter when implementing your type's `customMirror` property.
   ///
-  ///     ancestorRepresentation: .Customized({ super.customMirror })
-  ///
-  /// - Note: The traversal protocol modeled by `children`'s indices
-  ///   (`ForwardIndex`, `BidirectionalIndex`, or
-  ///   `RandomAccessIndex`) is captured so that the resulting
-  /// `Mirror`'s `children` may be upgraded later.  See the failable
-  /// initializers of `AnyBidirectionalCollection` and
-  /// `AnyRandomAccessCollection` for details.
+  /// - Parameters:
+  ///   - subject: The instance to represent in the new mirror.
+  ///   - unlabeledChildren: The children to use for the mirror. The collection
+  ///     traversal modeled by `unlabeledChildren` is captured so that the
+  ///     resulting mirror's children may be upgraded to a bidirectional or
+  ///     random access collection later. See the `children` property for
+  ///     details.
+  ///   - displayStyle: The preferred display style for the mirror when
+  ///     presented in the debugger or in a playground. The default is `nil`.
+  ///   - ancestorRepresentation: The means of generating the subject's
+  ///     ancestor representation. `ancestorRepresentation` is ignored if
+  ///     `subject` is not a class instance. The default is `.generated`.
   @_inlineable // FIXME(sil-serialize-all)
   public init<Subject, C : Collection>(
     _ subject: Subject,
@@ -291,29 +308,35 @@
       = subject is CustomLeafReflectable ? .suppressed : .generated
   }
 
-  /// Represent `subject` with labeled structure described by
-  /// `children`, using an optional `displayStyle`.
+  /// Creates a mirror representing the given subject using a dictionary
+  /// literal for the structure.
   ///
-  /// Pass a dictionary literal with `String` keys as `children`.  Be
-  /// aware that although an *actual* `Dictionary` is
-  /// arbitrarily-ordered, the ordering of the `Mirror`'s `children`
-  /// will exactly match that of the literal you pass.
+  /// You use this initializer from within your type's `customMirror`
+  /// implementation to create a customized mirror. Pass a dictionary literal
+  /// with string keys as `children`. Although an *actual* dictionary is
+  /// arbitrarily-ordered, when you create a mirror with a dictionary literal,
+  /// the ordering of the mirror's `children` will exactly match that of the
+  /// literal you pass.
   ///
-  /// If `subject` is not a class instance, `ancestorRepresentation`
-  /// is ignored.  Otherwise, `ancestorRepresentation` determines
+  /// If `subject` is a class instance, `ancestorRepresentation` determines
   /// whether ancestor classes will be represented and whether their
-  /// `customMirror` implementations will be used.  By default, a
-  /// representation is automatically generated and any `customMirror`
-  /// implementation is bypassed.  To prevent bypassing customized
-  /// ancestors, `customMirror` overrides should initialize the
-  /// `Mirror` with:
+  /// `customMirror` implementations will be used. By default, the
+  /// `customMirror` implementation of any ancestors is ignored. To prevent
+  /// bypassing customized ancestors, pass
+  /// `.customized({ super.customMirror })` as the `ancestorRepresentation`
+  /// parameter when implementing your type's `customMirror` property.
   ///
-  ///     ancestorRepresentation: .customized({ super.customMirror })
-  ///
-  /// - Note: The resulting `Mirror`'s `children` may be upgraded to
-  ///   `AnyRandomAccessCollection` later.  See the failable
-  ///   initializers of `AnyBidirectionalCollection` and
-  /// `AnyRandomAccessCollection` for details.
+  /// - Parameters:
+  ///   - subject: The instance to represent in the new mirror.
+  ///   - children: A dictionary literal to use as the structure for the
+  ///     mirror. The `children` collection of the resulting mirror may be
+  ///     upgraded to a random access collection later. See the `children`
+  ///     property for details.
+  ///   - displayStyle: The preferred display style for the mirror when
+  ///     presented in the debugger or in a playground. The default is `nil`.
+  ///   - ancestorRepresentation: The means of generating the subject's
+  ///     ancestor representation. `ancestorRepresentation` is ignored if
+  ///     `subject` is not a class instance. The default is `.generated`.
   @_inlineable // FIXME(sil-serialize-all)
   public init<Subject>(
     _ subject: Subject,
@@ -335,7 +358,7 @@
 
   /// The static type of the subject being reflected.
   ///
-  /// This type may differ from the subject's dynamic type when `self`
+  /// This type may differ from the subject's dynamic type when this mirror
   /// is the `superclassMirror` of another mirror.
   public let subjectType: Any.Type
 
@@ -343,9 +366,10 @@
   /// reflected subject.
   public let children: Children
 
-  /// Suggests a display style for the reflected subject.
+  /// A suggested display style for the reflected subject.
   public let displayStyle: DisplayStyle?
 
+  /// A mirror of the subject's superclass, if one exists.
   @_inlineable // FIXME(sil-serialize-all)
   public var superclassMirror: Mirror? {
     return _makeSuperclassMirror()
@@ -359,7 +383,7 @@
 
 /// A type that explicitly supplies its own mirror.
 ///
-/// You can create a mirror for any type using the `Mirror(reflect:)`
+/// You can create a mirror for any type using the `Mirror(reflecting:)`
 /// initializer, but if you are not satisfied with the mirror supplied for
 /// your type by default, you can make it conform to `CustomReflectable` and
 /// return a custom `Mirror` instance.
@@ -383,9 +407,10 @@
 ///
 /// Do not declare new conformances to this protocol; they will not
 /// work as expected.
-// FIXME(ABI)#49 (Sealed Protocols): this protocol should be "non-open" and you shouldn't be able to
-// create conformances.
-public protocol MirrorPath {}
+public protocol MirrorPath {
+  // FIXME(ABI)#49 (Sealed Protocols): this protocol should be "non-open" and
+  // you shouldn't be able to create conformances.
+}
 extension Int : MirrorPath {}
 extension String : MirrorPath {}
 
@@ -405,42 +430,50 @@
     internal var customMirror: Mirror { return mirror }
   }
 
-  /// Return a specific descendant of the reflected subject, or `nil`
-  /// Returns a specific descendant of the reflected subject, or `nil`
-  /// if no such descendant exists.
+  /// Returns a specific descendant of the reflected subject, or `nil` if no
+  /// such descendant exists.
   ///
-  /// A `String` argument selects the first `Child` with a matching label.
-  /// An integer argument *n* select the *n*th `Child`.  For example:
+  /// Pass a variadic list of string and integer arguments. Each string
+  /// argument selects the first child with a matching label. Each integer
+  /// argument selects the child at that offset. For example, passing
+  /// `1, "two", 3` as arguments to `myMirror.descendant(_:_:)` is equivalent
+  /// to:
   ///
-  ///     var d = Mirror(reflecting: x).descendant(1, "two", 3)
-  ///
-  /// is equivalent to:
-  ///
-  ///     var d = nil
-  ///     let children = Mirror(reflecting: x).children
-  ///     if let p0 = children.index(children.startIndex,
-  ///       offsetBy: 1, limitedBy: children.endIndex) {
-  ///       let grandChildren = Mirror(reflecting: children[p0].value).children
-  ///       SeekTwo: for g in grandChildren {
-  ///         if g.label == "two" {
-  ///           let greatGrandChildren = Mirror(reflecting: g.value).children
-  ///           if let p1 = greatGrandChildren.index(
-  ///             greatGrandChildren.startIndex,
-  ///             offsetBy: 3, limitedBy: greatGrandChildren.endIndex) {
-  ///             d = greatGrandChildren[p1].value
-  ///           }
-  ///           break SeekTwo
+  ///     var result: Any? = nil
+  ///     let children = myMirror.children
+  ///     if let i0 = children.index(
+  ///         children.startIndex, offsetBy: 1, limitedBy: children.endIndex),
+  ///         i0 != children.endIndex
+  ///     {
+  ///         let grandChildren = Mirror(reflecting: children[i0].value).children
+  ///         if let i1 = grandChildren.index(where: { $0.label == "two" }) {
+  ///             let greatGrandChildren =
+  ///                 Mirror(reflecting: grandChildren[i1].value).children
+  ///             if let i2 = greatGrandChildren.index(
+  ///                 greatGrandChildren.startIndex,
+  ///                 offsetBy: 3,
+  ///                 limitedBy: greatGrandChildren.endIndex),
+  ///                 i2 != greatGrandChildren.endIndex
+  ///             {
+  ///                 // Success!
+  ///                 result = greatGrandChildren[i2].value
+  ///             }
   ///         }
-  ///       }
   ///     }
   ///
-  /// As you can see, complexity for each element of the argument list
-  /// depends on the argument type and capabilities of the collection
-  /// used to initialize the corresponding subject's parent's mirror.
-  /// Each `String` argument results in a linear search.  In short,
-  /// this function is suitable for exploring the structure of a
-  /// `Mirror` in a REPL or playground, but don't expect it to be
-  /// efficient.
+  /// This function is suitable for exploring the structure of a mirror in a
+  /// REPL or playground, but is not intended to be efficient. The efficiency
+  /// of finding each element in the argument list depends on the argument
+  /// type and the capabilities of the each level of the mirror's `children`
+  /// collections. Each string argument requires a linear search, and unless
+  /// the underlying collection supports random-access traversal, each integer
+  /// argument also requires a linear operation.
+  ///
+  /// - Parameters:
+  ///   - first: The first mirror path component to access.
+  ///   - rest: Any remaining mirror path components.
+  /// - Returns: The descendant of this mirror specified by the given mirror
+  ///   path components if such a descendant exists; otherwise, `nil`.
   @_inlineable // FIXME(sil-serialize-all)
   public func descendant(
     _ first: MirrorPath, _ rest: MirrorPath...
@@ -698,19 +731,20 @@
 }
 
 extension PlaygroundQuickLook {
-  /// Initialize for the given `subject`.
+  /// Creates a new Quick Look for the given instance.
   ///
   /// If the dynamic type of `subject` conforms to
-  /// `CustomPlaygroundQuickLookable`, returns the result of calling
-  /// its `customPlaygroundQuickLook` property.  Otherwise, returns
-  /// a `PlaygroundQuickLook` synthesized for `subject` by the
-  /// language.  Note that in some cases the result may be
-  /// `.Text(String(reflecting: subject))`.
+  /// `CustomPlaygroundQuickLookable`, the result is found by calling its
+  /// `customPlaygroundQuickLook` property. Otherwise, the result is
+  /// synthesized by the language. In some cases, the synthesized result may
+  /// be `.text(String(reflecting: subject))`.
   ///
-  /// - Note: If the dynamic type of `subject` has value semantics,
-  ///   subsequent mutations of `subject` will not observable in
-  ///   `Mirror`.  In general, though, the observability of such
-  ///   mutations is unspecified.
+  /// - Note: If the dynamic type of `subject` has value semantics, subsequent
+  ///   mutations of `subject` will not observable in the Quick Look. In
+  ///   general, though, the observability of such mutations is unspecified.
+  ///
+  /// - Parameter subject: The instance to represent with the resulting Quick
+  ///   Look.
   @_inlineable // FIXME(sil-serialize-all)
   public init(reflecting subject: Any) {
     if let customized = subject as? CustomPlaygroundQuickLookable {
diff --git a/stdlib/public/core/Policy.swift b/stdlib/public/core/Policy.swift
index e4649b7..8128f8c 100644
--- a/stdlib/public/core/Policy.swift
+++ b/stdlib/public/core/Policy.swift
@@ -15,8 +15,8 @@
 //===----------------------------------------------------------------------===//
 // Standardized uninhabited type
 //===----------------------------------------------------------------------===//
-/// The return type of functions that do not return normally; a type with no
-/// values.
+/// The return type of functions that do not return normally, that is, a type
+/// with no values.
 ///
 /// Use `Never` as the return type when declaring a closure, function, or
 /// method that unconditionally throws an error, traps, or otherwise does
@@ -31,16 +31,16 @@
 //===----------------------------------------------------------------------===//
 // Standardized aliases
 //===----------------------------------------------------------------------===//
-/// The return type of functions that don't explicitly specify a return type;
-/// an empty tuple (i.e., `()`).
+/// The return type of functions that don't explicitly specify a return type,
+/// that is, an empty tuple `()`.
 ///
 /// When declaring a function or method, you don't need to specify a return
 /// type if no value will be returned. However, the type of a function,
 /// method, or closure always includes a return type, which is `Void` if
 /// otherwise unspecified.
 ///
-/// Use `Void` or an empty tuple as the return type when declaring a
-/// closure, function, or method that doesn't return a value.
+/// Use `Void` or an empty tuple as the return type when declaring a closure,
+/// function, or method that doesn't return a value.
 ///
 ///     // No return type declared:
 ///     func logMessage(_ s: String) {
diff --git a/stdlib/public/core/Sort.swift.gyb b/stdlib/public/core/Sort.swift.gyb
index b59c8cb..f7992d1 100644
--- a/stdlib/public/core/Sort.swift.gyb
+++ b/stdlib/public/core/Sort.swift.gyb
@@ -406,9 +406,15 @@
 % end
 // for p in preds
 
-/// Exchange the values of `a` and `b`.
+/// Exchanges the values of the two arguments.
 ///
-/// - Precondition: `a` and `b` do not alias each other.
+/// The two arguments must not alias each other. To swap two elements of a
+/// mutable collection, use the `swapAt(_:_:)` method of that collection
+/// instead of this function.
+///
+/// - Parameters:
+///   - a: The first value to swap.
+///   - b: The second value to swap.
 @_inlineable
 public func swap<T>(_ a: inout T, _ b: inout T) {
   // Semantically equivalent to (a, b) = (b, a).
diff --git a/stdlib/public/core/String.swift b/stdlib/public/core/String.swift
index 7552225..7339112 100644
--- a/stdlib/public/core/String.swift
+++ b/stdlib/public/core/String.swift
@@ -48,7 +48,7 @@
   /// encoding.
   ///
   /// - Parameters:
-  ///   - codeUnits: A collection of code units encoded in the ecoding
+  ///   - codeUnits: A collection of code units encoded in the encoding
   ///     specified in `sourceEncoding`.
   ///   - sourceEncoding: The encoding in which `codeUnits` should be
   ///     interpreted.
@@ -280,7 +280,7 @@
   /// encoding.
   ///
   /// - Parameters:
-  ///   - codeUnits: A collection of code units encoded in the ecoding
+  ///   - codeUnits: A collection of code units encoded in the encoding
   ///     specified in `sourceEncoding`.
   ///   - sourceEncoding: The encoding in which `codeUnits` should be
   ///     interpreted.
@@ -673,6 +673,12 @@
 @_fixed_layout
 public struct String {
   /// Creates an empty string.
+  ///
+  /// Using this initializer is equivalent to initializing a string with an
+  /// empty string literal.
+  ///
+  ///     let empty = ""
+  ///     let alsoEmpty = String()
   @_inlineable // FIXME(sil-serialize-all)
   public init() {
     _core = _StringCore()
diff --git a/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb b/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb
index 6be2abd..5af0bcd 100644
--- a/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb
+++ b/stdlib/public/core/StringRangeReplaceableCollection.swift.gyb
@@ -29,6 +29,11 @@
   ///     let zeroes = String(repeating: "0" as Character, count: 10)
   ///     print(zeroes)
   ///     // Prints "0000000000"
+  ///
+  /// - Parameters:
+  ///   - repeatedValue: The character to repeat.
+  ///   - count: The number of times to repeat `repeatedValue` in the 
+  ///     resulting string.
   @_inlineable // FIXME(sil-serialize-all)
   public init(repeating repeatedValue: Character, count: Int) {
     self.init(repeating: String(repeatedValue), count: count)
@@ -38,6 +43,22 @@
   // that String conforms to Collection:
   // - init<T>(_ value: T) where T : LosslessStringConvertible
   // - init<S>(_ characters: S) where S : Sequence, S.Element == Character
+  
+  /// Creates a new string containing the characters in the given sequence.
+  ///
+  /// You can use this initializer to create a new string from the result of
+  /// one or more collection operations on a string's characters. For example:
+  ///
+  ///     let str = "The rain in Spain stays mainly in the plain."
+  ///
+  ///     let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
+  ///     let disemvoweled = String(str.lazy.filter { !vowels.contains($0) })
+  ///
+  ///     print(disemvoweled)
+  ///     // Prints "Th rn n Spn stys mnly n th pln."
+  ///
+  /// - Parameter other: A string instance or another sequence of 
+  ///   characters.
   @_inlineable // FIXME(sil-serialize-all)
   public init<S : Sequence & LosslessStringConvertible>(_ other: S)
   where S.Element == Character {
@@ -171,14 +192,16 @@
 
   /// Accesses the character at the given position.
   ///
-  /// Indices for a subscripting a string are shared with the string's
-  /// `characters` view. For example:
+  /// You can use the same indices for subscripting a string and its substring.
+  /// For example, this code finds the first letter after the first space:
   ///
-  ///     let greeting = "Hello, friend!"
-  ///     if let i = greeting.characters.index(where: { $0 >= "A" && $0 <= "Z" }) {
-  ///         print("First capital letter: \(greeting[i])")
+  ///     let str = "Greetings, friend! How are you?"
+  ///     let firstSpace = str.index(of: " ") ?? str.endIndex
+  ///     let substr = str[firstSpace...]
+  ///     if let nextCapital = substr.index(where: { $0 >= "A" && $0 <= "Z" }) {
+  ///         print("Capital after a space: \(str[nextCapital])")
   ///     }
-  ///     // Prints "First capital letter: H"
+  ///     // Prints "Capital after a space: H"
   ///
   /// - Parameter i: A valid index of the string. `i` must be less than the
   ///   string's end index.
@@ -190,17 +213,18 @@
   /// Creates a new string containing the characters in the given sequence.
   ///
   /// You can use this initializer to create a new string from the result of
-  /// one or more operations on a string's `characters` view. For example:
+  /// one or more collection operations on a string's characters. For example:
   ///
   ///     let str = "The rain in Spain stays mainly in the plain."
   ///
   ///     let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
-  ///     let disemvoweled = String(str.characters.lazy.filter { !vowels.contains($0) })
+  ///     let disemvoweled = String(str.lazy.filter { !vowels.contains($0) })
   ///
   ///     print(disemvoweled)
   ///     // Prints "Th rn n Spn stys mnly n th pln."
   ///
-  /// - Parameter characters: A sequence of characters.
+  /// - Parameter characters: A string instance or another sequence of 
+  ///   characters.
   @_inlineable // FIXME(sil-serialize-all)
   public init<S : Sequence>(_ characters: S)
     where S.Iterator.Element == Character {
@@ -326,7 +350,7 @@
   /// removes the hyphen from the middle of a string.
   ///
   ///     var nonempty = "non-empty"
-  ///     if let i = nonempty.characters.index(of: "-") {
+  ///     if let i = nonempty.index(of: "-") {
   ///         nonempty.remove(at: i)
   ///     }
   ///     print(nonempty)
diff --git a/stdlib/public/core/Substring.swift.gyb b/stdlib/public/core/Substring.swift.gyb
index 4c6208d..8c0f007 100644
--- a/stdlib/public/core/Substring.swift.gyb
+++ b/stdlib/public/core/Substring.swift.gyb
@@ -205,7 +205,7 @@
   /// encoding.
   ///
   /// - Parameters:
-  ///   - codeUnits: A collection of code units encoded in the ecoding
+  ///   - codeUnits: A collection of code units encoded in the encoding
   ///     specified in `sourceEncoding`.
   ///   - sourceEncoding: The encoding in which `codeUnits` should be
   ///     interpreted.
diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
index 9b29437..0541c78 100644
--- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
@@ -42,7 +42,7 @@
 % for mutable in (True, False):
 %  Self = 'UnsafeMutableBufferPointer' if mutable else 'UnsafeBufferPointer'
 %  Mutable = 'Mutable' if mutable else ''
-/// A non-owning collection interface to a buffer of ${Mutable.lower()}
+/// A nonowning collection interface to a buffer of ${Mutable.lower()}
 /// elements stored contiguously in memory.
 ///
 /// You can use an `${Self}` instance in low level operations to eliminate
diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift
index cffeb4f..d80f6be 100644
--- a/stdlib/public/core/VarArgs.swift
+++ b/stdlib/public/core/VarArgs.swift
@@ -10,28 +10,30 @@
 //
 //===----------------------------------------------------------------------===//
 
-/// Instances of conforming types can be encoded, and appropriately
-/// passed, as elements of a C `va_list`.
+/// A type whose instances can be encoded, and appropriately passed, as
+/// elements of a C `va_list`.
 ///
-/// This protocol is useful in presenting C "varargs" APIs natively in
-/// Swift.  It only works for APIs that have a `va_list` variant, so
-/// for example, it isn't much use if all you have is:
+/// You use this protocol to present a native Swift interface to a C "varargs"
+/// API. For example, a program can import a C API like the one defined here:
 ///
-/// ~~~ c
-/// int c_api(int n, ...)
-/// ~~~
-///
-/// Given a version like this, though,
-///
-/// ~~~ c
+/// ~~~c
 /// int c_api(int, va_list arguments)
 /// ~~~
 ///
-/// you can write:
+/// To create a wrapper for the `c_api` function, write a function that takes
+/// `CVarArg` arguments, and then call the imported C function using the
+/// `withVaList(_:_:)` function:
 ///
 ///     func swiftAPI(_ x: Int, arguments: CVarArg...) -> Int {
-///       return withVaList(arguments) { c_api(x, $0) }
+///         return withVaList(arguments) { c_api(x, $0) }
 ///     }
+///
+/// Swift only imports C variadic functions that use a `va_list` for their
+/// arguments. C functions that use the `...` syntax for variadic arguments
+/// are not imported, and therefore can't be called using `CVarArg` arguments.
+///
+/// - Note: Declaring conformance to the `CVarArg` protocol for types defined
+///   outside the standard library is not supported.
 public protocol CVarArg {
   // Note: the protocol is public, but its requirement is stdlib-private.
   // That's because there are APIs operating on CVarArg instances, but
diff --git a/test/Generics/validate_stdlib_generic_signatures.swift b/test/Generics/validate_stdlib_generic_signatures.swift
new file mode 100644
index 0000000..eae4985
--- /dev/null
+++ b/test/Generics/validate_stdlib_generic_signatures.swift
@@ -0,0 +1,6 @@
+// Verifies that all of the generic signatures in the standard library are
+// minimal and canonical.
+
+// RUN: %target-typecheck-verify-swift -typecheck %s -verify-generic-signatures Swift
+
+// expected-no-diagnostics
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index e7c2b20..5a4851d 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -13,14 +13,14 @@
 // CHECK: @_T016class_resilience33ClassWithResilientlySizedPropertyC1r16resilient_struct9RectangleVvpWvd = {{(protected )?}}global [[INT]] 0
 // CHECK: @_T016class_resilience33ClassWithResilientlySizedPropertyC5colors5Int32VvpWvd = {{(protected )?}}global [[INT]] 0
 
-// CHECK: @_T016class_resilience14ResilientChildC5fields5Int32VvpWvd = {{(protected )?}}global [[INT]] {{12|16}}
+// CHECK: @_T016class_resilience14ResilientChildC5fields5Int32VvpWvd = {{(protected )?}}global [[INT]] {{8|16}}
 // CHECK: @_T016class_resilience21ResilientGenericChildC5fields5Int32VvpWvi = {{(protected )?}}global [[INT]] {{56|88}}
 
-// CHECK: @_T016class_resilience28ClassWithMyResilientPropertyC1rAA0eF6StructVvpWvd = {{(protected )?}}constant [[INT]] {{12|16}}
-// CHECK: @_T016class_resilience28ClassWithMyResilientPropertyC5colors5Int32VvpWvd = {{(protected )?}}constant [[INT]] {{16|20}}
+// CHECK: @_T016class_resilience28ClassWithMyResilientPropertyC1rAA0eF6StructVvpWvd = {{(protected )?}}constant [[INT]] {{8|16}}
+// CHECK: @_T016class_resilience28ClassWithMyResilientPropertyC5colors5Int32VvpWvd = {{(protected )?}}constant [[INT]] {{12|20}}
 
-// CHECK: @_T016class_resilience30ClassWithIndirectResilientEnumC1s14resilient_enum10FunnyShapeOvpWvd = {{(protected )?}}constant [[INT]] {{12|16}}
-// CHECK: @_T016class_resilience30ClassWithIndirectResilientEnumC5colors5Int32VvpWvd = {{(protected )?}}constant [[INT]] {{16|24}}
+// CHECK: @_T016class_resilience30ClassWithIndirectResilientEnumC1s14resilient_enum10FunnyShapeOvpWvd = {{(protected )?}}constant [[INT]] {{8|16}}
+// CHECK: @_T016class_resilience30ClassWithIndirectResilientEnumC5colors5Int32VvpWvd = {{(protected )?}}constant [[INT]] {{12|24}}
 
 import resilient_class
 import resilient_struct
diff --git a/test/IRGen/existentials_opaque_boxed.sil b/test/IRGen/existentials_opaque_boxed.sil
index 02c153a..2a57c9f 100644
--- a/test/IRGen/existentials_opaque_boxed.sil
+++ b/test/IRGen/existentials_opaque_boxed.sil
@@ -80,7 +80,7 @@
 // CHECK:  [[CONTAINER:%.*]] = alloca %T25existentials_opaque_boxed11ExistentialP
 // CHECK:  [[INLINEBUFFER:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* [[CONTAINER]], i32 0, i32 0
 // CHECK:  [[INLINEBUFFER:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* [[CONTAINER]], i32 0, i32 0
-// CHECK:  [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* getelementptr inbounds (%swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), {{(i64|i32)}} 48, {{(i64|i32)}} 7)
+// CHECK:  [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* getelementptr inbounds (%swift.full_boxmetadata, %swift.full_boxmetadata* @metadata, i32 0, i32 2), {{(i64 48|i32 40)}}, {{(i64|i32)}} 7)
 // CHECK:  [[BOX_ADDR:%.*]] = bitcast %swift.refcounted* [[BOX]] to <{ %swift.refcounted{{(, \[4 x i8\])?}}, [32 x i8] }>*
 // CHECK:  [[VALUE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted{{(, \[4 x i8\])?}}, [32 x i8] }>, <{ %swift.refcounted{{(, \[4 x i8\])?}}, [32 x i8] }>* [[BOX_ADDR]], i32 0, i32 {{(1|2)}}
 // CHECK:  [[INIT_EXIST_ADDR:%.*]] = bitcast [32 x i8]* [[VALUE_ADDR]] to %T25existentials_opaque_boxed14NotInlineFixedV*
@@ -136,7 +136,7 @@
 // CHECK:   [[VW2:%.*]] = load i8*, i8** [[VW_ADDR2]]
 // CHECK:   [[SIZE:%.*]] = ptrtoint i8* [[VW2]] to {{(i64|i32)}}
 // CHECK:   [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
-// CHECK:   [[HEADERSIZEPLUSALIGN:%.*]] = add {{(i64|i32)}} {{(16|12)}}, [[ALIGNMASK]]
+// CHECK:   [[HEADERSIZEPLUSALIGN:%.*]] = add {{(i64 16|i32 8)}}, [[ALIGNMASK]]
 // CHECK:   [[NOTALIGNMASK:%.*]] = xor {{(i64|i32)}} [[ALIGNMASK]], -1
 // CHECK:   [[ALIGNEDSTART:%.*]] = and {{(i64|i32)}} [[HEADERSIZEPLUSALIGN]], [[NOTALIGNMASK]]
 // CHECK:   [[HEAPSIZE:%.*]] = add {{(i64|i32)}} [[ALIGNEDSTART]], [[SIZE]]
@@ -179,7 +179,7 @@
 // CHECK:   [[REFADDR:%.*]] = bitcast [{{(24|12)}} x i8]* %0 to %swift.refcounted**
 // CHECK:   [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[REFADDR]]
 // CHECK:   [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
-// CHECK:   [[HEADERSIZEPLUSALIGN:%.*]] = add {{(i64|i32)}} {{(16|12)}}, [[ALIGNMASK]]
+// CHECK:   [[HEADERSIZEPLUSALIGN:%.*]] = add {{(i64 16|i32 8)}}, [[ALIGNMASK]]
 // CHECK:   [[NOTALIGNMASK:%.*]] = xor {{(i64|i32)}} [[ALIGNMASK]], -1
 // CHECK:   [[ALIGNEDSTART:%.*]] = and {{(i64|i32)}} [[HEADERSIZEPLUSALIGN]], [[NOTALIGNMASK]]
 // CHECK:   [[HEAPOBJ:%.*]] = bitcast %swift.refcounted* %9 to i8*
@@ -519,8 +519,8 @@
 // CHECK:  [[INLINEBUFFER:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* [[CONTAINER]], i32 0, i32 0
 // CHECK:  [[INLINEBUFFER:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* [[CONTAINER]], i32 0, i32 0
 // CHECK:  [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* getelementptr inbounds (%swift.full_boxmetadata, %swift.full_boxmetadata* @metadata.3, i32 0, i32 2), {{(i64|i32)}} 64, {{(i64|i32)}} 31)
-// CHECK:  [[BOX_ADDR:%.*]] = bitcast %swift.refcounted* [[BOX]] to <{ %swift.refcounted, [{{(20|16)}} x i8], [32 x i8] }>*
-// CHECK:  [[VALUE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [{{(20|16)}} x i8], [32 x i8] }>, <{ %swift.refcounted, [{{(20|16)}} x i8], [32 x i8] }>* [[BOX_ADDR]], i32 0, i32 {{(1|2)}}
+// CHECK:  [[BOX_ADDR:%.*]] = bitcast %swift.refcounted* [[BOX]] to <{ %swift.refcounted, [{{(16|24)}} x i8], [32 x i8] }>*
+// CHECK:  [[VALUE_ADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [{{(16|24)}} x i8], [32 x i8] }>, <{ %swift.refcounted, [{{(16|24)}} x i8], [32 x i8] }>* [[BOX_ADDR]], i32 0, i32 {{(1|2)}}
 // CHECK:  [[INIT_EXIST_ADDR:%.*]] = bitcast [32 x i8]* [[VALUE_ADDR]] to %T25existentials_opaque_boxed14FixedOveralignV*
 // CHECK:  [[INLINEBUFFER_ADDR:%.*]] = bitcast [{{(24|12)}} x i8]* [[INLINEBUFFER]] to %swift.refcounted**
 // CHECK:  store %swift.refcounted* [[BOX]], %swift.refcounted** [[INLINEBUFFER_ADDR]]
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index 8e5d64e..56f038f 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -75,7 +75,7 @@
 // CHECK-SAME: <i32 0x8000_0004>,
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x4000_0000 (class) + offset of C.x
-// CHECK-32-SAME: <i32 0x4000_000c> }>
+// CHECK-32-SAME: <i32 0x4000_0008> }>
 // CHECK-64-SAME: <i32 0x4000_0010> }>
 
 // -- %e: C.y
@@ -87,7 +87,7 @@
 // CHECK-SAME: <i32 0x8000_0004>,
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x4000_0000 (class) + offset of C.y
-// CHECK-32-SAME: <i32 0x4000_0010> }>
+// CHECK-32-SAME: <i32 0x4000_000c> }>
 // CHECK-64-SAME: <i32 0x4000_0018> }>
 
 // -- %f: C.z
@@ -99,7 +99,7 @@
 // CHECK-SAME: <i32 0x8000_0004>,
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x4000_0000 (class) + offset of C.z
-// CHECK-32-SAME: <i32 0x4000_001c> }>
+// CHECK-32-SAME: <i32 0x4000_0018> }>
 // CHECK-64-SAME: <i32 0x4000_0030> }>
 
 // -- %g: S.z.x
@@ -118,7 +118,7 @@
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 // CHECK: %swift.type* (i8*)*
 // -- 0x4000_0000 (class) + offset of C.x
-// CHECK-32-SAME: <i32 0x4000_000c> }>
+// CHECK-32-SAME: <i32 0x4000_0008> }>
 // CHECK-64-SAME: <i32 0x4000_0010> }>
 
 // -- %h: C.z.x
@@ -132,7 +132,7 @@
 // CHECK-64-SAME: <i32 0x8000_0014>,
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x4000_0000 (class) + offset of C.z
-// CHECK-32-SAME: <i32 0x4000_001c>,
+// CHECK-32-SAME: <i32 0x4000_0018>,
 // CHECK-64-SAME: <i32 0x4000_0030>,
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 // CHECK: %swift.type* (i8*)*
diff --git a/test/IRGen/literals.sil b/test/IRGen/literals.sil
index ce5987b..b45a16b 100644
--- a/test/IRGen/literals.sil
+++ b/test/IRGen/literals.sil
@@ -7,11 +7,11 @@
 // CHECK: [[U16_0:@.*]] = private unnamed_addr constant [8 x i16] [i16 104, i16 101, i16 108, i16 112, i16 9, i16 109, i16 101, i16 0]
 // CHECK: [[U16_1:@.*]] = private unnamed_addr constant [4 x i16] [i16 0, i16 120, i16 427, i16 0]
 // CHECK: @_T0s19_UTF16StringStorageCN = external global %objc_class
-// CHECK: [[UTF16_CSTR_0:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, i8, [8 x i16] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s19_UTF16StringStorageCN to %swift.type*), i32 4, i32 0 }, i32 7, i32 8, i8 0, i8 0, [8 x i16] [i16 104, i16 101, i16 108, i16 112, i16 9, i16 109, i16 101, i16 0] }
-// CHECK: [[UTF16_CSTR_1:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, i8, [9 x i16] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s19_UTF16StringStorageCN to %swift.type*), i32 4, i32 0 }, i32 8, i32 9, i8 0, i8 0, [9 x i16] [i16 104, i16 101, i16 108, i16 112, i16 9, i16 109, i16 101, i16 0, i16 0] }
+// CHECK: [[UTF16_CSTR_0:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, i8, [8 x i16] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s19_UTF16StringStorageCN to %swift.type*), i64 8589934594 }, i32 7, i32 8, i8 0, i8 0, [8 x i16] [i16 104, i16 101, i16 108, i16 112, i16 9, i16 109, i16 101, i16 0] }
+// CHECK: [[UTF16_CSTR_1:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, i8, [9 x i16] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s19_UTF16StringStorageCN to %swift.type*), i64 8589934594 }, i32 8, i32 9, i8 0, i8 0, [9 x i16] [i16 104, i16 101, i16 108, i16 112, i16 9, i16 109, i16 101, i16 0, i16 0] }
 // CHECK: @_T0s20_Latin1StringStorageCN = external global %objc_class
-// CHECK: [[CSTR_0:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, [12 x i8] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s20_Latin1StringStorageCN to %swift.type*), i32 4, i32 0 }, i32 11, i32 12, i8 0, [12 x i8] c"help\09me too\00" }
-// CHECK: [[CSTR_1:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, [13 x i8] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s20_Latin1StringStorageCN to %swift.type*), i32 4, i32 0 }, i32 12, i32 13, i8 0, [13 x i8] c"help\09me too\00\00" }
+// CHECK: [[CSTR_0:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, [12 x i8] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s20_Latin1StringStorageCN to %swift.type*), i64 8589934594 }, i32 11, i32 12, i8 0, [12 x i8] c"help\09me too\00" }
+// CHECK: [[CSTR_1:@.*]] = private unnamed_addr constant { %swift.refcounted, i32, i32, i8, [13 x i8] } { %swift.refcounted { %swift.type* bitcast (%objc_class* @_T0s20_Latin1StringStorageCN to %swift.type*), i64 8589934594 }, i32 12, i32 13, i8 0, [13 x i8] c"help\09me too\00\00" }
 
 sil_stage canonical
 
diff --git a/test/IRGen/objc_class_empty_fields.swift b/test/IRGen/objc_class_empty_fields.swift
index 5a3e204..dfdb5fd 100644
--- a/test/IRGen/objc_class_empty_fields.swift
+++ b/test/IRGen/objc_class_empty_fields.swift
@@ -5,7 +5,7 @@
 // SR-1055
 
 // CHECK-64: @_DATA__TtC23objc_class_empty_fields14OneEnumWrapper = private constant { {{.*}}* } { i32 {{[0-9]+}}, i32 16, i32 24
-// CHECK-32: @_DATA__TtC23objc_class_empty_fields14OneEnumWrapper = private constant { {{.*}}* } { i32 {{[0-9]+}}, i32 12, i32 16
+// CHECK-32: @_DATA__TtC23objc_class_empty_fields14OneEnumWrapper = private constant { {{.*}}* } { i32 {{[0-9]+}}, i32 8, i32 12
 
 enum OneCaseEnum {
     case X
diff --git a/test/IRGen/typed_boxes.sil b/test/IRGen/typed_boxes.sil
index 8999242..502d614 100644
--- a/test/IRGen/typed_boxes.sil
+++ b/test/IRGen/typed_boxes.sil
@@ -7,15 +7,13 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @pod_box_8_8_a
 sil @pod_box_8_8_a : $@convention(thin) () -> () {
 entry:
-  // CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[POD_8_8_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD:i[0-9]+]] 24, [[WORD]] 7)
+  // CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[POD_8_8_METADATA:@metadata[0-9.]*]], i32 0, i32 2), [[WORD:i[0-9]+]] [[POD_8_8_SIZE:[0-9]+]], [[WORD]] 7)
   %a = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.Int64>
-  // CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[4 x i8\], \[8 x i8\] \}>]]*
-  // CHECK-32: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 2
-  // CHECK-64: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[8 x i8\] \}>]]*
-  // CHECK-64: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
+  // CHECK: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[8 x i8\] \}>]]*
+  // CHECK: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
   // CHECK: [[BOX_DATA_1:%.*]] = bitcast [8 x i8]* [[BOX_DATA]] to i64*
   %b = project_box %a : $<τ_0_0> { var τ_0_0 } <Builtin.Int64>, 0
-  // CHECK: call void @swift_rt_swift_deallocUninitializedObject(%swift.refcounted* [[BOX]], [[WORD]] 24, [[WORD]] 7)
+  // CHECK: call void @swift_rt_swift_deallocUninitializedObject(%swift.refcounted* [[BOX]], [[WORD]] [[POD_8_8_SIZE]], [[WORD]] 7)
   dealloc_box %a : $<τ_0_0> { var τ_0_0 } <Builtin.Int64>
   return undef : $()
 }
@@ -23,15 +21,13 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @pod_box_8_8_b
 sil @pod_box_8_8_b : $@convention(thin) () -> () {
 entry:
-  // CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[POD_8_8_METADATA]], {{.*}} [[WORD]] 24, [[WORD]] 7)
+  // CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[POD_8_8_METADATA]], i32 0, i32 2), [[WORD]] [[POD_8_8_SIZE]], [[WORD]] 7)
   %a = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.FPIEEE64>
-  // CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[4 x i8\], \[8 x i8\] \}>]]*
-  // CHECK-32: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 2
-  // CHECK-64: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[8 x i8\] \}>]]*
-  // CHECK-64: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
+  // CHECK: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[8 x i8\] \}>]]*
+  // CHECK: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
   // CHECK: [[BOX_DATA_1:%.*]] = bitcast [8 x i8]* [[BOX_DATA]] to double*
   %b = project_box %a : $<τ_0_0> { var τ_0_0 } <Builtin.FPIEEE64>, 0
-  // CHECK: call void @swift_rt_swift_deallocUninitializedObject(%swift.refcounted* [[BOX]], [[WORD]] 24, [[WORD]] 7)
+  // CHECK: call void @swift_rt_swift_deallocUninitializedObject(%swift.refcounted* [[BOX]], [[WORD]] [[POD_8_8_SIZE]], [[WORD]] 7)
   dealloc_box %a : $<τ_0_0> { var τ_0_0 } <Builtin.FPIEEE64>
   return undef : $()
 }
@@ -46,7 +42,7 @@
 entry:
   // CHECK: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[POD_32_32_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 64, [[WORD]] 31)
   %a = alloc_box $<τ_0_0> { var τ_0_0 } <OverAligned>
-  // CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_32_LAYOUT:<\{ %swift.refcounted, \[20 x i8\], \[32 x i8\] \}>]]*
+  // CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_32_LAYOUT:<\{ %swift.refcounted, \[24 x i8\], \[32 x i8\] \}>]]*
   // CHECK-64: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* [[BOX]] to [[POD_32_32_LAYOUT:<\{ %swift.refcounted, \[16 x i8\], \[32 x i8\] \}>]]*
   // CHECK: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_32_32_LAYOUT]], [[POD_32_32_LAYOUT]]* [[BOX_RAW]], i32 0, i32 2
   // CHECK: [[BOX_DATA_1:%.*]] = bitcast [32 x i8]* [[BOX_DATA]] to %T11typed_boxes11OverAlignedV*
@@ -65,7 +61,7 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @rc_box_a
 sil @rc_box_a : $@convention(thin) () -> () {
 entry:
-  // CHECK-32: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[NATIVE_RC_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 16, [[WORD]] 3)
+  // CHECK-32: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[NATIVE_RC_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 12, [[WORD]] 3)
   // CHECK-64: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[NATIVE_RC_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 24, [[WORD]] 7)
   %a = alloc_box $<τ_0_0> { var τ_0_0 } <C>
   // CHECK: bitcast %swift.refcounted** {{%.*}} to %T11typed_boxes1CC**
@@ -78,7 +74,7 @@
 sil @rc_box_b : $@convention(thin) () -> () {
 entry:
   // TODO: Should reuse metadata
-  // CHECK-32: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[NATIVE_RC_METADATA]], {{.*}} [[WORD]] 16, [[WORD]] 3)
+  // CHECK-32: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[NATIVE_RC_METADATA]], {{.*}} [[WORD]] 12, [[WORD]] 3)
   // CHECK-64: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[NATIVE_RC_METADATA]], {{.*}} [[WORD]] 24, [[WORD]] 7)
   %a = alloc_box $<τ_0_0> { var τ_0_0 } <D>
   // CHECK: bitcast %swift.refcounted** {{%.*}} to %T11typed_boxes1DC**
@@ -90,7 +86,7 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @unknown_rc_box
 sil @unknown_rc_box : $@convention(thin) () -> () {
 entry:
-  // CHECK-32: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[UNKNOWN_RC_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 16, [[WORD]] 3)
+  // CHECK-32: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[UNKNOWN_RC_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 12, [[WORD]] 3)
   // CHECK-64: [[BOX:%.*]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* {{.*}} [[UNKNOWN_RC_METADATA:@metadata[0-9.]*]], {{.*}} [[WORD]] 24, [[WORD]] 7)
   %a = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.UnknownObject>
   %b = project_box %a : $<τ_0_0> { var τ_0_0 } <Builtin.UnknownObject>, 0
@@ -158,10 +154,8 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc i64 @proj_box
 sil @proj_box : $@convention(thin) (<τ_0_0> { var τ_0_0 } <Builtin.Int64>) -> Builtin.Int64 {
 entry(%0 : $<τ_0_0> { var τ_0_0 } <Builtin.Int64>):
-  // CHECK-32: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* %0 to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[4 x i8\], \[8 x i8\] \}>]]*
-  // CHECK-32: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 2
-  // CHECK-64: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* %0 to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[8 x i8\] \}>]]*
-  // CHECK-64: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
+  // CHECK: [[BOX_RAW:%.*]] = bitcast %swift.refcounted* %0 to [[POD_8_8_LAYOUT:<\{ %swift.refcounted, \[8 x i8\] \}>]]*
+  // CHECK: [[BOX_DATA:%.*]] = getelementptr inbounds [[POD_8_8_LAYOUT]], [[POD_8_8_LAYOUT]]* [[BOX_RAW]], i32 0, i32 1
   // CHECK: [[BOX_DATA_1:%.*]] = bitcast [8 x i8]* [[BOX_DATA]] to i64*
   %p = project_box %0 : $<τ_0_0> { var τ_0_0 } <Builtin.Int64>, 0
   // CHECK: [[R:%.*]] = load i64, i64* [[BOX_DATA_1]]
diff --git a/test/IRGen/vector_reduction.swift b/test/IRGen/vector_reduction.swift
index aa93041..8ebc383 100644
--- a/test/IRGen/vector_reduction.swift
+++ b/test/IRGen/vector_reduction.swift
@@ -7,7 +7,7 @@
 
 // We were missing target transform info and not vectorizing the loop below.
 
-// CHECK: xor <2 x i64>
+// CHECK: xor <{{(2|4|8)}} x i64>
 
 public func f(a: UnsafePointer<Int>, b: UnsafePointer<Int>, count: Int) -> Int {
   var c = 0
diff --git a/test/SIL/Parser/coroutines.sil b/test/SIL/Parser/coroutines.sil
new file mode 100644
index 0000000..2841c71
--- /dev/null
+++ b/test/SIL/Parser/coroutines.sil
@@ -0,0 +1,47 @@
+// RUN: %target-swift-frontend %s -emit-silgen -verify
+
+sil_stage raw
+
+import Swift
+
+sil @once_signature : $@yield_once () -> (@yields Int, @yields Float) {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
+
+sil @many_signature : $@yield_many () -> (@yields Int, @yields Float) {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
+
+sil @yield : $@yield_once (Int, Float) -> (@yields Int, @yields Float) {
+bb0(%0 : $Int, %1 : $Float):
+  yield (%0 : $Int, %1 : $Float), resume bb1, unwind bb2
+
+bb1:
+  %r = tuple ()
+  return %r : $()
+
+bb2:
+  unwind
+}
+
+sil @yield_many : $@yield_many (Int, Float) -> (@yields Int, @yields Float) {
+bb0(%0 : $Int, %1 : $Float):
+  yield (%0 : $Int, %1 : $Float), resume bb1, unwind bb3
+
+bb1:
+  yield (%0 : $Int, %1 : $Float), resume bb2, unwind bb4
+
+bb2:
+  %r = tuple ()
+  return %r : $()
+
+bb3:
+  unwind
+
+bb4:
+  unwind
+}
diff --git a/test/SIL/Parser/coroutines_failure_merge.sil b/test/SIL/Parser/coroutines_failure_merge.sil
new file mode 100644
index 0000000..bf791ee
--- /dev/null
+++ b/test/SIL/Parser/coroutines_failure_merge.sil
@@ -0,0 +1,20 @@
+// RUN: not --crash %target-swift-frontend %s -emit-silgen -verify
+
+sil_stage raw
+
+import Swift
+
+sil @yield : $@yield_many (Int, Float) -> (@yields Int, @yields Float) {
+bb0(%0 : $Int, %1 : $Float):
+  yield (%0 : $Int, %1 : $Float), resume bb1, unwind bb2
+
+bb1:
+  br bb3
+
+bb2:
+  br bb3
+
+bb3:
+  unreachable
+}
+
diff --git a/test/SIL/Parser/coroutines_failure_unwind_return.sil b/test/SIL/Parser/coroutines_failure_unwind_return.sil
new file mode 100644
index 0000000..4f66823
--- /dev/null
+++ b/test/SIL/Parser/coroutines_failure_unwind_return.sil
@@ -0,0 +1,18 @@
+// RUN: not --crash %target-swift-frontend %s -emit-silgen -verify
+
+sil_stage raw
+
+import Swift
+
+sil @yield : $@yield_once (Int, Float) -> (@yields Int, @yields Float) {
+bb0(%0 : $Int, %1 : $Float):
+  yield (%0 : $Int, %1 : $Float), resume bb1, unwind bb2
+
+bb1:
+  %r = tuple ()
+  return %r : $()
+
+bb2:
+  %r2 = tuple ()
+  return %r2 : $()
+}
diff --git a/test/SIL/Parser/coroutines_failure_unwind_reuse.sil b/test/SIL/Parser/coroutines_failure_unwind_reuse.sil
new file mode 100644
index 0000000..39c6dfb
--- /dev/null
+++ b/test/SIL/Parser/coroutines_failure_unwind_reuse.sil
@@ -0,0 +1,24 @@
+// RUN: not --crash %target-swift-frontend %s -emit-silgen -verify
+
+sil_stage raw
+
+import Swift
+
+sil @yield : $@yield_many (Int, Float) -> (@yields Int, @yields Float) {
+bb0(%0 : $Int, %1 : $Float):
+  yield (%0 : $Int, %1 : $Float), resume bb1, unwind bb3
+
+bb1:
+  yield (%0 : $Int, %1 : $Float), resume bb2, unwind bb3
+
+bb2:
+  %r = tuple ()
+  return %r : $()
+
+bb3:
+  unwind
+
+bb4:
+  unwind
+}
+
diff --git a/test/SIL/Parser/coroutines_failure_yieldonce_return.sil b/test/SIL/Parser/coroutines_failure_yieldonce_return.sil
new file mode 100644
index 0000000..05de652
--- /dev/null
+++ b/test/SIL/Parser/coroutines_failure_yieldonce_return.sil
@@ -0,0 +1,11 @@
+// RUN: not --crash %target-swift-frontend %s -emit-silgen -verify
+
+sil_stage canonical
+
+import Swift
+
+sil @once_signature : $@yield_once () -> (@yields Int, @yields Float) {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
diff --git a/test/SIL/Parser/coroutines_failure_yieldonce_twice.sil b/test/SIL/Parser/coroutines_failure_yieldonce_twice.sil
new file mode 100644
index 0000000..382169d
--- /dev/null
+++ b/test/SIL/Parser/coroutines_failure_yieldonce_twice.sil
@@ -0,0 +1,24 @@
+// RUN: not --crash %target-swift-frontend %s -emit-silgen -verify
+
+sil_stage canonical
+
+import Swift
+
+sil @yield : $@yield_once (Int, Float) -> (@yields Int, @yields Float) {
+bb0(%0 : $Int, %1 : $Float):
+  yield (%0 : $Int, %1 : $Float), resume bb1, unwind bb3
+
+bb1:
+  yield (%0 : $Int, %1 : $Float), resume bb2, unwind bb4
+
+bb2:
+  %r = tuple ()
+  return %r : $()
+
+bb3:
+  unwind
+
+bb4:
+  unwind
+}
+
diff --git a/test/SILGen/transparent_attribute.swift b/test/SILGen/transparent_attribute.swift
index 8174a77..f0a72fd 100644
--- a/test/SILGen/transparent_attribute.swift
+++ b/test/SILGen/transparent_attribute.swift
@@ -1,212 +1,14 @@
 // RUN: %target-swift-frontend -emit-silgen -emit-verbose-sil -enable-sil-ownership %s | %FileCheck %s
 
 // Test that the attribute gets set on default argument generators.
+
+// CHECK-LABEL: sil hidden [transparent] @_T021transparent_attribute0A23FuncWithDefaultArgumentS2i1x_tFfA_ : $@convention(thin) () -> Int {
+
+// CHECK-LABEL: sil hidden [transparent] @_T021transparent_attribute0A23FuncWithDefaultArgumentS2i1x_tF : $@convention(thin) (Int) -> Int {
+
 @_transparent func transparentFuncWithDefaultArgument (x: Int = 1) -> Int {
   return x
 }
 func useTransparentFuncWithDefaultArgument() -> Int {
-  return transparentFuncWithDefaultArgument();
-
-  // CHECK-LABEL: sil hidden @_T021transparent_attribute37useTransparentFuncWithDefaultArgumentSiyF
-  // CHECK: apply {{.*}} line:8:44
-  // CHECK: apply {{.*}} line:8:10
-  // CHECK: return
-  
-}
-
-func transparentFuncWithoutDefaultArgument (x: Int = 1) -> Int {
-  return x
-}
-func useTransparentFuncWithoutDefaultArgument() -> Int {
-  return transparentFuncWithoutDefaultArgument();
-
-  // CHECK-LABEL: sil hidden @_T021transparent_attribute40useTransparentFuncWithoutDefaultArgumentSiyF
-  // CHECK: apply {{.*}} line:21:47
-  // CHECK-NOT: transparent
-  // CHECK: apply {{.*}} line:21:10
-  // CHECK: return
-  
-}
-
-// Make sure the transparent attribute is set on constructors (allocating and initializing).
-struct StructWithTranspConstructor {
-  @_transparent init () {}
-}
-func testStructWithTranspConstructor() -> StructWithTranspConstructor {
-  return StructWithTranspConstructor()
-  
-  // transparent_attribute.StructWithTranspConstructor.constructor
-  // CHECK-APPLY: sil hidden @_T021transparent_attribute27StructWithTranspConstructorV{{[_0-9a-zA-Z]*}}fC
-  
-  // testStructWithTranspConstructor
-  // CHECK-APPLY: _T21transparent_attribute31testStructWithTranspConstructorFT_VS_27StructWithTranspConstructor
-  // CHECK: apply {{.*}} line:36:10
-  
-}
-
-struct MySt {}
-var _x = MySt()
-var x1 : MySt {
-  @_transparent
-  get {
-    return _x
-  }
-  @_transparent
-  set {
-    _x = newValue
-  }
-}
-var x2 : MySt {
-  @_transparent
-  set(v) {
-    _x = v
-  }
-  @_transparent
-  get {
-    return _x
-  }
-}
-func testProperty(z: MySt) {
-  x1 = z
-  x2 = z
-  var m1 : MySt = x1
-  var m2 : MySt = x2
-  // CHECK-APPLY: sil hidden @_T021transparent_attribute12testPropertyyAA4MyStV1z_tF
-  // CHECK: function_ref @_T021transparent_attribute2x1AA4MyStVvs
-  // CHECK-NEXT: apply
-  // CHECK: function_ref @_T021transparent_attribute2x2AA4MyStVvs
-  // CHECK-NEXT: apply
-  // CHECK: function_ref @_T021transparent_attribute2x1AA4MyStVvg
-  // CHECK-NEXT: apply
-  // CHECK: function_ref @_T021transparent_attribute2x2AA4MyStVvg
-  // CHECK-NEXT: apply
-}
-
-var _tr2 = MySt()
-var _tr3 = MySt()
-struct MyTranspStruct {}
-extension MyTranspStruct {
-  @_transparent
-  init(input : MySt) {}
-  mutating
-  func tr1() {}
-  var tr2: MySt {
-    get {
-      return _tr2
-    }
-    set {
-      _tr2 = newValue
-    }
-  }
-}
-
-extension MyTranspStruct {
-    @_transparent
-    var tr3: MySt {
-    get {
-      return _tr3
-    }
-    set {
-      _tr3 = newValue
-    }
-  }
-}
-
-func testStructExtension() {
-  var c : MyTranspStruct = MyTranspStruct(input: _x)
-  c.tr1()
-  var s : MySt = c.tr2
-  var t : MySt = c.tr3
-  // CHECK-APPLY: sil hidden @_TF21transparent_attribute13testStructExtensionFT_T_
-  // CHECK: [[INIT:%[0-9]+]] = function_ref @_T021transparent_attribute14MyTranspStructV{{[_0-9a-zA-Z]*}}fC
-  // CHECK: apply [[INIT]]
-  // CHECK: [[TR1:%[0-9]+]] = function_ref @_T021transparent_attribute14MyTranspStructV3tr1{{[_0-9a-zA-Z]*}}F
-  // CHECK: apply [[TR1]]
-  // CHECK: [[TR2:%[0-9]+]] = function_ref @_T021transparent_attribute14MyTranspStructV3tr2AA0C2StVvg
-  // CHECK: apply [[TR2]]
-  // CHECK: [[TR3:%[0-9]+]] = function_ref @_T021transparent_attribute14MyTranspStructV3tr3AA0C2StVvg
-  // CHECK: apply [[TR3]]
-}
-
-enum MyEnum {
-  case onetransp
-  case twotransp
-}
-
-extension MyEnum {
-  @_transparent
-  func tr3() {}
-}
-
-func testEnumExtension() {
-  MyEnum.onetransp.tr3()
-  // CHECK-APPLY: sil hidden @_T021transparent_attribute17testEnumExtensionyyF
-  // CHECK: [[TR3:%[0-9]+]] = function_ref @_T021transparent_attribute6MyEnumO3tr3{{[_0-9a-zA-Z]*}}F
-  // CHECK: [[INIT:%[0-9]+]] = enum $MyEnum, #MyEnum.onetransp!enumelt
-  // CHECK: apply [[TR3]]([[INIT]])
-}
-
-struct testVarDecl {
-  @_transparent var max: Int {
-    get {
-      return 0xFF
-    }
-    mutating
-    set {
-      max = 0xFF
-    }
-  }
-  func testVarDeclFoo () {
-    var z: Int = max
-    // CHECK-APPLY: sil hidden @_T021transparent_attribute11testVarDeclV0cdE3Foo{{[_0-9a-zA-Z]*}}F
-    // CHECK: [[TR4:%[0-9]+]] = function_ref @_T021transparent_attribute11testVarDeclV3maxSivg
-    // CHECK: apply [[TR4]]
-  }
-}
-
-struct testVarDeclShortenedSyntax {
-  @_transparent static var max: Int { return 0xFF };
-  func testVarDeclShortenedSyntaxfoo () {
-    var z: Int = testVarDeclShortenedSyntax.max
-    // CHECK-APPLY: sil hidden @_T021transparent_attribute26testVarDeclShortenedSyntaxV0cdeF9Syntaxfoo{{[_0-9a-zA-Z]*}}F
-    // CHECK: [[TR5:%[0-9]+]] = function_ref @_T021transparent_attribute26testVarDeclShortenedSyntaxV3maxSivgZ
-    // CHECK: apply [[TR5]]
-  }
-};
-
-@_transparent var transparentOnGlobalVar: Int {
-  get {
-    return 0xFF
-  }
-}
-// CHECK: sil hidden [transparent] @_T021transparent_attribute0A11OnGlobalVarSivg
-
-// Local functions in transparent context are fragile.
-@_transparent public func foo() {
-  // CHECK-LABEL: sil shared [serialized] @_T021transparent_attribute3fooyyF3barL_yyF : $@convention(thin) () -> ()
-  func bar() {}
-  bar()
-
-  // CHECK-LABEL: sil shared [serialized] @_T021transparent_attribute3fooyyFyycfU_ : $@convention(thin) () -> () {
-  let f: () -> () = {}
-  f()
-
-  // CHECK-LABEL: sil shared [serialized] @_T021transparent_attribute3fooyyF3zimL_yyF : $@convention(thin) () -> () {
-  func zim() {
-    // CHECK-LABEL: sil shared [serialized] @_T021transparent_attribute3fooyyF3zimL_yyF4zangL_yyF : $@convention(thin) () -> () {
-    func zang() {
-    }
-    zang()
-  }
-  zim()
-}
-
-
-// Check that @_versioned entities have public linkage.
-// CHECK-LABEL: sil @_T021transparent_attribute25referencedFromTransparentyyF : $@convention(thin) () -> () {
-@_versioned func referencedFromTransparent() {}
-
-// CHECK-LABEL: sil [transparent] [serialized] @_T021transparent_attribute23referencesVersionedFuncyycyF : $@convention(thin) () -> @owned @callee_owned () -> () {
-@_transparent public func referencesVersionedFunc() -> () -> () {
-  return referencedFromTransparent
+  return transparentFuncWithDefaultArgument()
 }
diff --git a/test/SILGen/versioned_attribute.swift b/test/SILGen/versioned_attribute.swift
index 5a01525..b544b48 100644
--- a/test/SILGen/versioned_attribute.swift
+++ b/test/SILGen/versioned_attribute.swift
@@ -1,5 +1,14 @@
 // RUN: %target-swift-frontend -emit-silgen -enable-sil-ownership -emit-verbose-sil %s | %FileCheck %s
 
+// Check that @_versioned entities have public linkage.
+// CHECK-LABEL: sil @_T019versioned_attribute25referencedFromTransparentyyF : $@convention(thin) () -> () {
+@_versioned func referencedFromTransparent() {}
+
+// CHECK-LABEL: sil [serialized] @_T019versioned_attribute23referencesVersionedFuncyycyF : $@convention(thin) () -> @owned @callee_owned () -> () {
+@_inlineable public func referencesVersionedFunc() -> () -> () {
+  return referencedFromTransparent
+}
+
 @_versioned class Horse {
   var mouth: AnyObject?
 }
diff --git a/test/Sema/diag_erroneous_iuo.swift b/test/Sema/diag_erroneous_iuo.swift
index 2e51057..d938be6 100644
--- a/test/Sema/diag_erroneous_iuo.swift
+++ b/test/Sema/diag_erroneous_iuo.swift
@@ -81,6 +81,8 @@
 
   var x: V
   var y: W
+  var fn1: (Int!) -> Int // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  var fn2: (Int) -> Int! // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
 
   subscript (
     index: ImplicitlyUnwrappedOptional<Int> // expected-error {{the spelling 'ImplicitlyUnwrappedOptional' is unsupported; use '!' after the type name}}{{12-40=}}{{43-43=!}}{{43-44=}}
@@ -138,18 +140,53 @@
 func vararg(_ first: Int, more: Int!...) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
 }
 
+func varargIdentifier(_ first: Int, more: ImplicitlyUnwrappedOptional<Int>...) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+}
+
 func iuoInTuple() -> (Int!) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
   return 1
 }
 
-func iuoInTuple2() -> (Float, Int!) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+func iuoInTupleIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
   return 1
 }
 
+func iuoInTuple2() -> (Float, Int!) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return (1.0, 1)
+}
+
+func iuoInTuple2Identifier() -> (Float, ImplicitlyUnwrappedOptional<Int>) { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return (1.0, 1)
+}
+
 func takesFunc(_ fn: (Int!) -> Int) -> Int { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
   return fn(0)
 }
 
+func takesFuncIdentifier(_ fn: (ImplicitlyUnwrappedOptional<Int>) -> Int) -> Int { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return fn(0)
+}
+
+func takesFunc2(_ fn: (Int) -> Int!) -> Int { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return fn(0)
+}
+
+func takesFunc2Identifier(_ fn: (Int) -> ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return fn(0)
+}
+
 func returnsFunc() -> (Int!) -> Int { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
   return { $0 }
 }
+
+func returnsFuncIdentifier() -> (ImplicitlyUnwrappedOptional<Int>) -> Int { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return { $0 }
+}
+
+func returnsFunc2() -> (Int) -> Int! { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return { $0 }
+}
+
+func returnsFunc2Identifier() -> (Int) -> ImplicitlyUnwrappedOptional<Int> { // expected-error {{implicitly unwrapped optionals are only allowed at top level and as function results}}
+  return { $0 }
+}
diff --git a/test/SourceKit/Indexing/index_swift_lib.swift b/test/SourceKit/Indexing/index_swift_lib.swift
deleted file mode 100644
index 16f52a2..0000000
--- a/test/SourceKit/Indexing/index_swift_lib.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-// REQUIRES: FIXME
-
-// RUN: %sourcekitd-test -req=index %swiftlib_dir/macosx/x86_64/Swift.swiftmodule -- %mcp_opt > %t.txt
-// RUN: %FileCheck %s -input-file %t.txt
-
-// CHECK:      key.name: "Dictionary",
-// CHECK-NEXT: key.usr: "s:Vs10Dictionary",
-
-// RUN: %FileCheck %s -input-file %t.txt -check-prefix=CHECK-INTERNAL
-// RUN: %sourcekitd-test -req=index %swiftlib_dir/macosx/x86_64/Foundation.swiftmodule -- %clang-importer-sdk %mcp_opt > %t.foundation.txt
-// RUN: %FileCheck %s -input-file %t.foundation.txt -check-prefix=CHECK-FOUNDATION
-
-// CHECK-INTERNAL-NOT: key.name: "_bridgeToObjectiveCUnconditional",
-
-// CHECK-FOUNDATION-NOT: _convertStringToNSString
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 6c36768..94fd5c1 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -6,14 +6,26 @@
 class C {<UnknownDecl>
   func bar(_ a: Int) <CodeBlock>{}</CodeBlock></UnknownDecl><UnknownDecl>
   func bar1(_ a: Float) -> Float <CodeBlock>{ <UnknownStmt>return <UnknownExpr><FloatLiteralExpr>-0.6 </FloatLiteralExpr>+ <FloatLiteralExpr>0.1 </FloatLiteralExpr>- <FloatLiteralExpr>0.3 </FloatLiteralExpr></UnknownExpr></UnknownStmt>}</CodeBlock></UnknownDecl><UnknownDecl>
+  func bar2(a: Int, b: Int, c:Int) -> Int <CodeBlock>{ <UnknownStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></UnknownStmt>}</CodeBlock></UnknownDecl><UnknownDecl>
+  func bar3(a: Int) -> Int <CodeBlock>{ <UnknownStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></UnknownStmt>}</CodeBlock></UnknownDecl><UnknownDecl>
+  func bar4(_ a: Int) -> Int <CodeBlock>{ <UnknownStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></UnknownStmt>}</CodeBlock></UnknownDecl><UnknownDecl>
   func foo() <CodeBlock>{<UnknownDecl>
     var a = /*comment*/<StringLiteralExpr>"abc"/*comment*/</StringLiteralExpr></UnknownDecl><UnknownDecl>
     var b = /*comment*/<IntegerLiteralExpr>+2/*comment*/</IntegerLiteralExpr></UnknownDecl><UnknownExpr>
-    bar(<IntegerLiteralExpr>1</IntegerLiteralExpr>)</UnknownExpr><UnknownExpr>
-    bar(<IntegerLiteralExpr>+10</IntegerLiteralExpr>)</UnknownExpr><UnknownExpr>
-    bar(<IntegerLiteralExpr>-10</IntegerLiteralExpr>)</UnknownExpr><UnknownExpr>
-    bar1(<FloatLiteralExpr>-1.1</FloatLiteralExpr>)</UnknownExpr><UnknownExpr>
-    bar1(<FloatLiteralExpr>1.1</FloatLiteralExpr>)</UnknownExpr><UnknownDecl>
-    var f = /*comments*/<FloatLiteralExpr>+0.1/*comments*/</FloatLiteralExpr></UnknownDecl>
+    bar(<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    bar(<FunctionCallArgument><IntegerLiteralExpr>+10</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    bar(<FunctionCallArgument><IntegerLiteralExpr>-10</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    bar1(<FunctionCallArgument><FloatLiteralExpr>-1.1</FloatLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    bar1(<FunctionCallArgument><FloatLiteralExpr>1.1</FloatLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownDecl>
+    var f = /*comments*/<FloatLiteralExpr>+0.1/*comments*/</FloatLiteralExpr></UnknownDecl><UnknownExpr>
+    foo()</UnknownExpr>
+  }</CodeBlock></UnknownDecl><UnknownDecl>
+
+  func foo1() <CodeBlock>{<UnknownExpr>
+    _ = bar2(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>b:<IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c:<IntegerLiteralExpr>2</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    _ = bar2(<FunctionCallArgument>a:<UnknownExpr><IntegerLiteralExpr>1 </IntegerLiteralExpr>+ <IntegerLiteralExpr>1</IntegerLiteralExpr></UnknownExpr>, </FunctionCallArgument><FunctionCallArgument>b:<UnknownExpr><IntegerLiteralExpr>2 </IntegerLiteralExpr>* <IntegerLiteralExpr>2 </IntegerLiteralExpr>+ <IntegerLiteralExpr>2</IntegerLiteralExpr></UnknownExpr>, </FunctionCallArgument><FunctionCallArgument>c:<UnknownExpr><IntegerLiteralExpr>2 </IntegerLiteralExpr>+ <IntegerLiteralExpr>2</IntegerLiteralExpr></UnknownExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    _ = bar2(<FunctionCallArgument>a : <UnknownExpr>bar2(<FunctionCallArgument>a: <IntegerLiteralExpr>1</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>b: <IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c: <IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr>, </FunctionCallArgument><FunctionCallArgument>b: <IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c: <IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    _ = bar3(<FunctionCallArgument>a : <UnknownExpr>bar3(<FunctionCallArgument>a: <UnknownExpr>bar3(<FunctionCallArgument>a: <IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr></FunctionCallArgument>)</UnknownExpr></FunctionCallArgument>)</UnknownExpr><UnknownExpr>
+    _ = bar4(<FunctionCallArgument><UnknownExpr>bar4(<FunctionCallArgument><UnknownExpr>bar4(<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</UnknownExpr></FunctionCallArgument>)</UnknownExpr></FunctionCallArgument>)</UnknownExpr>
   }</CodeBlock></UnknownDecl>
 }</UnknownDecl>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 839126a..68bc7ef 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -6,6 +6,9 @@
 class C {
   func bar(_ a: Int) {}
   func bar1(_ a: Float) -> Float { return -0.6 + 0.1 - 0.3 }
+  func bar2(a: Int, b: Int, c:Int) -> Int { return 1 }
+  func bar3(a: Int) -> Int { return 1 }
+  func bar4(_ a: Int) -> Int { return 1 }
   func foo() {
     var a = /*comment*/"abc"/*comment*/
     var b = /*comment*/+2/*comment*/
@@ -15,5 +18,14 @@
     bar1(-1.1)
     bar1(1.1)
     var f = /*comments*/+0.1/*comments*/
+    foo()
+  }
+
+  func foo1() {
+    _ = bar2(a:1, b:2, c:2)
+    _ = bar2(a:1 + 1, b:2 * 2 + 2, c:2 + 2)
+    _ = bar2(a : bar2(a: 1, b: 2, c: 3), b: 2, c: 3)
+    _ = bar3(a : bar3(a: bar3(a: 1)))
+    _ = bar4(bar4(bar4(1)))
   }
 }
diff --git a/test/attr/attr_availability_transitive_ios.swift b/test/attr/attr_availability_transitive_ios.swift
new file mode 100644
index 0000000..8ed79a0
--- /dev/null
+++ b/test/attr/attr_availability_transitive_ios.swift
@@ -0,0 +1,37 @@
+// RUN: %target-typecheck-verify-swift
+// REQUIRES: OS=ios
+
+// Allow referencing unavailable API in situations where the caller is marked unavailable in the same circumstances.
+
+@available(iOS, unavailable)
+func ios() {} // expected-note 2{{'ios()' has been explicitly marked unavailable here}}
+
+@available(iOSApplicationExtension, unavailable)
+func ios_extension() {}
+
+func call_ios_extension() {
+    ios_extension() // OK; ios_extension is only unavailable if -application-extension is passed.
+}
+func call_ios() {
+    ios() // expected-error {{'ios()' is unavailable}}
+}
+
+@available(iOS, unavailable)
+func ios_call_ios_extension() {
+    ios_extension() // OK; ios_extension is only unavailable if -application-extension is passed.
+}
+
+@available(iOS, unavailable)
+func ios_call_ios() {
+    ios() // OK; same
+}
+
+@available(iOSApplicationExtension, unavailable)
+func ios_extension_call_ios_extension() {
+    ios_extension()
+}
+
+@available(iOSApplicationExtension, unavailable)
+func ios_extension_call_ios() {
+    ios() // expected-error {{'ios()' is unavailable}}
+}
diff --git a/test/attr/attr_availability_transitive_ios_extension.swift b/test/attr/attr_availability_transitive_ios_extension.swift
new file mode 100644
index 0000000..6f73286
--- /dev/null
+++ b/test/attr/attr_availability_transitive_ios_extension.swift
@@ -0,0 +1,37 @@
+// RUN: %target-typecheck-verify-swift -application-extension
+// REQUIRES: OS=ios
+
+// Allow referencing unavailable API in situations where the caller is marked unavailable in the same circumstances.
+
+@available(iOS, unavailable)
+func ios() {} // expected-note 2{{'ios()' has been explicitly marked unavailable here}}
+
+@available(iOSApplicationExtension, unavailable)
+func ios_extension() {} // expected-note 2{{'ios_extension()' has been explicitly marked unavailable here}}
+
+func call_ios_extension() {
+    ios_extension() // expected-error {{'ios_extension()' is unavailable}}
+}
+func call_ios() {
+    ios() // expected-error {{'ios()' is unavailable}}
+}
+
+@available(iOS, unavailable)
+func ios_call_ios_extension() {
+    ios_extension() // expected-error {{'ios_extension()' is unavailable}}
+}
+
+@available(iOS, unavailable)
+func ios_call_ios() {
+    ios()
+}
+
+@available(iOSApplicationExtension, unavailable)
+func ios_extension_call_ios_extension() {
+    ios_extension()
+}
+
+@available(iOSApplicationExtension, unavailable)
+func ios_extension_call_ios() {
+    ios() // expected-error {{'ios()' is unavailable}}
+}
diff --git a/test/attr/attr_availability_transitive_multiple.swift b/test/attr/attr_availability_transitive_multiple.swift
new file mode 100644
index 0000000..8ef579d
--- /dev/null
+++ b/test/attr/attr_availability_transitive_multiple.swift
@@ -0,0 +1,18 @@
+// RUN: %target-typecheck-verify-swift
+// REQUIRES: OS=macosx
+
+// Check that only the platform we are compiling for is considered when allowing access to unavailable declarations.
+
+@available(iOS, unavailable)
+@available(OSX, unavailable)
+func unavailable() {} // expected-note {{'unavailable()' has been explicitly marked unavailable here}}
+
+@available(iOS, unavailable)
+func call_with_ios_unavailable() {
+	unavailable() // expected-error {{'unavailable()' is unavailable}}
+}
+
+@available(OSX, unavailable)
+func call_with_osx_unavailable() {
+	unavailable() // OK: same
+}
diff --git a/test/attr/attr_availability_transitive_nested.swift b/test/attr/attr_availability_transitive_nested.swift
new file mode 100644
index 0000000..7d8b474
--- /dev/null
+++ b/test/attr/attr_availability_transitive_nested.swift
@@ -0,0 +1,25 @@
+// RUN: %target-typecheck-verify-swift
+// REQUIRES: OS=macosx
+
+// Make sure that a compatible unavailable wrapping doesn't allow referencing declarations that are completely unavailable.
+
+@available(iOS, unavailable)
+class Outer {
+  @available(*, unavailable)
+  func completelyBadMethod() {} // expected-note {{'completelyBadMethod()' has been explicitly marked unavailable here}}
+}
+
+@available(iOS, unavailable)
+func test(outer: Outer) {
+  outer.completelyBadMethod() // expected-error {{'completelyBadMethod()' is unavailable}}
+}
+
+@available(*, unavailable)
+class Outer2 { // expected-note {{'Outer2' has been explicitly marked unavailable here}}
+	@available(iOS, unavailable)
+    func innerUnavailable() {}
+}
+@available(iOS, unavailable)
+func test2(outer: Outer2) { // expected-error {{'Outer2' is unavailable}}
+  outer.innerUnavailable()
+}
diff --git a/test/attr/attr_availability_transitive_osx.swift b/test/attr/attr_availability_transitive_osx.swift
new file mode 100644
index 0000000..eadaf60
--- /dev/null
+++ b/test/attr/attr_availability_transitive_osx.swift
@@ -0,0 +1,37 @@
+// RUN: %target-typecheck-verify-swift
+// REQUIRES: OS=macosx
+
+// Allow referencing unavailable API in situations where the caller is marked unavailable in the same circumstances.
+
+@available(OSX, unavailable)
+func osx() {} // expected-note 2{{'osx()' has been explicitly marked unavailable here}}
+
+@available(OSXApplicationExtension, unavailable)
+func osx_extension() {}
+
+func call_osx_extension() {
+    osx_extension() // OK; osx_extension is only unavailable if -application-extension is passed.
+}
+func call_osx() {
+    osx() // expected-error {{'osx()' is unavailable}}
+}
+
+@available(OSX, unavailable)
+func osx_call_osx_extension() {
+    osx_extension() // OK; osx_extension is only unavailable if -application-extension is passed.
+}
+
+@available(OSX, unavailable)
+func osx_call_osx() {
+    osx() // OK; same
+}
+
+@available(OSXApplicationExtension, unavailable)
+func osx_extension_call_osx_extension() {
+    osx_extension()
+}
+
+@available(OSXApplicationExtension, unavailable)
+func osx_extension_call_osx() {
+    osx() // expected-error {{'osx()' is unavailable}}
+}
diff --git a/test/attr/attr_availability_transitive_osx_extension.swift b/test/attr/attr_availability_transitive_osx_extension.swift
new file mode 100644
index 0000000..949ef68
--- /dev/null
+++ b/test/attr/attr_availability_transitive_osx_extension.swift
@@ -0,0 +1,37 @@
+// RUN: %target-typecheck-verify-swift -application-extension
+// REQUIRES: OS=macosx
+
+// Allow referencing unavailable API in situations where the caller is marked unavailable in the same circumstances.
+
+@available(OSX, unavailable)
+func osx() {} // expected-note 2{{'osx()' has been explicitly marked unavailable here}}
+
+@available(OSXApplicationExtension, unavailable)
+func osx_extension() {} // expected-note 2{{'osx_extension()' has been explicitly marked unavailable here}}
+
+func call_osx_extension() {
+    osx_extension() // expected-error {{'osx_extension()' is unavailable}}
+}
+func call_osx() {
+    osx() // expected-error {{'osx()' is unavailable}}
+}
+
+@available(OSX, unavailable)
+func osx_call_osx_extension() {
+    osx_extension() // expected-error {{'osx_extension()' is unavailable}}
+}
+
+@available(OSX, unavailable)
+func osx_call_osx() {
+    osx()
+}
+
+@available(OSXApplicationExtension, unavailable)
+func osx_extension_call_osx_extension() {
+    osx_extension()
+}
+
+@available(OSXApplicationExtension, unavailable)
+func osx_extension_call_osx() {
+    osx() // expected-error {{'osx()' is unavailable}}
+}
diff --git a/test/decl/ext/protocol.swift b/test/decl/ext/protocol.swift
index 117a0b5..36af2df 100644
--- a/test/decl/ext/protocol.swift
+++ b/test/decl/ext/protocol.swift
@@ -959,3 +959,43 @@
 extension A & B { // okay
 
 }
+
+// Suppress near-miss warning for unlabeled initializers.
+protocol P9 {
+  init(_: Int)
+  init(_: Double)
+}
+
+extension P9 {
+  init(_ i: Int) {
+    self.init(Double(i))
+  }
+}
+
+struct X9 : P9 {
+  init(_: Float) { }
+}
+
+extension X9 {
+  init(_: Double) { }
+}
+
+// Suppress near-miss warning for unlabeled subscripts.
+protocol P10 {
+  subscript (_: Int) -> Int { get }
+  subscript (_: Double) -> Double { get }
+}
+
+extension P10 {
+  subscript(i: Int) -> Int {
+    return Int(self[Double(i)])
+  }
+}
+
+struct X10 : P10 {
+  subscript(f: Float) -> Float { return f }
+}
+
+extension X10 {
+  subscript(d: Double) -> Double { return d }
+}
diff --git a/test/stdlib/KeyPathImplementation.swift b/test/stdlib/KeyPathImplementation.swift
index 8ccde01..8151dc1 100644
--- a/test/stdlib/KeyPathImplementation.swift
+++ b/test/stdlib/KeyPathImplementation.swift
@@ -12,8 +12,7 @@
   return (offset + alignMask) & ~alignMask
 }
 
-// FIXME: Object header size will eventually be MemoryLayout<Int>.size * 2
-let classHeaderSize = MemoryLayout<Int>.size + 8
+let classHeaderSize = MemoryLayout<Int>.size * 2
 
 class C<T> {
   var x: Int
diff --git a/test/stdlib/StringDiagnostics.swift b/test/stdlib/StringDiagnostics.swift
index 2712ee3..1d36b11 100644
--- a/test/stdlib/StringDiagnostics.swift
+++ b/test/stdlib/StringDiagnostics.swift
@@ -53,6 +53,9 @@
   let a10 = nsString <= s // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}} {{21-21= as String}}
   let a11 = nsString >= s // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}} {{21-21= as String}}
   let a12 = nsString > s // expected-error{{'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?}} {{21-21= as String}}
+  
+  // Shouldn't suggest 'as' in a pattern-matching context, as opposed to all these other situations
+  if case nsString = "" {} // expected-error{{expression pattern of type 'NSString' cannot match values of type 'String'}}
 }
 
 func testStringDeprecation(hello: String) {
diff --git a/test/stdlib/TestNSNumberBridging.swift b/test/stdlib/TestNSNumberBridging.swift
index f5c4685..1638226 100644
--- a/test/stdlib/TestNSNumberBridging.swift
+++ b/test/stdlib/TestNSNumberBridging.swift
@@ -658,16 +658,16 @@
             let uint = (number!) as? UInt
             expectEqual(UInt(exactly: interestingValue), uint)
 
-            // these are disabled because of https://bugs.swift.org/browse/SR-4634
-            if uint! != UInt(UInt32.max) && uint! != UInt(UInt32.max - 1) {
-                let float = (number!) as? Float
-                let expectedFloat = Float(uint!)
-                testFloat(expectedFloat, float)
+            let float = (number!) as? Float
+            let expectedFloat = Float(exactly: uint!)
+            if UInt.bitWidth == 32 && uint! >= UInt.max - 1 {
+              expectNil(expectedFloat)
+            } else {
+              testFloat(expectedFloat, float)
             }
-            
-            
+          
             let double = (number!) as? Double
-            let expectedDouble = Double(uint!)
+            let expectedDouble = Double(exactly: uint!)
             testDouble(expectedDouble, double)
         }
         let bridged = interestingValue as NSNumber
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 5cf9e47..943ae43 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -1282,6 +1282,9 @@
       return true;
     if (VD->getBaseName().empty())
       return true;
+    // This shouldn't happen, being forgiving here.
+    if (!VD->hasAccess())
+      return true;
     switch (VD->getFormalAccess()) {
     case AccessLevel::Internal:
     case AccessLevel::Private:
diff --git a/validation-test/Reflection/functions.swift b/validation-test/Reflection/functions.swift
index 3b4e0b2..8786247 100644
--- a/validation-test/Reflection/functions.swift
+++ b/validation-test/Reflection/functions.swift
@@ -26,8 +26,8 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=16 alignment=4 stride=16
-// CHECK-32-NEXT:   (field offset=12
+// CHECK-32-NEXT: (closure_context size=12 alignment=4 stride=12
+// CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
@@ -45,8 +45,8 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=28 alignment=4 stride=28
-// CHECK-32-NEXT:   (field offset=12
+// CHECK-32-NEXT: (closure_context size=24 alignment=4 stride=24
+// CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=metadata offset=12
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096)))))
@@ -85,8 +85,8 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=16 alignment=4 stride=16
-// CHECK-32-NEXT:   (field offset=12
+// CHECK-32-NEXT: (closure_context size=12 alignment=4 stride=12
+// CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
@@ -103,12 +103,12 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=40 alignment=4 stride=40
+// CHECK-32-NEXT: (closure_context size=36 alignment=4 stride=36
+// CHECK-32-NEXT:   (field offset=24
+// CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field offset=28
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field offset=32
-// CHECK-32-NEXT:     (reference kind=strong refcounting=native))
-// CHECK-32-NEXT:   (field offset=36
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native)))
 
 // CHECK-64:      Type info:
@@ -132,14 +132,14 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=28 alignment=4 stride=28
+// CHECK-32-NEXT: (closure_context size=24 alignment=4 stride=24
+// CHECK-32-NEXT:   (field offset=8
+// CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field offset=12
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field offset=16
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field offset=20
-// CHECK-32-NEXT:     (reference kind=strong refcounting=native))
-// CHECK-32-NEXT:   (field offset=24
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native)))
 
 // CHECK-64:      Type info:
@@ -171,7 +171,7 @@
   // CHECK-32: (class functions.CapturingClass)
   
   // CHECK-32: Type info:
-  // CHECK-32: (class_instance size=12 alignment=1 stride=12
+  // CHECK-32: (class_instance size=8 alignment=1 stride=8
   @_semantics("optimize.sil.never")
   func arity0Capture1() -> () -> () {
     let closure = {
@@ -204,8 +204,8 @@
   // CHECK-32: (builtin Builtin.NativeObject)
 
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=32 alignment=8 stride=32
-  // CHECK-32-NEXT:   (field offset=16
+  // CHECK-32:        (closure_context size=24 alignment=8 stride=24
+  // CHECK-32-NEXT:   (field offset=8
   // CHECK-32-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
   // CHECK-32-NEXT:       (field offset=0
   // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
@@ -245,8 +245,8 @@
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=20 alignment=4 stride=20
-  // CHECK-32-NEXT:   (field offset=12
+  // CHECK-32:        (closure_context size=16 alignment=4 stride=16
+  // CHECK-32-NEXT:   (field offset=8
   // CHECK-32-NEXT:     (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=0
   // CHECK-32-NEXT:       (field offset=0
   // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
@@ -283,8 +283,8 @@
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=16 alignment=4 stride=16
-  // CHECK-32-NEXT:   (field offset=12
+  // CHECK-32:        (closure_context size=12 alignment=4 stride=12
+  // CHECK-32-NEXT:   (field offset=8
   // CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
   // CHECK-32-NEXT:       (field name=some offset=0
   // CHECK-32-NEXT:         (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096
@@ -326,7 +326,7 @@
 
   // CHECK-32:        Type info:
   // CHECK-32:        (closure_context size=32 alignment=8 stride=32
-  // CHECK-32-NEXT:   (field offset=12
+  // CHECK-32-NEXT:   (field offset=8
   // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
   // CHECK-32-NEXT:   (field offset=16
   // CHECK-32-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
@@ -367,10 +367,10 @@
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32: Type info:
-  // CHECK-32: (closure_context size=20 alignment=4 stride=20
-  // CHECK-32:   (field offset=12
+  // CHECK-32: (closure_context size=16 alignment=4 stride=16
+  // CHECK-32:   (field offset=8
   // CHECK-32:     (reference kind=strong refcounting=native))
-  // CHECK-32:   (field offset=16
+  // CHECK-32:   (field offset=12
   // CHECK-32:     (reference kind=strong refcounting=native)))
   @_semantics("optimize.sil.never")
   func arity1Capture2() -> (Int) -> () {
@@ -408,7 +408,7 @@
   
   // CHECK-32: Type info:
   // CHECK-32: (closure_context size=32 alignment=8 stride=32
-  // CHECK-32:   (field offset=12
+  // CHECK-32:   (field offset=8
   // CHECK-32:     (reference kind=strong refcounting=native))
   // CHECK-32:   (field offset=16
   // CHECK-32:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
@@ -457,7 +457,7 @@
   
   // CHECK-32: Type info:
   // CHECK-32: (closure_context size=32 alignment=8 stride=32
-  // CHECK-32:   (field offset=12
+  // CHECK-32:   (field offset=8
   // CHECK-32:     (reference kind=strong refcounting=native))
   // CHECK-32:   (field offset=16
   // CHECK-32:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
@@ -510,8 +510,8 @@
 // CHECK-32: (builtin Builtin.NativeObject)
 
 // CHECK-32:        Type info:
-// CHECK-32:        (closure_context size=16 alignment=4 stride=16
-// CHECK-32-NEXT:   (field offset=12
+// CHECK-32:        (closure_context size=12 alignment=4 stride=12
+// CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (reference kind=weak refcounting=native)))
 
 reflect(function: C().captureUnownedSelf())
@@ -531,8 +531,8 @@
 // CHECK-32: (builtin Builtin.NativeObject)
 
 // CHECK-32:        Type info:
-// CHECK-32:        (closure_context size=16 alignment=4 stride=16
-// CHECK-32-NEXT:   (field offset=12
+// CHECK-32:        (closure_context size=12 alignment=4 stride=12
+// CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (reference kind=unowned refcounting=native)))
 
 doneReflecting()
diff --git a/validation-test/Reflection/functions_objc.swift b/validation-test/Reflection/functions_objc.swift
index dd56664..8e05508 100644
--- a/validation-test/Reflection/functions_objc.swift
+++ b/validation-test/Reflection/functions_objc.swift
@@ -15,16 +15,16 @@
 // CHECK-32-NEXT: (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=40 alignment=4 stride=40 num_extra_inhabitants=0
-// CHECK-32-NEXT:   (field offset=12
+// CHECK-32-NEXT: (closure_context size=36 alignment=4 stride=36 num_extra_inhabitants=0
+// CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field offset=16
+// CHECK-32-NEXT:   (field offset=12
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
-// CHECK-32-NEXT:   (field offset=20
+// CHECK-32-NEXT:   (field offset=16
 // CHECK-32-NEXT:     (builtin size=16 alignment=4 stride=16 num_extra_inhabitants=0))
-// CHECK-32-NEXT:   (field offset=36
+// CHECK-32-NEXT:   (field offset=32
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown)))
 
 // CHECK-64:      Type reference:
diff --git a/validation-test/Reflection/inherits_Swift.swift b/validation-test/Reflection/inherits_Swift.swift
index 67a1c50..7b0aa77 100644
--- a/validation-test/Reflection/inherits_Swift.swift
+++ b/validation-test/Reflection/inherits_Swift.swift
@@ -37,12 +37,12 @@
 // CHECK-32: (class inherits_Swift.BaseClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=17 alignment=4 stride=20 num_extra_inhabitants=0
-// CHECK-32-NEXT:   (field name=w offset=12
+// CHECK-32-NEXT: (class_instance size=13 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32-NEXT:   (field name=w offset=8
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=x offset=16
+// CHECK-32-NEXT:   (field name=x offset=12
 // CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
@@ -73,12 +73,12 @@
 // CHECK-32: (class inherits_Swift.DerivedClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=24 alignment=4 stride=24 num_extra_inhabitants=0
-// CHECK-32-NEXT:   (field name=y offset=17
+// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-32-NEXT:   (field name=y offset=13
 // CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
-// CHECK-32-NEXT:   (field name=z offset=20
+// CHECK-32-NEXT:   (field name=z offset=16
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Array.swift b/validation-test/Reflection/reflect_Array.swift
index c8b84e7..01996e3 100644
--- a/validation-test/Reflection/reflect_Array.swift
+++ b/validation-test/Reflection/reflect_Array.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_Array.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
 // (unstable implementation details omitted)
 
diff --git a/validation-test/Reflection/reflect_Bool.swift b/validation-test/Reflection/reflect_Bool.swift
index 9cabb01..7f0fe57 100644
--- a/validation-test/Reflection/reflect_Bool.swift
+++ b/validation-test/Reflection/reflect_Bool.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Bool.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=13 alignment=1 stride=13 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
diff --git a/validation-test/Reflection/reflect_Character.swift b/validation-test/Reflection/reflect_Character.swift
index d6911ed..cb05d37 100644
--- a/validation-test/Reflection/reflect_Character.swift
+++ b/validation-test/Reflection/reflect_Character.swift
@@ -42,8 +42,8 @@
 // CHECK-32: (class reflect_Character.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
-// CHECK-32-NEXT:   (field name=t offset=16
+// CHECK-32-NEXT: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32-NEXT:   (field name=t offset=8
 // CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_representation offset=0
 // CHECK-32-NEXT:         (multi_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=0
diff --git a/validation-test/Reflection/reflect_Dictionary.swift b/validation-test/Reflection/reflect_Dictionary.swift
index 2eecc2d..5a33cdf 100644
--- a/validation-test/Reflection/reflect_Dictionary.swift
+++ b/validation-test/Reflection/reflect_Dictionary.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_Dictionary.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
diff --git a/validation-test/Reflection/reflect_Double.swift b/validation-test/Reflection/reflect_Double.swift
index 80904ed..f95deee 100644
--- a/validation-test/Reflection/reflect_Double.swift
+++ b/validation-test/Reflection/reflect_Double.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Double.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=16
+// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Float.swift b/validation-test/Reflection/reflect_Float.swift
index d59b985..fec3513 100644
--- a/validation-test/Reflection/reflect_Float.swift
+++ b/validation-test/Reflection/reflect_Float.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Float.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Int.swift b/validation-test/Reflection/reflect_Int.swift
index a8b8488..056943b 100644
--- a/validation-test/Reflection/reflect_Int.swift
+++ b/validation-test/Reflection/reflect_Int.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Int.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Int16.swift b/validation-test/Reflection/reflect_Int16.swift
index d51a0e1..3818d73 100644
--- a/validation-test/Reflection/reflect_Int16.swift
+++ b/validation-test/Reflection/reflect_Int16.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Int16.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=14 alignment=2 stride=14 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=10 alignment=2 stride=10 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Int32.swift b/validation-test/Reflection/reflect_Int32.swift
index a2d642e..26da3ae 100644
--- a/validation-test/Reflection/reflect_Int32.swift
+++ b/validation-test/Reflection/reflect_Int32.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Int32.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Int64.swift b/validation-test/Reflection/reflect_Int64.swift
index d1a1c1b..9ef651c 100644
--- a/validation-test/Reflection/reflect_Int64.swift
+++ b/validation-test/Reflection/reflect_Int64.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Int64.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=16
+// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_Int8.swift b/validation-test/Reflection/reflect_Int8.swift
index b79ff1f..fd8db13 100644
--- a/validation-test/Reflection/reflect_Int8.swift
+++ b/validation-test/Reflection/reflect_Int8.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_Int8.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=13 alignment=1 stride=13 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_NSArray.swift b/validation-test/Reflection/reflect_NSArray.swift
index 7abeb2c..f0d735a 100644
--- a/validation-test/Reflection/reflect_NSArray.swift
+++ b/validation-test/Reflection/reflect_NSArray.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_NSArray.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_NSNumber.swift b/validation-test/Reflection/reflect_NSNumber.swift
index 4f8c3f8..e80fd09 100644
--- a/validation-test/Reflection/reflect_NSNumber.swift
+++ b/validation-test/Reflection/reflect_NSNumber.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_NSNumber.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_NSSet.swift b/validation-test/Reflection/reflect_NSSet.swift
index f0c1f5c..5704edb 100644
--- a/validation-test/Reflection/reflect_NSSet.swift
+++ b/validation-test/Reflection/reflect_NSSet.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_NSSet.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_NSString.swift b/validation-test/Reflection/reflect_NSString.swift
index ee02334..ab8fa0c 100644
--- a/validation-test/Reflection/reflect_NSString.swift
+++ b/validation-test/Reflection/reflect_NSString.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_NSString.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_Set.swift b/validation-test/Reflection/reflect_Set.swift
index dcfb477..267bd21 100644
--- a/validation-test/Reflection/reflect_Set.swift
+++ b/validation-test/Reflection/reflect_Set.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_Set.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
diff --git a/validation-test/Reflection/reflect_String.swift b/validation-test/Reflection/reflect_String.swift
index 2e8dde6..2941249 100644
--- a/validation-test/Reflection/reflect_String.swift
+++ b/validation-test/Reflection/reflect_String.swift
@@ -34,8 +34,8 @@
 // CHECK-32: (class reflect_String.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=24 alignment=4 stride=24
-// CHECK-32-NEXT:   (field name=t offset=12
+// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20
+// CHECK-32-NEXT:   (field name=t offset=8
 // CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
diff --git a/validation-test/Reflection/reflect_UInt.swift b/validation-test/Reflection/reflect_UInt.swift
index 3f951d3..94309fb 100644
--- a/validation-test/Reflection/reflect_UInt.swift
+++ b/validation-test/Reflection/reflect_UInt.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_UInt.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_UInt16.swift b/validation-test/Reflection/reflect_UInt16.swift
index 8d9ee6b..d7ec13b 100644
--- a/validation-test/Reflection/reflect_UInt16.swift
+++ b/validation-test/Reflection/reflect_UInt16.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_UInt16.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=14 alignment=2 stride=14 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=10 alignment=2 stride=10 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_UInt32.swift b/validation-test/Reflection/reflect_UInt32.swift
index 4fd5dcd..5123abd 100644
--- a/validation-test/Reflection/reflect_UInt32.swift
+++ b/validation-test/Reflection/reflect_UInt32.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_UInt32.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_UInt64.swift b/validation-test/Reflection/reflect_UInt64.swift
index 2c8248a..6e672df 100644
--- a/validation-test/Reflection/reflect_UInt64.swift
+++ b/validation-test/Reflection/reflect_UInt64.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_UInt64.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=16
+// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_UInt8.swift b/validation-test/Reflection/reflect_UInt8.swift
index e02710a..4f94618 100644
--- a/validation-test/Reflection/reflect_UInt8.swift
+++ b/validation-test/Reflection/reflect_UInt8.swift
@@ -35,8 +35,8 @@
 // CHECK-32: (class reflect_UInt8.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=13 alignment=1 stride=13 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
diff --git a/validation-test/Reflection/reflect_empty_class.swift b/validation-test/Reflection/reflect_empty_class.swift
index 1f337fe..6c54d94 100644
--- a/validation-test/Reflection/reflect_empty_class.swift
+++ b/validation-test/Reflection/reflect_empty_class.swift
@@ -26,7 +26,7 @@
 // CHECK-32: (class reflect_empty_class.EmptyClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=1 stride=12 num_extra_inhabitants=0)
+// CHECK-32: (class_instance size=8 alignment=1 stride=8 num_extra_inhabitants=0)
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_existential.swift b/validation-test/Reflection/reflect_existential.swift
index 1247dc6..a871580 100644
--- a/validation-test/Reflection/reflect_existential.swift
+++ b/validation-test/Reflection/reflect_existential.swift
@@ -37,8 +37,8 @@
 // CHECK-32:   (protocol_composition))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=28 alignment=4 stride=28 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=24 alignment=4 stride=24 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=0
 // CHECK-32:       (field name=metadata offset=12
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096)))))
@@ -65,8 +65,8 @@
 // CHECK-32:     (protocol reflect_existential.P)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=32 alignment=4 stride=32 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=28 alignment=4 stride=28 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=0
 // CHECK-32:       (field name=metadata offset=12
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
@@ -95,8 +95,8 @@
 // CHECK-32:     (protocol reflect_existential.P)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
 // CHECK-32:       (field name=object offset=0
 // CHECK-32:         (reference kind=strong refcounting=unknown))
@@ -125,8 +125,8 @@
 // CHECK-32:     (protocol reflect_existential.CP)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
 // CHECK-32:       (field name=object offset=0
 // CHECK-32:         (reference kind=strong refcounting=unknown))
@@ -157,8 +157,8 @@
 // CHECK-32:     (protocol reflect_existential.P)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
-// CHECK-32:   (field name=t offset=12
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32:   (field name=t offset=8
 // CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
 // CHECK-32:       (field name=object offset=0
 // CHECK-32:         (reference kind=strong refcounting=native))
diff --git a/validation-test/Reflection/reflect_multiple_types.swift b/validation-test/Reflection/reflect_multiple_types.swift
index bdcfba9..c477b22 100644
--- a/validation-test/Reflection/reflect_multiple_types.swift
+++ b/validation-test/Reflection/reflect_multiple_types.swift
@@ -205,15 +205,15 @@
 // CHECK-32: (class reflect_multiple_types.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=129 alignment=8 stride=136 num_extra_inhabitants=0
-// CHECK-32-NEXT:   (field name=t00 offset=12
+// CHECK-32-NEXT: (class_instance size=121 alignment=8 stride=128 num_extra_inhabitants=0
+// CHECK-32-NEXT:   (field name=t00 offset=8
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
 // (unstable implementation details omitted)
-// CHECK-32:   (field name=t01 offset=16
+// CHECK-32:   (field name=t01 offset=12
 // CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
-// CHECK-32-NEXT:   (field name=t02 offset=24
+// CHECK-32-NEXT:   (field name=t02 offset=16
 // CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_representation offset=0
 // CHECK-32-NEXT:         (multi_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=0
@@ -223,68 +223,68 @@
 // CHECK-32-NEXT:             (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096
 // CHECK-32-NEXT:               (field name=_nativeBuffer offset=0
 // CHECK-32-NEXT:                 (reference kind=strong refcounting=native))))))
-// CHECK-32-NEXT:   (field name=t03 offset=32
+// CHECK-32-NEXT:   (field name=t03 offset=24
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-32:   (field name=t04 offset=40
+// CHECK-32:   (field name=t04 offset=32
 // CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t05 offset=48
+// CHECK-32-NEXT:   (field name=t05 offset=40
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t06 offset=52
+// CHECK-32-NEXT:   (field name=t06 offset=44
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t07 offset=56
+// CHECK-32-NEXT:   (field name=t07 offset=48
 // CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t08 offset=60
+// CHECK-32-NEXT:   (field name=t08 offset=52
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t09 offset=64
+// CHECK-32-NEXT:   (field name=t09 offset=56
 // CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t10 offset=72
+// CHECK-32-NEXT:   (field name=t10 offset=64
 // CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t11 offset=76
+// CHECK-32-NEXT:   (field name=t11 offset=68
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
-// CHECK-32-NEXT:   (field name=t12 offset=80
+// CHECK-32-NEXT:   (field name=t12 offset=72
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
-// CHECK-32-NEXT:   (field name=t13 offset=84
+// CHECK-32-NEXT:   (field name=t13 offset=76
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
-// CHECK-32-NEXT:   (field name=t14 offset=88
+// CHECK-32-NEXT:   (field name=t14 offset=80
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
-// CHECK-32-NEXT:   (field name=t15 offset=92
+// CHECK-32-NEXT:   (field name=t15 offset=84
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-32:   (field name=t16 offset=96
+// CHECK-32:   (field name=t16 offset=88
 // CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-32:   (field name=t17 offset=108
+// CHECK-32:   (field name=t17 offset=100
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t18 offset=112
+// CHECK-32-NEXT:   (field name=t18 offset=104
 // CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t19 offset=116
+// CHECK-32-NEXT:   (field name=t19 offset=108
 // CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t20 offset=120
+// CHECK-32-NEXT:   (field name=t20 offset=112
 // CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-32-NEXT:   (field name=t21 offset=128
+// CHECK-32-NEXT:   (field name=t21 offset=120
 // CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-32-NEXT:       (field name=_value offset=0
 // CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
diff --git a/validation-test/stdlib/FloatingPointConversion.swift.gyb b/validation-test/stdlib/FloatingPointConversion.swift.gyb
index 9882102..3a96da7 100644
--- a/validation-test/stdlib/FloatingPointConversion.swift.gyb
+++ b/validation-test/stdlib/FloatingPointConversion.swift.gyb
@@ -115,75 +115,59 @@
 
 %  end # for in all_floating_point_types (Other)
 
-%{
-
-float_to_int_conversion_template = gyb.parse_template("float_to_int_conversion",
-"""
-% for int_ty in all_integer_types(word_bits):
-%  OtherInt = int_ty.stdlib_name
-%  OtherMin = int_ty.min
-%  OtherMax = int_ty.max
-%  (FloatMin, FloatMax) = getFtoIBounds(self_type.bits, int_ty.bits, int_ty.is_signed)
-
-%  for testValue in [0, FloatMin, FloatMax, FloatMin - 1, FloatMax + 1, OtherMin, OtherMax]:
-
-%    if testValue < OtherMin or testValue > OtherMax: 
-%          # Can't construct `other` value, do nothing and continue.
-
-%    elif testValue >= FloatMin and testValue <= FloatMax:
-
-FixedPointConversionTruncations.test("${OtherInt}to${Self}Conversion/${testValue}") {
-  expectEqual(${Self}(${testValue} as ${OtherInt}), ${testValue})
-}
-
-FixedPointConversionFailures.test("${OtherInt}to${Self}FailableConversion/${testValue}") {
-  expectEqual(${Self}(exactly: ${testValue} as ${OtherInt}), ${testValue})
-}
-
-%    else:
-
-FixedPointConversionTruncations.test("${OtherInt}to${Self}Truncation/${testValue}") {
-  let value: ${OtherInt} = ${testValue}
-  let result = ${Self}(value)
-  expectNotEqual(${OtherInt}(result), value)
-}
-
-FixedPointConversionFailures.test("${OtherInt}to${Self}Failure/${testValue}") {
-  let value: ${OtherInt} = ${testValue}
-  let result = ${Self}(exactly: value)
-  expectEqual(result, ${OtherMin} as ${Self})
-  expectEqual(${OtherInt}(result!), value)
-}
-
-%    end
-
-%  end # testValue in testValues
-%  end # for in all_integer_types (Other)
-""")
-}%
-
 #if arch(i386) || arch(arm)
-
-  ${gyb.execute_template(
-      float_to_int_conversion_template,
-      word_bits=32,
-      **locals()
-      )}
-
+% int_types = all_integer_types(32)
 #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-
-  ${gyb.execute_template(
-      float_to_int_conversion_template,
-      word_bits=64,
-      **locals()
-      )}
-
+% int_types = all_integer_types(64)
 #else
-
 _UnimplementedError()
-
 #endif
 
+% for int_ty in int_types:
+%  OtherInt = int_ty.stdlib_name
+
+extension ${OtherInt} {
+  static var _test${Self}Conversion: [(${OtherInt}, ${OtherInt}, ${OtherInt}?)] {
+    if bitWidth > ${Self}.significandBitCount + 1 {
+      let bitOffset = ${Self}.significandBitCount + 1
+      let limit: ${OtherInt} = ~(~0 << bitOffset)
+      let over: ${OtherInt} = 1 + limit << 1
+      return [
+        (0, 0, 0),
+        (limit, limit, limit),
+        (over, over + 1, nil),
+%   if int_ty.is_signed:
+        (-limit, -limit, -limit),
+        (-over, -(over + 1), nil),
+%   end
+      ]
+    } else {
+      return [
+        (0, 0, 0),
+        (.min, .min, .min),
+        (.max, .max, .max),
+      ]
+    }
+  }
+}
+
+FixedPointConversionTruncations.test("${OtherInt}to${Self}")
+  .forEach(in: ${OtherInt}._test${Self}Conversion) {
+    value, roundedExpectation, exactExpectation in
+
+  let roundedResult = ${Self}(value)
+  expectEqual(roundedResult, ${Self}(roundedExpectation))
+
+  let exactResult = ${Self}(exactly: value)
+  if let expectation = exactExpectation {
+    expectEqual(exactResult!, ${Self}(expectation))
+  } else {
+    expectNil(exactResult)
+  }
+}
+
+%  end # for in int_types
+
 %  if Self == 'Float80':
 #endif
 %  end
diff --git a/validation-test/stdlib/ValidationNSNumberBridging.swift b/validation-test/stdlib/ValidationNSNumberBridging.swift
index 3e99a47..61255c4 100644
--- a/validation-test/stdlib/ValidationNSNumberBridging.swift
+++ b/validation-test/stdlib/ValidationNSNumberBridging.swift
@@ -652,16 +652,16 @@
             let uint = (number!) as? UInt
             expectEqual(UInt(exactly: interestingValue), uint)
 
-            // these are disabled because of https://bugs.swift.org/browse/SR-4634
-            if uint! != UInt(UInt32.max) && uint! != UInt(UInt32.max - 1) {
-                let float = (number!) as? Float
-                let expectedFloat = Float(uint!)
-                testFloat(expectedFloat, float)
+            let float = (number!) as? Float
+            let expectedFloat = Float(exactly: uint!)
+            if UInt.bitWidth == 32 && uint! >= UInt.max - 1 {
+              expectNil(expectedFloat)
+            } else {
+              testFloat(expectedFloat, float)
             }
-            
-            
+
             let double = (number!) as? Double
-            let expectedDouble = Double(uint!)
+            let expectedDouble = Double(exactly: uint!)
             testDouble(expectedDouble, double)
         }
         let bridged = interestingValue as NSNumber