Merge pull request #13613 from aschwaighofer/fix_unowned_refcount_insertion

When inserting retain/releases for sil_unowned types use the right in…
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 112b5d6..497cfb0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -207,6 +207,10 @@
     "Whether to enable CrashReporter integration"
     FALSE)
 
+option(SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
+    "Enable the Swift stable ABI's class marker bit"
+    FALSE)
+
 set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault" CACHE STRING
     "The name of the toolchain to pass to 'xcrun'")
 
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 78c574e..fefc6bb 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -175,9 +175,13 @@
   static ::= 'Z'
   curry-thunk ::= 'Tc'
 
+  label-list ::= empty-list            // represents complete absence of parameter labels
+  label-list ::= ('_' | identifier)*   // '_' is inserted as placeholder for empty label,
+                                       // since the number of labels should match the number of parameters
+
   // The leading type is the function type
-  entity-spec ::= type file-discriminator? 'fC'      // allocating constructor
-  entity-spec ::= type file-discriminator? 'fc'      // non-allocating constructor
+  entity-spec ::= label-list type file-discriminator? 'fC'      // allocating constructor
+  entity-spec ::= label-list type file-discriminator? 'fc'      // non-allocating constructor
   entity-spec ::= type 'fU' INDEX            // explicit anonymous closure expression
   entity-spec ::= type 'fu' INDEX            // implicit anonymous closure
   entity-spec ::= 'fA' INDEX                 // default argument N+1 generator
@@ -189,11 +193,11 @@
   entity-spec ::= 'Tv' NATURAL               // outlined global variable (from context function)
   entity-spec ::= 'Te' bridge-spec           // outlined objective c method call
 
-  entity-spec ::= decl-name function-signature generic-signature? 'F'    // function
-  entity-spec ::= type file-discriminator? 'i' ACCESSOR                  // subscript
-  entity-spec ::= decl-name type 'v' ACCESSOR                            // variable
-  entity-spec ::= decl-name type 'fp'                // generic type parameter
-  entity-spec ::= decl-name type 'fo'                // enum element (currently not used)
+  entity-spec ::= decl-name label-list function-signature generic-signature? 'F'    // function
+  entity-spec ::= label-list type file-discriminator? 'i' ACCESSOR                  // subscript
+  entity-spec ::= decl-name label-list? type 'v' ACCESSOR                           // variable
+  entity-spec ::= decl-name type 'fp'                                               // generic type parameter
+  entity-spec ::= decl-name type 'fo'                                               // enum element (currently not used)
 
   ACCESSOR ::= 'm'                           // materializeForSet
   ACCESSOR ::= 's'                           // setter
@@ -351,7 +355,8 @@
   function-signature ::= params-type params-type throws? // results and parameters
 
   params-type := type 'z'? 'h'?              // tuple in case of multiple parameters or a single parameter with a single tuple type
-                                             // with optional inout convention, shared convention
+                                             // with optional inout convention, shared convention. parameters don't have labels,
+                                             // they are mangled separately as part of the entity.
   params-type := empty-list                  // shortcut for no parameters
 
   throws ::= 'K'                             // 'throws' annotation on function types
diff --git a/docs/Runtime.md b/docs/Runtime.md
index a7a8899..10347ba 100644
--- a/docs/Runtime.md
+++ b/docs/Runtime.md
@@ -314,8 +314,9 @@
 000000000001e620 T _swift_allocateGenericValueMetadata
 0000000000022be0 T _swift_initClassMetadata_UniversalStrategy
 000000000001c100 T _swift_initEnumMetadataMultiPayload
-000000000001bd60 T _swift_initEnumValueWitnessTableSinglePayload
-0000000000022a20 T _swift_initStructMetadata_UniversalStrategy
+000000000001bd60 T _swift_initEnumMetadataSingleCase
+000000000001bd60 T _swift_initEnumMetadataSinglePayload
+0000000000022a20 T _swift_initStructMetadata
 0000000000024230 T _swift_initializeSuperclass
 0000000000028b60 T _swift_instantiateObjCClass
 ```
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index fdd3a02..a5f9f2b 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -86,12 +86,16 @@
 }
 
 /// Swift class flags.
+/// These flags are valid only when isTypeMetadata().
+/// When !isTypeMetadata() these flags will collide with other Swift ABIs.
 enum class ClassFlags : uint32_t {
-  /// Is this a Swift 1 class?
-  IsSwift1 = 0x1,
+  /// Is this a Swift class from the Darwin pre-stable ABI?
+  /// This bit is clear in stable ABI Swift classes.
+  /// The Objective-C runtime also reads this bit.
+  IsSwiftPreStableABI = 0x1,
 
-  /// Does this class use Swift 1.0 refcounting?
-  UsesSwift1Refcounting = 0x2,
+  /// Does this class use Swift refcounting?
+  UsesSwiftRefcounting = 0x2,
 
   /// Has this class a custom name, specified with the @objc attribute?
   HasCustomObjCName = 0x4
@@ -747,6 +751,62 @@
   return uintptr_t(flags) & uintptr_t(ExclusivityFlags::WarningOnly);
 }
 
+/// Flags for struct layout.
+enum class StructLayoutFlags : uintptr_t {
+  /// Reserve space for 256 layout algorithms.
+  AlgorithmMask     = 0xff,
+
+  /// The ABI baseline algorithm, i.e. the algorithm implemented in Swift 5.
+  Swift5Algorithm   = 0x00,
+
+  /// Is the value-witness table mutable in place, or does layout need to
+  /// clone it?
+  IsVWTMutable      = 0x100,
+};
+static inline StructLayoutFlags operator|(StructLayoutFlags lhs,
+                                          StructLayoutFlags rhs) {
+  return StructLayoutFlags(uintptr_t(lhs) | uintptr_t(rhs));
+}
+static inline StructLayoutFlags &operator|=(StructLayoutFlags &lhs,
+                                            StructLayoutFlags rhs) {
+  return (lhs = (lhs | rhs));
+}
+static inline StructLayoutFlags getLayoutAlgorithm(StructLayoutFlags flags) {
+  return StructLayoutFlags(uintptr_t(flags)
+                             & uintptr_t(StructLayoutFlags::AlgorithmMask));
+}
+static inline bool isValueWitnessTableMutable(StructLayoutFlags flags) {
+  return uintptr_t(flags) & uintptr_t(StructLayoutFlags::IsVWTMutable);
+}
+
+/// Flags for enum layout.
+enum class EnumLayoutFlags : uintptr_t {
+  /// Reserve space for 256 layout algorithms.
+  AlgorithmMask     = 0xff,
+
+  /// The ABI baseline algorithm, i.e. the algorithm implemented in Swift 5.
+  Swift5Algorithm   = 0x00,
+
+  /// Is the value-witness table mutable in place, or does layout need to
+  /// clone it?
+  IsVWTMutable      = 0x100,
+};
+static inline EnumLayoutFlags operator|(EnumLayoutFlags lhs,
+                                        EnumLayoutFlags rhs) {
+  return EnumLayoutFlags(uintptr_t(lhs) | uintptr_t(rhs));
+}
+static inline EnumLayoutFlags &operator|=(EnumLayoutFlags &lhs,
+                                          EnumLayoutFlags rhs) {
+  return (lhs = (lhs | rhs));
+}
+static inline EnumLayoutFlags getLayoutAlgorithm(EnumLayoutFlags flags) {
+  return EnumLayoutFlags(uintptr_t(flags)
+                           & uintptr_t(EnumLayoutFlags::AlgorithmMask));
+}
+static inline bool isValueWitnessTableMutable(EnumLayoutFlags flags) {
+  return uintptr_t(flags) & uintptr_t(EnumLayoutFlags::IsVWTMutable);
+}
+
 } // end namespace swift
 
 #endif /* SWIFT_ABI_METADATAVALUES_H */
diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h
index e611b58..57a60d6 100644
--- a/include/swift/AST/ASTContext.h
+++ b/include/swift/AST/ASTContext.h
@@ -482,8 +482,8 @@
   FuncDecl *getEqualIntDecl() const;
 
   /// Retrieve the declaration of
-  /// Swift._mixForSynthesizedHashValue (Int, Int) -> Int.
-  FuncDecl *getMixForSynthesizedHashValueDecl() const;
+  /// Swift._combineHashValues(Int, Int) -> Int.
+  FuncDecl *getCombineHashValuesDecl() const;
 
   /// Retrieve the declaration of Swift._mixInt(Int) -> Int.
   FuncDecl *getMixIntDecl() const;
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index 58330b0..fcef79d 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -287,8 +287,17 @@
 
   SWIFT_INLINE_BITFIELD_EMPTY(ImplicitConversionExpr, Expr);
 
-  SWIFT_INLINE_BITFIELD(TupleShuffleExpr, ImplicitConversionExpr, 2,
-    TypeImpact : 2
+  SWIFT_INLINE_BITFIELD_FULL(TupleShuffleExpr, ImplicitConversionExpr, 2+16+16+16,
+    TypeImpact : 2,
+    : NumPadBits,
+    NumCallerDefaultArgs : 16,
+    /// This contains an entry for each element in the Expr type.  Each element
+    /// specifies which index from the SubExpr that the destination element gets.
+    /// If the element value is DefaultInitialize, then the destination value
+    /// gets the default initializer for that tuple element value.
+    NumElementMappings : 16,
+    /// The arguments that are packed into the variadic element.
+    NumVariadicArgs : 16
   );
 
   SWIFT_INLINE_BITFIELD(InOutToPointerExpr, ImplicitConversionExpr, 1,
@@ -299,6 +308,21 @@
     IsNonAccessing : 1
   );
 
+  SWIFT_INLINE_BITFIELD_FULL(ErasureExpr, ImplicitConversionExpr, 32,
+    : NumPadBits,
+    NumConformances : 32
+  );
+
+  SWIFT_INLINE_BITFIELD_FULL(UnresolvedSpecializeExpr, Expr, 32,
+    : NumPadBits,
+    NumUnresolvedParams : 32
+  );
+
+  SWIFT_INLINE_BITFIELD_FULL(CaptureListExpr, Expr, 32,
+    : NumPadBits,
+    NumCaptures : 32
+  );
+
   SWIFT_INLINE_BITFIELD(ApplyExpr, Expr, 1+1,
     ThrowsIsSet : 1,
     Throws : 1
@@ -371,6 +395,9 @@
     SWIFT_INLINE_BITS(ParenExpr);
     SWIFT_INLINE_BITS(SequenceExpr);
     SWIFT_INLINE_BITS(CollectionExpr);
+    SWIFT_INLINE_BITS(ErasureExpr);
+    SWIFT_INLINE_BITS(UnresolvedSpecializeExpr);
+    SWIFT_INLINE_BITS(CaptureListExpr);
   } Bits;
 
 private:
@@ -2824,7 +2851,20 @@
 /// If hasScalarSource() is true, the subexpression should be treated
 /// as if it were implicitly injected into a single-element tuple
 /// type.  Otherwise, the subexpression is known to have a tuple type.
-class TupleShuffleExpr : public ImplicitConversionExpr {
+class TupleShuffleExpr final : public ImplicitConversionExpr,
+    private llvm::TrailingObjects<TupleShuffleExpr, Expr *, int, unsigned> {
+  friend TrailingObjects;
+
+  size_t numTrailingObjects(OverloadToken<Expr *>) const {
+    return Bits.TupleShuffleExpr.NumCallerDefaultArgs;
+  }
+  size_t numTrailingObjects(OverloadToken<int>) const {
+    return Bits.TupleShuffleExpr.NumElementMappings;
+  }
+  size_t numTrailingObjects(OverloadToken<unsigned>) const {
+    return Bits.TupleShuffleExpr.NumVariadicArgs;
+  }
+
 public:
   enum : int {
     /// The element mapping value indicating that a field of the destination
@@ -2859,12 +2899,6 @@
   };
 
 private:
-  /// This contains an entry for each element in the Expr type.  Each element
-  /// specifies which index from the SubExpr that the destination element gets.
-  /// If the element value is DefaultInitialize, then the destination value
-  /// gets the default initializer for that tuple element value.
-  ArrayRef<int> ElementMapping;
-
   /// If we're doing a varargs shuffle, this is the array type to build.
   Type VarargsArrayTy;
 
@@ -2872,28 +2906,41 @@
   /// declaration.
   ConcreteDeclRef DefaultArgsOwner;
 
-  /// The arguments that are packed into the variadic element.
-  ArrayRef<unsigned> VariadicArgs;
-
-  MutableArrayRef<Expr *> CallerDefaultArgs;
-
-public:
-  TupleShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping, 
+  TupleShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping,
                    TypeImpact typeImpact,
                    ConcreteDeclRef defaultArgsOwner,
                    ArrayRef<unsigned> VariadicArgs,
                    Type VarargsArrayTy,
-                   MutableArrayRef<Expr *> CallerDefaultArgs,
+                   ArrayRef<Expr *> CallerDefaultArgs,
                    Type ty)
     : ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty),
-      ElementMapping(elementMapping), VarargsArrayTy(VarargsArrayTy),
-      DefaultArgsOwner(defaultArgsOwner), VariadicArgs(VariadicArgs),
-      CallerDefaultArgs(CallerDefaultArgs)
-  {
+      VarargsArrayTy(VarargsArrayTy), DefaultArgsOwner(defaultArgsOwner) {
     Bits.TupleShuffleExpr.TypeImpact = typeImpact;
+    Bits.TupleShuffleExpr.NumCallerDefaultArgs = CallerDefaultArgs.size();
+    Bits.TupleShuffleExpr.NumElementMappings = elementMapping.size();
+    Bits.TupleShuffleExpr.NumVariadicArgs = VariadicArgs.size();
+    std::uninitialized_copy(CallerDefaultArgs.begin(), CallerDefaultArgs.end(),
+                            getTrailingObjects<Expr*>());
+    std::uninitialized_copy(elementMapping.begin(), elementMapping.end(),
+                            getTrailingObjects<int>());
+    std::uninitialized_copy(VariadicArgs.begin(), VariadicArgs.end(),
+                            getTrailingObjects<unsigned>());
   }
 
-  ArrayRef<int> getElementMapping() const { return ElementMapping; }
+public:
+  static TupleShuffleExpr *create(ASTContext &ctx, Expr *subExpr,
+                                  ArrayRef<int> elementMapping,
+                                  TypeImpact typeImpact,
+                                  ConcreteDeclRef defaultArgsOwner,
+                                  ArrayRef<unsigned> VariadicArgs,
+                                  Type VarargsArrayTy,
+                                  ArrayRef<Expr *> CallerDefaultArgs,
+                                  Type ty);
+
+  ArrayRef<int> getElementMapping() const {
+    return {getTrailingObjects<int>(),
+            Bits.TupleShuffleExpr.NumElementMappings};
+  }
 
   /// What is the type impact of this shuffle?
   TypeImpact getTypeImpact() const {
@@ -2917,16 +2964,25 @@
   }
 
   /// Retrieve the argument indices for the variadic arguments.
-  ArrayRef<unsigned> getVariadicArgs() const { return VariadicArgs; }
+  ArrayRef<unsigned> getVariadicArgs() const {
+    return {getTrailingObjects<unsigned>(),
+            Bits.TupleShuffleExpr.NumVariadicArgs};
+  }
 
   /// Retrieve the owner of the default arguments.
   ConcreteDeclRef getDefaultArgsOwner() const { return DefaultArgsOwner; }
 
   /// Retrieve the caller-defaulted arguments.
-  ArrayRef<Expr *> getCallerDefaultArgs() const { return CallerDefaultArgs; }
+  ArrayRef<Expr *> getCallerDefaultArgs() const {
+    return {getTrailingObjects<Expr*>(),
+            Bits.TupleShuffleExpr.NumCallerDefaultArgs};
+  }
 
   /// Retrieve the caller-defaulted arguments.
-  MutableArrayRef<Expr *> getCallerDefaultArgs() { return CallerDefaultArgs; }
+  MutableArrayRef<Expr *> getCallerDefaultArgs() {
+    return {getTrailingObjects<Expr*>(),
+            Bits.TupleShuffleExpr.NumCallerDefaultArgs};
+  }
 
   static bool classof(const Expr *E) {
     return E->getKind() == ExprKind::TupleShuffle;
@@ -3090,14 +3146,21 @@
 ///
 /// "Appropriate kind" means e.g. a concrete/existential metatype if the
 /// result is an existential metatype.
-class ErasureExpr : public ImplicitConversionExpr {
-  ArrayRef<ProtocolConformanceRef> Conformances;
+class ErasureExpr final : public ImplicitConversionExpr,
+    private llvm::TrailingObjects<ErasureExpr, ProtocolConformanceRef> {
+  friend TrailingObjects;
 
-public:
   ErasureExpr(Expr *subExpr, Type type,
               ArrayRef<ProtocolConformanceRef> conformances)
-    : ImplicitConversionExpr(ExprKind::Erasure, subExpr, type),
-      Conformances(conformances) {}
+    : ImplicitConversionExpr(ExprKind::Erasure, subExpr, type) {
+    Bits.ErasureExpr.NumConformances = conformances.size();
+    std::uninitialized_copy(conformances.begin(), conformances.end(),
+                            getTrailingObjects<ProtocolConformanceRef>());
+  }
+
+public:
+  static ErasureExpr *create(ASTContext &ctx, Expr *subExpr, Type type,
+                             ArrayRef<ProtocolConformanceRef> conformances);
 
   /// \brief Retrieve the mapping specifying how the type of the subexpression
   /// maps to the resulting existential type. If the resulting existential
@@ -3110,7 +3173,8 @@
   /// type is either an archetype or an existential type that conforms to
   /// that corresponding protocol).
   ArrayRef<ProtocolConformanceRef> getConformances() const {
-    return Conformances;
+    return {getTrailingObjects<ProtocolConformanceRef>(),
+            Bits.ErasureExpr.NumConformances };
   }
 
   static bool classof(const Expr *E) {
@@ -3189,28 +3253,43 @@
 
 /// UnresolvedSpecializeExpr - Represents an explicit specialization using
 /// a type parameter list (e.g. "Vector<Int>") that has not been resolved.
-class UnresolvedSpecializeExpr : public Expr {
+class UnresolvedSpecializeExpr final : public Expr,
+    private llvm::TrailingObjects<UnresolvedSpecializeExpr, TypeLoc> {
+  friend TrailingObjects;
+
   Expr *SubExpr;
   SourceLoc LAngleLoc;
   SourceLoc RAngleLoc;
-  MutableArrayRef<TypeLoc> UnresolvedParams;
-public:
+
   UnresolvedSpecializeExpr(Expr *SubExpr,
                            SourceLoc LAngleLoc,
-                           MutableArrayRef<TypeLoc> UnresolvedParams,
+                           ArrayRef<TypeLoc> UnresolvedParams,
                            SourceLoc RAngleLoc)
     : Expr(ExprKind::UnresolvedSpecialize, /*Implicit=*/false),
-      SubExpr(SubExpr),
-      LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
-      UnresolvedParams(UnresolvedParams) { }
+      SubExpr(SubExpr), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {
+    Bits.UnresolvedSpecializeExpr.NumUnresolvedParams = UnresolvedParams.size();
+    std::uninitialized_copy(UnresolvedParams.begin(), UnresolvedParams.end(),
+                            getTrailingObjects<TypeLoc>());
+  }
+
+public:
+  static UnresolvedSpecializeExpr *
+  create(ASTContext &ctx, Expr *SubExpr, SourceLoc LAngleLoc,
+         ArrayRef<TypeLoc> UnresolvedParams, SourceLoc RAngleLoc);
   
   Expr *getSubExpr() const { return SubExpr; }
   void setSubExpr(Expr *e) { SubExpr = e; }
   
   /// \brief Retrieve the list of type parameters. These parameters have not yet
   /// been bound to archetypes of the entity to be specialized.
-  ArrayRef<TypeLoc> getUnresolvedParams() const { return UnresolvedParams; }
-  MutableArrayRef<TypeLoc> getUnresolvedParams() { return UnresolvedParams; }
+  ArrayRef<TypeLoc> getUnresolvedParams() const {
+    return {getTrailingObjects<TypeLoc>(),
+            Bits.UnresolvedSpecializeExpr.NumUnresolvedParams};
+  }
+  MutableArrayRef<TypeLoc> getUnresolvedParams() {
+    return {getTrailingObjects<TypeLoc>(),
+            Bits.UnresolvedSpecializeExpr.NumUnresolvedParams};
+  }
   
   SourceLoc getLoc() const { return LAngleLoc; }
   SourceLoc getLAngleLoc() const { return LAngleLoc; }
@@ -3645,17 +3724,30 @@
 /// CaptureList wraps the ClosureExpr.  The dynamic semantics are that evaluates
 /// the variable bindings from the capture list, then evaluates the
 /// subexpression (the closure itself) and returns the result.
-class CaptureListExpr : public Expr {
-  ArrayRef<CaptureListEntry> captureList;
+class CaptureListExpr final : public Expr,
+    private llvm::TrailingObjects<CaptureListExpr, CaptureListEntry> {
+  friend TrailingObjects;
+
   ClosureExpr *closureBody;
-public:
+
   CaptureListExpr(ArrayRef<CaptureListEntry> captureList,
                   ClosureExpr *closureBody)
     : Expr(ExprKind::CaptureList, /*Implicit=*/false, Type()),
-      captureList(captureList), closureBody(closureBody) {
+      closureBody(closureBody) {
+    Bits.CaptureListExpr.NumCaptures = captureList.size();
+    std::uninitialized_copy(captureList.begin(), captureList.end(),
+                            getTrailingObjects<CaptureListEntry>());
   }
 
-  ArrayRef<CaptureListEntry> getCaptureList() { return captureList; }
+public:
+  static CaptureListExpr *create(ASTContext &ctx,
+                                 ArrayRef<CaptureListEntry> captureList,
+                                 ClosureExpr *closureBody);
+
+  ArrayRef<CaptureListEntry> getCaptureList() {
+    return {getTrailingObjects<CaptureListEntry>(),
+            Bits.CaptureListExpr.NumCaptures};
+  }
   ClosureExpr *getClosureBody() { return closureBody; }
   const ClosureExpr *getClosureBody() const { return closureBody; }
 
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 6e80301..d7167bc 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -289,12 +289,13 @@
   );
 
   enum { NumAFTExtInfoBits = 7 };
-  SWIFT_INLINE_BITFIELD(AnyFunctionType, TypeBase, NumAFTExtInfoBits+10,
+  SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+16,
     /// Extra information which affects how the function is called, like
     /// regparm and the calling convention.
     ExtInfo : NumAFTExtInfoBits,
 
-    NumParams : 10
+    : NumPadBits,
+    NumParams : 16
   );
 
   SWIFT_INLINE_BITFIELD_FULL(ArchetypeType, TypeBase, 1+1+1+16,
@@ -1037,7 +1038,7 @@
 /// is produced when parsing types and when name binding type aliases, and is
 /// installed in declaration that use these erroneous types.  All uses of a
 /// declaration of invalid type should be ignored and not re-diagnosed.
-class ErrorType : public TypeBase {
+class ErrorType final : public TypeBase {
   friend class ASTContext;
   // The Error type is always canonical.
   ErrorType(ASTContext &C, Type originalType,
@@ -5104,6 +5105,17 @@
     return ty->getTrailingObjects<Type>();
   llvm_unreachable("Unhandled BoundGenericType!");
 }
+
+inline ArrayRef<AnyFunctionType::Param> AnyFunctionType::getParams() const {
+  switch (getKind()) {
+  case TypeKind::Function:
+    return cast<FunctionType>(this)->getParams();
+  case TypeKind::GenericFunction:
+    return cast<GenericFunctionType>(this)->getParams();
+  default:
+    llvm_unreachable("Undefined function type");
+  }
+}
   
 /// \brief If this is a method in a type or extension thereof, compute
 /// and return a parameter to be used for the 'self' argument.  The type of
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index b3fb777..1fea5fc 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -18,6 +18,7 @@
 #ifndef SWIFT_BASIC_LANGOPTIONS_H
 #define SWIFT_BASIC_LANGOPTIONS_H
 
+#include "swift/Config.h"
 #include "swift/Basic/LLVM.h"
 #include "swift/Basic/Version.h"
 #include "clang/Basic/VersionTuple.h"
@@ -128,6 +129,10 @@
     /// configuration options.
     bool EnableObjCInterop = true;
 
+    /// On Darwin platforms, use the pre-stable ABI's mark bit for Swift
+    /// classes instead of the stable ABI's bit.
+    bool UseDarwinPreStableABIBit = !bool(SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT);
+
     /// Enables checking that uses of @objc require importing
     /// the Foundation module.
     /// This is enabled by default because SILGen can crash in such a case, but
diff --git a/include/swift/Config.h.in b/include/swift/Config.h.in
index 652fbf4..b45083e 100644
--- a/include/swift/Config.h.in
+++ b/include/swift/Config.h.in
@@ -8,4 +8,6 @@
 
 #cmakedefine HAVE_UNICODE_LIBEDIT 1
 
+#cmakedefine01 SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
+
 #endif // SWIFT_CONFIG_H
diff --git a/include/swift/IDE/RefactoringKinds.def b/include/swift/IDE/RefactoringKinds.def
index 0e6a1ae..ecd3667 100644
--- a/include/swift/IDE/RefactoringKinds.def
+++ b/include/swift/IDE/RefactoringKinds.def
@@ -55,6 +55,11 @@
 RANGE_REFACTORING(MoveMembersToExtension, "Move To Extension", move.members.to.extension)
 
 RANGE_REFACTORING(ConvertStringsConcatenationToInterpolation, "Convert to String Interpolation", convert.string-concatenation.interpolation)
+
+RANGE_REFACTORING(ExpandTernaryExpr, "Expand Ternary Expression", expand.ternary.expr)
+
+RANGE_REFACTORING(ConvertToTernaryExpr, "Convert To Ternary Expression", convert.ternary.expr)
+
 #undef CURSOR_REFACTORING
 #undef RANGE_REFACTORING
 #undef SEMANTIC_REFACTORING
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index 1fb56df..ef2d095 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -126,13 +126,13 @@
   ///
   /// This is only preserved if this Lexer was constructed with
   /// `TriviaRetentionMode::WithTrivia`.
-  syntax::TriviaList LeadingTrivia;
+  syntax::Trivia LeadingTrivia;
 
   /// The current trailing trivia for the next token.
   ///
   /// This is only preserved if this Lexer was constructed with
   /// `TriviaRetentionMode::WithTrivia`.
-  syntax::TriviaList TrailingTrivia;
+  syntax::Trivia TrailingTrivia;
   
   Lexer(const Lexer&) = delete;
   void operator=(const Lexer&) = delete;
@@ -255,7 +255,7 @@
       TokStart = Tok.getLoc();
     auto S = getStateForBeginningOfTokenLoc(TokStart);
     if (TriviaRetention == TriviaRetentionMode::WithTrivia)
-      S.LeadingTrivia = LeadingTrivia.Pieces;
+      S.LeadingTrivia = LeadingTrivia;
     return S;
   }
 
@@ -503,7 +503,7 @@
   void lexOperatorIdentifier();
   void lexHexNumber();
   void lexNumber();
-  void lexTrivia(syntax::TriviaList &T, bool IsForTrailingTrivia);
+  void lexTrivia(syntax::Trivia &T, bool IsForTrailingTrivia);
   static unsigned lexUnicodeEscape(const char *&CurPtr, Lexer *Diags);
 
   unsigned lexCharacter(const char *&CurPtr,
diff --git a/include/swift/Parse/LexerState.h b/include/swift/Parse/LexerState.h
index ec0ed9c..5151d2b 100644
--- a/include/swift/Parse/LexerState.h
+++ b/include/swift/Parse/LexerState.h
@@ -39,7 +39,7 @@
 private:
   explicit LexerState(SourceLoc Loc) : Loc(Loc) {}
   SourceLoc Loc;
-  llvm::Optional<syntax::TriviaList> LeadingTrivia;
+  llvm::Optional<syntax::Trivia> LeadingTrivia;
   friend class Lexer;
 };
 
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 717127b..94e4c2b 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -1295,6 +1295,10 @@
   ParserResult<Stmt> parseStmtReturn(SourceLoc tryLoc);
   ParserResult<Stmt> parseStmtThrow(SourceLoc tryLoc);
   ParserResult<Stmt> parseStmtDefer();
+  ParserStatus
+  parseStmtConditionElement(SmallVectorImpl<StmtConditionElement> &result,
+                            Diag<> DefaultID, StmtKind ParentKind,
+                            StringRef &BindingKindStr);
   ParserStatus parseStmtCondition(StmtCondition &Result, Diag<> ID,
                                   StmtKind ParentKind);
   ParserResult<PoundAvailableInfo> parseStmtConditionPoundAvailable();
diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h
index e77064b..1b4acee 100644
--- a/include/swift/Remote/MetadataReader.h
+++ b/include/swift/Remote/MetadataReader.h
@@ -894,9 +894,9 @@
     case MetadataKind::ForeignClass: {
       auto namePtrAddress =
         Meta.getAddress() + TargetForeignClassMetadata<Runtime>::OffsetToName;
-      StoredPointer namePtr;
-      if (!Reader->readInteger(RemoteAddress(namePtrAddress), &namePtr) ||
-          namePtr == 0)
+      
+      StoredPointer namePtr = resolveRelativeOffset<int32_t>(namePtrAddress);
+      if (namePtr == 0)
         return BuiltType();
       std::string name;
       if (!Reader->readString(RemoteAddress(namePtr), name))
diff --git a/include/swift/Runtime/Config.h b/include/swift/Runtime/Config.h
index ca8b293..c0e5e4f 100644
--- a/include/swift/Runtime/Config.h
+++ b/include/swift/Runtime/Config.h
@@ -65,6 +65,16 @@
 #error Masking ISAs are incompatible with opaque ISAs
 #endif
 
+/// Which bits in the class metadata are used to distinguish Swift classes
+/// from ObjC classes?
+#ifndef SWIFT_CLASS_IS_SWIFT_MASK
+# if __APPLE__ && SWIFT_OBJC_INTEROP && SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
+#  define SWIFT_CLASS_IS_SWIFT_MASK 2ULL
+# else
+#  define SWIFT_CLASS_IS_SWIFT_MASK 1ULL
+# endif
+#endif
+
 // We try to avoid global constructors in the runtime as much as possible.
 // These macros delimit allowed global ctors.
 #if __clang__
diff --git a/include/swift/Runtime/Enum.h b/include/swift/Runtime/Enum.h
index 6102ff7..2b514ae 100644
--- a/include/swift/Runtime/Enum.h
+++ b/include/swift/Runtime/Enum.h
@@ -33,17 +33,29 @@
 using EnumMetadata = TargetEnumMetadata<InProcess>;
 struct TypeLayout;
 
-/// \brief Initialize the value witness table for a generic, single-payload
-///        enum instance.
+/// \brief Initialize the type metadata for a single-case enum type.
 ///
-/// \param vwtable - pointer to the instantiated but uninitialized value
-///                  witness table for the enum.
+/// \param enumType - pointer to the instantiated but uninitialized metadata
+///                   for the enum.
+/// \param flags - flags controlling the layout
+/// \param payload - type metadata for the payload of the enum.
+SWIFT_RUNTIME_EXPORT
+void swift_initEnumMetadataSingleCase(EnumMetadata *enumType,
+                                      EnumLayoutFlags flags,
+                                      const TypeLayout *payload);
+
+/// \brief Initialize the type metadata for a single-payload enum type.
+///
+/// \param enumType - pointer to the instantiated but uninitialized metadata
+///                   for the enum.
+/// \param flags - flags controlling the layout
 /// \param payload - type metadata for the payload case of the enum.
 /// \param emptyCases - the number of empty cases in the enum.
 SWIFT_RUNTIME_EXPORT
-void swift_initEnumValueWitnessTableSinglePayload(ValueWitnessTable *vwtable,
-                                                  const TypeLayout *payload,
-                                                  unsigned emptyCases);
+void swift_initEnumMetadataSinglePayload(EnumMetadata *enumType,
+                                         EnumLayoutFlags flags,
+                                         const TypeLayout *payload,
+                                         unsigned emptyCases);
 
 /// \brief Faster variant of the above which avoids digging into the enum type
 /// metadata when the caller already has the payload information handy.
@@ -81,11 +93,11 @@
                                      unsigned emptyCases)
   SWIFT_CC(RegisterPreservingCC);
 
-/// \brief Initialize the value witness table for a generic, multi-payload
+/// \brief Initialize the type metadata for a generic, multi-payload
 ///        enum instance.
 SWIFT_RUNTIME_EXPORT
-void swift_initEnumMetadataMultiPayload(ValueWitnessTable *vwtable,
-                                        EnumMetadata *enumType,
+void swift_initEnumMetadataMultiPayload(EnumMetadata *enumType,
+                                        EnumLayoutFlags flags,
                                         unsigned numPayloads,
                                         const TypeLayout * const *payloadTypes);
 
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index b869107..7e94796 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -1355,7 +1355,7 @@
 
   /// Is this object a valid swift type metadata?
   bool isTypeMetadata() const {
-    return (Data & 1);
+    return (Data & SWIFT_CLASS_IS_SWIFT_MASK);
   }
   /// A different perspective on the same bit
   bool isPureObjC() const {
@@ -1567,86 +1567,152 @@
   using StoredPointer = typename Runtime::StoredPointer;
   using StoredSize = typename Runtime::StoredSize;
   using InitializationFunction_t =
-    void (*)(TargetForeignTypeMetadata<Runtime> *selectedMetadata);
+    void (TargetForeignTypeMetadata<Runtime> *selectedMetadata);
   using RuntimeMetadataPointer =
       ConstTargetMetadataPointer<Runtime, swift::TargetForeignTypeMetadata>;
 
+  /// An invasive cache for the runtime-uniqued lookup structure that is stored
+  /// in the header prefix of foreign metadata records.
+  ///
+  /// Prior to initialization, as emitted by the compiler, this contains the
+  /// initialization flags.
+  /// After initialization, it holds a pointer to the actual, runtime-uniqued
+  /// metadata for this type.
+  struct CacheValue {
+    StoredSize Value;
+    
+    /// Work around a bug in libstdc++'s std::atomic that requires the type to
+    /// be default-constructible.
+    CacheValue() = default;
+    
+    explicit CacheValue(RuntimeMetadataPointer p)
+      : Value(reinterpret_cast<StoredSize>(p))
+    {}
+
+    /// Various flags. The largest flag bit should be less than 4096 so that
+    /// a flag set is distinguishable from a valid pointer.
+    enum : StoredSize {
+      /// This metadata has an initialization callback function.  If
+      /// this flag is not set, the metadata object needn't actually
+      /// have a InitializationFunction field, and that field will be
+      /// undefined.
+      HasInitializationFunction = 0x1,
+      
+      LargestFlagMask = 0xFFF,
+    };    
+
+    /// True if the metadata record associated with this cache has not been
+    /// initialized, so contains a flag set describing parameters to the
+    /// initialization operation. isFlags() == !isInitialized()
+    bool isFlags() const {
+      return Value <= LargestFlagMask;
+    }
+    /// True if the metadata record associated with this cache has an
+    /// initialization function which must be run if it is picked as the
+    /// canonical metadata record for its key.
+    ///
+    /// Undefined if !isFlags().
+    bool hasInitializationFunction() const {
+      assert(isFlags());
+      return Value & HasInitializationFunction;
+    }
+    
+    /// True if the metadata record associated with this cache has been
+    /// initialized, so the cache contains an absolute pointer to the
+    /// canonical metadata record for its key. isInitialized() == !isFlags()
+    bool isInitialized() const {
+      return !isFlags();
+    }
+    
+    /// Gets the cached pointer to the unique canonical metadata record for
+    /// this metadata record's key.
+    ///
+    /// Undefined if !isInitialized().
+    RuntimeMetadataPointer getCachedUniqueMetadata() const {
+      assert(isInitialized());
+      return RuntimeMetadataPointer(Value);
+    }
+  };
+
+
   /// Foreign type metadata may have extra header fields depending on
   /// the flags.
   struct HeaderPrefix {
     /// An optional callback performed when a particular metadata object
     /// is chosen as the unique structure.
+    ///
     /// If there is no initialization function, this metadata record can be
     /// assumed to be immutable (except for the \c Unique invasive cache
-    /// field).
-    InitializationFunction_t InitializationFunction;
+    /// field). The field is not present unless the HasInitializationFunction
+    /// flag is set.
+    RelativeDirectPointer<InitializationFunction_t> InitializationFunction;
     
-    /// The Swift-mangled name of the type. This is the uniquing key for the
-    /// type.
-    TargetPointer<Runtime, const char> Name;
+    /// The uniquing key for the metadata record. Metadata records with the
+    /// same Name string are considered equivalent by the runtime, and the
+    /// runtime will pick one to be canonical.
+    RelativeDirectPointer<const char> Name;
 
-    /// A pointer to the actual, runtime-uniqued metadata for this
-    /// type.  This is essentially an invasive cache for the lookup
-    /// structure.
-    mutable std::atomic<RuntimeMetadataPointer> Unique;
-
-    /// Various flags.
-    enum : StoredSize {
-      /// This metadata has an initialization callback function.  If
-      /// this flag is not set, the metadata object needn't actually
-      /// have a InitializationFunction field.
-      HasInitializationFunction = 0x1,
-    } Flags;
+    mutable std::atomic<CacheValue> Cache;
   };
 
   struct HeaderType : HeaderPrefix, TypeMetadataHeader {};
 
-  static constexpr int OffsetToName =
-    (int) offsetof(HeaderType, Name) - (int) sizeof(HeaderType);
+  static constexpr int32_t OffsetToName =
+    (int32_t) offsetof(HeaderType, Name) - (int32_t) sizeof(HeaderType);
 
   TargetPointer<Runtime, const char> getName() const {
     return reinterpret_cast<TargetPointer<Runtime, const char>>(
-      asFullMetadata(this)->Name);
+      asFullMetadata(this)->Name.get());
   }
 
-  RuntimeMetadataPointer getCachedUniqueMetadata() const {
-#if __alpha__
-    // TODO: This can be a relaxed-order load if there is no initialization
-    // function. On platforms we care about, consume is no more expensive than
-    // relaxed, so there's no reason to branch here (and LLVM isn't smart
-    // enough to eliminate it when it's not needed).
-    if (!hasInitializationFunction())
-      return asFullMetadata(this)->Unique.load(std::memory_order_relaxed);
-#endif
-    return asFullMetadata(this)->Unique.load(SWIFT_MEMORY_ORDER_CONSUME);
+  CacheValue getCacheValue() const {
+    /// NB: This can be a relaxed-order load if there is no initialization
+    /// function. On platforms Swift currently targets, consume is no more
+    /// expensive than relaxed, so there's no reason to branch here (and LLVM
+    /// isn't smart enough to eliminate it when it's not needed).
+    ///
+    /// A port to a platform where relaxed is significantly less expensive than
+    /// consume (historically, Alpha) would probably want to preserve the
+    /// 'hasInitializationFunction' bit in its own word to be able to avoid
+    /// the consuming load when not needed.
+    return asFullMetadata(this)->Cache
+      .load(SWIFT_MEMORY_ORDER_CONSUME);
   }
 
   void setCachedUniqueMetadata(RuntimeMetadataPointer unique) const {
-    assert((static_cast<RuntimeMetadataPointer>(asFullMetadata(this)->Unique) ==
-                nullptr ||
-            asFullMetadata(this)->Unique == unique) &&
-           "already set unique metadata");
+    auto cache = getCacheValue();
+
+    // If the cache was already set to a pointer, we're done. We ought to
+    // converge on a single unique pointer.
+    if (cache.isInitialized()) {
+      assert(cache.getCachedUniqueMetadata() == unique
+             && "already set unique metadata to something else");
+      return;
+    }
+    
+    auto newCache = CacheValue(unique);
 
     // If there is no initialization function, this can be a relaxed store.
-    if (!hasInitializationFunction())
-      asFullMetadata(this)->Unique.store(unique, std::memory_order_relaxed);
+    if (cache.hasInitializationFunction())
+      asFullMetadata(this)->Cache.store(newCache, std::memory_order_relaxed);
     
     // Otherwise, we need a release store to publish the result of
-    // initialization
+    // initialization.
     else
-      asFullMetadata(this)->Unique.store(unique, std::memory_order_release);
+      asFullMetadata(this)->Cache.store(newCache, std::memory_order_release);
   }
   
-  StoredSize getFlags() const {
-    return asFullMetadata(this)->Flags;
-  }
+  /// Return the initialization function for this metadata record.
+  ///
+  /// As a prerequisite, the metadata record must not have been initialized yet,
+  /// and must have an initialization function to begin with, otherwise the
+  /// result is undefined.
+  InitializationFunction_t *getInitializationFunction() const {
+#ifndef NDEBUG
+    auto cache = getCacheValue();
+    assert(cache.hasInitializationFunction());
+#endif
 
-  bool hasInitializationFunction() const {
-    return getFlags() & HeaderPrefix::HasInitializationFunction;
-  }
-
-  InitializationFunction_t getInitializationFunction() const {
-    assert(hasInitializationFunction());
     return asFullMetadata(this)->InitializationFunction;
   }
 };
@@ -2901,10 +2967,11 @@
 /// Initialize the value witness table and struct field offset vector for a
 /// struct, using the "Universal" layout strategy.
 SWIFT_RUNTIME_EXPORT
-void swift_initStructMetadata_UniversalStrategy(size_t numFields,
-                                         const TypeLayout * const *fieldTypes,
-                                         size_t *fieldOffsets,
-                                         ValueWitnessTable *vwtable);
+void swift_initStructMetadata(StructMetadata *self,
+                              StructLayoutFlags flags,
+                              size_t numFields,
+                              const TypeLayout * const *fieldTypes,
+                              size_t *fieldOffsets);
 
 /// Relocate the metadata for a class and copy fields from the given template.
 /// The final size of the metadata is calculated at runtime from the size of
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index add1e4f..5bee126 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -968,37 +968,47 @@
               SizeTy->getPointerTo()),
          ATTRS(NoUnwind))
 
-// void swift_initStructMetadata_UniversalStrategy(size_t numFields,
-//                                              TypeLayout * const *fieldTypes,
-//                                              size_t *fieldOffsets,
-//                                              value_witness_table_t *vwtable);
-FUNCTION(InitStructMetadataUniversal,
-         swift_initStructMetadata_UniversalStrategy, DefaultCC,
+// void swift_initStructMetadata(Metadata *structType,
+//                               StructLayoutFlags flags,
+//                               size_t numFields,
+//                               TypeLayout * const *fieldTypes,
+//                               size_t *fieldOffsets);
+FUNCTION(InitStructMetadata,
+         swift_initStructMetadata, DefaultCC,
          RETURNS(VoidTy),
-         ARGS(SizeTy, Int8PtrPtrTy->getPointerTo(),
-              SizeTy->getPointerTo(), WitnessTablePtrTy),
+         ARGS(TypeMetadataPtrTy, SizeTy, SizeTy, Int8PtrPtrTy->getPointerTo(0),
+              SizeTy->getPointerTo()),
          ATTRS(NoUnwind))
 
-// void swift_initEnumValueWitnessTableSinglePayload(value_witness_table_t *vwt,
-//                                                   TypeLayout *payload,
-//                                                   unsigned num_empty_cases);
-FUNCTION(InitEnumValueWitnessTableSinglePayload,
-         swift_initEnumValueWitnessTableSinglePayload,
+// void swift_initEnumMetadataSingleCase(Metadata *enumType,
+//                                       EnumLayoutFlags flags,
+//                                       TypeLayout *payload);
+FUNCTION(InitEnumMetadataSingleCase,
+         swift_initEnumMetadataSingleCase,
          DefaultCC,
          RETURNS(VoidTy),
-         ARGS(WitnessTablePtrTy, Int8PtrPtrTy, Int32Ty),
+         ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy),
          ATTRS(NoUnwind))
 
-// void swift_initEnumMetadataMultiPayload(value_witness_table_t *vwt,
-//                                         Metadata *enumType,
+// void swift_initEnumMetadataSinglePayload(Metadata *enumType,
+//                                          EnumLayoutFlags flags,
+//                                          TypeLayout *payload,
+//                                          unsigned num_empty_cases);
+FUNCTION(InitEnumMetadataSinglePayload,
+         swift_initEnumMetadataSinglePayload,
+         DefaultCC,
+         RETURNS(VoidTy),
+         ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy, Int32Ty),
+         ATTRS(NoUnwind))
+
+// void swift_initEnumMetadataMultiPayload(Metadata *enumType,
 //                                         size_t numPayloads,
 //                                         TypeLayout * const *payloadTypes);
 FUNCTION(InitEnumMetadataMultiPayload,
          swift_initEnumMetadataMultiPayload,
          DefaultCC,
          RETURNS(VoidTy),
-         ARGS(WitnessTablePtrTy, TypeMetadataPtrTy, SizeTy,
-              Int8PtrPtrTy->getPointerTo(0)),
+         ARGS(TypeMetadataPtrTy, SizeTy, SizeTy, Int8PtrPtrTy->getPointerTo(0)),
          ATTRS(NoUnwind))
 
 // int swift_getEnumCaseSinglePayload(opaque_t *obj, Metadata *payload,
diff --git a/include/swift/SIL/Dominance.h b/include/swift/SIL/Dominance.h
index 79e20d8..539c580 100644
--- a/include/swift/SIL/Dominance.h
+++ b/include/swift/SIL/Dominance.h
@@ -52,6 +52,11 @@
   /// Does instruction A properly dominate instruction B?
   bool properlyDominates(SILInstruction *a, SILInstruction *b);
 
+  /// Does instruction A dominate instruction B?
+  bool dominates(SILInstruction *a, SILInstruction *b) {
+    return a == b || properlyDominates(a, b);
+  }
+
   /// Does value A properly dominate instruction B?
   bool properlyDominates(SILValue a, SILInstruction *b);
 
@@ -74,6 +79,7 @@
   }
 
   using DominatorTreeBase::properlyDominates;
+  using DominatorTreeBase::dominates;
 
   bool isValid(SILFunction *F) const {
     return getNode(&F->front()) != nullptr;
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 3329c15..d4b007c 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -2604,26 +2604,21 @@
 
 /// Represents an invocation of builtin functionality provided by the code
 /// generator.
-class BuiltinInst
+class BuiltinInst final
     : public InstructionBase<SILInstructionKind::BuiltinInst,
-                             SingleValueInstruction> {
+                             SingleValueInstruction>,
+      private llvm::TrailingObjects<BuiltinInst, Operand, Substitution> {
+  friend TrailingObjects;
   friend SILBuilder;
 
   /// The name of the builtin to invoke.
   Identifier Name;
-  
-  /// The number of tail-allocated substitutions, allocated after the operand
-  /// list's tail allocation.
-  unsigned NumSubstitutions;
-  
-  /// The value arguments to the builtin.
-  TailAllocatedOperandList<0> Operands;
-  
-  Substitution *getSubstitutionsStorage() {
-    return reinterpret_cast<Substitution*>(Operands.asArray().end());
+
+  size_t numTrailingObjects(OverloadToken<Operand>) const {
+    return SILInstruction::Bits.BuiltinInst.NumOperands;
   }
-  const Substitution *getSubstitutionsStorage() const {
-    return reinterpret_cast<const Substitution*>(Operands.asArray().end());
+  size_t numTrailingObjects(OverloadToken<Substitution>) const {
+    return SILInstruction::Bits.BuiltinInst.NumSubstitutions;
   }
 
   BuiltinInst(SILDebugLocation DebugLoc, Identifier Name, SILType ReturnType,
@@ -2635,6 +2630,12 @@
                              ArrayRef<SILValue> Args, SILModule &M);
 
 public:
+  ~BuiltinInst() {
+    for (auto &op : getAllOperands()) {
+      op.~Operand();
+    }
+  }
+
   /// Return the name of the builtin operation.
   Identifier getName() const { return Name; }
   void setName(Identifier I) { Name = I; }
@@ -2670,29 +2671,33 @@
   /// True if this builtin application has substitutions, which represent type
   /// parameters to the builtin.
   bool hasSubstitutions() const {
-    return NumSubstitutions != 0;
+    return SILInstruction::Bits.BuiltinInst.NumSubstitutions != 0;
   }
 
   /// Return the type parameters to the builtin.
   SubstitutionList getSubstitutions() const {
-    return {getSubstitutionsStorage(), NumSubstitutions};
+    return {getTrailingObjects<Substitution>(),
+            SILInstruction::Bits.BuiltinInst.NumSubstitutions};
   }
   /// Return the type parameters to the builtin.
   MutableArrayRef<Substitution> getSubstitutions() {
-    return {getSubstitutionsStorage(), NumSubstitutions};
+    return {getTrailingObjects<Substitution>(),
+            SILInstruction::Bits.BuiltinInst.NumSubstitutions};
   }
   
   /// The arguments to the builtin.
   ArrayRef<Operand> getAllOperands() const {
-    return Operands.asArray();
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.BuiltinInst.NumOperands};
   }
   /// The arguments to the builtin.
   MutableArrayRef<Operand> getAllOperands() {
-    return Operands.asArray();
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.BuiltinInst.NumOperands};
   }
   /// The arguments to the builtin.
   OperandValueArrayRef getArguments() const {
-    return Operands.asValueArray();
+    return OperandValueArrayRef(getAllOperands());
   }
 };
   
@@ -2837,9 +2842,6 @@
   };
 
 private:
-  unsigned Length;
-  Encoding TheEncoding;
-
   StringLiteralInst(SILDebugLocation DebugLoc, StringRef text,
                     Encoding encoding, SILType ty);
 
@@ -2849,11 +2851,14 @@
 public:
   /// getValue - Return the string data for the literal, in UTF-8.
   StringRef getValue() const {
-    return {getTrailingObjects<char>(), Length};
+    return {getTrailingObjects<char>(),
+            SILInstruction::Bits.StringLiteralInst.Length};
   }
 
   /// getEncoding - Return the desired encoding of the text.
-  Encoding getEncoding() const { return TheEncoding; }
+  Encoding getEncoding() const {
+    return Encoding(SILInstruction::Bits.StringLiteralInst.TheEncoding);
+  }
 
   /// getCodeUnitCount - Return encoding-based length of the string
   /// literal in code units.
@@ -2881,9 +2886,6 @@
   };
 
 private:
-  unsigned Length;
-  Encoding TheEncoding;
-
   ConstStringLiteralInst(SILDebugLocation DebugLoc, StringRef text,
                          Encoding encoding, SILType ty);
 
@@ -2893,10 +2895,15 @@
 
 public:
   /// getValue - Return the string data for the literal, in UTF-8.
-  StringRef getValue() const { return {getTrailingObjects<char>(), Length}; }
+  StringRef getValue() const {
+    return {getTrailingObjects<char>(),
+            SILInstruction::Bits.ConstStringLiteralInst.Length};
+  }
 
   /// getEncoding - Return the desired encoding of the text.
-  Encoding getEncoding() const { return TheEncoding; }
+  Encoding getEncoding() const {
+    return Encoding(SILInstruction::Bits.ConstStringLiteralInst.TheEncoding);
+  }
 
   /// getCodeUnitCount - Return encoding-based length of the string
   /// literal in code units.
@@ -4382,13 +4389,13 @@
 };
 
 /// StructInst - Represents a constructed loadable struct.
-class StructInst
+class StructInst final
     : public InstructionBase<SILInstructionKind::StructInst,
-                             SingleValueInstruction> {
+                             SingleValueInstruction>,
+      private llvm::TrailingObjects<StructInst, Operand> {
+  friend TrailingObjects;
   friend SILBuilder;
 
-  TailAllocatedOperandList<0> Operands;
-
   /// Because of the storage requirements of StructInst, object
   /// creation goes through 'create()'.
   StructInst(SILDebugLocation DebugLoc, SILType Ty,
@@ -4399,18 +4406,32 @@
                             ArrayRef<SILValue> Elements, SILModule &M);
 
 public:
+  ~StructInst() {
+    for (auto &op : getAllOperands()) {
+      op.~Operand();
+    }
+  }
+
   /// The elements referenced by this StructInst.
   MutableArrayRef<Operand> getElementOperands() {
-    return Operands.getDynamicAsArray();
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.StructInst.NumOperands};
   }
 
   /// The elements referenced by this StructInst.
   OperandValueArrayRef getElements() const {
-    return Operands.getDynamicValuesAsArray();
+    return OperandValueArrayRef({getTrailingObjects<Operand>(),
+                                 SILInstruction::Bits.StructInst.NumOperands});
   }
 
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
+  ArrayRef<Operand> getAllOperands() const {
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.StructInst.NumOperands};
+  }
+  MutableArrayRef<Operand> getAllOperands() {
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.StructInst.NumOperands};
+  }
 
   SILValue getFieldValue(const VarDecl *V) const {
     return getOperandForField(V)->get();
@@ -4740,13 +4761,13 @@
 
 
 /// TupleInst - Represents a constructed loadable tuple.
-class TupleInst
+class TupleInst final
     : public InstructionBase<SILInstructionKind::TupleInst,
-                             SingleValueInstruction> {
+                             SingleValueInstruction>,
+      private llvm::TrailingObjects<TupleInst, Operand> {
+  friend TrailingObjects;
   friend SILBuilder;
 
-  TailAllocatedOperandList<0> Operands;
-
   /// Because of the storage requirements of TupleInst, object
   /// creation goes through 'create()'.
   TupleInst(SILDebugLocation DebugLoc, SILType Ty,
@@ -4757,14 +4778,22 @@
                            ArrayRef<SILValue> Elements, SILModule &M);
 
 public:
+  ~TupleInst() {
+    for (auto &op : getAllOperands()) {
+      op.~Operand();
+    }
+  }
+
   /// The elements referenced by this TupleInst.
   MutableArrayRef<Operand> getElementOperands() {
-    return Operands.getDynamicAsArray();
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.TupleInst.NumOperands};
   }
 
   /// The elements referenced by this TupleInst.
   OperandValueArrayRef getElements() const {
-    return Operands.getDynamicValuesAsArray();
+    return OperandValueArrayRef({getTrailingObjects<Operand>(),
+                                 SILInstruction::Bits.TupleInst.NumOperands});
   }
 
   /// Return the i'th value referenced by this TupleInst.
@@ -4777,8 +4806,14 @@
     return operand->getOperandNumber();
   }
 
-  ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
-  MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
+  ArrayRef<Operand> getAllOperands() const {
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.TupleInst.NumOperands};
+  }
+  MutableArrayRef<Operand> getAllOperands() {
+    return {getTrailingObjects<Operand>(),
+            SILInstruction::Bits.TupleInst.NumOperands};
+  }
 
   TupleType *getTupleType() const {
     return getType().getSwiftRValueType()->castTo<TupleType>();
diff --git a/include/swift/SIL/SILNode.h b/include/swift/SIL/SILNode.h
index 6120cc4..d2e91a4 100644
--- a/include/swift/SIL/SILNode.h
+++ b/include/swift/SIL/SILNode.h
@@ -145,6 +145,22 @@
   SWIFT_INLINE_BITFIELD_EMPTY(LiteralInst, SingleValueInstruction);
   SWIFT_INLINE_BITFIELD_EMPTY(AllocationInst, SingleValueInstruction);
 
+  SWIFT_INLINE_BITFIELD_FULL(StructInst, SingleValueInstruction, 32,
+    : NumPadBits,
+    NumOperands : 32
+  );
+
+  SWIFT_INLINE_BITFIELD_FULL(TupleInst, SingleValueInstruction, 32,
+    : NumPadBits,
+    NumOperands : 32
+  );
+
+  SWIFT_INLINE_BITFIELD_FULL(BuiltinInst, SingleValueInstruction,
+                             64-NumSingleValueInstructionBits,
+    NumSubstitutions : 32-NumSingleValueInstructionBits,
+    NumOperands : 32
+  );
+
   SWIFT_INLINE_BITFIELD_FULL(IntegerLiteralInst, LiteralInst, 32,
     : NumPadBits,
     numBits : 32
@@ -155,6 +171,18 @@
     numBits : 32
   );
 
+  SWIFT_INLINE_BITFIELD_FULL(StringLiteralInst, LiteralInst, 2+32,
+    TheEncoding : 2,
+    : NumPadBits,
+    Length : 32
+  );
+
+  SWIFT_INLINE_BITFIELD_FULL(ConstStringLiteralInst, LiteralInst, 1+32,
+    TheEncoding : 1,
+    : NumPadBits,
+    Length : 32
+  );
+
   SWIFT_INLINE_BITFIELD(DeallocRefInst, DeallocationInst, 1,
     OnStack : 1
   );
@@ -339,6 +367,11 @@
     SWIFT_INLINE_BITS(BeginAccessInst);
     SWIFT_INLINE_BITS(EndAccessInst);
     SWIFT_INLINE_BITS(MetatypeInst);
+    SWIFT_INLINE_BITS(BuiltinInst);
+    SWIFT_INLINE_BITS(StringLiteralInst);
+    SWIFT_INLINE_BITS(ConstStringLiteralInst);
+    SWIFT_INLINE_BITS(StructInst);
+    SWIFT_INLINE_BITS(TupleInst);
   } Bits;
 
 private:
diff --git a/include/swift/SIL/SILPrintContext.h b/include/swift/SIL/SILPrintContext.h
index 1ac3c3e..17b390f 100644
--- a/include/swift/SIL/SILPrintContext.h
+++ b/include/swift/SIL/SILPrintContext.h
@@ -29,7 +29,7 @@
 class SILPrintContext {
 public:
   struct ID {
-    enum ID_Kind { SILBasicBlock, SILUndef, SSAValue } Kind;
+    enum ID_Kind { SILBasicBlock, SILUndef, SSAValue, Null } Kind;
     unsigned Number;
 
     // A stable ordering of ID objects.
diff --git a/include/swift/SIL/SILWitnessVisitor.h b/include/swift/SIL/SILWitnessVisitor.h
index 9c6f2d0..a2a9e70 100644
--- a/include/swift/SIL/SILWitnessVisitor.h
+++ b/include/swift/SIL/SILWitnessVisitor.h
@@ -24,6 +24,7 @@
 #include "swift/AST/ProtocolAssociations.h"
 #include "swift/AST/Types.h"
 #include "swift/SIL/TypeLowering.h"
+#include "llvm/Support/ErrorHandling.h"
 
 namespace swift {
 
diff --git a/include/swift/Syntax/RawSyntax.h b/include/swift/Syntax/RawSyntax.h
index 3982724..70fcad7 100644
--- a/include/swift/Syntax/RawSyntax.h
+++ b/include/swift/Syntax/RawSyntax.h
@@ -126,27 +126,51 @@
   }
 
   /// Add some number of newlines to the position, resetting the column.
-  void addNewlines(uint32_t NewLines) {
+  /// Size is byte size of newline char.
+  /// '\n' and '\r' are 1, '\r\n' is 2.
+  void addNewlines(uint32_t NewLines, uint32_t Size) {
     Line += NewLines;
     Column = 1;
-    Offset += NewLines;
+    Offset += NewLines * Size;
   }
-
+  
   /// Use some text as a reference for adding to the absolute position,
   /// taking note of newlines, etc.
   void addText(StringRef Str) {
-    for (auto C : Str) {
-      addCharacter(C);
+    const char * C = Str.begin();
+    while (C != Str.end()) {
+      switch (*C++) {
+      case '\n':
+        addNewlines(1, 1);
+        break;
+      case '\r':
+        if (C != Str.end() && *C == '\n') {
+          addNewlines(1, 2);
+          ++C;
+        } else {
+          addNewlines(1, 1);
+        }
+        break;
+      default:
+        addColumns(1);
+        break;
+      }
     }
   }
 
   /// Use some character as a reference for adding to the absolute position,
   /// taking note of newlines, etc.
+  /// Take care that consecutive call of this function with '\r' and '\n'
+  /// causes increase of 2 Line but desirable result may be 1 Line.
   void addCharacter(char C) {
-    if (C == '\n') {
-      addNewlines(1);
-    } else {
+    switch (C) {
+    case '\n':
+    case '\r':
+      addNewlines(1, 1);
+      break;
+    default:
       addColumns(1);
+      break;
     }
   }
 
diff --git a/include/swift/Syntax/Serialization/SyntaxSerialization.h b/include/swift/Syntax/Serialization/SyntaxSerialization.h
index 9259095..aaf68af 100644
--- a/include/swift/Syntax/Serialization/SyntaxSerialization.h
+++ b/include/swift/Syntax/Serialization/SyntaxSerialization.h
@@ -69,6 +69,7 @@
       case syntax::TriviaKind::Formfeed:
       case syntax::TriviaKind::Newline:
       case syntax::TriviaKind::CarriageReturn:
+      case syntax::TriviaKind::CarriageReturnLineFeed:
       case syntax::TriviaKind::Backtick:
         out.mapRequired("value", value.Count);
         break;
@@ -95,6 +96,7 @@
     out.enumCase(value, "Formfeed", syntax::TriviaKind::Formfeed);
     out.enumCase(value, "Newline", syntax::TriviaKind::Newline);
     out.enumCase(value, "CarriageReturn", syntax::TriviaKind::CarriageReturn);
+    out.enumCase(value, "CarriageReturnLineFeed", syntax::TriviaKind::CarriageReturnLineFeed);
     out.enumCase(value, "LineComment", syntax::TriviaKind::LineComment);
     out.enumCase(value, "BlockComment", syntax::TriviaKind::BlockComment);
     out.enumCase(value, "DocLineComment", syntax::TriviaKind::DocLineComment);
diff --git a/include/swift/Syntax/SyntaxNodes.h.gyb b/include/swift/Syntax/SyntaxNodes.h.gyb
index 78baadd..45037f9 100644
--- a/include/swift/Syntax/SyntaxNodes.h.gyb
+++ b/include/swift/Syntax/SyntaxNodes.h.gyb
@@ -99,7 +99,6 @@
 
 %   end
 % end
-
 }
 }
 
diff --git a/include/swift/Syntax/Trivia.h b/include/swift/Syntax/Trivia.h
index 16c0601..ff3a6cc 100644
--- a/include/swift/Syntax/Trivia.h
+++ b/include/swift/Syntax/Trivia.h
@@ -113,6 +113,9 @@
 
   /// A newline '\r' character.
   CarriageReturn,
+  
+  /// A newline consists of contiguous '\r' and '\n' characters.
+  CarriageReturnLineFeed,
 
   /// A developer line comment, starting with '//'
   LineComment,
@@ -189,6 +192,12 @@
   static TriviaPiece carriageReturns(unsigned Count) {
     return {TriviaKind::CarriageReturn, Count};
   }
+  
+  /// Return a piece of trivia for some number of two bytes sequence
+  /// consists of CR and LF in a row.
+  static TriviaPiece carriageReturnLineFeeds(unsigned Count) {
+    return {TriviaKind::CarriageReturnLineFeed, Count};
+  }
 
   /// Return a piece of trivia for a single line of ('//') developer comment.
   static TriviaPiece lineComment(const OwnedString Text) {
@@ -241,10 +250,16 @@
       case TriviaKind::VerticalTab:
       case TriviaKind::Formfeed:
         return Count;
+      case TriviaKind::CarriageReturnLineFeed:
+        return Count * 2;
     }
   }
 
   void accumulateAbsolutePosition(AbsolutePosition &Pos) const;
+  
+  /// Try to compose this and Next to one TriviaPiece.
+  /// It returns true if it is succeeded.
+  bool trySquash(const TriviaPiece &Next);
 
   /// Print a debug representation of this trivia piece to the provided output
   /// stream and indentation level.
@@ -336,6 +351,10 @@
       Len += P.getTextLength();
     return Len;
   }
+  
+  /// Append Next TriviaPiece or compose last TriviaPiece and
+  /// Next TriviaPiece to one last TriviaPiece if it can.
+  void appendOrSquash(const TriviaPiece &Next);
 
   /// Dump a debug representation of this Trivia collection to standard error.
   void dump() const;
@@ -411,6 +430,15 @@
     }
     return {{TriviaPiece::carriageReturns(Count)}};
   }
+  
+  /// Return a collection of trivia of some number of two bytes sequence
+  /// consists of CR and LF in a row.
+  static Trivia carriageReturnLineFeeds(unsigned Count) {
+    if (Count == 0) {
+      return {};
+    }
+    return {{TriviaPiece::carriageReturnLineFeeds(Count)}};
+  }
 
   /// Return a collection of trivia with a single line of ('//')
   /// developer comment.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7ba377e..d53d188 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -194,8 +194,8 @@
   /// func ==(Int, Int) -> Bool
   FuncDecl *EqualIntDecl = nullptr;
 
-  /// func _mixForSynthesizedHashValue(Int, Int) -> Int
-  FuncDecl *MixForSynthesizedHashValueDecl = nullptr;
+  /// func _combineHashValues(Int, Int) -> Int
+  FuncDecl *CombineHashValuesDecl = nullptr;
 
   /// func _mixInt(Int) -> Int
   FuncDecl *MixIntDecl = nullptr;
@@ -1048,9 +1048,9 @@
   return decl;
 }
 
-FuncDecl *ASTContext::getMixForSynthesizedHashValueDecl() const {
-  if (Impl.MixForSynthesizedHashValueDecl)
-    return Impl.MixForSynthesizedHashValueDecl;
+FuncDecl *ASTContext::getCombineHashValuesDecl() const {
+  if (Impl.CombineHashValuesDecl)
+    return Impl.CombineHashValuesDecl;
 
   auto resolver = getLazyResolver();
   auto intType = getIntDecl()->getDeclaredType();
@@ -1066,8 +1066,8 @@
   };
 
   auto decl = lookupLibraryIntrinsicFunc(
-      *this, "_mixForSynthesizedHashValue", resolver, callback);
-  Impl.MixForSynthesizedHashValueDecl = decl;
+      *this, "_combineHashValues", resolver, callback);
+  Impl.CombineHashValuesDecl = decl;
   return decl;
 }
 
@@ -3605,17 +3605,6 @@
   return properties;
 }
 
-ArrayRef<AnyFunctionType::Param> AnyFunctionType::getParams() const {
-  switch (getKind()) {
-  case TypeKind::Function:
-    return cast<FunctionType>(this)->getParams();
-  case TypeKind::GenericFunction:
-    return cast<GenericFunctionType>(this)->getParams();
-  default:
-    llvm_unreachable("Undefined function type");
-  }
-}
-
 AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const {
   if (isa<FunctionType>(this))
     return FunctionType::get(getInput(), getResult(), info);
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 5456345..e44c544 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -2710,6 +2710,24 @@
         }
       }
 
+      if (CD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
+        if (!CD->getInterfaceType() ||
+            !CD->getInterfaceType()->is<AnyFunctionType>()) {
+          Out << "Expected FuncDecl to have a function type!\n";
+          abort();
+        }
+
+        auto resultTy = CD->getResultInterfaceType();
+
+        // FIXME: Update to look for plain Optional once
+        // ImplicitlyUnwrappedOptional is removed
+        if (!resultTy->getAnyOptionalObjectType()) {
+          Out << "implicitly unwrapped optional attribute should only be set "
+                 "on functions with optional return types\n";
+          abort();
+        }
+      }
+
       verifyCheckedBase(CD);
     }
 
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 9d56d05..7dbaf8c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1370,6 +1370,49 @@
   return ::new(Buffer) SequenceExpr(elements);
 }
 
+ErasureExpr *ErasureExpr::create(ASTContext &ctx, Expr *subExpr, Type type,
+                                 ArrayRef<ProtocolConformanceRef> conformances){
+  auto size = totalSizeToAlloc<ProtocolConformanceRef>(conformances.size());
+  auto mem = ctx.Allocate(size, alignof(ErasureExpr));
+  return ::new(mem) ErasureExpr(subExpr, type, conformances);
+}
+
+UnresolvedSpecializeExpr *UnresolvedSpecializeExpr::create(ASTContext &ctx,
+                                             Expr *SubExpr, SourceLoc LAngleLoc,
+                                             ArrayRef<TypeLoc> UnresolvedParams,
+                                             SourceLoc RAngleLoc) {
+  auto size = totalSizeToAlloc<TypeLoc>(UnresolvedParams.size());
+  auto mem = ctx.Allocate(size, alignof(UnresolvedSpecializeExpr));
+  return ::new(mem) UnresolvedSpecializeExpr(SubExpr, LAngleLoc,
+                                             UnresolvedParams, RAngleLoc);
+}
+
+CaptureListExpr *CaptureListExpr::create(ASTContext &ctx,
+                                         ArrayRef<CaptureListEntry> captureList,
+                                         ClosureExpr *closureBody) {
+  auto size = totalSizeToAlloc<CaptureListEntry>(captureList.size());
+  auto mem = ctx.Allocate(size, alignof(CaptureListExpr));
+  return ::new(mem) CaptureListExpr(captureList, closureBody);
+}
+
+TupleShuffleExpr *TupleShuffleExpr::create(ASTContext &ctx,
+                                           Expr *subExpr,
+                                           ArrayRef<int> elementMapping,
+                                           TypeImpact typeImpact,
+                                           ConcreteDeclRef defaultArgsOwner,
+                                           ArrayRef<unsigned> VariadicArgs,
+                                           Type VarargsArrayTy,
+                                           ArrayRef<Expr *> CallerDefaultArgs,
+                                           Type ty) {
+  auto size = totalSizeToAlloc<Expr*, int, unsigned>(CallerDefaultArgs.size(),
+                                                     elementMapping.size(),
+                                                     VariadicArgs.size());
+  auto mem = ctx.Allocate(size, alignof(TupleShuffleExpr));
+  return ::new(mem) TupleShuffleExpr(subExpr, elementMapping, typeImpact,
+                                     defaultArgsOwner, VariadicArgs,
+                                     VarargsArrayTy, CallerDefaultArgs, ty);
+}
+
 SourceRange TupleExpr::getSourceRange() const {
   SourceLoc start = SourceLoc();
   SourceLoc end = SourceLoc();
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 5b7c020..c396385 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1184,6 +1184,12 @@
                    Target.isOSDarwin());
   Opts.EnableSILOpaqueValues |= Args.hasArg(OPT_enable_sil_opaque_values);
 
+#if SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
+  Opts.UseDarwinPreStableABIBit = false;
+#else
+  Opts.UseDarwinPreStableABIBit = true;
+#endif
+
   // Must be processed after any other language options that could affect
   // platform conditions.
   bool UnsupportedOS, UnsupportedArch;
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index bc794c7..28325a6 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -1793,6 +1793,395 @@
   return false;
 }
 
+/// Abstract helper class containing info about an IfExpr
+/// that can be expanded into an IfStmt.
+class ExpandableTernaryExprInfo {
+
+public:
+  virtual ~ExpandableTernaryExprInfo() {}
+
+  virtual IfExpr *getIf() = 0;
+
+  virtual SourceRange getNameRange() = 0;
+
+  virtual Type getType() = 0;
+
+  virtual bool shouldDeclareNameAndType() {
+    return !getType().isNull();
+  }
+
+  virtual bool isValid() {
+
+    //Ensure all public properties are non-nil and valid
+    if (!getIf() || !getNameRange().isValid())
+      return false;
+    if (shouldDeclareNameAndType() && getType().isNull())
+      return false;
+
+    return true; //valid
+  }
+
+  CharSourceRange getNameCharRange(const SourceManager &SM) {
+    return Lexer::getCharSourceRangeFromSourceRange(SM, getNameRange());
+  }
+};
+
+/// Concrete subclass containing info about an AssignExpr
+/// where the source is the expandable IfExpr.
+class ExpandableAssignTernaryExprInfo: public ExpandableTernaryExprInfo {
+
+public:
+  ExpandableAssignTernaryExprInfo(AssignExpr *Assign): Assign(Assign) {}
+
+  IfExpr *getIf() {
+    if (!Assign)
+      return nullptr;
+
+    return dyn_cast<IfExpr>(Assign->getSrc());
+  }
+
+  SourceRange getNameRange() {
+    auto Invalid = SourceRange();
+
+    if (!Assign)
+      return Invalid;
+
+    if (auto dest = Assign->getDest())
+      return dest->getSourceRange();
+
+    return Invalid;
+  }
+
+  Type getType() {
+    return nullptr;
+  }
+
+private:
+  AssignExpr *Assign = nullptr;
+};
+
+/// Concrete subclass containing info about a PatternBindingDecl
+/// where the pattern initializer is the expandable IfExpr.
+class ExpandableBindingTernaryExprInfo: public ExpandableTernaryExprInfo {
+
+public:
+  ExpandableBindingTernaryExprInfo(PatternBindingDecl *Binding):
+  Binding(Binding) {}
+
+  IfExpr *getIf() {
+    if (Binding && Binding->getNumPatternEntries() == 1)
+      return dyn_cast<IfExpr>(Binding->getInit(0));
+
+    return nullptr;
+  }
+
+  SourceRange getNameRange() {
+    if (auto Pattern = getNamePattern())
+      return Pattern->getSourceRange();
+
+    return SourceRange();
+  }
+
+  Type getType() {
+    if (auto Pattern = getNamePattern())
+      return Pattern->getType();
+
+    return nullptr;
+  }
+
+private:
+  Pattern *getNamePattern() {
+    if (!Binding || Binding->getNumPatternEntries() != 1)
+      return nullptr;
+
+    auto Pattern = Binding->getPattern(0);
+
+    if (!Pattern)
+      return nullptr;
+
+    if (auto TyPattern = dyn_cast<TypedPattern>(Pattern))
+      Pattern = TyPattern->getSubPattern();
+
+    return Pattern;
+  }
+
+  PatternBindingDecl *Binding = nullptr;
+};
+
+std::unique_ptr<ExpandableTernaryExprInfo>
+findExpandableTernaryExpression(ResolvedRangeInfo Info) {
+
+  if (Info.Kind != RangeKind::SingleDecl
+      && Info.Kind != RangeKind:: SingleExpression)
+    return nullptr;
+
+  if (Info.ContainedNodes.size() != 1)
+    return nullptr;
+
+  if (auto D = Info.ContainedNodes[0].dyn_cast<Decl*>())
+    if (auto Binding = dyn_cast<PatternBindingDecl>(D))
+      return llvm::make_unique<ExpandableBindingTernaryExprInfo>(Binding);
+
+  if (auto E = Info.ContainedNodes[0].dyn_cast<Expr*>())
+    if (auto Assign = dyn_cast<AssignExpr>(E))
+      return llvm::make_unique<ExpandableAssignTernaryExprInfo>(Assign);
+
+  return nullptr;
+}
+
+bool RefactoringActionExpandTernaryExpr::
+isApplicable(ResolvedRangeInfo Info, DiagnosticEngine &Diag) {
+  auto Target = findExpandableTernaryExpression(Info);
+  return Target && Target->isValid();
+}
+
+bool RefactoringActionExpandTernaryExpr::performChange() {
+  auto Target = findExpandableTernaryExpression(RangeInfo);
+
+  if (!Target || !Target->isValid())
+    return true; //abort
+
+  auto NameCharRange = Target->getNameCharRange(SM);
+
+  auto IfRange = Target->getIf()->getSourceRange();
+  auto IfCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, IfRange);
+
+  auto CondRange = Target->getIf()->getCondExpr()->getSourceRange();
+  auto CondCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, CondRange);
+
+  auto ThenRange = Target->getIf()->getThenExpr()->getSourceRange();
+  auto ThenCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, ThenRange);
+
+  auto ElseRange = Target->getIf()->getElseExpr()->getSourceRange();
+  auto ElseCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, ElseRange);
+
+  llvm::SmallString<64> DeclBuffer;
+  llvm::raw_svector_ostream OS(DeclBuffer);
+
+  llvm::StringRef Space = " ";
+  llvm::StringRef NewLine = "\n";
+
+  if (Target->shouldDeclareNameAndType()) {
+    //Specifier will not be replaced; append after specifier
+    OS << NameCharRange.str() << tok::colon << Space;
+    OS << Target->getType() << NewLine;
+  }
+
+  OS << tok::kw_if << Space;
+  OS << CondCharRange.str() << Space;
+  OS << tok::l_brace << NewLine;
+
+  OS << NameCharRange.str() << Space;
+  OS << tok::equal << Space;
+  OS << ThenCharRange.str() << NewLine;
+
+  OS << tok::r_brace << Space;
+  OS << tok::kw_else << Space;
+  OS << tok::l_brace << NewLine;
+
+  OS << NameCharRange.str() << Space;
+  OS << tok::equal << Space;
+  OS << ElseCharRange.str() << NewLine;
+
+  OS << tok::r_brace;
+
+  //Start replacement with name range, skip the specifier
+  auto ReplaceRange(NameCharRange);
+  ReplaceRange.widen(IfCharRange);
+
+  EditConsumer.accept(SM, ReplaceRange, DeclBuffer.str());
+
+  return false; //don't abort
+}
+
+/// Struct containing info about an IfStmt that can be converted into an IfExpr.
+struct ConvertToTernaryExprInfo {
+  ConvertToTernaryExprInfo() {}
+
+  Expr *AssignDest() {
+
+    if (!Then || !Then->getDest() || !Else || !Else->getDest())
+      return nullptr;
+
+    auto ThenDest = Then->getDest();
+    auto ElseDest = Else->getDest();
+
+    if (ThenDest->getKind() != ElseDest->getKind())
+      return nullptr;
+
+    switch (ThenDest->getKind()) {
+      case ExprKind::DeclRef: {
+        auto ThenRef = dyn_cast<DeclRefExpr>(Then->getDest());
+        auto ElseRef = dyn_cast<DeclRefExpr>(Else->getDest());
+
+        if (!ThenRef || !ThenRef->getDecl() || !ElseRef || !ElseRef->getDecl())
+          return nullptr;
+
+        auto ThenName = ThenRef->getDecl()->getFullName();
+        auto ElseName = ElseRef->getDecl()->getFullName();
+
+        if (ThenName.compare(ElseName) != 0)
+          return nullptr;
+
+        return Then->getDest();
+      }
+      case ExprKind::Tuple: {
+        auto ThenTuple = dyn_cast<TupleExpr>(Then->getDest());
+        auto ElseTuple = dyn_cast<TupleExpr>(Else->getDest());
+
+        if (!ThenTuple || !ElseTuple)
+          return nullptr;
+
+        auto ThenNames = ThenTuple->getElementNames();
+        auto ElseNames = ElseTuple->getElementNames();
+
+        if (!ThenNames.equals(ElseNames))
+          return nullptr;
+
+        return ThenTuple;
+      }
+      default:
+        return nullptr;
+    }
+  }
+
+  Expr *ThenSrc() {
+    if (!Then)
+      return nullptr;
+    return Then->getSrc();
+  }
+
+  Expr *ElseSrc() {
+    if (!Else)
+      return nullptr;
+    return Else->getSrc();
+  }
+
+  bool isValid() {
+    if (!Cond || !AssignDest() || !ThenSrc() || !ElseSrc()
+        || !IfRange.isValid())
+      return false;
+
+    return true;
+  }
+
+  PatternBindingDecl *Binding = nullptr; //optional
+
+  Expr *Cond = nullptr; //required
+  AssignExpr *Then = nullptr; //required
+  AssignExpr *Else = nullptr; //required
+  SourceRange IfRange;
+};
+
+ConvertToTernaryExprInfo
+findConvertToTernaryExpression(ResolvedRangeInfo Info) {
+
+  auto notFound = ConvertToTernaryExprInfo();
+
+  if (Info.Kind != RangeKind::SingleStatement
+      && Info.Kind != RangeKind::MultiStatement)
+    return notFound;
+
+  if (Info.ContainedNodes.size() == 0)
+    return notFound;
+
+  struct AssignExprFinder: public SourceEntityWalker {
+
+    AssignExpr *Assign = nullptr;
+
+    AssignExprFinder(Stmt* S) {
+      if (S)
+        walk(S);
+    }
+
+    virtual bool walkToExprPre(Expr *E) {
+      Assign = dyn_cast<AssignExpr>(E);
+      return false;
+    }
+  };
+
+  ConvertToTernaryExprInfo Target;
+
+  IfStmt *If = nullptr;
+
+  if (Info.ContainedNodes.size() == 1) {
+    if (auto S = Info.ContainedNodes[0].dyn_cast<Stmt*>())
+      If = dyn_cast<IfStmt>(S);
+  }
+
+  if (Info.ContainedNodes.size() == 2) {
+    if (auto D = Info.ContainedNodes[0].dyn_cast<Decl*>())
+      Target.Binding = dyn_cast<PatternBindingDecl>(D);
+    if (auto S = Info.ContainedNodes[1].dyn_cast<Stmt*>())
+      If = dyn_cast<IfStmt>(S);
+  }
+
+  if (!If)
+    return notFound;
+
+  auto CondList = If->getCond();
+
+  if (CondList.size() != 1)
+    return notFound;
+
+  Target.Cond = CondList[0].getBooleanOrNull();
+  Target.IfRange = If->getSourceRange();
+
+  Target.Then = AssignExprFinder(If->getThenStmt()).Assign;
+  Target.Else = AssignExprFinder(If->getElseStmt()).Assign;
+
+  return Target;
+}
+
+bool RefactoringActionConvertToTernaryExpr::
+isApplicable(ResolvedRangeInfo Info, DiagnosticEngine &Diag) {
+  return findConvertToTernaryExpression(Info).isValid();
+}
+
+bool RefactoringActionConvertToTernaryExpr::performChange() {
+  auto Target = findConvertToTernaryExpression(RangeInfo);
+
+  if (!Target.isValid())
+    return true; //abort
+
+  llvm::SmallString<64> DeclBuffer;
+  llvm::raw_svector_ostream OS(DeclBuffer);
+
+  llvm::StringRef Space = " ";
+
+  auto IfRange = Target.IfRange;
+  auto ReplaceRange = Lexer::getCharSourceRangeFromSourceRange(SM, IfRange);
+
+  auto CondRange = Target.Cond->getSourceRange();
+  auto CondCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, CondRange);
+
+  auto ThenRange = Target.ThenSrc()->getSourceRange();
+  auto ThenCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, ThenRange);
+
+  auto ElseRange = Target.ElseSrc()->getSourceRange();
+  auto ElseCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, ElseRange);
+
+  CharSourceRange DestCharRange;
+
+  if (Target.Binding) {
+    auto DestRange = Target.Binding->getSourceRange();
+    DestCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, DestRange);
+    ReplaceRange.widen(DestCharRange);
+  } else {
+    auto DestRange = Target.AssignDest()->getSourceRange();
+    DestCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, DestRange);
+  }
+
+  OS << DestCharRange.str() << Space << tok::equal << Space;
+  OS << CondCharRange.str() << Space << tok::question_postfix << Space;
+  OS << ThenCharRange.str() << Space << tok::colon << Space;
+  OS << ElseCharRange.str();
+
+  EditConsumer.accept(SM, ReplaceRange, DeclBuffer.str());
+
+  return false; //don't abort
+}
+
 /// The helper class analyzes a given nominal decl or an extension decl to
 /// decide whether stubs are required to filled in and the context in which
 /// these stubs should be filled.
diff --git a/lib/IRGen/FixedTypeInfo.h b/lib/IRGen/FixedTypeInfo.h
index 8d7465d..188dcea 100644
--- a/lib/IRGen/FixedTypeInfo.h
+++ b/lib/IRGen/FixedTypeInfo.h
@@ -226,7 +226,7 @@
   /// Fixed-size types never need dynamic value witness table instantiation.
   void initializeMetadata(IRGenFunction &IGF,
                           llvm::Value *metadata,
-                          llvm::Value *vwtable,
+                          bool isVWTMutable,
                           SILType T) const override {}
 
   void collectArchetypeMetadata(
diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp
index de064a0..c260771 100644
--- a/lib/IRGen/GenCall.cpp
+++ b/lib/IRGen/GenCall.cpp
@@ -1281,8 +1281,10 @@
   assert(LastArgWritten == 1 && "emitting unnaturally to indirect result");
 
   Args[0] = result.getAddress();
+  SILFunctionConventions FnConv(CurCallee.getSubstFunctionType(),
+                                IGF.getSILModule());
   addIndirectResultAttributes(IGF.IGM, CurCallee.getMutableAttributes(),
-                              0, true);
+                              0, FnConv.getNumIndirectSILResults() <= 1);
 #ifndef NDEBUG
   LastArgWritten = 0; // appease an assert
 #endif
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index 7776b2d..eb1bca6 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -130,6 +130,14 @@
 using namespace swift;
 using namespace irgen;
 
+static llvm::Constant *emitEnumLayoutFlags(IRGenModule &IGM, bool isVWTMutable){
+  // For now, we always use the Swift 5 algorithm.
+  auto flags = EnumLayoutFlags::Swift5Algorithm;
+  if (isVWTMutable) flags |= EnumLayoutFlags::IsVWTMutable;
+
+  return IGM.getSize(Size(uintptr_t(flags)));
+}
+
 SpareBitVector getBitVectorFromAPInt(const APInt &bits, unsigned startBit = 0) {
   if (startBit == 0) {
     return SpareBitVector::fromAPInt(bits);
@@ -587,78 +595,21 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
       // Fixed-size enums don't need dynamic witness table initialization.
       if (TIK >= Fixed) return;
 
-      assert(!ElementsWithPayload.empty() &&
+      assert(ElementsWithPayload.size() == 1 &&
              "empty singleton enum should not be dynamic!");
 
-      // Get the value witness table for the element.
-      SILType eltTy = T.getEnumElementType(ElementsWithPayload[0].decl,
-                                           IGM.getSILModule());
-      llvm::Value *eltLayout = IGF.emitTypeLayoutRef(eltTy);
-
-      Address vwtAddr(vwtable, IGF.IGM.getPointerAlignment());
-      Address eltLayoutAddr(eltLayout, IGF.IGM.getPointerAlignment());
-
-      auto getWitnessDestAndSrc = [&](ValueWitness witness,
-                                      Address *dest,
-                                      Address *src) {
-        *dest = IGF.Builder.CreateConstArrayGEP(vwtAddr,
-                                   unsigned(witness), IGF.IGM.getPointerSize());
-        *src = IGF.Builder.CreateConstArrayGEP(eltLayoutAddr,
-          unsigned(witness) - unsigned(ValueWitness::First_TypeLayoutWitness),
-          IGF.IGM.getPointerSize());
-      };
-
-      auto copyWitnessFromElt = [&](ValueWitness witness) {
-        Address dest, src;
-        getWitnessDestAndSrc(witness, &dest, &src);
-        auto val = IGF.Builder.CreateLoad(src);
-        IGF.Builder.CreateStore(val, dest);
-      };
-
-      copyWitnessFromElt(ValueWitness::Size);
-      copyWitnessFromElt(ValueWitness::Stride);
-
-      // Copy flags over, adding HasEnumWitnesses flag
-      auto copyFlagsFromElt = [&](ValueWitness witness) -> llvm::Value* {
-        Address dest, src;
-        getWitnessDestAndSrc(witness, &dest, &src);
-        auto val = IGF.Builder.CreateLoad(src);
-        auto ewFlag = IGF.Builder.CreatePtrToInt(val, IGF.IGM.SizeTy);
-        auto ewMask
-          = IGF.IGM.getSize(Size(ValueWitnessFlags::HasEnumWitnesses));
-        ewFlag = IGF.Builder.CreateOr(ewFlag, ewMask);
-        auto flag = IGF.Builder.CreateIntToPtr(ewFlag,
-                                              dest.getType()->getElementType());
-        IGF.Builder.CreateStore(flag, dest);
-        return val;
-      };
-
-      auto flags = copyFlagsFromElt(ValueWitness::Flags);
-
-      // If the original type had extra inhabitants, carry over its
-      // extra inhabitant flags.
-      auto xiBB = llvm::BasicBlock::Create(IGF.IGM.getLLVMContext());
-      auto noXIBB = llvm::BasicBlock::Create(IGF.IGM.getLLVMContext());
-
-      auto xiFlag = IGF.Builder.CreatePtrToInt(flags, IGF.IGM.SizeTy);
-      auto xiMask
-        = IGF.IGM.getSize(Size(ValueWitnessFlags::Enum_HasExtraInhabitants));
-      xiFlag = IGF.Builder.CreateAnd(xiFlag, xiMask);
-      auto xiBool = IGF.Builder.CreateICmpNE(xiFlag,
-                                             IGF.IGM.getSize(Size(0)));
-      IGF.Builder.CreateCondBr(xiBool, xiBB, noXIBB);
-
-      IGF.Builder.emitBlock(xiBB);
-      ConditionalDominanceScope condition(IGF);
-      copyWitnessFromElt(ValueWitness::ExtraInhabitantFlags);
-      IGF.Builder.CreateBr(noXIBB);
-
-      IGF.Builder.emitBlock(noXIBB);
+      auto payloadTy = T.getEnumElementType(ElementsWithPayload[0].decl,
+                                            IGM.getSILModule());
+      auto payloadLayout = IGF.emitTypeLayoutRef(payloadTy);
+      auto flags = emitEnumLayoutFlags(IGF.IGM, isVWTMutable);
+      IGF.Builder.CreateCall(
+                    IGF.IGM.getInitEnumMetadataSingleCaseFn(),
+                    {metadata, flags, payloadLayout});
     }
 
     bool mayHaveExtraInhabitants(IRGenModule &IGM) const override {
@@ -904,7 +855,7 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
       // No-payload enums are always fixed-size so never need dynamic value
       // witness table initialization.
@@ -2846,7 +2797,7 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
       // Fixed-size enums don't need dynamic witness table initialization.
       if (TIK >= Fixed) return;
@@ -2858,10 +2809,10 @@
       auto payloadLayout = IGF.emitTypeLayoutRef(payloadTy);
       auto emptyCasesVal = llvm::ConstantInt::get(IGF.IGM.Int32Ty,
                                                   ElementsWithNoPayload.size());
-
+      auto flags = emitEnumLayoutFlags(IGF.IGM, isVWTMutable);
       IGF.Builder.CreateCall(
-                    IGF.IGM.getInitEnumValueWitnessTableSinglePayloadFn(),
-                    {vwtable, payloadLayout, emptyCasesVal});
+                    IGF.IGM.getInitEnumMetadataSinglePayloadFn(),
+                    {metadata, flags, payloadLayout, emptyCasesVal});
     }
 
     /// \group Extra inhabitants
@@ -4744,7 +4695,7 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
       // Fixed-size enums don't need dynamic metadata initialization.
       if (TIK >= Fixed) return;
@@ -4754,8 +4705,9 @@
       auto numPayloadsVal = llvm::ConstantInt::get(IGF.IGM.SizeTy,
                                                    ElementsWithPayload.size());
 
+      auto flags = emitEnumLayoutFlags(IGF.IGM, isVWTMutable);
       IGF.Builder.CreateCall(IGF.IGM.getInitEnumMetadataMultiPayloadFn(),
-                             {vwtable, metadata, numPayloadsVal,
+                             {metadata, flags, numPayloadsVal,
                               payloadLayoutArray});
     }
 
@@ -5139,7 +5091,7 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
       llvm_unreachable("resilient enums cannot be defined");
     }
@@ -5392,9 +5344,9 @@
     }
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
-      return Strategy.initializeMetadata(IGF, metadata, vwtable, T);
+      return Strategy.initializeMetadata(IGF, metadata, isVWTMutable, T);
     }
     bool mayHaveExtraInhabitants(IRGenModule &IGM) const override {
       return Strategy.mayHaveExtraInhabitants(IGM);
diff --git a/lib/IRGen/GenEnum.h b/lib/IRGen/GenEnum.h
index b82a370..262f88e 100644
--- a/lib/IRGen/GenEnum.h
+++ b/lib/IRGen/GenEnum.h
@@ -372,7 +372,7 @@
 
   virtual void initializeMetadata(IRGenFunction &IGF,
                                   llvm::Value *metadata,
-                                  llvm::Value *vwtable,
+                                  bool isVWTMutable,
                                   SILType T) const = 0;
 
   virtual bool mayHaveExtraInhabitants(IRGenModule &IGM) const = 0;
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index c728254..0a07b69 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -2779,14 +2779,9 @@
     bool HasDependentMetadata = false;
     
     /// Set to true if the value witness table for the generic type is dependent
-    /// on its generic parameters. If true, the value witness will be
-    /// tail-emplaced inside the metadata pattern and initialized by the fill
-    /// function. Implies HasDependentMetadata.
+    /// on its generic parameters. Implies HasDependentMetadata.
     bool HasDependentVWT = false;
     
-    /// The offset of the tail-allocated dependent VWT, if any.
-    Size DependentVWTPoint = Size::invalid();
-
     template <class... T>
     GenericMetadataBuilderBase(IRGenModule &IGM, T &&...args)
       : super(IGM, std::forward<T>(args)...) {}
@@ -2852,31 +2847,13 @@
         value = IGF.Builder.CreateBitCast(value, IGM.Int8PtrTy);
         IGF.Builder.CreateStore(value, dest);
       }
-      
-      // Initialize the instantiated dependent value witness table, if we have
-      // one.
-      llvm::Value *vwtableValue = nullptr;
-      if (HasDependentVWT) {
-        assert(!AddressPoint.isInvalid() && "did not set valid address point!");
-        assert(!DependentVWTPoint.isInvalid() && "did not set dependent VWT point!");
-        
-        // Fill in the pointer from the metadata to the VWT. The VWT pointer
-        // always immediately precedes the address point.
-        auto vwtAddr = createPointerSizedGEP(IGF, metadataWords,
-                                             DependentVWTPoint - AddressPoint);
-        vwtableValue = IGF.Builder.CreateBitCast(vwtAddr.getAddress(),
-                                                 IGF.IGM.WitnessTablePtrTy);
 
-        auto vwtAddrVal = IGF.Builder.CreateBitCast(vwtableValue, IGM.Int8PtrTy);
-        auto vwtRefAddr = createPointerSizedGEP(IGF, metadataWords,
-                                                Size(0) - IGM.getPointerSize());
-        IGF.Builder.CreateStore(vwtAddrVal, vwtRefAddr);
-        
+      // A dependent VWT means that we have dependent metadata.
+      if (HasDependentVWT)
         HasDependentMetadata = true;
-      }
 
       if (HasDependentMetadata) {
-        asImpl().emitInitializeMetadata(IGF, metadataValue, vwtableValue);
+        asImpl().emitInitializeMetadata(IGF, metadataValue, false);
       }
       
       // The metadata is now complete.
@@ -2912,13 +2889,6 @@
       // Lay out the template data.
       super::layout();
       
-      // If we have a dependent value witness table, emit its template.
-      if (HasDependentVWT) {
-        // Note the dependent VWT offset.
-        DependentVWTPoint = getNextOffsetFromTemplateHeader();
-        asImpl().addDependentValueWitnessTablePattern();
-      }
-      
       // Fill in the header:
 
       //   Metadata *(*CreateFunction)(GenericMetadata *, const void*);
@@ -3009,7 +2979,7 @@
 void irgen::emitInitializeFieldOffsetVector(IRGenFunction &IGF,
                                             SILType T,
                                             llvm::Value *metadata,
-                                            llvm::Value *vwtable) {
+                                            bool isVWTMutable) {
   auto *target = T.getNominalOrBoundGenericNominal();
   llvm::Value *fieldVector
     = emitAddressOfFieldOffsetVector(IGF, metadata, target)
@@ -3045,15 +3015,18 @@
   auto numFields = IGF.IGM.getSize(Size(storedProperties.size()));
 
   if (isa<ClassDecl>(target)) {
-    assert(vwtable == nullptr);
     IGF.Builder.CreateCall(IGF.IGM.getInitClassMetadataUniversalFn(),
                            {metadata, numFields,
                             fields.getAddress(), fieldVector});
   } else {
     assert(isa<StructDecl>(target));
-    IGF.Builder.CreateCall(IGF.IGM.getInitStructMetadataUniversalFn(),
-                           {numFields, fields.getAddress(),
-                            fieldVector, vwtable});
+    StructLayoutFlags flags = StructLayoutFlags::Swift5Algorithm;
+    if (isVWTMutable)
+      flags |= StructLayoutFlags::IsVWTMutable;
+
+    IGF.Builder.CreateCall(IGF.IGM.getInitStructMetadataFn(),
+                           {metadata, IGF.IGM.getSize(Size(uintptr_t(flags))),
+                            numFields, fields.getAddress(), fieldVector});
   }
 
   IGF.Builder.CreateLifetimeEnd(fields,
@@ -3360,16 +3333,16 @@
     }
 
     void addClassFlags() {
-      // Always set a flag saying that this is a Swift 1.0 class.
-      ClassFlags flags = ClassFlags::IsSwift1;
+      auto flags = ClassFlags();
 
-      // Set a flag if the class uses Swift 1.0 refcounting.
+      // Set a flag if the class uses Swift refcounting.
       auto type = Target->getDeclaredType()->getCanonicalType();
       if (getReferenceCountingForType(IGM, type)
             == ReferenceCounting::Native) {
-        flags |= ClassFlags::UsesSwift1Refcounting;
+        flags |= ClassFlags::UsesSwiftRefcounting;
       }
 
+      // Set a flag if the class has a custom ObjC name.
       DeclAttributes attrs = Target->getAttrs();
       if (auto objc = attrs.getAttribute<ObjCAttr>()) {
         if (objc->getName())
@@ -3438,17 +3411,21 @@
       if (!IGM.ObjCInterop) {
         // with no Objective-C runtime, just give an empty pointer with the
         // swift bit set.
+        // FIXME: Remove null data altogether rdar://problem/18801263
         B.addInt(IGM.IntPtrTy, 1);
         return;
       }
+
       // Derive the RO-data.
       llvm::Constant *data = emitClassPrivateData(IGM, Target);
 
-      // We always set the low bit to indicate this is a Swift class.
-      data = llvm::ConstantExpr::getPtrToInt(data, IGM.IntPtrTy);
-      data = llvm::ConstantExpr::getAdd(data,
-                                    llvm::ConstantInt::get(IGM.IntPtrTy, 1));
+      // Set a low bit to indicate this class has Swift metadata.
+      auto bit = llvm::ConstantInt::get(IGM.IntPtrTy,
+                                        IGM.UseDarwinPreStableABIBit ? 1 : 2);
 
+      // Emit data + bit.
+      data = llvm::ConstantExpr::getPtrToInt(data, IGM.IntPtrTy);
+      data = llvm::ConstantExpr::getAdd(data, bit);
       B.add(data);
     }
 
@@ -3505,8 +3482,7 @@
         auto classTy = Target->getDeclaredTypeInContext()->getCanonicalType();
         auto loweredClassTy = IGF.IGM.getLoweredType(classTy);
         emitInitializeFieldOffsetVector(IGF, loweredClassTy,
-                                        metadata,
-                                        /*vwtable=*/nullptr);
+                                        metadata, /*VWT is mutable*/ false);
 
         // Realizing the class with the ObjC runtime will copy back to the
         // field offset globals for us; but if ObjC interop is disabled, we
@@ -3923,10 +3899,6 @@
       DependentMetaclassRODataPoint -= TemplateHeaderSize;
     }
                             
-    void addDependentValueWitnessTablePattern() {
-      llvm_unreachable("classes should never have dependent vwtables");
-    }
-
     void noteStartOfFieldOffsets(ClassDecl *whichClass) {}
     
     void noteEndOfFieldOffsets(ClassDecl *whichClass) {}
@@ -3960,7 +3932,7 @@
 
     void emitInitializeMetadata(IRGenFunction &IGF,
                                 llvm::Value *metadata,
-                                llvm::Value *vwtable) {
+                                bool isVWTMutable) {
       assert(!HasDependentVWT && "class should never have dependent VWT");
 
       // Fill in the metaclass pointer.
@@ -4553,12 +4525,8 @@
   SILType loweredType = IGF.IGM.getLoweredType(AbstractionPattern(type), type);
   auto &ti = IGF.IGM.getTypeInfo(loweredType);
   if (!ti.isFixedSize()) {
-    // We assume that that value witness table will already have been written
-    // into the metadata; just load it.
-    llvm::Value *vwtable = IGF.emitValueWitnessTableRefForMetadata(metadata);
-
     // Initialize the metadata.
-    ti.initializeMetadata(IGF, metadata, vwtable, loweredType.getAddressType());
+    ti.initializeMetadata(IGF, metadata, true, loweredType.getAddressType());
   }
 
   return metadata;
@@ -4659,7 +4627,7 @@
 
     void addValueWitnessTable() {
       auto type = this->Target->getDeclaredType()->getCanonicalType();
-      B.add(emitValueWitnessTable(IGM, type));
+      B.add(emitValueWitnessTable(IGM, type, false));
     }
 
     void createMetadataAccessFunction() {
@@ -4677,11 +4645,8 @@
     CanType unboundType
       = decl->getDeclaredType()->getCanonicalType();
     
-    dependent = hasDependentValueWitnessTable(IGM, unboundType);    
-    if (dependent)
-      return llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
-    else
-      return emitValueWitnessTable(IGM, unboundType);
+    dependent = hasDependentValueWitnessTable(IGM, unboundType);
+    return emitValueWitnessTable(IGM, unboundType, dependent);
   }
   
   /// A builder for metadata templates.
@@ -4712,18 +4677,13 @@
                                                     HasDependentVWT));
     }
                         
-    void addDependentValueWitnessTablePattern() {
-      emitDependentValueWitnessTablePattern(IGM, B,
-                        Target->getDeclaredType()->getCanonicalType());
-    }
-                        
     void emitInitializeMetadata(IRGenFunction &IGF,
                                 llvm::Value *metadata,
-                                llvm::Value *vwtable) {
+                                bool isVWTMutable) {
       // Nominal types are always preserved through SIL lowering.
       auto structTy = Target->getDeclaredTypeInContext()->getCanonicalType();
       IGM.getTypeInfoForUnlowered(structTy)
-        .initializeMetadata(IGF, metadata, vwtable,
+        .initializeMetadata(IGF, metadata, isVWTMutable,
                             IGF.IGM.getLoweredType(structTy));
     }
   };
@@ -4814,7 +4774,7 @@
 
     void addValueWitnessTable() {
       auto type = Target->getDeclaredType()->getCanonicalType();
-      B.add(emitValueWitnessTable(IGM, type));
+      B.add(emitValueWitnessTable(IGM, type, false));
     }
 
     void addPayloadSize() {
@@ -4862,11 +4822,6 @@
                                                     HasDependentVWT));
     }
 
-    void addDependentValueWitnessTablePattern() {
-      emitDependentValueWitnessTablePattern(IGM, B,
-                          Target->getDeclaredType()->getCanonicalType());
-    }
-
     void addPayloadSize() {
       // In all cases where a payload size is demanded in the metadata, it's
       // runtime-dependent, so fill in a zero here.
@@ -4880,11 +4835,11 @@
 
     void emitInitializeMetadata(IRGenFunction &IGF,
                                 llvm::Value *metadata,
-                                llvm::Value *vwtable) {
+                                bool isVWTMutable) {
       // Nominal types are always preserved through SIL lowering.
       auto enumTy = Target->getDeclaredTypeInContext()->getCanonicalType();
       IGM.getTypeInfoForUnlowered(enumTy)
-        .initializeMetadata(IGF, metadata, vwtable,
+        .initializeMetadata(IGF, metadata, isVWTMutable,
                             IGF.IGM.getLoweredType(enumTy));
     }
   };
@@ -5001,8 +4956,9 @@
     void layout() {
       if (asImpl().requiresInitializationFunction())
         asImpl().addInitializationFunction();
+      else
+        asImpl().addPaddingForInitializationFunction();
       asImpl().addForeignName();
-      asImpl().addUniquePointer();
       asImpl().addForeignFlags();
       super::layout();
     }
@@ -5015,11 +4971,8 @@
 
     void addForeignName() {
       CanType targetType = asImpl().getTargetType();
-      B.add(getMangledTypeName(IGM, targetType));
-    }
-
-    void addUniquePointer() {
-      B.addNullPointer(IGM.TypeMetadataPtrTy);
+      B.addRelativeAddress(getMangledTypeName(IGM, targetType,
+                                              /*relative addressed?*/ true));
     }
 
     void addInitializationFunction() {
@@ -5045,7 +4998,23 @@
 
       IGF.Builder.CreateRetVoid();
 
-      B.add(fn);
+      B.addRelativeAddress(fn);
+    }
+    
+    void addPaddingForInitializationFunction() {
+      // The initialization function field is placed at the least offset of the
+      // record so it can be omitted when not needed. However, the metadata
+      // record is still pointer-aligned, so on 64 bit platforms we need to
+      // occupy the space to keep the rest of the record with the right layout.
+      switch (IGM.getPointerSize().getValue()) {
+      case 4:
+        break;
+      case 8:
+        B.addInt32(0);
+        break;
+      default:
+        llvm_unreachable("unsupported word size");
+      }
     }
 
     void noteAddressPoint() {
@@ -5127,7 +5096,7 @@
 
     void addValueWitnessTable() {
       auto type = this->Target->getDeclaredType()->getCanonicalType();
-      B.add(emitValueWitnessTable(IGM, type));
+      B.add(emitValueWitnessTable(IGM, type, false));
     }
 
     void flagUnfilledFieldOffset() {
@@ -5156,7 +5125,7 @@
 
     void addValueWitnessTable() {
       auto type = this->Target->getDeclaredType()->getCanonicalType();
-      B.add(emitValueWitnessTable(IGM, type));
+      B.add(emitValueWitnessTable(IGM, type, false));
     }
     
     void addPayloadSize() const {
diff --git a/lib/IRGen/GenMeta.h b/lib/IRGen/GenMeta.h
index 62af738..decfc83 100644
--- a/lib/IRGen/GenMeta.h
+++ b/lib/IRGen/GenMeta.h
@@ -258,7 +258,7 @@
   void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
                                        SILType T,
                                        llvm::Value *metadata,
-                                       llvm::Value *vwtable);
+                                       bool isVWTMutable);
 
   /// Adjustment indices for the address points of various metadata.
   /// Size is in words.
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index db8d946..902bcc7 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -323,19 +323,10 @@
     // The Self type is abstract, so we can fulfill its metadata from
     // the Self metadata parameter.
     addSelfMetadataFulfillment(selfTy);
-  } else {
-    // If the Self type is concrete, we have a witness thunk with a
-    // fully substituted Self type. The witness table parameter is not
-    // used.
-    //
-    // FIXME: As above, we should fulfill the Self metadata and
-    // conformance from our two special paramaters here. However, the
-    // Self metadata will be inexact.
-    //
-    // For now, just fulfill the generic arguments of 'Self'.
-    considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
   }
 
+  considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
+
   // The witness table for the Self : P conformance can be
   // fulfilled from the Self witness table parameter.
   Sources.emplace_back(MetadataSource::Kind::SelfWitnessTable,
diff --git a/lib/IRGen/GenStruct.cpp b/lib/IRGen/GenStruct.cpp
index c120fcf..92db298 100644
--- a/lib/IRGen/GenStruct.cpp
+++ b/lib/IRGen/GenStruct.cpp
@@ -512,9 +512,9 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
-      emitInitializeFieldOffsetVector(IGF, T, metadata, vwtable);
+      emitInitializeFieldOffsetVector(IGF, T, metadata, isVWTMutable);
     }
   };
 
diff --git a/lib/IRGen/GenTuple.cpp b/lib/IRGen/GenTuple.cpp
index 5b2e96a..470ff9e 100644
--- a/lib/IRGen/GenTuple.cpp
+++ b/lib/IRGen/GenTuple.cpp
@@ -343,7 +343,7 @@
 
     void initializeMetadata(IRGenFunction &IGF,
                             llvm::Value *metadata,
-                            llvm::Value *vwtable,
+                            bool isVWTMutable,
                             SILType T) const override {
       // Tuple value witness tables are instantiated by the runtime along with
       // their metadata. We should never try to initialize one in the compiler.
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index 84247a4..c8cea57 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -1063,17 +1063,28 @@
 /// Emit a value-witness table for the given type, which is assumed to
 /// be non-dependent.
 llvm::Constant *irgen::emitValueWitnessTable(IRGenModule &IGM,
-                                             CanType abstractType) {
+                                             CanType abstractType,
+                                             bool isPattern) {
   // We shouldn't emit global value witness tables for generic type instances.
   assert(!isa<BoundGenericType>(abstractType) &&
          "emitting VWT for generic instance");
 
+  // We should never be making a pattern if the layout isn't fixed.
+  // The reverse can be true for types whose layout depends on
+  // resilient types.
+  assert((!isPattern || hasDependentValueWitnessTable(IGM, abstractType)) &&
+         "emitting VWT pattern for fixed-layout type");
+
   ConstantInitBuilder builder(IGM);
   auto witnesses = builder.beginArray(IGM.Int8PtrTy);
 
   bool canBeConstant = false;
   addValueWitnessesForAbstractType(IGM, witnesses, abstractType, canBeConstant);
 
+  // If this is just an instantiation pattern, we should never be modifying
+  // it in-place.
+  if (isPattern) canBeConstant = true;
+
   auto addr = IGM.getAddrOfValueWitnessTable(abstractType,
                                              witnesses.finishAndCreateFuture());
   auto global = cast<llvm::GlobalVariable>(addr);
@@ -1163,25 +1174,6 @@
   return layout;
 }
 
-/// Emit the elements of a dependent value witness table template into a
-/// vector.
-void irgen::emitDependentValueWitnessTablePattern(IRGenModule &IGM,
-                                                  ConstantStructBuilder &B,
-                                                  CanType abstractType) {
-  // We shouldn't emit global value witness tables for generic type instances.
-  assert(!isa<BoundGenericType>(abstractType) &&
-         "emitting VWT for generic instance");
-
-  // We shouldn't emit global value witness tables for fixed-layout types.
-  assert(hasDependentValueWitnessTable(IGM, abstractType) &&
-         "emitting VWT pattern for fixed-layout type");
-
-  bool canBeConstant = false;
-  auto witnesses = B.beginArray(IGM.Int8PtrTy);
-  addValueWitnessesForAbstractType(IGM, witnesses, abstractType, canBeConstant);
-  witnesses.finishAndAddTo(B);
-}
-
 FixedPacking TypeInfo::getFixedPacking(IRGenModule &IGM) const {
   auto fixedTI = dyn_cast<FixedTypeInfo>(this);
 
diff --git a/lib/IRGen/GenValueWitness.h b/lib/IRGen/GenValueWitness.h
index db435a7..f12ca5d 100644
--- a/lib/IRGen/GenValueWitness.h
+++ b/lib/IRGen/GenValueWitness.h
@@ -37,16 +37,13 @@
   /// dependent on its generic parameters.
   bool hasDependentValueWitnessTable(IRGenModule &IGM, CanType ty);
 
-  /// Emit a value-witness table for the given type, which is assumed
-  /// to be non-dependent.
-  llvm::Constant *emitValueWitnessTable(IRGenModule &IGM, CanType type);
-
-  /// Emit the elements of a dependent value witness table template into a
-  /// vector.
-  void emitDependentValueWitnessTablePattern(IRGenModule &IGM,
-                                             ConstantStructBuilder &B,
-                                             CanType abstractType);
-
+  /// Emit a value-witness table for the given type.
+  ///
+  /// \param isPattern - true if the table just serves as an instantiation
+  ///   pattern and does not need to be modifiable in-place (if the type
+  ///   does not have static layout for some reason)
+  llvm::Constant *emitValueWitnessTable(IRGenModule &IGM, CanType type,
+                                        bool isPattern);
 }
 }
 
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 3da9183..201ec05 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -134,6 +134,7 @@
       OutputFilename(OutputFilename),
       TargetInfo(SwiftTargetInfo::get(*this)), DebugInfo(nullptr),
       ModuleHash(nullptr), ObjCInterop(Context.LangOpts.EnableObjCInterop),
+      UseDarwinPreStableABIBit(Context.LangOpts.UseDarwinPreStableABIBit),
       Types(*new TypeConverter(*this)) {
   irgen.addGenModule(SF, this);
 
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 73ef85b..cebf099 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -413,6 +413,9 @@
   /// Does the current target require Objective-C interoperation?
   bool ObjCInterop = true;
 
+  /// Is the current target using the Darwin pre-stable ABI's class marker bit?
+  bool UseDarwinPreStableABIBit = true;
+
   /// Should we add value names to local IR values?
   bool EnableValueNames = false;
 
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index d91674d..5015f01 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -3754,13 +3754,32 @@
   dbgname = getVarName(i, IsAnonymous);
 # endif
 
-  (void) Decl;
-
   auto addr = type.allocateStack(*this, i->getElementType(), dbgname);
-
-  emitDebugInfoForAllocStack(i, type, addr.getAddress().getAddress());
-  
   setLoweredStackAddress(i, addr);
+
+  // Generate Debug Info.
+  if (!Decl)
+    return;
+  emitDebugInfoForAllocStack(i, type, addr.getAddress().getAddress());
+
+  // To make it unambiguous whether a `var` binding has been initialized,
+  // zero-initialize the first pointer-sized field. LLDB uses this to
+  // recognize to detect uninitizialized variables. This can be removed once
+  // swiftc switches to @llvm.dbg.addr() intrinsics. This dead store will get
+  // optimized away when optimizations are enabled.
+  if (!Decl->getType()->getClassOrBoundGenericClass())
+    return;
+
+  auto *AI = dyn_cast<llvm::AllocaInst>(addr.getAddress().getAddress());
+  if (!AI)
+    return;
+
+  auto &DL = IGM.DataLayout;
+  if (DL.getTypeSizeInBits(AI->getAllocatedType()) < DL.getPointerSize())
+    return;
+  auto *BC = Builder.CreateBitCast(AI, IGM.OpaquePtrTy->getPointerTo());
+  Builder.CreateStore(llvm::ConstantPointerNull::get(IGM.OpaquePtrTy), BC,
+                      IGM.getPointerAlignment());
 }
 
 static void
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 5ad86c3..f707feb 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -36,9 +36,8 @@
 using namespace swift;
 using namespace swift::irgen;
 
-static GenericEnvironment *getGenericEnvironment(SILModule &Mod,
-                                                 CanSILFunctionType loweredTy) {
-  return loweredTy->getGenericSignature()->createGenericEnvironment();
+static GenericEnvironment *getGenericEnvironment(CanSILFunctionType loweredTy) {
+  return loweredTy->getGenericSignature().getGenericEnvironment();
 }
 
 /// Utility to determine if this is a large loadable type
@@ -201,22 +200,16 @@
 }
 
 // Get the function type or the optional function type
-static SILFunctionType *getInnerFunctionType(SILType storageType) {
-  CanType currCanType = storageType.getSwiftRValueType();
-  if (SILFunctionType *currSILFunctionType =
-          dyn_cast<SILFunctionType>(currCanType.getPointer())) {
+static CanSILFunctionType getInnerFunctionType(SILType storageType) {
+  if (auto currSILFunctionType = storageType.getAs<SILFunctionType>()) {
     return currSILFunctionType;
   }
-  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 (auto optionalType = storageType.getAnyOptionalObjectType()) {
+    if (auto currSILFunctionType = optionalType.getAs<SILFunctionType>()) {
       return currSILFunctionType;
     }
   }
-  return nullptr;
+  return CanSILFunctionType();
 }
 
 static SILType getNewOptionalFunctionType(GenericEnvironment *GenericEnv,
@@ -257,9 +250,6 @@
 static bool modResultType(SILFunction *F, irgen::IRGenModule &Mod) {
   GenericEnvironment *genEnv = F->getGenericEnvironment();
   auto loweredTy = F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(F->getModule(), loweredTy);
-  }
 
   return shouldTransformResults(genEnv, loweredTy, Mod);
 }
@@ -545,10 +535,6 @@
     return visitInstr(applySite.getInstruction());
   }
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-  auto loweredTy = pass.F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-  }
   for (Operand &operand : applySite.getArgumentOperands()) {
     SILValue currOperand = operand.get();
     SILType silType = currOperand->getType();
@@ -573,10 +559,6 @@
   // Check callee - need new generic env:
   CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
   GenericEnvironment *genEnvCallee = nullptr;
-  if (origSILFunctionType->isPolymorphic()) {
-    genEnvCallee = getGenericEnvironment(
-        applySite.getModule(), CanSILFunctionType(origSILFunctionType));
-  }
   auto newSILFunctionType =
       getNewSILFunctionType(genEnvCallee, origSILFunctionType, pass.Mod);
   if (origSILFunctionType != newSILFunctionType) {
@@ -608,10 +590,8 @@
 
   GenericEnvironment *genEnv = nullptr;
   if (fnType->isPolymorphic()) {
-    genEnv = getGenericEnvironment(instr->getModule(), fnType);
+    genEnv = getGenericEnvironment(fnType);
   }
-  Lowering::GenericContextScope GenericScope(
-      instr->getModule().Types, fnType->getGenericSignature());
   if (shouldTransformFunctionType(genEnv, fnType, pass.Mod)) {
     pass.methodInstsToMod.push_back(instr);
     return;
@@ -633,9 +613,11 @@
   auto *F = arg->getFunction();
   SILType storageType = arg->getType();
   GenericEnvironment *genEnv = F->getGenericEnvironment();
-  auto loweredTy = F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(F->getModule(), loweredTy);
+  CanType currCanType = storageType.getSwiftRValueType();
+  if (auto funcType = dyn_cast<SILFunctionType>(currCanType)) {
+    if (funcType->isPolymorphic()) {
+      genEnv = getGenericEnvironment(funcType);
+    }
   }
   SILType newSILType = getNewSILType(genEnv, storageType, Mod);
   // We (currently) only care about function signatures
@@ -716,10 +698,6 @@
 
 void LargeValueVisitor::visitResultTyInst(SingleValueInstruction *instr) {
   GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment();
-  auto loweredTy = instr->getFunction()->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(instr->getModule(), loweredTy);
-  }
   SILType currSILType = instr->getType().getObjectType();
   SILType newSILType = getNewSILType(genEnv, currSILType, pass.Mod);
   if (currSILType != newSILType) {
@@ -735,12 +713,10 @@
 
 void LargeValueVisitor::visitTupleInst(SingleValueInstruction *instr) {
   SILType currSILType = instr->getType().getObjectType();
-  CanType currCanType = currSILType.getSwiftRValueType();
-  if (auto funcType = dyn_cast<SILFunctionType>(currCanType)) {
-    CanSILFunctionType canFuncType = CanSILFunctionType(funcType);
+  if (auto funcType = currSILType.getAs<SILFunctionType>()) {
     GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment();
-    if (!genEnv && canFuncType->isPolymorphic()) {
-      genEnv = getGenericEnvironment(instr->getModule(), canFuncType);
+    if (!genEnv && funcType->isPolymorphic()) {
+      genEnv = getGenericEnvironment(funcType);
     }
     auto newSILFunctionType =
         getNewSILFunctionType(genEnv, funcType, pass.Mod);
@@ -785,10 +761,6 @@
 static bool modNonFuncTypeResultType(SILFunction *F, irgen::IRGenModule &Mod) {
   GenericEnvironment *genEnv = F->getGenericEnvironment();
   auto loweredTy = F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(F->getModule(), loweredTy);
-  }
-
   return modNonFuncTypeResultType(genEnv, loweredTy, Mod);
 }
 
@@ -967,12 +939,6 @@
       SILType currType = unoptimizableLoad->getType().getObjectType();
       GenericEnvironment *genEnv =
           unoptimizableLoad->getFunction()->getGenericEnvironment();
-      auto loweredTy =
-          unoptimizableLoad->getFunction()->getLoweredFunctionType();
-      if (!genEnv && loweredTy->isPolymorphic()) {
-        genEnv =
-            getGenericEnvironment(unoptimizableLoad->getModule(), loweredTy);
-      }
       SILType newSILType = getNewSILType(genEnv, currType, Mod);
       if (currType == newSILType) {
         break;
@@ -1027,10 +993,6 @@
       SILType currType = unoptimizableLoad->getType().getObjectType();
       GenericEnvironment *genEnv =
           userIns->getFunction()->getGenericEnvironment();
-      auto loweredTy = userIns->getFunction()->getLoweredFunctionType();
-      if (!genEnv && loweredTy->isPolymorphic()) {
-        genEnv = getGenericEnvironment(userIns->getModule(), loweredTy);
-      }
       SILType newSILType = getNewSILType(genEnv, currType, pass.Mod);
       if (currType == newSILType) {
         break;
@@ -1150,9 +1112,6 @@
 void LoadableStorageAllocation::insertIndirectReturnArgs() {
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
   auto loweredTy = pass.F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-  }
   auto singleResult = loweredTy->getSingleResult();
   SILType resultStorageType = singleResult.getSILStorageType();
   auto canType = resultStorageType.getSwiftRValueType();
@@ -1177,10 +1136,6 @@
   SILBuilderWithScope argBuilder(entry->begin());
 
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-  auto loweredTy = pass.F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-  }
 
   for (SILArgument *arg : entry->getArguments()) {
     SILType storageType = arg->getType();
@@ -1220,7 +1175,6 @@
 }
 
 void LoadableStorageAllocation::convertApplyResults() {
-  auto &silModue = pass.F->getModule();
   for (auto &BB : *pass.F) {
     for (auto &II : BB) {
       auto *currIns = &II;
@@ -1235,12 +1189,7 @@
         continue;
       }
       CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
-      Lowering::GenericContextScope GenericScope(
-          silModue.Types, origSILFunctionType->getGenericSignature());
       GenericEnvironment *genEnv = nullptr;
-      if (origSILFunctionType->isPolymorphic()) {
-        genEnv = getGenericEnvironment(silModue, origSILFunctionType);
-      }
       if (!shouldTransformResults(genEnv, origSILFunctionType, pass.Mod)) {
         continue;
       }
@@ -1248,14 +1197,12 @@
       auto resultStorageType = singleResult.getSILStorageType();
       if (!isLargeLoadableType(genEnv, resultStorageType, pass.Mod)) {
         // Make sure it is a function type
-        auto canType = resultStorageType.getSwiftRValueType();
-        if (!isa<SILFunctionType>(canType)) {
-          // Check if it is an optional funciton type
-          OptionalTypeKind optKind;
-          auto optionalType = canType.getAnyOptionalObjectType(optKind);
+        if (!resultStorageType.is<SILFunctionType>()) {
+          // Check if it is an optional function type
+          auto optionalType = resultStorageType.getAnyOptionalObjectType();
           assert(optionalType &&
                  "Expected SILFunctionType or Optional for the result type");
-          assert(dyn_cast<SILFunctionType>(optionalType.getPointer()) &&
+          assert(optionalType.is<SILFunctionType>() &&
                  "Expected a SILFunctionType inside the optional Type");
         }
         continue;
@@ -1288,10 +1235,6 @@
   for (SILArgument *arg : entry->getArguments()) {
     SILType storageType = arg->getType();
     GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-    auto loweredTy = pass.F->getLoweredFunctionType();
-    if (!genEnv && loweredTy->isPolymorphic()) {
-      genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-    }
     SILType newSILType = getNewSILType(genEnv, storageType, pass.Mod);
     if (!isLargeLoadableType(genEnv, storageType, pass.Mod) &&
         (newSILType != storageType)) {
@@ -1307,10 +1250,6 @@
 void LoadableStorageAllocation::convertIndirectBasicBlockArgs() {
   SILBasicBlock *entry = pass.F->getEntryBlock();
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-  auto loweredTy = pass.F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-  }
   for (SILBasicBlock &BB : *pass.F) {
     if (&BB == entry) {
       // Already took care of function args
@@ -1570,10 +1509,6 @@
       SILType currType = instr->getType().getObjectType();
       GenericEnvironment *genEnv =
           instr->getFunction()->getGenericEnvironment();
-      auto loweredTy = instr->getFunction()->getLoweredFunctionType();
-      if (!genEnv && loweredTy->isPolymorphic()) {
-        genEnv = getGenericEnvironment(instr->getModule(), loweredTy);
-      }
       SILType newSILType = getNewSILType(genEnv, currType, Mod);
       if (currType == newSILType) {
         allUsesAreReplaceable = false;
@@ -1596,7 +1531,7 @@
   auto funcType = currSILType.castTo<SILFunctionType>();
   GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment();
   if (!genEnv && funcType->isPolymorphic()) {
-    genEnv = getGenericEnvironment(instr->getModule(), funcType);
+    genEnv = getGenericEnvironment(funcType);
   }
   auto newFnType = getNewSILFunctionType(genEnv, funcType, Mod);
   SILType newSILType =
@@ -1667,10 +1602,7 @@
                             LoadableStorageAllocation &allocator) {
 
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-  auto loweredTy = pass.F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-  }
+
   bool repeat = false;
   llvm::SetVector<SILInstruction *> currentModApplies;
   do {
@@ -1713,9 +1645,7 @@
           loadArg->setOperand(newArg);
 
           // If the load is of a function type - do not replace it.
-          auto loadedType = loadArg->getType();
-          auto canLoadedType = loadedType.getSwiftRValueType();
-          if (dyn_cast<SILFunctionType>(canLoadedType.getPointer())) {
+          if (loadArg->getType().is<SILFunctionType>()) {
             continue;
           }
 
@@ -1757,9 +1687,7 @@
       instr->getParent()->erase(instr);
 
       // If the load is of a function type - do not replace it.
-      auto loadedType = loadArg->getType();
-      auto canLoadedType = loadedType.getSwiftRValueType();
-      if (dyn_cast<SILFunctionType>(canLoadedType.getPointer())) {
+      if (loadArg->getType().is<SILFunctionType>()) {
         continue;
       }
 
@@ -1789,9 +1717,7 @@
             allocateAndSetForArgumentOperand(pass, currOperand, applyInst);
           } else if (auto *load = dyn_cast<LoadInst>(currOperandInstr)) {
             // If the load is of a function type - do not replace it.
-            auto loadedType = load->getType();
-            auto canLoadedType = loadedType.getSwiftRValueType();
-            if (dyn_cast<SILFunctionType>(canLoadedType.getPointer())) {
+            if (load->getType().is<SILFunctionType>()) {
               continue;
             }
 
@@ -1978,8 +1904,7 @@
     auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
     GenericEnvironment *genEnvForMethod = nullptr;
     if (currSILFunctionType->isPolymorphic()) {
-      genEnvForMethod = getGenericEnvironment(
-          instr->getModule(), CanSILFunctionType(currSILFunctionType));
+      genEnvForMethod = getGenericEnvironment(currSILFunctionType);
     }
     SILType newSILType = SILType::getPrimitiveObjectType(
         getNewSILFunctionType(genEnvForMethod, currSILFunctionType, pass.Mod));
@@ -2068,9 +1993,6 @@
 static bool rewriteFunctionReturn(StructLoweringState &pass) {
   GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
   auto loweredTy = pass.F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
-  }
   SILFunction *F = pass.F;
   SILType resultTy = loweredTy->getAllResultsType();
   SILType newSILType = getNewSILType(genEnv, resultTy, pass.Mod);
@@ -2100,8 +2022,7 @@
 void LoadableByAddress::runOnFunction(SILFunction *F) {
   CanSILFunctionType funcType = F->getLoweredFunctionType();
   IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
-  Lowering::GenericContextScope GenericScope(getModule()->Types,
-                                             funcType->getGenericSignature());
+
   if (F->isExternalDeclaration()) {
     if (!modifiableFunction(funcType)) {
       return;
@@ -2110,9 +2031,9 @@
     GenericEnvironment *genEnv = F->getGenericEnvironment();
     auto loweredTy = F->getLoweredFunctionType();
     if (!genEnv && loweredTy->isPolymorphic()) {
-      genEnv = getGenericEnvironment(F->getModule(), loweredTy);
+      genEnv = getGenericEnvironment(loweredTy);
     }
-    if (shouldTransformFunctionType(genEnv, F->getLoweredFunctionType(),
+    if (shouldTransformFunctionType(genEnv, loweredTy,
                                     *currIRMod)) {
       modFuncs.insert(F);
     }
@@ -2159,11 +2080,10 @@
                                   IRGenModule &Mod, SILBuilder &builder) {
   SILType currSILType = op->getType();
   if (auto funcType = currSILType.getAs<SILFunctionType>()) {
-    CanSILFunctionType canFuncType = CanSILFunctionType(funcType);
     GenericEnvironment *genEnv =
         containingInstr->getFunction()->getGenericEnvironment();
-    if (!genEnv && canFuncType->isPolymorphic()) {
-      genEnv = getGenericEnvironment(containingInstr->getModule(), canFuncType);
+    if (!genEnv && funcType->isPolymorphic()) {
+      genEnv = getGenericEnvironment(funcType);
     }
     auto newFnType = getNewSILFunctionType(genEnv, funcType, Mod);
     SILType newSILType = SILType::getPrimitiveObjectType(newFnType);
@@ -2186,25 +2106,6 @@
   return op;
 }
 
-static SmallVector<Substitution, 4>
-getNewSubs(SubstitutionList origSubs, swift::irgen::IRGenModule *currIRMod,
-           swift::GenericEnvironment *genEnv) {
-  SmallVector<Substitution, 4> newSubs;
-  for (auto sub : origSubs) {
-    Type origType = sub.getReplacement();
-    CanType origCanType = origType->getCanonicalType();
-    if (!origCanType->isLegalSILType()) {
-      newSubs.push_back(sub);
-      continue;
-    }
-    SILType origSILType = SILType::getPrimitiveObjectType(origCanType);
-    SILType newSILType = getNewSILType(genEnv, origSILType, *currIRMod);
-    Type newType = newSILType.getSwiftRValueType()->getRValueType();
-    newSubs.push_back(Substitution(newType, sub.getConformances()));
-  }
-  return newSubs;
-}
-
 void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
   auto *F = applyInst->getFunction();
   IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
@@ -2221,18 +2122,10 @@
     }
   }
   CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
-  auto origCanType = CanSILFunctionType(origSILFunctionType);
-  Lowering::GenericContextScope GenericScope(
-      getModule()->Types, origCanType->getGenericSignature());
   GenericEnvironment *genEnv = nullptr;
-  if (origSILFunctionType->isPolymorphic()) {
-    genEnv = getGenericEnvironment(applyInst->getModule(),
-                                   CanSILFunctionType(origSILFunctionType));
-  }
   CanSILFunctionType newSILFunctionType =
       getNewSILFunctionType(genEnv, origSILFunctionType, *currIRMod);
-  CanSILFunctionType newCanSILFuncType(newSILFunctionType);
-  SILFunctionConventions newSILFunctionConventions(newCanSILFuncType,
+  SILFunctionConventions newSILFunctionConventions(newSILFunctionType,
                                                    *getModule());
   SmallVector<SILValue, 8> callArgs;
   SILBuilderWithScope applyBuilder(applyInst);
@@ -2240,15 +2133,14 @@
   // Find the new alloc we created earlier.
   // and pass it as first parameter:
   if (applyInst->getKind() != SILInstructionKind::PartialApplyInst &&
-      modNonFuncTypeResultType(genEnv, origCanType, *currIRMod) &&
+      modNonFuncTypeResultType(genEnv, origSILFunctionType, *currIRMod) &&
       modifiableApply(applySite, *getIRGenModule())) {
     assert(allApplyRetToAllocMap.find(applyInst) !=
            allApplyRetToAllocMap.end());
     auto newAlloc = allApplyRetToAllocMap.find(applyInst)->second;
     callArgs.push_back(newAlloc);
   }
-  SmallVector<Substitution, 4> newSubs =
-      getNewSubs(applySite.getSubstitutions(), currIRMod, genEnv);
+
   // Collect arg operands
   for (Operand &operand : applySite.getArgumentOperands()) {
     SILValue currOperand = operand.get();
@@ -2261,7 +2153,8 @@
   case SILInstructionKind::ApplyInst: {
     auto *castedApply = cast<ApplyInst>(applyInst);
     SILValue newApply =
-      applyBuilder.createApply(castedApply->getLoc(), callee, newSubs,
+      applyBuilder.createApply(castedApply->getLoc(), callee,
+                               applySite.getSubstitutions(),
                                callArgs, castedApply->isNonThrowing());
     castedApply->replaceAllUsesWith(newApply);
     break;
@@ -2269,7 +2162,8 @@
   case SILInstructionKind::TryApplyInst: {
     auto *castedApply = cast<TryApplyInst>(applyInst);
     applyBuilder.createTryApply(
-        castedApply->getLoc(), callee, newSubs, callArgs,
+        castedApply->getLoc(), callee,
+        applySite.getSubstitutions(), callArgs,
         castedApply->getNormalBB(), castedApply->getErrorBB());
     break;
   }
@@ -2277,13 +2171,12 @@
     auto *castedApply = cast<PartialApplyInst>(applyInst);
     // Change the type of the Closure
     auto partialApplyConvention = castedApply->getType()
-                                      .getSwiftRValueType()
-                                      ->getAs<SILFunctionType>()
+                                      .getAs<SILFunctionType>()
                                       ->getCalleeConvention();
 
     auto newApply =
       applyBuilder.createPartialApply(castedApply->getLoc(), callee,
-                                      newSubs, callArgs,
+                                      applySite.getSubstitutions(), callArgs,
                                       partialApplyConvention);
     castedApply->replaceAllUsesWith(newApply);
     break;
@@ -2320,16 +2213,9 @@
   for (auto *enumInstr : uncheckedEnumDataOfFunc) {
     SILBuilderWithScope enumBuilder(enumInstr);
     SILFunction *F = enumInstr->getFunction();
-    CanSILFunctionType funcType = F->getLoweredFunctionType();
     IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
-    Lowering::GenericContextScope GenericScope(getModule()->Types,
-                                               funcType->getGenericSignature());
     SILType origType = enumInstr->getType();
     GenericEnvironment *genEnv = F->getGenericEnvironment();
-    auto loweredTy = F->getLoweredFunctionType();
-    if (!genEnv && loweredTy->isPolymorphic()) {
-      genEnv = getGenericEnvironment(F->getModule(), loweredTy);
-    }
     SILType newType = getNewSILType(genEnv, origType, *currIRMod);
     auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
         enumInstr->getElement(), F->getModule());
@@ -2354,16 +2240,9 @@
   for (auto *enumInstr : uncheckedTakeEnumDataAddrOfFunc) {
     SILBuilderWithScope enumBuilder(enumInstr);
     SILFunction *F = enumInstr->getFunction();
-    CanSILFunctionType funcType = F->getLoweredFunctionType();
     IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
-    Lowering::GenericContextScope GenericScope(getModule()->Types,
-                                               funcType->getGenericSignature());
     SILType origType = enumInstr->getType();
     GenericEnvironment *genEnv = F->getGenericEnvironment();
-    auto loweredTy = F->getLoweredFunctionType();
-    if (!genEnv && loweredTy->isPolymorphic()) {
-      genEnv = getGenericEnvironment(F->getModule(), loweredTy);
-    }
     SILType newType = getNewSILType(genEnv, origType, *currIRMod);
     auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
         enumInstr->getElement(), F->getModule());
@@ -2410,15 +2289,8 @@
       currSILType = thinToPointer->getOperand()->getType();
     }
     auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
-    Lowering::GenericContextScope GenericScope(
-        getModule()->Types,
-        currSILFunctionType->getGenericSignature());
     GenericEnvironment *genEnv =
         convInstr->getFunction()->getGenericEnvironment();
-    auto loweredTy = convInstr->getFunction()->getLoweredFunctionType();
-    if (!genEnv && loweredTy->isPolymorphic()) {
-      genEnv = getGenericEnvironment(convInstr->getModule(), loweredTy);
-    }
     CanSILFunctionType newFnType =
         getNewSILFunctionType(genEnv, currSILFunctionType, *currIRMod);
     SILType newType = SILType::getPrimitiveObjectType(newFnType);
@@ -2458,14 +2330,8 @@
         getIRGenModule()->IRGen.getGenModule(builtinInstr->getFunction());
     auto *F = builtinInstr->getFunction();
     GenericEnvironment *genEnv = F->getGenericEnvironment();
-    auto loweredTy = F->getLoweredFunctionType();
-    if (!genEnv && loweredTy->isPolymorphic()) {
-      genEnv = getGenericEnvironment(F->getModule(), loweredTy);
-    }
     auto resultTy = builtinInstr->getType();
     auto newResultTy = getNewSILType(genEnv, resultTy, *currIRMod);
-    auto newSubs =
-        getNewSubs(builtinInstr->getSubstitutions(), currIRMod, genEnv);
 
     llvm::SmallVector<SILValue, 5> newArgs;
     for (auto oldArg : builtinInstr->getArguments()) {
@@ -2474,7 +2340,8 @@
 
     SILBuilderWithScope builtinBuilder(builtinInstr);
     auto *newInstr = builtinBuilder.createBuiltin(
-        builtinInstr->getLoc(), builtinInstr->getName(), newResultTy, newSubs,
+        builtinInstr->getLoc(), builtinInstr->getName(), newResultTy,
+        builtinInstr->getSubstitutions(),
         newArgs);
     builtinInstr->replaceAllUsesWith(newInstr);
     builtinInstr->getParent()->erase(builtinInstr);
@@ -2484,12 +2351,9 @@
 void LoadableByAddress::updateLoweredTypes(SILFunction *F) {
   IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
   CanSILFunctionType funcType = F->getLoweredFunctionType();
-  Lowering::GenericContextScope GenericScope(getModule()->Types,
-                                             funcType->getGenericSignature());
   GenericEnvironment *genEnv = F->getGenericEnvironment();
-  auto loweredTy = F->getLoweredFunctionType();
-  if (!genEnv && loweredTy->isPolymorphic()) {
-    genEnv = getGenericEnvironment(F->getModule(), loweredTy);
+  if (!genEnv && funcType->isPolymorphic()) {
+    genEnv = getGenericEnvironment(funcType);
   }
   auto newFuncTy = getNewSILFunctionType(genEnv, funcType, *currIRMod);
   F->rewriteLoweredTypeUnsafe(newFuncTy);
@@ -2557,40 +2421,39 @@
         } else if (auto *CFI = dyn_cast<ConvertFunctionInst>(&I)) {
           SILValue val = CFI->getConverted();
           SILType currType = val->getType();
-          CanType currCanType = currType.getSwiftRValueType();
-          auto *fType = dyn_cast<SILFunctionType>(currCanType.getPointer());
+          auto fType = currType.getAs<SILFunctionType>();
           assert(fType && "Expected SILFunctionType");
-          if (modifiableFunction(CanSILFunctionType(fType))) {
+          if (modifiableFunction(fType)) {
             conversionInstrs.insert(CFI);
           }
         } else if (auto *TTI = dyn_cast<ThinToThickFunctionInst>(&I)) {
 
-          CanType canType = TTI->getCallee()->getType().getSwiftRValueType();
-          auto *fType = canType->castTo<SILFunctionType>();
+          auto canType = TTI->getCallee()->getType();
+          auto fType = canType.castTo<SILFunctionType>();
 
-          if (modifiableFunction(CanSILFunctionType(fType)))
+          if (modifiableFunction(fType))
             conversionInstrs.insert(TTI);
 
         } else if (auto *LI = dyn_cast<LoadInst>(&I)) {
           SILType currType = LI->getType();
-          if (auto *fType = getInnerFunctionType(currType)) {
-            if (modifiableFunction(CanSILFunctionType(fType))) {
+          if (auto fType = getInnerFunctionType(currType)) {
+            if (modifiableFunction(fType)) {
               // need to re-create these loads: re-write type cache
               loadInstrsOfFunc.insert(LI);
             }
           }
         } else if (auto *UED = dyn_cast<UncheckedEnumDataInst>(&I)) {
           SILType currType = UED->getType();
-          if (auto *fType = getInnerFunctionType(currType)) {
-            if (modifiableFunction(CanSILFunctionType(fType))) {
+          if (auto fType = getInnerFunctionType(currType)) {
+            if (modifiableFunction(fType)) {
               // need to re-create these loads: re-write type cache
               uncheckedEnumDataOfFunc.insert(UED);
             }
           }
         } else if (auto *UED = dyn_cast<UncheckedTakeEnumDataAddrInst>(&I)) {
           SILType currType = UED->getType();
-          if (auto *fType = getInnerFunctionType(currType)) {
-            if (modifiableFunction(CanSILFunctionType(fType))) {
+          if (auto fType = getInnerFunctionType(currType)) {
+            if (modifiableFunction(fType)) {
               // need to re-create these loads: re-write type cache
               uncheckedTakeEnumDataAddrOfFunc.insert(UED);
             }
diff --git a/lib/IRGen/ResilientTypeInfo.h b/lib/IRGen/ResilientTypeInfo.h
index 7edc2d9..0cd02c1 100644
--- a/lib/IRGen/ResilientTypeInfo.h
+++ b/lib/IRGen/ResilientTypeInfo.h
@@ -157,7 +157,7 @@
 
   void initializeMetadata(IRGenFunction &IGF,
                           llvm::Value *metadata,
-                          llvm::Value *vwtable,
+                          bool isVWTMutable,
                           SILType T) const override {
     // Resilient value types and archetypes always refer to an existing type.
     // A witness table should never be independently initialized for one.
diff --git a/lib/IRGen/TypeInfo.h b/lib/IRGen/TypeInfo.h
index e1370f2..907bb89 100644
--- a/lib/IRGen/TypeInfo.h
+++ b/lib/IRGen/TypeInfo.h
@@ -392,7 +392,7 @@
   /// for fixed-size types.
   virtual void initializeMetadata(IRGenFunction &IGF,
                                   llvm::Value *metadata,
-                                  llvm::Value *vwtable,
+                                  bool isVWTMutable,
                                   SILType T) const = 0;
 
   /// Get the tag of a single payload enum with a payload of this type (\p T) e.g
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 92c478d..60871f3 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -2119,6 +2119,8 @@
 
   case '\n':
   case '\r':
+    assert(TriviaRetention != TriviaRetentionMode::WithTrivia &&
+           "newlines should be eaten by lexTrivia as LeadingTrivia");
     NextToken.setAtStartOfLine(true);
     goto Restart;  // Skip whitespace.
 
@@ -2287,7 +2289,7 @@
   return L.peekNextToken();
 }
 
-void Lexer::lexTrivia(syntax::TriviaList &Pieces, bool IsForTrailingTrivia) {
+void Lexer::lexTrivia(syntax::Trivia &Pieces, bool IsForTrailingTrivia) {
   if (TriviaRetention == TriviaRetentionMode::WithoutTrivia)
     return;
 
@@ -2298,46 +2300,34 @@
   // TODO: Handle invalid UTF8 sequence which is skipped in lexImpl().
   switch (*CurPtr++) {
   case '\n':
+    if (IsForTrailingTrivia)
+      break;
+    NextToken.setAtStartOfLine(true);
+    Pieces.appendOrSquash(TriviaPiece::newlines(1));
+    goto Restart;
   case '\r':
     if (IsForTrailingTrivia)
       break;
     NextToken.setAtStartOfLine(true);
-    LLVM_FALLTHROUGH;
-  case ' ':
-  case '\t':
-  case '\v':
-  case '\f': {
-    auto Char = CurPtr[-1];
-    // Consume consective same characters.
-    while (*CurPtr == Char)
+    if (CurPtr[0] == '\n') {
+      Pieces.appendOrSquash(TriviaPiece::carriageReturnLineFeeds(1));
       ++CurPtr;
-
-    auto Length = CurPtr - TriviaStart;
-    switch (Char) {
-    case ' ':
-      Pieces.push_back(TriviaPiece::spaces(Length));
-      break;
-    case '\n':
-      // FIXME: CR+LF shoud form one trivia piece
-      Pieces.push_back(TriviaPiece::newlines(Length));
-      break;
-    case '\r':
-      Pieces.push_back(TriviaPiece::carriageReturns(Length));
-      break;
-    case '\t':
-      Pieces.push_back(TriviaPiece::tabs(Length));
-      break;
-    case '\v':
-      Pieces.push_back(TriviaPiece::verticalTabs(Length));
-      break;
-    case '\f':
-      Pieces.push_back(TriviaPiece::formfeeds(Length));
-      break;
-    default:
-      llvm_unreachable("Invalid character for whitespace trivia");
+    } else {
+      Pieces.appendOrSquash(TriviaPiece::carriageReturns(1));
     }
     goto Restart;
-  }
+  case ' ':
+    Pieces.appendOrSquash(TriviaPiece::spaces(1));
+    goto Restart;
+  case '\t':
+    Pieces.appendOrSquash(TriviaPiece::tabs(1));
+    goto Restart;
+  case '\v':
+    Pieces.appendOrSquash(TriviaPiece::verticalTabs(1));
+    goto Restart;
+  case '\f':
+    Pieces.appendOrSquash(TriviaPiece::formfeeds(1));
+    goto Restart;
   case '/':
     if (IsForTrailingTrivia || isKeepingComments()) {
       // Don't lex comments as trailing trivias (for now).
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 96333bd..d391b9c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3789,6 +3789,10 @@
   // Properties in protocols use sufficiently limited syntax that we have a
   // special parsing loop for them.  SIL mode uses the same syntax.
   if (Flags.contains(PD_InProtocol) || isInSILMode()) {
+    if (Tok.is(tok::r_brace)) {
+      // Give syntax node an empty statement list.
+      SyntaxParsingContext StmtListContext(SyntaxContext, SyntaxKind::StmtList);
+    }
     while (Tok.isNot(tok::r_brace)) {
       if (Tok.is(tok::eof))
         return true;
@@ -3863,13 +3867,14 @@
     return false;
   }
 
-
   // Otherwise, we have a normal var or subscript declaration, parse the full
   // complement of specifiers, along with their bodies.
 
   // If the body is completely empty, preserve it.  This is at best a getter with
   // an implicit fallthrough off the end.
   if (Tok.is(tok::r_brace)) {
+    // Give syntax node an empty statement list.
+    SyntaxParsingContext StmtListContext(SyntaxContext, SyntaxKind::StmtList);
     diagnose(Tok, diag::computed_property_no_accessors);
     return true;
   }
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 01ea2c7..7a49db4 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -57,6 +57,7 @@
       return makeParserCodeCompletionResult<Expr>();
     if (pattern.isNull())
       return nullptr;
+    SyntaxContext->setCreateSyntax(SyntaxKind::UnresolvedPatternExpr);
     return makeParserResult(new (Context) UnresolvedPatternExpr(pattern.get()));
   }
   
@@ -1211,8 +1212,8 @@
         SmallVector<TypeLoc, 8> locArgs;
         for (auto ty : args)
           locArgs.push_back(ty);
-        Result = makeParserResult(new (Context) UnresolvedSpecializeExpr(
-            Result.get(), LAngleLoc, Context.AllocateCopy(locArgs), RAngleLoc));
+        Result = makeParserResult(UnresolvedSpecializeExpr::create(Context,
+                                  Result.get(), LAngleLoc, locArgs, RAngleLoc));
       }
 
       continue;
@@ -1546,6 +1547,13 @@
                      ? VarDecl::Specifier::Let
                      : VarDecl::Specifier::Var;
       auto pattern = createBindingFromPattern(loc, name, specifier);
+      if (SyntaxContext->isEnabled()) {
+        PatternSyntax PatternNode =
+            SyntaxFactory::makeIdentifierPattern(SyntaxContext->popToken());
+        ExprSyntax ExprNode =
+            SyntaxFactory::makeUnresolvedPatternExpr(PatternNode);
+        SyntaxContext->addSyntax(ExprNode);
+      }
       Result = makeParserResult(new (Context) UnresolvedPatternExpr(pattern));
       break;
     }
@@ -2207,9 +2215,8 @@
     SmallVector<TypeLoc, 8> locArgs;
     for (auto ty : args)
       locArgs.push_back(ty);
-    E = new (Context) UnresolvedSpecializeExpr(E, LAngleLoc,
-                                               Context.AllocateCopy(locArgs),
-                                               RAngleLoc);
+    E = UnresolvedSpecializeExpr::create(Context, E, LAngleLoc, locArgs,
+                                         RAngleLoc);
   }
   return E;
 }
@@ -2780,8 +2787,7 @@
   // If the closure includes a capture list, create an AST node for it as well.
   Expr *result = closure;
   if (!captureList.empty())
-    result = new (Context) CaptureListExpr(Context.AllocateCopy(captureList),
-                                           closure);
+    result = CaptureListExpr::create(Context, captureList, closure);
 
   return makeParserResult(Status, result);
 }
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 7d1e365..59d05ee 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -848,6 +848,7 @@
     return parsePatternTuple();
     
   case tok::kw__:
+    PatternCtx.setCreateSyntax(SyntaxKind::WildcardPattern);
     return makeParserResult(new (Context) AnyPattern(consumeToken(tok::kw__)));
     
   case tok::identifier: {
@@ -874,6 +875,7 @@
     
   case tok::kw_var:
   case tok::kw_let: {
+    PatternCtx.setCreateSyntax(SyntaxKind::ValueBindingPattern);
     bool isLet = Tok.is(tok::kw_let);
     SourceLoc varLoc = consumeToken();
     
@@ -956,6 +958,8 @@
 ///   pattern-tuple-body:
 ///     pattern-tuple-element (',' pattern-tuple-body)*
 ParserResult<Pattern> Parser::parsePatternTuple() {
+  SyntaxParsingContext TuplePatternCtxt(SyntaxContext,
+                                        SyntaxKind::TuplePattern);
   StructureMarkerRAII ParsingPatternTuple(*this, Tok);
   SourceLoc LPLoc = consumeToken(tok::l_paren);
   SourceLoc RPLoc;
@@ -966,7 +970,7 @@
     parseList(tok::r_paren, LPLoc, RPLoc,
               /*AllowSepAfterLast=*/false,
               diag::expected_rparen_tuple_pattern_list,
-              SyntaxKind::Unknown,
+              SyntaxKind::TuplePatternElementList,
               [&] () -> ParserStatus {
     // Parse the pattern tuple element.
     ParserStatus EltStatus;
@@ -994,10 +998,13 @@
 ParserResult<Pattern> Parser::
 parseOptionalPatternTypeAnnotation(ParserResult<Pattern> result,
                                    bool isOptional) {
+  if (!Tok.is(tok::colon))
+    return result;
 
   // Parse an optional type annotation.
-  if (!consumeIf(tok::colon))
-    return result;
+  SyntaxParsingContext TypeAnnotationCtxt(SyntaxContext,
+                                          SyntaxKind::TypeAnnotation);
+  consumeToken(tok::colon);
 
   Pattern *P;
   if (result.isNull())
@@ -1032,9 +1039,11 @@
   // parse pattern nodes for productions shared by pattern and expression
   // grammar. For short-term ease of initial implementation, we always go
   // through the expr parser for ambiguous productions.
+  SyntaxParsingContext PatternCtx(SyntaxContext, SyntaxContextKind::Pattern);
 
   // Parse productions that can only be patterns.
   if (Tok.isAny(tok::kw_var, tok::kw_let)) {
+    PatternCtx.setCreateSyntax(SyntaxKind::ValueBindingPattern);
     assert(Tok.isAny(tok::kw_let, tok::kw_var) && "expects var or let");
     bool isLet = Tok.is(tok::kw_let);
     SourceLoc varLoc = consumeToken();
@@ -1044,6 +1053,7 @@
   
   // matching-pattern ::= 'is' type
   if (Tok.is(tok::kw_is)) {
+    PatternCtx.setCreateSyntax(SyntaxKind::IsTypePattern);
     SourceLoc isLoc = consumeToken(tok::kw_is);
     ParserResult<TypeRepr> castType = parseType();
     if (castType.isNull() || castType.hasCodeCompletion())
@@ -1062,7 +1072,14 @@
     return makeParserCodeCompletionStatus();
   if (subExpr.isNull())
     return nullptr;
-  
+
+  if (SyntaxContext->isEnabled()) {
+    if (auto UPES = PatternCtx.popIf<UnresolvedPatternExprSyntax>()) {
+      PatternCtx.addSyntax(UPES->getPattern());
+    } else {
+      PatternCtx.setCreateSyntax(SyntaxKind::ExpressionPattern);
+    }
+  }
   // The most common case here is to parse something that was a lexically
   // obvious pattern, which will come back wrapped in an immediate
   // UnresolvedPatternExpr.  Transform this now to simplify later code.
@@ -1148,4 +1165,3 @@
     return canParseType();
   return true;
 }
-
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 9a685c6..131218d 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -569,12 +569,15 @@
     if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
     if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
     return parseStmtContinue();
-  case tok::kw_fallthrough:
+  case tok::kw_fallthrough: {
     if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
     if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
+
+    SyntaxContext->setCreateSyntax(SyntaxKind::FallthroughStmt);
     return makeParserResult(
         new (Context) FallthroughStmt(consumeToken(tok::kw_fallthrough)));
   }
+  }
 }
 
 /// parseBraceItemList - A brace enclosed expression/statement/decl list.  For
@@ -615,6 +618,7 @@
 ///     'break' identifier?
 ///
 ParserResult<Stmt> Parser::parseStmtBreak() {
+  SyntaxContext->setCreateSyntax(SyntaxKind::BreakStmt);
   SourceLoc Loc = consumeToken(tok::kw_break);
   SourceLoc TargetLoc;
   Identifier Target;
@@ -637,6 +641,7 @@
 ///     'continue' identifier?
 ///
 ParserResult<Stmt> Parser::parseStmtContinue() {
+  SyntaxContext->setCreateSyntax(SyntaxKind::ContinueStmt);
   SourceLoc Loc = consumeToken(tok::kw_continue);
   SourceLoc TargetLoc;
   Identifier Target;
@@ -660,7 +665,7 @@
 ///     'return' expr?
 ///   
 ParserResult<Stmt> Parser::parseStmtReturn(SourceLoc tryLoc) {
-  SyntaxParsingContext LocalContext(SyntaxContext, SyntaxKind::ReturnStmt);
+  SyntaxContext->setCreateSyntax(SyntaxKind::ReturnStmt);
   SourceLoc ReturnLoc = consumeToken(tok::kw_return);
 
   if (Tok.is(tok::code_complete)) {
@@ -725,6 +730,7 @@
 ///   'throw' expr
 ///
 ParserResult<Stmt> Parser::parseStmtThrow(SourceLoc tryLoc) {
+  SyntaxContext->setCreateSyntax(SyntaxKind::ThrowStmt);
   SourceLoc throwLoc = consumeToken(tok::kw_throw);
   SourceLoc exprLoc;
   if (Tok.isNot(tok::eof))
@@ -759,6 +765,7 @@
 ///     'defer' brace-stmt
 ///
 ParserResult<Stmt> Parser::parseStmtDefer() {
+  SyntaxContext->setCreateSyntax(SyntaxKind::DeferStmt);
   SourceLoc DeferLoc = consumeToken(tok::kw_defer);
   
   // Macro expand out the defer into a closure and call, which we can typecheck
@@ -991,7 +998,10 @@
     VD->setHasNonPatternBindingInit();
 
   // Parse the optional 'where' guard.
-  if (P.consumeIf(tok::kw_where, result.WhereLoc)) {
+  if (P.Tok.is(tok::kw_where)) {
+    SyntaxParsingContext WhereClauseCtxt(P.SyntaxContext,
+                                         SyntaxKind::WhereClause);
+    result.WhereLoc = P.consumeToken(tok::kw_where);
     SourceLoc startOfGuard = P.Tok.getLoc();
 
     auto diagKind = [=]() -> Diag<> {
@@ -1073,6 +1083,8 @@
 
 // #available(...)
 ParserResult<PoundAvailableInfo> Parser::parseStmtConditionPoundAvailable() {
+  SyntaxParsingContext ConditonCtxt(SyntaxContext,
+                                    SyntaxKind::AvailabilityCondition);
   SourceLoc PoundLoc = consumeToken(tok::pound_available);
 
   if (!Tok.isFollowingLParen()) {
@@ -1184,6 +1196,175 @@
   return Status;
 }
 
+ParserStatus
+Parser::parseStmtConditionElement(SmallVectorImpl<StmtConditionElement> &result,
+                                  Diag<> DefaultID, StmtKind ParentKind,
+                                  StringRef &BindingKindStr) {
+  ParserStatus Status;
+
+  // Parse a leading #available condition if present.
+  if (Tok.is(tok::pound_available)) {
+    auto res = parseStmtConditionPoundAvailable();
+    if (res.isNull() || res.hasCodeCompletion()) {
+      Status |= res;
+      return Status;
+    }
+    BindingKindStr = StringRef();
+    result.push_back({res.get()});
+    return Status;
+  }
+
+  // Handle code completion after the #.
+  if (Tok.is(tok::pound) && peekToken().is(tok::code_complete)) {
+    consumeToken(); // '#' token.
+    auto CodeCompletionPos = consumeToken();
+    auto Expr = new (Context) CodeCompletionExpr(CodeCompletionPos);
+    if (CodeCompletion)
+      CodeCompletion->completeAfterPound(Expr, ParentKind);
+    result.push_back(Expr);
+    Status.setHasCodeCompletion();
+    return Status;
+  }
+
+  // Parse the basic expression case.  If we have a leading let/var/case
+  // keyword or an assignment, then we know this is a binding.
+  if (Tok.isNot(tok::kw_let, tok::kw_var, tok::kw_case)) {
+    // If we lack it, then this is theoretically a boolean condition.
+    // However, we also need to handle migrating from Swift 2 syntax, in
+    // which a comma followed by an expression could actually be a pattern
+    // clause followed by a binding.  Determine what we have by checking for a
+    // syntactically valid pattern followed by an '=', which can never be a
+    // boolean condition.
+    //
+    // However, if this is the first clause, and we see "x = y", then this is
+    // almost certainly a typo for '==' and definitely not a continuation of
+    // another clause, so parse it as an expression.  This also avoids
+    // lookahead + backtracking on simple if conditions that are obviously
+    // boolean conditions.
+    auto isBooleanExpr = [&]() -> bool {
+      Parser::BacktrackingScope Backtrack(*this);
+      return !canParseTypedPattern() || Tok.isNot(tok::equal);
+    };
+
+    if (BindingKindStr.empty() || isBooleanExpr()) {
+      auto diagID = result.empty() ? DefaultID :
+        diag::expected_expr_conditional;
+      auto BoolExpr = parseExprBasic(diagID);
+      Status |= BoolExpr;
+      if (BoolExpr.isNull())
+        return Status;
+      result.push_back(BoolExpr.get());
+      BindingKindStr = StringRef();
+      return Status;
+    }
+  }
+
+  SyntaxParsingContext ConditionCtxt(SyntaxContext);
+
+  SourceLoc IntroducerLoc;
+  if (Tok.isAny(tok::kw_let, tok::kw_var, tok::kw_case)) {
+    BindingKindStr = Tok.getText();
+    IntroducerLoc = consumeToken();
+  } else {
+    // If we lack the leading let/var/case keyword, then we're here because
+    // the user wrote something like "if let x = foo(), y = bar() {".  Fix
+    // this by inserting a new 'let' keyword before y.
+    IntroducerLoc = Tok.getLoc();
+    assert(!BindingKindStr.empty() &&
+            "Shouldn't get here without a leading binding");
+    diagnose(Tok.getLoc(), diag::expected_binding_keyword, BindingKindStr)
+      .fixItInsert(Tok.getLoc(), BindingKindStr.str()+" ");
+  }
+
+  // We're parsing a conditional binding.
+  assert(CurDeclContext->isLocalContext() &&
+          "conditional binding in non-local context?!");
+    
+  ParserResult<Pattern> ThePattern;
+    
+  if (BindingKindStr == "case") {
+    ConditionCtxt.setCreateSyntax(SyntaxKind::MatchingPatternCondition);
+    // In our recursive parse, remember that we're in a matching pattern.
+    llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
+      T(InVarOrLetPattern, IVOLP_InMatchingPattern);
+    ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
+  } else if ((BindingKindStr == "let" || BindingKindStr == "var") &&
+              Tok.is(tok::kw_case)) {
+    ConditionCtxt.setCreateSyntax(SyntaxKind::Unknown);
+    // If will probably be a common typo to write "if let case" instead of
+    // "if case let" so detect this and produce a nice fixit.
+    diagnose(IntroducerLoc, diag::wrong_condition_case_location,
+              BindingKindStr)
+    .fixItRemove(IntroducerLoc)
+    .fixItInsertAfter(Tok.getLoc(), " " + BindingKindStr.str());
+
+    consumeToken(tok::kw_case);
+    
+    bool wasLet = BindingKindStr == "let";
+    
+    // In our recursive parse, remember that we're in a var/let pattern.
+    llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
+      T(InVarOrLetPattern, wasLet ? IVOLP_InLet : IVOLP_InVar);
+    
+    BindingKindStr = "case";
+    ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
+    
+    if (ThePattern.isNonNull()) {
+      auto *P = new (Context) VarPattern(IntroducerLoc, wasLet,
+                                          ThePattern.get(), /*impl*/false);
+      ThePattern = makeParserResult(P);
+    }
+
+  } else {
+    ConditionCtxt.setCreateSyntax(SyntaxKind::OptionalBindingCondition);
+    // Otherwise, this is an implicit optional binding "if let".
+    ThePattern = parseMatchingPatternAsLetOrVar(BindingKindStr == "let",
+                                                IntroducerLoc,
+                                                /*isExprBasic*/ true);
+    // The let/var pattern is part of the statement.
+    if (Pattern *P = ThePattern.getPtrOrNull())
+      P->setImplicit();
+  }
+
+  ThePattern = parseOptionalPatternTypeAnnotation(ThePattern,
+                                                  BindingKindStr != "case");
+  Status |= ThePattern;
+    
+  if (ThePattern.isNull() || ThePattern.hasCodeCompletion())
+    return Status;
+
+  // Conditional bindings must have an initializer.
+  Expr *Init;
+  if (Tok.is(tok::equal)) {
+    SyntaxParsingContext InitCtxt(SyntaxContext, SyntaxKind::InitializerClause);
+    consumeToken();
+    ParserResult<Expr> InitExpr
+      = parseExprBasic(diag::expected_expr_conditional_var);
+    Status |= InitExpr;
+    if (InitExpr.isNull())
+      return Status;
+    Init = InitExpr.get();
+    
+  } else {
+    // Although we require an initializer, recover by parsing as if it were
+    // merely omitted.
+    diagnose(Tok, diag::conditional_var_initializer_required);
+    Init = new (Context) ErrorExpr(ThePattern.get()->getEndLoc());
+  }
+  
+  result.push_back({IntroducerLoc, ThePattern.get(), Init});
+  IntroducerLoc = SourceLoc();
+  
+  // Add variable bindings from the pattern to our current scope and mark
+  // them as being having a non-pattern-binding initializer.
+  ThePattern.get()->forEachVariable([&](VarDecl *VD) {
+    if (VD->hasName())
+      addToScope(VD);
+    VD->setHasNonPatternBindingInit();
+  });
+  return Status;
+}
+
 /// Parse the condition of an 'if' or 'while'.
 ///
 ///   condition:
@@ -1198,16 +1379,32 @@
 ///
 ParserStatus Parser::parseStmtCondition(StmtCondition &Condition,
                                         Diag<> DefaultID, StmtKind ParentKind) {
+  SyntaxParsingContext ConditionListCtxt(SyntaxContext,
+                                         SyntaxKind::ConditionElementList);
   ParserStatus Status;
   Condition = StmtCondition();
 
   SmallVector<StmtConditionElement, 4> result;
 
-  // This little helper function is used to consume a separator comma if
-  // present, it returns false if it isn't there.  It also gracefully handles
-  // the case when the user used && instead of comma, since that is a common
-  // error.
-  auto consumeSeparatorComma = [&]() -> bool {
+  // For error recovery purposes, keep track of the disposition of the last
+  // pattern binding we saw ('let', 'var', or 'case').
+  StringRef BindingKindStr;
+  
+  // We have a simple comma separated list of clauses, but also need to handle
+  // a variety of common errors situations (including migrating from Swift 2
+  // syntax).
+  while (true) {
+    SyntaxParsingContext ConditionElementCtxt(SyntaxContext,
+                                              SyntaxKind::ConditionElement);
+    Status |= parseStmtConditionElement(result, DefaultID, ParentKind,
+                                        BindingKindStr);
+    if (Status.shouldStopParsing())
+      break;
+
+    // If a comma exists consume it and succeed.
+    if (consumeIf(tok::comma))
+      continue;
+    
     // If we have an "&&" token followed by a continuation of the statement
     // condition, then fixit the "&&" to "," and keep going.
     if (Tok.isAny(tok::oper_binary_spaced, tok::oper_binary_unspaced) &&
@@ -1215,7 +1412,7 @@
       diagnose(Tok, diag::expected_comma_stmtcondition)
         .fixItReplaceChars(getEndOfPreviousLoc(), Tok.getRange().getEnd(), ",");
       consumeToken();
-      return true;
+      continue;
     }
 
     // Boolean conditions are separated by commas, not the 'where' keyword, as
@@ -1224,182 +1421,11 @@
       diagnose(Tok, diag::expected_comma_stmtcondition)
         .fixItReplaceChars(getEndOfPreviousLoc(), Tok.getRange().getEnd(), ",");
       consumeToken();
-      return true;
-    }
-    
-    // Otherwise, if a comma exists consume it and succeed.
-    return consumeIf(tok::comma);
-  };
-  
- 
-  // For error recovery purposes, keep track of the disposition of the last
-  // pattern binding we saw ('let', 'var', or 'case').
-  StringRef BindingKindStr;
-  
-  // We have a simple comma separated list of clauses, but also need to handle
-  // a variety of common errors situations (including migrating from Swift 2
-  // syntax).
-  bool isFirstIteration = true;
-  while (isFirstIteration || consumeSeparatorComma()) {
-    isFirstIteration = false;
-    
-    // Parse a leading #available condition if present.
-    if (Tok.is(tok::pound_available)) {
-      auto res = parseStmtConditionPoundAvailable();
-      if (res.isNull() || res.hasCodeCompletion()) {
-        Status |= res;
-        return Status;
-      }
-      
-      result.push_back({res.get()});
-      BindingKindStr = StringRef();
       continue;
     }
     
-    // Handle code completion after the #.
-    if (Tok.is(tok::pound) && peekToken().is(tok::code_complete)) {
-      consumeToken(); // '#' token.
-      auto CodeCompletionPos = consumeToken();
-      auto Expr = new (Context) CodeCompletionExpr(CodeCompletionPos);
-      if (CodeCompletion)
-        CodeCompletion->completeAfterPound(Expr, ParentKind);
-      result.push_back(Expr);
-      Status.setHasCodeCompletion();
-      return Status;
-    }
-    
-    // Parse the basic expression case.  If we have a leading let/var/case
-    // keyword or an assignment, then we know this is a binding.
-    if (Tok.isNot(tok::kw_let, tok::kw_var, tok::kw_case)) {
-      // If we lack it, then this is theoretically a boolean condition.
-      // However, we also need to handle migrating from Swift 2 syntax, in
-      // which a comma followed by an expression could actually be a pattern
-      // clause followed by a binding.  Determine what we have by checking for a
-      // syntactically valid pattern followed by an '=', which can never be a
-      // boolean condition.
-      //
-      // However, if this is the first clause, and we see "x = y", then this is
-      // almost certainly a typo for '==' and definitely not a continuation of
-      // another clause, so parse it as an expression.  This also avoids
-      // lookahead + backtracking on simple if conditions that are obviously
-      // boolean conditions.
-      auto isBooleanExpr = [&]() -> bool {
-        Parser::BacktrackingScope Backtrack(*this);
-        return !canParseTypedPattern() || Tok.isNot(tok::equal);
-      };
-
-      if (BindingKindStr.empty() || isBooleanExpr()) {
-        auto diagID = result.empty() ? DefaultID :
-              diag::expected_expr_conditional;
-        auto BoolExpr = parseExprBasic(diagID);
-        Status |= BoolExpr;
-        if (BoolExpr.isNull())
-          return Status;
-        result.push_back(BoolExpr.get());
-        BindingKindStr = StringRef();
-        continue;
-      }
-    }
-    
-    SourceLoc IntroducerLoc;
-    if (Tok.isAny(tok::kw_let, tok::kw_var, tok::kw_case)) {
-      BindingKindStr = Tok.getText();
-      IntroducerLoc = consumeToken();
-    } else {
-      // If we lack the leading let/var/case keyword, then we're here because
-      // the user wrote something like "if let x = foo(), y = bar() {".  Fix
-      // this by inserting a new 'let' keyword before y.
-      IntroducerLoc = Tok.getLoc();
-      assert(!BindingKindStr.empty() &&
-             "Shouldn't get here without a leading binding");
-      diagnose(Tok.getLoc(), diag::expected_binding_keyword, BindingKindStr)
-        .fixItInsert(Tok.getLoc(), BindingKindStr.str()+" ");
-    }
-
-    
-    // We're parsing a conditional binding.
-    assert(CurDeclContext->isLocalContext() &&
-           "conditional binding in non-local context?!");
-    
-    ParserResult<Pattern> ThePattern;
-    
-    if (BindingKindStr == "case") {
-      // In our recursive parse, remember that we're in a matching pattern.
-      llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
-        T(InVarOrLetPattern, IVOLP_InMatchingPattern);
-      ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
-    } else if ((BindingKindStr == "let" || BindingKindStr == "var") &&
-               Tok.is(tok::kw_case)) {
-      // If will probably be a common typo to write "if let case" instead of
-      // "if case let" so detect this and produce a nice fixit.
-      diagnose(IntroducerLoc, diag::wrong_condition_case_location,
-               BindingKindStr)
-      .fixItRemove(IntroducerLoc)
-      .fixItInsertAfter(Tok.getLoc(), " " + BindingKindStr.str());
-
-      consumeToken(tok::kw_case);
-      
-      bool wasLet = BindingKindStr == "let";
-      
-      // In our recursive parse, remember that we're in a var/let pattern.
-      llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
-        T(InVarOrLetPattern, wasLet ? IVOLP_InLet : IVOLP_InVar);
-      
-      BindingKindStr = "case";
-      ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
-      
-      if (ThePattern.isNonNull()) {
-        auto *P = new (Context) VarPattern(IntroducerLoc, wasLet,
-                                           ThePattern.get(), /*impl*/false);
-        ThePattern = makeParserResult(P);
-      }
-
-    } else {
-      // Otherwise, this is an implicit optional binding "if let".
-      ThePattern = parseMatchingPatternAsLetOrVar(BindingKindStr == "let",
-                                                  IntroducerLoc,
-                                                  /*isExprBasic*/ true);
-      // The let/var pattern is part of the statement.
-      if (Pattern *P = ThePattern.getPtrOrNull())
-        P->setImplicit();
-    }
-
-    ThePattern = parseOptionalPatternTypeAnnotation(ThePattern,
-                                                    BindingKindStr != "case");
-    Status |= ThePattern;
-    
-    if (ThePattern.isNull() || ThePattern.hasCodeCompletion())
-      return Status;
-
-    // Conditional bindings must have an initializer.
-    Expr *Init;
-    if (consumeIf(tok::equal)) {
-      ParserResult<Expr> InitExpr
-        = parseExprBasic(diag::expected_expr_conditional_var);
-      Status |= InitExpr;
-      if (InitExpr.isNull())
-        return Status;
-      Init = InitExpr.get();
-      
-    } else {
-      // Although we require an initializer, recover by parsing as if it were
-      // merely omitted.
-      diagnose(Tok, diag::conditional_var_initializer_required);
-      Init = new (Context) ErrorExpr(ThePattern.get()->getEndLoc());
-    }
-    
-    result.push_back({IntroducerLoc, ThePattern.get(), Init});
-    IntroducerLoc = SourceLoc();
-    
-    // Add variable bindings from the pattern to our current scope and mark
-    // them as being having a non-pattern-binding initializer.
-    ThePattern.get()->forEachVariable([&](VarDecl *VD) {
-      if (VD->hasName())
-        addToScope(VD);
-      VD->setHasNonPatternBindingInit();
-    });
-    
-  } while (consumeSeparatorComma());
+    break;
+  }; 
   
   Condition = Context.AllocateCopy(result);
   return Status;
@@ -1412,6 +1438,7 @@
 ///    'else' stmt-brace
 ///    'else' stmt-if
 ParserResult<Stmt> Parser::parseStmtIf(LabeledStmtInfo LabelInfo) {
+  SyntaxContext->setCreateSyntax(SyntaxKind::IfStmt);
   SourceLoc IfLoc = consumeToken(tok::kw_if);
 
   ParserStatus Status;
@@ -1472,10 +1499,12 @@
   ParserResult<Stmt> ElseBody;
   if (Tok.is(tok::kw_else)) {
     ElseLoc = consumeToken(tok::kw_else);
-    if (Tok.is(tok::kw_if))
+    if (Tok.is(tok::kw_if)) {
+      SyntaxParsingContext ElseIfCtxt(SyntaxContext, SyntaxKind::IfStmt);
       ElseBody = parseStmtIf(LabeledStmtInfo());
-    else
+    } else {
       ElseBody = parseBraceItemList(diag::expected_lbrace_after_else);
+    }
     Status |= ElseBody;
   }
 
@@ -1489,6 +1518,7 @@
 ///     'guard' condition 'else' stmt-brace
 ///
 ParserResult<Stmt> Parser::parseStmtGuard() {
+  SyntaxContext->setCreateSyntax(SyntaxKind::GuardStmt);
   SourceLoc GuardLoc = consumeToken(tok::kw_guard);
   
   ParserStatus Status;
@@ -1615,6 +1645,7 @@
 ///   stmt-repeat:
 ///     (identifier ':')? 'repeat' stmt-brace 'while' expr
 ParserResult<Stmt> Parser::parseStmtRepeat(LabeledStmtInfo labelInfo) {
+  SyntaxContext->setCreateSyntax(SyntaxKind::RepeatWhileStmt);
   SourceLoc repeatLoc = consumeToken(tok::kw_repeat);
 
   ParserStatus status;
@@ -1658,6 +1689,7 @@
 ///     (identifier ':')? 'do' stmt-brace
 ///     (identifier ':')? 'do' stmt-brace stmt-catch+
 ParserResult<Stmt> Parser::parseStmtDo(LabeledStmtInfo labelInfo) {
+  SyntaxContext->setCreateSyntax(SyntaxKind::DoStmt);
   SourceLoc doLoc = consumeToken(tok::kw_do);
 
   ParserStatus status;
@@ -1671,6 +1703,8 @@
 
   // If the next token is 'catch', this is a 'do'/'catch' statement.
   if (Tok.is(tok::kw_catch)) {
+    SyntaxParsingContext CatchListCtxt(SyntaxContext,
+                                       SyntaxKind::CatchClauseList);
     // Parse 'catch' clauses 
     SmallVector<CatchStmt*, 4> allClauses;
     do {
@@ -1736,6 +1770,7 @@
 /// This routine promises to return a non-null result unless there was
 /// a code-completion token in the pattern.
 ParserResult<CatchStmt> Parser::parseStmtCatch() {
+  SyntaxParsingContext CatchClauseCtxt(SyntaxContext, SyntaxKind::CatchClause);
   // A catch block has its own scope for variables bound out of the pattern.
   Scope S(this, ScopeKind::CatchVars);
 
@@ -1799,6 +1834,7 @@
 ///     (identifier ':')? 'for' pattern 'in' expr-basic \
 ///             ('where' expr-basic)? stmt-brace
 ParserResult<Stmt> Parser::parseStmtForEach(LabeledStmtInfo LabelInfo) {
+  SyntaxContext->setCreateSyntax(SyntaxKind::ForInStmt);
   SourceLoc ForLoc = consumeToken(tok::kw_for);
   ParserStatus Status;
   ParserResult<Pattern> pattern;
@@ -1894,7 +1930,10 @@
 
   // Parse the 'where' expression if present.
   ParserResult<Expr> Where;
-  if (consumeIf(tok::kw_where)) {
+  if (Tok.is(tok::kw_where)) {
+    SyntaxParsingContext WhereClauseCtxt(SyntaxContext,
+                                         SyntaxKind::WhereClause);
+    consumeToken();
     Where = parseExprBasic(diag::expected_foreach_where_expr);
     if (Where.isNull())
       Where = makeParserErrorResult(new (Context) ErrorExpr(Tok.getLoc()));
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 70d52bb..f09cf19 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -845,6 +845,8 @@
     return SyntaxKind::FunctionParameter;
   case SyntaxKind::TupleTypeElementList:
     return SyntaxKind::TupleTypeElement;
+  case SyntaxKind::TuplePatternElementList:
+    return SyntaxKind::TuplePatternElement;
   default:
     return SyntaxKind::Unknown;
   }
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index 43f9a26..8dc3d5b 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -417,8 +417,9 @@
 
   while (I && I->getNumOperands() == 1 &&
          I->getNumTypeDependentOperands() == 0) {
-    // All the open instructions are single-value instructions.
-    auto SVI = dyn_cast<SingleValueInstruction>(I->getOperand(0));
+    // All the open instructions are single-value instructions.  Operands may
+    // be null when code is being transformed.
+    auto SVI = dyn_cast_or_null<SingleValueInstruction>(I->getOperand(0));
     // Within SimplifyCFG this function may be called for an instruction
     // within unreachable code. And within an unreachable block it can happen
     // that defs do not dominate uses (because there is no dominance defined).
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 7d00386..d5a0e78 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -373,11 +373,9 @@
                                  SubstitutionList Substitutions,
                                  ArrayRef<SILValue> Args,
                                  SILModule &M) {
-  void *Buffer = M.allocateInst(
-                              sizeof(BuiltinInst)
-                                + decltype(Operands)::getExtraSize(Args.size())
-                                + sizeof(Substitution) * Substitutions.size(),
-                              alignof(BuiltinInst));
+  auto Size = totalSizeToAlloc<swift::Operand, Substitution>(Args.size(),
+                                                          Substitutions.size());
+  auto Buffer = M.allocateInst(Size, alignof(BuiltinInst));
   return ::new (Buffer) BuiltinInst(Loc, Name, ReturnType, Substitutions,
                                     Args);
 }
@@ -385,12 +383,17 @@
 BuiltinInst::BuiltinInst(SILDebugLocation Loc, Identifier Name,
                          SILType ReturnType, SubstitutionList Subs,
                          ArrayRef<SILValue> Args)
-    : InstructionBase(Loc, ReturnType), Name(Name),
-      NumSubstitutions(Subs.size()), Operands(this, Args) {
-  static_assert(IsTriviallyCopyable<Substitution>::value,
-                "assuming Substitution is trivially copyable");
-  memcpy(getSubstitutionsStorage(), Subs.begin(),
-         sizeof(Substitution) * Subs.size());
+    : InstructionBase(Loc, ReturnType), Name(Name) {
+  SILInstruction::Bits.BuiltinInst.NumSubstitutions = Subs.size();
+  assert(SILInstruction::Bits.BuiltinInst.NumSubstitutions == Subs.size() &&
+         "Truncation");
+  SILInstruction::Bits.BuiltinInst.NumOperands = Args.size();
+  Operand *dynamicSlot = getTrailingObjects<Operand>();
+  for (auto value : Args) {
+    new (dynamicSlot++) Operand(this, value);
+  }
+  std::uninitialized_copy(Subs.begin(), Subs.end(),
+                          getTrailingObjects<Substitution>());
 }
 
 InitBlockStorageHeaderInst *
@@ -736,8 +739,9 @@
 
 StringLiteralInst::StringLiteralInst(SILDebugLocation Loc, StringRef Text,
                                      Encoding encoding, SILType Ty)
-    : InstructionBase(Loc, Ty), Length(Text.size()),
-      TheEncoding(encoding) {
+    : InstructionBase(Loc, Ty) {
+  SILInstruction::Bits.StringLiteralInst.TheEncoding = unsigned(encoding);
+  SILInstruction::Bits.StringLiteralInst.Length = Text.size();
   memcpy(getTrailingObjects<char>(), Text.data(), Text.size());
 }
 
@@ -752,16 +756,18 @@
 }
 
 uint64_t StringLiteralInst::getCodeUnitCount() {
-  if (TheEncoding == Encoding::UTF16)
+  auto E = unsigned(Encoding::UTF16);
+  if (SILInstruction::Bits.StringLiteralInst.TheEncoding == E)
     return unicode::getUTF16Length(getValue());
-  return Length;
+  return SILInstruction::Bits.StringLiteralInst.Length;
 }
 
 ConstStringLiteralInst::ConstStringLiteralInst(SILDebugLocation Loc,
                                                StringRef Text,
                                                Encoding encoding, SILType Ty)
-    : InstructionBase(Loc, Ty),
-      Length(Text.size()), TheEncoding(encoding) {
+    : InstructionBase(Loc, Ty) {
+  SILInstruction::Bits.ConstStringLiteralInst.TheEncoding = unsigned(encoding);
+  SILInstruction::Bits.ConstStringLiteralInst.Length = Text.size();
   memcpy(getTrailingObjects<char>(), Text.data(), Text.size());
 }
 
@@ -777,9 +783,10 @@
 }
 
 uint64_t ConstStringLiteralInst::getCodeUnitCount() {
-  if (TheEncoding == Encoding::UTF16)
+  auto E = unsigned(Encoding::UTF16);
+  if (SILInstruction::Bits.ConstStringLiteralInst.TheEncoding == E)
     return unicode::getUTF16Length(getValue());
-  return Length;
+  return SILInstruction::Bits.ConstStringLiteralInst.Length;
 }
 
 StoreInst::StoreInst(
@@ -902,15 +909,19 @@
 
 StructInst *StructInst::create(SILDebugLocation Loc, SILType Ty,
                                ArrayRef<SILValue> Elements, SILModule &M) {
-  void *Buffer = M.allocateInst(sizeof(StructInst) +
-                            decltype(Operands)::getExtraSize(Elements.size()),
-                            alignof(StructInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
+  auto Buffer = M.allocateInst(Size, alignof(StructInst));
   return ::new(Buffer) StructInst(Loc, Ty, Elements);
 }
 
 StructInst::StructInst(SILDebugLocation Loc, SILType Ty,
                        ArrayRef<SILValue> Elems)
-    : InstructionBase(Loc, Ty), Operands(this, Elems) {
+    : InstructionBase(Loc, Ty) {
+  SILInstruction::Bits.StructInst.NumOperands = Elems.size();
+  Operand *dynamicSlot = getTrailingObjects<Operand>();
+  for (auto value : Elems) {
+    new (dynamicSlot++) Operand(this, value);
+  }
   assert(!Ty.getStructOrBoundGenericStruct()->hasUnreferenceableStorage());
 }
 
@@ -930,15 +941,20 @@
 
 TupleInst *TupleInst::create(SILDebugLocation Loc, SILType Ty,
                              ArrayRef<SILValue> Elements, SILModule &M) {
-  void *Buffer = M.allocateInst(sizeof(TupleInst) +
-                            decltype(Operands)::getExtraSize(Elements.size()),
-                            alignof(TupleInst));
+  auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
+  auto Buffer = M.allocateInst(Size, alignof(TupleInst));
   return ::new(Buffer) TupleInst(Loc, Ty, Elements);
 }
 
 TupleInst::TupleInst(SILDebugLocation Loc, SILType Ty,
                      ArrayRef<SILValue> Elems)
-    : InstructionBase(Loc, Ty), Operands(this, Elems) {}
+    : InstructionBase(Loc, Ty) {
+  SILInstruction::Bits.TupleInst.NumOperands = Elems.size();
+  Operand *dynamicSlot = getTrailingObjects<Operand>();
+  for (auto value : Elems) {
+    new (dynamicSlot++) Operand(this, value);
+  }
+}
 
 MetatypeInst::MetatypeInst(SILDebugLocation Loc, SILType Metatype,
                            ArrayRef<SILValue> TypeDependentOperands)
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 0a9af39..b644ab7 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -104,6 +104,7 @@
       DEF_COL(ID::SILUndef, RED)
       DEF_COL(ID::SILBasicBlock, GREEN)
       DEF_COL(ID::SSAValue, MAGENTA)
+      DEF_COL(ID::Null, YELLOW)
     }
     OS.resetColor();
     OS.changeColor(Color);
@@ -128,6 +129,7 @@
     return;
   case ID::SILBasicBlock: OS << "bb"; break;
   case ID::SSAValue: OS << '%'; break;
+  case ID::Null: OS << "<<NULL OPERAND>>"; return;
   }
   OS << Number;
 }
@@ -509,10 +511,10 @@
   }
 
   SILValuePrinterInfo getIDAndType(SILValue V) {
-    return {Ctx.getID(V), V->getType()};
+    return {Ctx.getID(V), V ? V->getType() : SILType()};
   }
   SILValuePrinterInfo getIDAndTypeAndOwnership(SILValue V) {
-    return {Ctx.getID(V), V->getType(), V.getOwnershipKind()};
+    return {Ctx.getID(V), V ? V->getType() : SILType(), V.getOwnershipKind()};
   }
 
   //===--------------------------------------------------------------------===//
@@ -1081,7 +1083,11 @@
     interleave(AI->getArguments(),
                [&](const SILValue &arg) { *this << Ctx.getID(arg); },
                [&] { *this << ", "; });
-    *this << ") : " << AI->getCallee()->getType();
+    *this << ") : ";
+    if (auto callee = AI->getCallee())
+      *this << callee->getType();
+    else
+      *this << "<<NULL CALLEE>>";
   }
 
   void visitApplyInst(ApplyInst *AI) {
@@ -2975,6 +2981,9 @@
 }
 
 ID SILPrintContext::getID(const SILNode *node) {
+  if (node == nullptr)
+    return {ID::Null, ~0U};
+
   if (isa<SILUndef>(node))
     return {ID::SILUndef, 0};
   
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index e508a2d..2c4d895 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -4975,16 +4975,14 @@
   }
   
   // Create the tuple shuffle.
-  ArrayRef<int> mapping = tc.Context.AllocateCopy(sources);
-  auto callerDefaultArgsCopy = tc.Context.AllocateCopy(callerDefaultArgs);
   return
-    cs.cacheType(new (tc.Context) TupleShuffleExpr(
-                     expr, mapping,
+    cs.cacheType(TupleShuffleExpr::create(tc.Context,
+                     expr, sources,
                      TupleShuffleExpr::TupleToTuple,
                      callee,
-                     tc.Context.AllocateCopy(variadicArgs),
+                     variadicArgs,
                      arrayType,
-                     callerDefaultArgsCopy,
+                     callerDefaultArgs,
                      toSugarType));
 }
 
@@ -5073,13 +5071,13 @@
   Type destSugarTy = hasInit? toTuple
                             : TupleType::get(sugarFields, tc.Context);
                             
-  return cs.cacheType(new (tc.Context) TupleShuffleExpr(expr,
-                                        tc.Context.AllocateCopy(elements),
+  return cs.cacheType(TupleShuffleExpr::create(tc.Context, expr,
+                                        elements,
                                         TupleShuffleExpr::ScalarToTuple,
                                         callee,
-                                        tc.Context.AllocateCopy(variadicArgs),
+                                        variadicArgs,
                                         arrayType,
-                                     tc.Context.AllocateCopy(callerDefaultArgs),
+                                        callerDefaultArgs,
                                         destSugarTy));
 }
 
@@ -5215,8 +5213,8 @@
           new (ctx) OpaqueValueExpr(expr->getLoc(),
                                     fromType));
     
-    auto *result =
-      cs.cacheType(new (ctx) ErasureExpr(archetypeVal, toType, conformances));
+    auto *result = cs.cacheType(ErasureExpr::create(ctx, archetypeVal, toType,
+                                                    conformances));
     return cs.cacheType(
         new (ctx) OpenExistentialExpr(expr, archetypeVal, result,
                                       cs.getType(result)));
@@ -5238,7 +5236,7 @@
     }
   }
 
-  return cs.cacheType(new (ctx) ErasureExpr(expr, toType, conformances));
+  return cs.cacheType(ErasureExpr::create(ctx, expr, toType, conformances));
 }
 
 /// Given that the given expression is an implicit conversion added
@@ -5704,17 +5702,10 @@
   }
 
   // Create the tuple shuffle.
-  ArrayRef<int> mapping = tc.Context.AllocateCopy(sources);
-  auto callerDefaultArgsCopy = tc.Context.AllocateCopy(callerDefaultArgs);
-  return
-    cs.cacheType(new (tc.Context) TupleShuffleExpr(
-                     arg, mapping,
-                     typeImpact,
-                     callee,
-                     tc.Context.AllocateCopy(variadicArgs),
-                     sliceType,
-                     callerDefaultArgsCopy,
-                     paramType));
+  return cs.cacheType(TupleShuffleExpr::create(tc.Context, arg, sources,
+                                               typeImpact, callee, variadicArgs,
+                                               sliceType, callerDefaultArgs,
+                                               paramType));
 }
 
 static ClosureExpr *getClosureLiteralExpr(Expr *expr) {
diff --git a/lib/Sema/ConstraintLocator.h b/lib/Sema/ConstraintLocator.h
index b8f3794..23a3bbd 100644
--- a/lib/Sema/ConstraintLocator.h
+++ b/lib/Sema/ConstraintLocator.h
@@ -231,8 +231,6 @@
     llvm_unreachable("Unhandled PathElementKind in switch.");
   }
 
-  template<unsigned N> struct incomplete;
-  
   /// \brief One element in the path of a locator, which can include both
   /// a kind (PathElementKind) and a value used to describe specific
   /// kinds further (e.g., the position of a tuple element).
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 7a6bbea..d5b6ab6 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -745,34 +745,34 @@
   return integerExpr;
 }
 
-/// Returns a new assignment expression that mixes the hash value of an
+/// Returns a new assignment expression that combines the hash value of an
 /// expression into a variable.
 /// \p C The AST context.
-/// \p resultVar The variable into which the hash value will be mixed.
-/// \p exprToHash The expression whose hash value should be mixed in.
-/// \return The expression that mixes the hash value into the result variable.
-static Expr* mixInHashExpr_hashValue(ASTContext &C,
-                                     VarDecl* resultVar,
-                                     Expr *exprToHash) {
+/// \p resultVar The variable into which the hash value will be combined.
+/// \p exprToHash The expression whose hash value should be combined.
+/// \return The expression that combines the hash value into the variable.
+static Expr* combineHashValuesAssignmentExpr(ASTContext &C,
+                                             VarDecl* resultVar,
+                                             Expr *exprToHash) {
   // <exprToHash>.hashValue
   auto hashValueExpr = new (C) UnresolvedDotExpr(exprToHash, SourceLoc(),
                                                  C.Id_hashValue, DeclNameLoc(),
                                                  /*implicit*/ true);
 
-  // _mixForSynthesizedHashValue(result, <exprToHash>.hashValue)
-  auto mixinFunc = C.getMixForSynthesizedHashValueDecl();
-  auto mixinFuncExpr = new (C) DeclRefExpr(mixinFunc, DeclNameLoc(),
-                                           /*implicit*/ true);
+  // _combineHashValues(result, <exprToHash>.hashValue)
+  auto combineFunc = C.getCombineHashValuesDecl();
+  auto combineFuncExpr = new (C) DeclRefExpr(combineFunc, DeclNameLoc(),
+                                             /*implicit*/ true);
   auto rhsResultExpr = new (C) DeclRefExpr(resultVar, DeclNameLoc(),
                                            /*implicit*/ true);
-  auto mixinResultExpr = CallExpr::createImplicit(
-      C, mixinFuncExpr, { rhsResultExpr, hashValueExpr }, {});
+  auto combineResultExpr = CallExpr::createImplicit(
+    C, combineFuncExpr, { rhsResultExpr, hashValueExpr }, {});
 
-  // result = _mixForSynthesizedHashValue(result, <exprToHash>.hashValue)
+  // result = _combineHashValues(result, <exprToHash>.hashValue)
   auto lhsResultExpr = new (C) DeclRefExpr(resultVar, DeclNameLoc(),
                                            /*implicit*/ true);
   auto assignExpr = new (C) AssignExpr(lhsResultExpr, SourceLoc(),
-                                       mixinResultExpr, /*implicit*/ true);
+                                       combineResultExpr, /*implicit*/ true);
   return assignExpr;
 }
 
@@ -853,9 +853,9 @@
 
     // If the enum has no associated values, we use the ordinal alone as the
     // hash value, because that is sufficient for a good distribution. If any
-    // case do have associated values, then the ordinal is used as the first
-    // term mixed into _mixForSynthesizedHashValue, and the final result after
-    // mixing in the payload is passed to _mixInt to improve the distribution.
+    // case does have associated values, then the ordinal is used as the first
+    // term combined into _combineHashValues, and the final result after
+    // combining the payload is passed to _mixInt to improve the distribution.
 
     // result = <ordinal>
     {
@@ -868,13 +868,14 @@
     }
 
     if (!hasNoAssociatedValues) {
-      // Generate a sequence of expressions that mix the payload's hash values
-      // into result.
+      // Generate a sequence of expressions that combine the payload's hash
+      // values into result.
       for (auto payloadVar : payloadVars) {
         auto payloadVarRef = new (C) DeclRefExpr(payloadVar, DeclNameLoc(),
                                                  /*implicit*/ true);
-        // result = _mixForSynthesizedHashValue(result, <payloadVar>.hashValue)
-        auto mixExpr = mixInHashExpr_hashValue(C, resultVar, payloadVarRef);
+        // result = _combineHashValues(result, <payloadVar>.hashValue)
+        auto mixExpr = combineHashValuesAssignmentExpr(C, resultVar,
+                                                       payloadVarRef);
         mixExpressions.emplace_back(ASTNode(mixExpr));
       }
 
@@ -953,7 +954,7 @@
   auto storedProperties =
     structDecl->getStoredProperties(/*skipInaccessible=*/true);
 
-  // For each stored property, generate a statement that mixes its hash value
+  // For each stored property, generate a statement that combines its hash value
   // into the result.
   for (auto propertyDecl : storedProperties) {
     auto propertyRef = new (C) DeclRefExpr(propertyDecl, DeclNameLoc(),
@@ -962,8 +963,9 @@
                                        /*implicit*/ true);
     auto selfPropertyExpr = new (C) DotSyntaxCallExpr(propertyRef, SourceLoc(),
                                                       selfRef);
-    // result = _mixForSynthesizedHashValue(result, <property>.hashValue)
-    auto mixExpr = mixInHashExpr_hashValue(C, resultVar, selfPropertyExpr);
+    // result = _combineHashValues(result, <property>.hashValue)
+    auto mixExpr = combineHashValuesAssignmentExpr(C, resultVar,
+                                                   selfPropertyExpr);
     statements.emplace_back(ASTNode(mixExpr));
   }
 
@@ -1014,11 +1016,11 @@
   //       result = 0
   //     case B(let a0):
   //       result = 1
-  //       result = _mixForSynthesizedHashValue(result, a0.hashValue)
+  //       result = _combineHashValues(result, a0.hashValue)
   //     case C(let a0, let a1):
   //       result = 2
-  //       result = _mixForSynthesizedHashValue(result, a0.hashValue)
-  //       result = _mixForSynthesizedHashValue(result, a1.hashValue)
+  //       result = _combineHashValues(result, a0.hashValue)
+  //       result = _combineHashValues(result, a1.hashValue)
   //     }
   //     result = _mixInt(result)
   //     return result
@@ -1030,8 +1032,8 @@
   //   var y: String
   //   @derived var hashValue: Int {
   //     var result: Int = 0
-  //     result = _mixForSynthesizedHashValue(result, x.hashValue)
-  //     result = _mixForSynthesizedHashValue(result, y.hashValue)
+  //     result = _combineHashValues(result, x.hashValue)
+  //     result = _combineHashValues(result, y.hashValue)
   //     result = _mixInt(result)
   //     return result
   //   }
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 06718f0..e100ab9 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -1307,6 +1307,13 @@
         secondType = req.getSecondType();
       }
 
+      // Don't do further checking on error types.
+      if (firstType->hasError() || (secondType && secondType->hasError())) {
+        // Another requirement will fail later; just continue.
+        valid = false;
+        continue;
+      }
+
       bool requirementFailure = false;
       if (listener && !listener->shouldCheck(kind, firstType, secondType))
         continue;
diff --git a/lib/Sema/TypeCheckProtocol.h b/lib/Sema/TypeCheckProtocol.h
index ed3df98..375dd9d 100644
--- a/lib/Sema/TypeCheckProtocol.h
+++ b/lib/Sema/TypeCheckProtocol.h
@@ -139,7 +139,7 @@
 #ifndef NDEBUG
   LLVM_ATTRIBUTE_USED
 #endif
-  void dump();
+  void dump() const;
 };
 
 class RequirementEnvironment;
@@ -707,6 +707,12 @@
                    const llvm::SetVector<AssociatedTypeDecl *> &allUnresolved,
                    ValueDecl *req);
 
+  /// Infer associated type witnesses for the given associated type.
+  InferredAssociatedTypesByWitnesses inferTypeWitnessesViaAssociatedType(
+                   ConformanceChecker &checker,
+                   const llvm::SetVector<AssociatedTypeDecl *> &allUnresolved,
+                   AssociatedTypeDecl *assocType);
+
   /// Infer associated type witnesses for all relevant value requirements.
   ///
   /// \param assocTypes The set of associated types we're interested in.
@@ -728,12 +734,30 @@
   /// known to the compiler.
   Type computeDerivedTypeWitness(AssociatedTypeDecl *assocType);
 
+  /// Compute a type witness without using a specific potential witness,
+  /// e.g., using a fixed type (from a refined protocol), default type
+  /// on an associated type, or deriving the type.
+  ///
+  /// \param allowDerived Whether to allow "derived" type witnesses.
+  Type computeAbstractTypeWitness(AssociatedTypeDecl *assocType,
+                                  bool allowDerived);
+
   /// Substitute the current type witnesses into the given interface type.
   Type substCurrentTypeWitnesses(Type type);
 
+  /// Retrieve substitution options with a tentative type witness
+  /// operation that queries the current set of type witnesses.
+  SubstOptions getSubstOptionsWithCurrentTypeWitnesses();
+
   /// Check whether the current set of type witnesses meets the
   /// requirements of the protocol.
-  bool checkCurrentTypeWitnesses();
+  bool checkCurrentTypeWitnesses(
+         const SmallVectorImpl<std::pair<ValueDecl *, ValueDecl *>>
+           &valueWitnesses);
+
+  /// Check the current type witnesses against the
+  /// requirements of the given constrained extension.
+  bool checkConstrainedExtension(ExtensionDecl *ext);
 
   /// Top-level operation to find solutions for the given unresolved
   /// associated types.
diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp
index bc785b4..ffb1263 100644
--- a/lib/Sema/TypeCheckProtocolInference.cpp
+++ b/lib/Sema/TypeCheckProtocolInference.cpp
@@ -63,7 +63,7 @@
   out << ")";
 }
 
-void InferredTypeWitnessesSolution::dump() {
+void InferredTypeWitnessesSolution::dump() const {
   llvm::errs() << "Type Witnesses:\n";
   for (auto &typeWitness : TypeWitnesses) {
     llvm::errs() << "  " << typeWitness.first->getName() << " := ";
@@ -394,9 +394,21 @@
     if (!req)
       continue;
 
-    // We only look at value witnesses.
-    if (isa<AssociatedTypeDecl>(req))
+    // Infer type witnesses for associated types.
+    if (auto assocType = dyn_cast<AssociatedTypeDecl>(req)) {
+      // If this is not one of the associated types we are trying to infer,
+      // just continue.
+      if (assocTypes.count(assocType) == 0)
+        continue;
+
+      auto reqInferred = inferTypeWitnessesViaAssociatedType(checker,
+                                                             assocTypes,
+                                                             assocType);
+      if (!reqInferred.empty())
+        result.push_back({req, std::move(reqInferred)});
+
       continue;
+    }
 
     // Skip operator requirements, because they match globally and
     // therefore tend to cause deduction mismatches.
@@ -429,7 +441,8 @@
 
     // Infer associated types from the potential value witnesses for
     // this requirement.
-    auto reqInferred = inferTypeWitnessesViaValueWitnesses(checker, assocTypes, req);
+    auto reqInferred =
+      inferTypeWitnessesViaValueWitnesses(checker, assocTypes, req);
     if (reqInferred.empty())
       continue;
 
@@ -526,6 +539,63 @@
   return type;
 }
 
+InferredAssociatedTypesByWitnesses
+AssociatedTypeInference::inferTypeWitnessesViaAssociatedType(
+                   ConformanceChecker &checker,
+                   const llvm::SetVector<AssociatedTypeDecl *> &allUnresolved,
+                   AssociatedTypeDecl *assocType) {
+  auto &tc = checker.TC;
+
+  // Form the default name _Default_Foo.
+  Identifier defaultName;
+  {
+    SmallString<32> defaultNameStr;
+    {
+      llvm::raw_svector_ostream out(defaultNameStr);
+      out << "_Default_";
+      out << assocType->getName().str();
+    }
+
+    defaultName = tc.Context.getIdentifier(defaultNameStr);
+  }
+
+  // Look for types with the given default name that have appropriate
+  // @_implements attributes.
+  InferredAssociatedTypesByWitnesses result;
+  auto lookupOptions = defaultMemberTypeLookupOptions;
+  lookupOptions -= NameLookupFlags::PerformConformanceCheck;
+  for (auto candidate : tc.lookupMember(dc, adoptee, defaultName,
+                                        lookupOptions)) {
+    // We want type declarations.
+    auto typeDecl = dyn_cast<TypeDecl>(candidate.getValueDecl());
+    if (!typeDecl || isa<AssociatedTypeDecl>(typeDecl))
+      continue;
+
+    // We only find these within a protocol extension.
+    auto defaultProto = typeDecl->getDeclContext()
+                          ->getAsProtocolOrProtocolExtensionContext();
+    if (!defaultProto)
+      continue;
+
+    // Determine the witness type.
+    Type witnessType = getWitnessTypeForMatching(tc, conformance, typeDecl);
+    if (!witnessType) continue;
+
+    if (auto witnessMetaType = witnessType->getAs<AnyMetatypeType>())
+      witnessType = witnessMetaType->getInstanceType();
+    else
+      continue;
+
+    // Add this result.
+    InferredAssociatedTypesByWitness inferred;
+    inferred.Witness = typeDecl;
+    inferred.Inferred.push_back({assocType, witnessType});
+    result.push_back(std::move(inferred));
+  }
+
+  return result;
+}
+
 /// Attempt to resolve a type witness via a specific value witness.
 InferredAssociatedTypesByWitness
 AssociatedTypeInference::inferTypeWitnessesViaValueWitness(ValueDecl *req,
@@ -787,6 +857,42 @@
   return derivedType;
 }
 
+Type
+AssociatedTypeInference::computeAbstractTypeWitness(
+                                              AssociatedTypeDecl *assocType,
+                                              bool allowDerived) {
+  // We don't have a type witness for this associated type, so go
+  // looking for more options.
+  if (Type concreteType = computeFixedTypeWitness(assocType))
+    return concreteType;
+
+  // If we can form a default type, do so.
+  if (Type defaultType = computeDefaultTypeWitness(assocType))
+    return defaultType;
+
+  // If we can derive a type witness, do so.
+  if (allowDerived) {
+    if (Type derivedType = computeDerivedTypeWitness(assocType))
+      return derivedType;
+  }
+
+  // If there is a generic parameter of the named type, use that.
+  if (auto gpList = dc->getGenericParamsOfContext()) {
+    GenericTypeParamDecl *foundGP = nullptr;
+    for (auto gp : *gpList) {
+      if (gp->getName() == assocType->getName()) {
+        foundGP = gp;
+        break;
+      }
+    }
+
+    if (foundGP)
+      return dc->mapTypeIntoContext(foundGP->getDeclaredInterfaceType());
+  }
+
+  return Type();
+}
+
 Type AssociatedTypeInference::substCurrentTypeWitnesses(Type type) {
   // Local function that folds dependent member types with non-dependent
   // bases into actual member references.
@@ -898,7 +1004,44 @@
   }
 }
 
-bool AssociatedTypeInference::checkCurrentTypeWitnesses() {
+SubstOptions
+AssociatedTypeInference::getSubstOptionsWithCurrentTypeWitnesses() {
+  SubstOptions options(None);
+  AssociatedTypeInference *self = this;
+  options.getTentativeTypeWitness =
+    [self](const NormalProtocolConformance *conformance,
+           AssociatedTypeDecl *assocType) -> TypeBase * {
+      auto thisProto = self->conformance->getProtocol();
+      if (conformance == self->conformance) {
+        // Okay: we have the associated type we need.
+      } else if (conformance->getType()->isEqual(
+                   self->conformance->getType()) &&
+                 thisProto->inheritsFrom(conformance->getProtocol())) {
+        // Find an associated type with the same name in the given
+        // protocol.
+        AssociatedTypeDecl *foundAssocType = nullptr;
+        for (auto result : thisProto->lookupDirect(
+                                             assocType->getName(),
+                                             /*ignoreNewExtensions=*/true)) {
+          foundAssocType = dyn_cast<AssociatedTypeDecl>(result);
+          if (foundAssocType) break;
+        }
+
+      if (!foundAssocType) return nullptr;
+      assocType = foundAssocType;
+    } else {
+      return nullptr;
+    }
+
+    Type type = self->typeWitnesses.begin(assocType)->first;
+    return type->mapTypeOutOfContext().getPointer();
+  };
+  return options;
+}
+
+bool AssociatedTypeInference::checkCurrentTypeWitnesses(
+       const SmallVectorImpl<std::pair<ValueDecl *, ValueDecl *>>
+         &valueWitnesses) {
   // Fold the dependent member types within this type.
   for (auto assocType : proto->getAssociatedTypeMembers()) {
     if (conformance->hasTypeWitness(assocType))
@@ -924,15 +1067,7 @@
   if (!proto->isRequirementSignatureComputed()) return false;
 
   // Check any same-type requirements in the protocol's requirement signature.
-  SubstOptions options(None);
-  options.getTentativeTypeWitness =
-    [&](const NormalProtocolConformance *conformance,
-        AssociatedTypeDecl *assocType) -> TypeBase * {
-      if (conformance != this->conformance) return nullptr;
-
-      auto type = typeWitnesses.begin(assocType)->first;
-      return type->mapTypeOutOfContext().getPointer();
-    };
+  SubstOptions options = getSubstOptionsWithCurrentTypeWitnesses();
 
   auto typeInContext = dc->mapTypeIntoContext(adoptee);
 
@@ -959,12 +1094,55 @@
 
   case RequirementCheckResult::Success:
   case RequirementCheckResult::SubstitutionFailure:
-    return false;
+    break;
+  }
+
+  // Check for extra requirements in the constrained extensions that supply
+  // defaults.
+  SmallPtrSet<ExtensionDecl *, 4> checkedExtensions;
+  for (const auto &valueWitness : valueWitnesses) {
+    // We only perform this additional checking for default associated types.
+    if (!isa<TypeDecl>(valueWitness.first)) continue;
+
+    auto witness = valueWitness.second;
+    if (!witness) continue;
+
+    auto ext = dyn_cast<ExtensionDecl>(witness->getDeclContext());
+    if (!ext) continue;
+
+    if (!ext->isConstrainedExtension()) continue;
+    if (!checkedExtensions.insert(ext).second) continue;
+
+    if (checkConstrainedExtension(ext)) return true;
   }
 
   return false;
 }
 
+bool AssociatedTypeInference::checkConstrainedExtension(ExtensionDecl *ext) {
+  auto typeInContext = dc->mapTypeIntoContext(adoptee);
+  auto subs = typeInContext->getContextSubstitutions(ext);
+
+  SubstOptions options = getSubstOptionsWithCurrentTypeWitnesses();
+  switch (tc.checkGenericArguments(
+                       dc, SourceLoc(), SourceLoc(), adoptee,
+                       ext->getGenericSignature()->getGenericParams(),
+                       ext->getGenericSignature()->getRequirements(),
+                       QueryTypeSubstitutionMap{subs},
+                       LookUpConformanceInModule(ext->getModuleContext()),
+                                   nullptr, ConformanceCheckFlags::InExpression,
+                                   nullptr,
+                                   options)) {
+  case RequirementCheckResult::Success:
+  case RequirementCheckResult::SubstitutionFailure:
+    return false;
+
+  case RequirementCheckResult::Failure:
+  case RequirementCheckResult::UnsatisfiedDependency:
+    return true;
+  }
+}
+
 void AssociatedTypeInference::findSolutions(
                    ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
                    SmallVectorImpl<InferredTypeWitnessesSolution> &solutions) {
@@ -1008,65 +1186,26 @@
         continue;
       }
 
-      // We don't have a type witness for this associated type, so go
-      // looking for more options.
-      if (Type concreteType = computeFixedTypeWitness(assocType)) {
-        if (concreteType->hasError()) {
+      // Try to compute the type without the aid of a specific potential
+      // witness.
+      if (Type type = computeAbstractTypeWitness(assocType,
+                                                 /*allowDerived=*/true)) {
+        if (type->hasError()) {
           recordMissing();
           return;
         }
 
-        typeWitnesses.insert(assocType, {concreteType, reqDepth});
+        typeWitnesses.insert(assocType, {type, reqDepth});
         continue;
       }
 
-      // If we can form a default type, do so.
-      if (Type defaultType = computeDefaultTypeWitness(assocType)) {
-        if (defaultType->hasError()) {
-          recordMissing();
-          return;
-        }
-
-        typeWitnesses.insert(assocType, {defaultType, reqDepth});
-        continue;
-      }
-
-      // If we can derive a type witness, do so.
-      if (Type derivedType = computeDerivedTypeWitness(assocType)) {
-        if (derivedType->hasError()) {
-          recordMissing();
-          return;
-        }
-
-        typeWitnesses.insert(assocType, {derivedType, reqDepth});
-        continue;
-      }
-
-      // If there is a generic parameter of the named type, use that.
-      if (auto gpList = dc->getGenericParamsOfContext()) {
-        GenericTypeParamDecl *foundGP = nullptr;
-        for (auto gp : *gpList) {
-          if (gp->getName() == assocType->getName()) {
-            foundGP = gp;
-            break;
-          }
-        }
-
-        if (foundGP) {
-          auto gpType = dc->mapTypeIntoContext(
-                          foundGP->getDeclaredInterfaceType());
-          typeWitnesses.insert(assocType, {gpType, reqDepth});
-          continue;
-        }
-      }
-
       // The solution is incomplete.
       recordMissing();
       return;
     }
 
     /// Check the current set of type witnesses.
-    bool invalid = checkCurrentTypeWitnesses();
+    bool invalid = checkCurrentTypeWitnesses(valueWitnesses);
 
     // Determine whether there is already a solution with the same
     // bindings.
@@ -1109,17 +1248,50 @@
   // looking for solutions involving each one.
   const auto &inferredReq = inferred[reqDepth];
   for (const auto &witnessReq : inferredReq.second) {
+    llvm::SaveAndRestore<unsigned> savedNumTypeWitnesses(numTypeWitnesses);
+
+    // If we inferred a type witness via a default, try both with and without
+    // the default.
+    if (isa<TypeDecl>(inferredReq.first)) {
+      // Recurse without considering this type.
+      valueWitnesses.push_back({inferredReq.first, nullptr});
+      findSolutionsRec(unresolvedAssocTypes, solutions, nonViableSolutions,
+                       valueWitnesses, numTypeWitnesses,
+                       numValueWitnessesInProtocolExtensions, reqDepth + 1);
+      valueWitnesses.pop_back();
+
+      ++numTypeWitnesses;
+      for (const auto &typeWitness : witnessReq.Inferred) {
+        auto known = typeWitnesses.begin(typeWitness.first);
+        if (known != typeWitnesses.end()) continue;
+
+        // Enter a new scope for the type witnesses hash table.
+        TypeWitnessesScope typeWitnessesScope(typeWitnesses);
+        typeWitnesses.insert(typeWitness.first, {typeWitness.second, reqDepth});
+
+        valueWitnesses.push_back({inferredReq.first, witnessReq.Witness});
+        findSolutionsRec(unresolvedAssocTypes, solutions, nonViableSolutions,
+                         valueWitnesses, numTypeWitnesses,
+                         numValueWitnessesInProtocolExtensions, reqDepth + 1);
+        valueWitnesses.pop_back();
+      }
+
+      continue;
+    }
+
     // Enter a new scope for the type witnesses hash table.
     TypeWitnessesScope typeWitnessesScope(typeWitnesses);
-    llvm::SaveAndRestore<unsigned> savedNumTypeWitnesses(numTypeWitnesses);
 
     // Record this value witness, popping it when we exit the current scope.
     valueWitnesses.push_back({inferredReq.first, witnessReq.Witness});
-    if (witnessReq.Witness->getDeclContext()->getAsProtocolExtensionContext())
+    if (!isa<TypeDecl>(inferredReq.first) &&
+        witnessReq.Witness->getDeclContext()->getAsProtocolExtensionContext())
       ++numValueWitnessesInProtocolExtensions;
     SWIFT_DEFER {
-      if (witnessReq.Witness->getDeclContext()->getAsProtocolExtensionContext())
+      if (!isa<TypeDecl>(inferredReq.first) &&
+          witnessReq.Witness->getDeclContext()->getAsProtocolExtensionContext())
         --numValueWitnessesInProtocolExtensions;
+
       valueWitnesses.pop_back();
     };
 
@@ -1130,7 +1302,11 @@
       // conflicts, there is no solution.
       auto known = typeWitnesses.begin(typeWitness.first);
       if (known != typeWitnesses.end()) {
-        // If witnesses for two difference requirements inferred the same
+        // Don't overwrite a defaulted associated type witness.
+        if (isa<TypeDecl>(valueWitnesses[known->second].second))
+          continue;
+
+        // If witnesses for two different requirements inferred the same
         // type, we're okay.
         if (known->first->isEqual(typeWitness.second))
           continue;
@@ -1192,6 +1368,22 @@
   // consider these unordered since neither extension's generic signature
   // is a superset of the other.
 
+  // If one of the declarations is null, it implies that we're working with
+  // a skipped associated type default. Prefer that default to something
+  // that came from a protocol extension.
+  if (!decl1 || !decl2) {
+    if (!decl1 &&
+        decl2 && decl2->getDeclContext()->getAsProtocolExtensionContext())
+      return Comparison::Worse;
+
+    if (!decl2 &&
+        decl1 && decl1->getDeclContext()->getAsProtocolExtensionContext())
+      return Comparison::Better;
+
+    return Comparison::Unordered;
+  }
+
+
   // If the witnesses come from the same decl context, score normally.
   auto dc1 = decl1->getDeclContext();
   auto dc2 = decl2->getDeclContext();
diff --git a/lib/Syntax/README.md b/lib/Syntax/README.md
index e3488e3..7d1e914 100644
--- a/lib/Syntax/README.md
+++ b/lib/Syntax/README.md
@@ -425,7 +425,7 @@
 auto ReturnKW = SyntaxFactory::makeReturnKeyword({}, Trivia::spaces(1));
 
 // This ReturnStmtSyntax is floating, with no root.
-auto Return = SyntaxFactory::makeReturnStmt(ReturnKW, Integer, 
+auto Return = SyntaxFactory::makeReturnStmt(ReturnKW, Integer,
                                             /*Semicolon=*/ None);
 
 auto RightBrace = SyntaxFactory::makeLeftBraceToken({}, {});
@@ -466,7 +466,7 @@
 
 A couple of interesting points and reminders:
 - All strong references point downward in the tree.
-- One `SyntaxData` for each `RawSyntax`.  
+- One `SyntaxData` for each `RawSyntax`.
   Remember, a `SyntaxData` is essentially a `RawSyntax` with a parent pointer
   and cached `SyntaxData` children.
 - Parent pointers are omitted here but there are weak references pointing
@@ -530,14 +530,11 @@
 ## Adding new Syntax Nodes
 
 Here's a handy checklist when implementing a production in the grammar.
-- Check that the corresponding `lib/AST` node has `SourceLocs` for all terms. If
-  it doesn't, [file a Swift bug][NewSwiftBug] and fix that first.
-  - **Add the `Syntax` bug label!**
 - Check if it's not already being worked on, and then
-  [file a Swift bug][NewSwiftBug], noting which grammar productions
-  are affected.
+  [file a Swift bug](https://bugs.swift.org/secure/CreateIssue!default.jspa),
+  noting which grammar productions are affected.
   - **Add the `Syntax` bug label!**
-- Create the `${KIND}` entry in the appropriate Python file (Expr, Stmt, 
+- Create the `${KIND}` entry in the appropriate Python file (Expr, Stmt,
   Pattern, etc.).
   - Add C++ unit tests for `with` APIs for all layout elements
       (e.g. `withLeftTypeIdentifier(...)`).
@@ -558,4 +555,47 @@
     - check for a zero-diff print with `-round-trip-parse`
 - Update `lib/Syntax/Status.md` if applicable.
 
-[NewSwiftBug]: https://bugs.swift.org/secure/CreateIssue!default.jspa)
+## Try libSyntax in Xcode
+
+Here's how to build a Swift command line tool in Xcode using libSyntax:
+1. Download the latest open source toolchain from swift.org:
+  [Trunk Development (master)](https://swift.org/download/#snapshots).
+2. Run the downloaded package installer.
+3. Start Xcode and specify the just-installed toolchain to use in
+`Xcode->Toolchains->Swift Development Snapshot...`
+4. Create a new Swift command line tool project in Xcode.
+5. In the project's build setting, specify two variables:
+    - Runpath search paths: `$(TOOLCHAIN_DIR)/usr/lib/swift/macosx`
+    - Library search paths: `$(TOOLCHAIN_DIR)/usr/lib/swift/macosx`
+6. Now, in `main.swift`, we can `import SwiftSyntax` and experiment with its APIs.
+  For example, the following code snippet renames every function called `foo` to `bar`.
+
+```swift
+import Foundation
+import SwiftSyntax
+
+class Renamer: SyntaxRewriter {
+  override func visit(_ node: FunctionDeclSyntax) -> DeclSyntax {
+    if node.identifier.text == "foo" {
+      return super.visit(node.withIdentifier(SyntaxFactory.makeIdentifier("bar")))
+    } else {
+      return super.visit(node)
+    }
+  }
+}
+
+// Parse a .swift file
+let currentFile = URL(fileURLWithPath: "/tmp/test.swift")
+let currentFileContents = try String(contentsOf: currentFile)
+let parsed = try Syntax.parse(currentFile)
+
+// Print the original file
+print("\n//======== Original =========\n")
+print(parsed)
+
+let R = Renamer()
+
+// Print the file after renaming
+print("\n//======== Renamed =========\n")
+print(R.visit(parsed))
+```
diff --git a/lib/Syntax/Status.md b/lib/Syntax/Status.md
index eb2460d..8a66126 100644
--- a/lib/Syntax/Status.md
+++ b/lib/Syntax/Status.md
@@ -91,33 +91,34 @@
 ### Done:
   * BraceStmt
   * ReturnStmt
-
-### Not-started (UnknownStmt):
   * DeferStmt
-  * IfStmt
-  * GuardStmt
-  * WhileStmt
   * DoStmt
-  * DoCatchStmt
   * RepeatWhileStmt
-  * ForEachStmt
-  * SwitchStmt
-  * CaseStmt
-  * CatchStmt
   * BreakStmt
   * ContinueStmt
   * FallthroughStmt
-  * FailStmt
   * ThrowStmt
 
+### Not-started (UnknownStmt):
+  * IfStmt
+  * GuardStmt
+  * WhileStmt
+  * ForEachStmt
+  * SwitchStmt
+
 ## Pattern
-### Not-started:
-  * ParenPattern
+### Done:
+  * IdentifierPattern
+  * WildcardPattern
   * TuplePattern
-  * NamedPattern
-  * AnyPattern
-  * TypedPattern
-  * VarPattern
+  * ExpressionPattern
+  * ValueBindingPattern
+  * IsTypePattern
+
+### Not-started:
+  * AsTypePattern
+  * OptionalPattern
+  * EnumCasePattern
 
 ## TypeRepr
 ### Done:
diff --git a/lib/Syntax/SyntaxFactory.cpp.gyb b/lib/Syntax/SyntaxFactory.cpp.gyb
index d811d0a..80a51fb 100644
--- a/lib/Syntax/SyntaxFactory.cpp.gyb
+++ b/lib/Syntax/SyntaxFactory.cpp.gyb
@@ -110,50 +110,13 @@
     static std::pair<bool, std::function<bool(const Syntax&)>>
       ChildrenConditions[${child_count}] = {
 %    for child in node.children:
+%       check = check_child_condition(child)
 %       if child.is_optional:
 %         option = "true"
 %       else:
 %         option = "false"
-%       if child.token_choices:
-        {   ${option},
-            [](const Syntax &S) {
-              // check ${child.name}.
-              if (auto Tok = S.getAs<TokenSyntax>()) {
-                auto Kind = Tok->getTokenKind();
-%           tok_checks = []
-%           for choice in child.token_choices:
-%             tok_checks.append("Kind == tok::%s" % choice.kind)
-%           end
-%           all_checks = ' || '.join(tok_checks)
-                return ${all_checks};
-              }
-              return false;
-            }
-        },
-%       elif child.text_choices:
-        {   ${option},
-            [](const Syntax &S) {
-              // check ${child.name}.
-              if (auto Tok = S.getAs<TokenSyntax>()) {
-                auto Text = Tok->getText();
-%           tok_checks = []
-%           for choice in child.text_choices:
-%             tok_checks.append("Text == \"%s\"" % choice)
-%           end
-%           all_checks = ' || '.join(tok_checks)
-                return ${all_checks};
-              }
-              return false;
-            }
-        },
-%       else:
-        {   ${option},
-            [](const Syntax &S) {
-              // check ${child.name}.
-              return S.getAs<${child.type_name}>().hasValue();
-            }
-        },
 %       end
+        {   ${option}, ${check} },
 %    end
     };
     Optional<Syntax> Parameters[${child_count}];
diff --git a/lib/Syntax/SyntaxNodes.cpp.gyb b/lib/Syntax/SyntaxNodes.cpp.gyb
index 9b51cf9..753f70c 100644
--- a/lib/Syntax/SyntaxNodes.cpp.gyb
+++ b/lib/Syntax/SyntaxNodes.cpp.gyb
@@ -41,9 +41,18 @@
 %         token_kind = child.main_token().kind
 %         choices = ", ".join("\"%s\"" % choice
 %                             for choice in child.text_choices)
-  syntax_assert_child_token_text(raw, ${child.name}, 
+  syntax_assert_child_token_text(raw, ${child.name},
                                  tok::${token_kind}, ${choices});
 %       end
+%       if child.node_choices:
+#ifndef NDEBUG
+        {
+          auto child = make<Syntax>(raw->getChild(Cursor::${child.name}));
+%         content = check_child_condition(child) + '(child)'
+          assert(${content});
+        }
+#endif
+%       end
 %     end
 }
 %   end
diff --git a/lib/Syntax/Trivia.cpp b/lib/Syntax/Trivia.cpp
index a2f49f1..e144e30 100644
--- a/lib/Syntax/Trivia.cpp
+++ b/lib/Syntax/Trivia.cpp
@@ -58,6 +58,9 @@
   case TriviaKind::CarriageReturn:
     OS << "carriage_return " << Count;
     break;
+  case TriviaKind::CarriageReturnLineFeed:
+    OS << "carriage_return_line_feed " << Count;
+    break;
   case TriviaKind::LineComment:
     OS << "line_comment" << Text.str();
     break;
@@ -101,7 +104,10 @@
     break;
   case TriviaKind::Newline:
   case TriviaKind::CarriageReturn:
-    Pos.addNewlines(Count);
+    Pos.addNewlines(Count, 1);
+    break;
+  case TriviaKind::CarriageReturnLineFeed:
+    Pos.addNewlines(Count, 2);
     break;
   case TriviaKind::Space:
   case TriviaKind::Backtick:
@@ -113,6 +119,29 @@
   }
 }
 
+bool TriviaPiece::trySquash(const TriviaPiece &Next) {
+  if (Kind != Next.Kind) { return false; }
+  
+  switch (Kind) {
+    case TriviaKind::Space:
+    case TriviaKind::Tab:
+    case TriviaKind::VerticalTab:
+    case TriviaKind::Formfeed:
+    case TriviaKind::Newline:
+    case TriviaKind::CarriageReturn:
+    case TriviaKind::CarriageReturnLineFeed:
+      Count += Next.Count;
+      return true;
+    case TriviaKind::LineComment:
+    case TriviaKind::BlockComment:
+    case TriviaKind::DocLineComment:
+    case TriviaKind::DocBlockComment:
+    case TriviaKind::GarbageText:
+    case TriviaKind::Backtick:
+      return false;
+  }
+}
+
 void TriviaPiece::print(llvm::raw_ostream &OS) const {
   switch (Kind) {
   case TriviaKind::Space:
@@ -133,6 +162,11 @@
   case TriviaKind::CarriageReturn:
     printRepeated(OS, '\r', Count);
     break;
+  case TriviaKind::CarriageReturnLineFeed:
+    for (unsigned i = 0; i < Count; i++) {
+      OS << "\r\n";
+    }
+    break;
   case TriviaKind::LineComment:
   case TriviaKind::BlockComment:
   case TriviaKind::DocLineComment:
@@ -148,6 +182,17 @@
 
 #pragma mark - Trivia collection
 
+void Trivia::appendOrSquash(const TriviaPiece &Next) {
+  if (Pieces.size() > 0) {
+    TriviaPiece &last = Pieces.back();
+    if (last.trySquash(Next)) {
+      return;
+    }
+  }
+  
+  push_back(Next);
+}
+
 Trivia Trivia::appending(const Trivia &Other) const {
   auto NewPieces = Pieces;
   std::copy(Other.begin(), Other.end(), std::back_inserter(NewPieces));
diff --git a/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb b/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb
index 75b39d1..00e5940 100644
--- a/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb
+++ b/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb
@@ -506,11 +506,6 @@
         let first = extractedResult[i].value
         let second = extractedResult[extractedResult.index(after: i)].value
         let result = lessImpl(second, first)
-        if result {
-          print("yep ** Result should be true \(result)")
-        } else {
-          print("yep ** Test passed result is false")
-        }
         expectFalse(result)
       }
     }
diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp
index d0de9e3..d2a55bb 100644
--- a/stdlib/public/Reflection/TypeLowering.cpp
+++ b/stdlib/public/Reflection/TypeLowering.cpp
@@ -975,7 +975,7 @@
       // further.
       if (CaseTI != nullptr) {
         // Below logic should match the runtime function
-        // swift_initEnumValueWitnessTableSinglePayload().
+        // swift_initEnumMetadataSinglePayload().
         NumExtraInhabitants = CaseTI->getNumExtraInhabitants();
         if (NumExtraInhabitants >= NoPayloadCases) {
           // Extra inhabitants can encode all no-payload cases.
diff --git a/stdlib/public/core/Flatten.swift b/stdlib/public/core/Flatten.swift
index 9a2733c..a3c806c 100644
--- a/stdlib/public/core/Flatten.swift
+++ b/stdlib/public/core/Flatten.swift
@@ -566,7 +566,7 @@
 }
 
 // @available(*, deprecated, renamed: "FlattenCollection.Index")
-public typealias FlattenCollectionIndex<T> = FlattenCollection<T>.Index where T : BidirectionalCollection, T.Element : BidirectionalCollection
+public typealias FlattenCollectionIndex<T> = FlattenCollection<T>.Index where T : Collection, T.Element : Collection
 @available(*, deprecated, renamed: "FlattenCollection.Index")
 public typealias FlattenBidirectionalCollectionIndex<T> = FlattenCollection<T>.Index where T : BidirectionalCollection, T.Element : BidirectionalCollection
 @available(*, deprecated, renamed: "FlattenCollection")
diff --git a/stdlib/public/core/Hashing.swift b/stdlib/public/core/Hashing.swift
index 5a4ca72..116ba67 100644
--- a/stdlib/public/core/Hashing.swift
+++ b/stdlib/public/core/Hashing.swift
@@ -188,13 +188,21 @@
 
 /// Returns a new value that combines the two given hash values.
 ///
+/// Combining is performed using [a hash function][ref] described by T.C. Hoad
+/// and J. Zobel, which is also adopted in the Boost C++ libraries.
+///
 /// This function is used by synthesized implementations of `hashValue` to
 /// combine the hash values of individual `struct` fields and associated values
 /// of `enum`s. It is factored out into a standard library function so that the
 /// specific hashing logic can be refined without requiring major changes to the
 /// code that creates the synthesized AST nodes.
+///
+/// [ref]: http://goanna.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf
 @_transparent
 public // @testable
-func _mixForSynthesizedHashValue(_ oldValue: Int, _ nextValue: Int) -> Int {
-  return 31 &* oldValue &+ nextValue
+func _combineHashValues(_ firstValue: Int, _ secondValue: Int) -> Int {
+  let magic = 0x9e3779b9 as UInt // Based on the golden ratio.
+  var x = UInt(bitPattern: firstValue)
+  x ^= UInt(bitPattern: secondValue) &+ magic &+ (x &<< 6) &+ (x &>> 2)
+  return Int(bitPattern: x)
 }
diff --git a/stdlib/public/core/RandomAccessCollection.swift b/stdlib/public/core/RandomAccessCollection.swift
index aff7d21..079f965 100644
--- a/stdlib/public/core/RandomAccessCollection.swift
+++ b/stdlib/public/core/RandomAccessCollection.swift
@@ -166,6 +166,13 @@
   }
 }
 
+// Provides an alternative default associated type witness for Indices
+// for random access collections with strideable indices.
+extension RandomAccessCollection where Index : Strideable, Index.Stride == Int {
+  @_implements(Collection, Indices)
+  public typealias _Default_Indices = CountableRange<Index>
+}
+
 extension RandomAccessCollection
 where Index : Strideable, 
       Index.Stride == Int,
diff --git a/stdlib/public/core/Sequence.swift b/stdlib/public/core/Sequence.swift
index deaf468..accf446 100644
--- a/stdlib/public/core/Sequence.swift
+++ b/stdlib/public/core/Sequence.swift
@@ -612,6 +612,13 @@
   ) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index)
 }
 
+// Provides a default associated type witness for Iterator when the
+// Self type is both a Sequence and an Iterator.
+extension Sequence where Self: IteratorProtocol {
+  // @_implements(Sequence, Iterator)
+  public typealias _Default_Iterator = Self
+}
+
 /// A default makeIterator() function for `IteratorProtocol` instances that
 /// are declared to conform to `Sequence`
 extension Sequence where Self.Iterator == Self {
@@ -622,7 +629,6 @@
   }
 }
 
-
 /// A sequence that lazily consumes and drops `n` elements from an underlying
 /// `Base` iterator before possibly returning the first available element.
 ///
diff --git a/stdlib/public/core/SwiftNativeNSArray.swift b/stdlib/public/core/SwiftNativeNSArray.swift
index aa57fcb..5189acc 100644
--- a/stdlib/public/core/SwiftNativeNSArray.swift
+++ b/stdlib/public/core/SwiftNativeNSArray.swift
@@ -262,6 +262,7 @@
 #else
 // Empty shim version for non-objc platforms.
 @_versioned
+@_fixed_layout
 internal class _SwiftNativeNSArrayWithContiguousStorage {
   @_inlineable
   @_versioned
diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt
index 44dff74..5d88134 100644
--- a/stdlib/public/runtime/CMakeLists.txt
+++ b/stdlib/public/runtime/CMakeLists.txt
@@ -1,6 +1,11 @@
 set(swift_runtime_compile_flags ${SWIFT_RUNTIME_CORE_CXX_FLAGS})
 set(swift_runtime_linker_flags ${SWIFT_RUNTIME_CORE_LINK_FLAGS})
 
+if(SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT)
+  list(APPEND swift_runtime_compile_flags
+      "-DSWIFT_DARWIN_ENABLE_STABLE_ABI_BIT=1")
+endif()
+
 if(SWIFT_RUNTIME_CLOBBER_FREED_OBJECTS)
   list(APPEND swift_runtime_compile_flags
       "-DSWIFT_RUNTIME_CLOBBER_FREED_OBJECTS=1")
diff --git a/stdlib/public/runtime/Enum.cpp b/stdlib/public/runtime/Enum.cpp
index 21eef71..e547848 100644
--- a/stdlib/public/runtime/Enum.cpp
+++ b/stdlib/public/runtime/Enum.cpp
@@ -26,10 +26,45 @@
 
 using namespace swift;
 
+static EnumValueWitnessTable *getMutableVWTableForInit(EnumMetadata *self,
+                                                       EnumLayoutFlags flags) {
+  auto oldTable =
+    static_cast<const EnumValueWitnessTable *>(self->getValueWitnesses());
+
+  // If we can alter the existing table in-place, do so.
+  if (isValueWitnessTableMutable(flags))
+    return const_cast<EnumValueWitnessTable*>(oldTable);
+
+  // Otherwise, allocate permanent memory for it and copy the existing table.
+  void *memory = allocateMetadata(sizeof(EnumValueWitnessTable),
+                                  alignof(EnumValueWitnessTable));
+  auto newTable = new (memory) EnumValueWitnessTable(*oldTable);
+  self->setValueWitnesses(newTable);
+
+  return newTable;
+}
+
 void
-swift::swift_initEnumValueWitnessTableSinglePayload(ValueWitnessTable *vwtable,
-                                                const TypeLayout *payloadLayout,
-                                                unsigned emptyCases) {
+swift::swift_initEnumMetadataSingleCase(EnumMetadata *self,
+                                        EnumLayoutFlags layoutFlags,
+                                        const TypeLayout *payloadLayout) {
+  auto vwtable = getMutableVWTableForInit(self, layoutFlags);
+
+  vwtable->size = payloadLayout->size;
+  vwtable->stride = payloadLayout->stride;
+  vwtable->flags = payloadLayout->flags.withEnumWitnesses(true);
+
+  if (payloadLayout->flags.hasExtraInhabitants()) {
+    auto ew = static_cast<ExtraInhabitantsValueWitnessTable*>(vwtable);
+    ew->extraInhabitantFlags = payloadLayout->getExtraInhabitantFlags();
+  }
+}
+
+void
+swift::swift_initEnumMetadataSinglePayload(EnumMetadata *self,
+                                           EnumLayoutFlags layoutFlags,
+                                           const TypeLayout *payloadLayout,
+                                           unsigned emptyCases) {
   size_t payloadSize = payloadLayout->size;
   unsigned payloadNumExtraInhabitants
     = payloadLayout->getNumExtraInhabitants();
@@ -47,6 +82,8 @@
                                       emptyCases - payloadNumExtraInhabitants,
                                       1 /*payload case*/);
   }
+
+  auto vwtable = getMutableVWTableForInit(self, layoutFlags);
   
   size_t align = payloadLayout->flags.getAlignment();
   vwtable->size = size;
@@ -128,8 +165,8 @@
 }
 
 void
-swift::swift_initEnumMetadataMultiPayload(ValueWitnessTable *vwtable,
-                                     EnumMetadata *enumType,
+swift::swift_initEnumMetadataMultiPayload(EnumMetadata *enumType,
+                                     EnumLayoutFlags layoutFlags,
                                      unsigned numPayloads,
                                      const TypeLayout * const *payloadLayouts) {
   // Accumulate the layout requirements of the payloads.
@@ -151,7 +188,9 @@
   unsigned totalSize = payloadSize + getNumTagBytes(payloadSize,
                                 enumType->Description->Enum.getNumEmptyCases(),
                                 numPayloads);
-  
+
+  auto vwtable = getMutableVWTableForInit(enumType, layoutFlags);
+
   // Set up the layout info in the vwtable.
   vwtable->size = totalSize;
   vwtable->flags = ValueWitnessFlags()
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 2e2ba73..1fb82aa 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -1278,25 +1278,57 @@
 /*** Structs ***************************************************************/
 /***************************************************************************/
 
+static ValueWitnessTable *getMutableVWTableForInit(StructMetadata *self,
+                                                   StructLayoutFlags flags,
+                                                   bool hasExtraInhabitants) {
+  auto oldTable = self->getValueWitnesses();
+
+  // If we can alter the existing table in-place, do so.
+  if (isValueWitnessTableMutable(flags))
+    return const_cast<ValueWitnessTable*>(oldTable);
+
+  // Otherwise, allocate permanent memory for it and copy the existing table.
+  ValueWitnessTable *newTable;
+  if (hasExtraInhabitants) {
+    void *memory = allocateMetadata(sizeof(ExtraInhabitantsValueWitnessTable),
+                                    alignof(ExtraInhabitantsValueWitnessTable));
+    newTable = new (memory) ExtraInhabitantsValueWitnessTable(
+              *static_cast<const ExtraInhabitantsValueWitnessTable*>(oldTable));
+  } else {
+    void *memory = allocateMetadata(sizeof(ValueWitnessTable),
+                                    alignof(ValueWitnessTable));
+    newTable = new (memory) ValueWitnessTable(*oldTable);
+  }
+  self->setValueWitnesses(newTable);
+
+  return newTable;
+}
+
 /// Initialize the value witness table and struct field offset vector for a
 /// struct, using the "Universal" layout strategy.
-void swift::swift_initStructMetadata_UniversalStrategy(size_t numFields,
+void swift::swift_initStructMetadata(StructMetadata *structType,
+                                     StructLayoutFlags layoutFlags,
+                                     size_t numFields,
                                      const TypeLayout * const *fieldTypes,
-                                     size_t *fieldOffsets,
-                                     ValueWitnessTable *vwtable) {
+                                     size_t *fieldOffsets) {
   auto layout = BasicLayout::initialForValueType();
   performBasicLayout(layout, fieldTypes, numFields,
     [&](size_t i, const TypeLayout *fieldType, size_t offset) {
       assignUnlessEqual(fieldOffsets[i], offset);
     });
 
+  bool hasExtraInhabitants = fieldTypes[0]->flags.hasExtraInhabitants();
+
+  auto vwtable =
+    getMutableVWTableForInit(structType, layoutFlags, hasExtraInhabitants);
+
   vwtable->size = layout.size;
   vwtable->flags = layout.flags;
   vwtable->stride = layout.stride;
   
   // We have extra inhabitants if the first element does.
   // FIXME: generalize this.
-  if (fieldTypes[0]->flags.hasExtraInhabitants()) {
+  if (hasExtraInhabitants) {
     vwtable->flags = vwtable->flags.withExtraInhabitants(true);
     auto xiVWT = cast<ExtraInhabitantsValueWitnessTable>(vwtable);
     xiVWT->extraInhabitantFlags = fieldTypes[0]->getExtraInhabitantFlags();
@@ -2464,14 +2496,15 @@
 const ForeignTypeMetadata *
 swift::swift_getForeignTypeMetadata(ForeignTypeMetadata *nonUnique) {
   // Fast path: check the invasive cache.
-  if (auto unique = nonUnique->getCachedUniqueMetadata()) {
-    return unique;
+  auto cache = nonUnique->getCacheValue();
+  if (cache.isInitialized()) {
+    return cache.getCachedUniqueMetadata();
   }
 
   // Okay, check the global map.
   auto &foreignTypes = ForeignTypes.get();
   GlobalString key(nonUnique->getName());
-  bool hasInit = nonUnique->hasInitializationFunction();
+  bool hasInit = cache.hasInitializationFunction();
 
   const ForeignTypeMetadata *uniqueMetadata;
   bool inserted;
@@ -2900,3 +2933,6 @@
                                                  std::memory_order_relaxed);
 }
 
+void *swift::allocateMetadata(size_t size, size_t alignment) {
+  return MetadataAllocator().Allocate(size, alignment);
+}
diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h
index 0e350e7..fd48475 100644
--- a/stdlib/public/runtime/Private.h
+++ b/stdlib/public/runtime/Private.h
@@ -193,6 +193,8 @@
 #endif
   }
 
+  void *allocateMetadata(size_t size, size_t align);
+
 } // end namespace swift
 
 #endif /* SWIFT_RUNTIME_PRIVATE_H */
diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm
index 9b1c7d1..6860b99 100644
--- a/stdlib/public/runtime/SwiftObject.mm
+++ b/stdlib/public/runtime/SwiftObject.mm
@@ -443,7 +443,7 @@
 bool swift::usesNativeSwiftReferenceCounting(const ClassMetadata *theClass) {
 #if SWIFT_OBJC_INTEROP
   if (!theClass->isTypeMetadata()) return false;
-  return (theClass->getFlags() & ClassFlags::UsesSwift1Refcounting);
+  return (theClass->getFlags() & ClassFlags::UsesSwiftRefcounting);
 #else
   return true;
 #endif
diff --git a/test/DebugInfo/uninitialized.swift b/test/DebugInfo/uninitialized.swift
new file mode 100644
index 0000000..ca3549e
--- /dev/null
+++ b/test/DebugInfo/uninitialized.swift
@@ -0,0 +1,11 @@
+// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
+class MyClass {}
+
+// CHECK: define {{.*}} @_T013uninitialized1fyyF
+public func f() {
+  var object: MyClass
+  // CHECK: %[[OBJ:.*]] = alloca %[[T:.*]]*, align
+  // CHECK: call void @llvm.dbg.declare(metadata %[[T]]** %[[OBJ]],
+  // CHECK: %[[BC:.*]] = bitcast %[[T]]** %[[OBJ]] to %swift.opaque**, !dbg
+  // CHECK: store %swift.opaque* null, %swift.opaque** %[[BC]], align {{.*}}, !dbg
+}
diff --git a/test/IRGen/cf.sil b/test/IRGen/cf.sil
index 24e5e00..18af675 100644
--- a/test/IRGen/cf.sil
+++ b/test/IRGen/cf.sil
@@ -7,11 +7,18 @@
 // CHECK: [[REFRIGERATOR:%TSo14CCRefrigeratorC]] = type
 // CHECK: [[OBJC:%objc_object]] = type
 
-// CHECK: [[REFRIGERATOR_NAME:@.*]] = private unnamed_addr constant [20 x i8] c"So14CCRefrigeratorC\00"
+// CHECK: [[REFRIGERATOR_NAME:@.*]] = private constant [20 x i8] c"So14CCRefrigeratorC\00"
 
-// CHECK-32: @_T0So14CCRefrigeratorCN = linkonce_odr hidden global <{ {{.*}} }> <{ i8* getelementptr inbounds ([20 x i8], [20 x i8]* [[REFRIGERATOR_NAME]], i32 0, i32 0), [[TYPE]]* null, i32 0, i8** @_T0BOWV, i32 16, [[TYPE]]* null, i8* null, i8* null, i8* null }>
+// CHECK-32: @_T0So14CCRefrigeratorCN = linkonce_odr hidden global <{ {{.*}} }> <{
+// CHECK-32-SAME: [[REFRIGERATOR_NAME]] to i32
+// CHECK-32-SAME: i32 0,
+// CHECK-32-SAME: i8** @_T0BOWV, i32 16, [[TYPE]]* null, i8* null, i8* null, i8* null }>
 
-// CHECK-64: @_T0So14CCRefrigeratorCN = linkonce_odr hidden global <{ {{.*}} }> <{ i8* getelementptr inbounds ([20 x i8], [20 x i8]* [[REFRIGERATOR_NAME]], i64 0, i64 0), [[TYPE]]* null, i64 0, i8** @_T0BOWV, i64 16, [[TYPE]]* null, i8* null, i8* null, i8* null }>
+// CHECK-64: @_T0So14CCRefrigeratorCN = linkonce_odr hidden global <{ {{.*}} }> <{
+// CHECK-64-SAME: i32 0,
+// CHECK-64-SAME: i32 trunc {{.*}} [[REFRIGERATOR_NAME]] to i64
+// CHECK-64-SAME: i64 0,
+// CHECK-64-SAME: i8** @_T0BOWV, i64 16, [[TYPE]]* null, i8* null, i8* null, i8* null }>
 
 sil_stage canonical
 
@@ -35,5 +42,5 @@
 // CHECK-NEXT: ret void
 
 // CHECK:    define linkonce_odr hidden [[TYPE]]* @_T0So14CCRefrigeratorCMa()
-// CHECK-32:    call [[TYPE]]* @swift_getForeignTypeMetadata([[TYPE]]* bitcast (i8* getelementptr inbounds (i8, i8* bitcast ({{.*}}* @_T0So14CCRefrigeratorCN to i8*), i32 16) to [[TYPE]]*))
-// CHECK-64:    call [[TYPE]]* @swift_getForeignTypeMetadata([[TYPE]]* bitcast (i8* getelementptr inbounds (i8, i8* bitcast ({{.*}}* @_T0So14CCRefrigeratorCN to i8*), i64 32) to [[TYPE]]*))
+// CHECK-32:    call [[TYPE]]* @swift_getForeignTypeMetadata([[TYPE]]* bitcast (i8* getelementptr inbounds (i8, i8* bitcast ({{.*}}* @_T0So14CCRefrigeratorCN to i8*), i32 12) to [[TYPE]]*))
+// CHECK-64:    call [[TYPE]]* @swift_getForeignTypeMetadata([[TYPE]]* bitcast (i8* getelementptr inbounds (i8, i8* bitcast ({{.*}}* @_T0So14CCRefrigeratorCN to i8*), i64 24) to [[TYPE]]*))
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index 78308d6..236c5c3 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -26,6 +26,8 @@
 
 // CHECK: @_T016class_resilience14ResilientChildCMo = {{(protected )?}}global [[INT]] 0
 
+// CHECK: @_T016class_resilience16FixedLayoutChildCMo = {{(protected )?}}global [[INT]] 0
+
 // CHECK: @_T016class_resilience21ResilientGenericChildCMo = {{(protected )?}}global [[INT]] 0
 
 // CHECK: @_T016class_resilience17MyResilientParentCMo = {{(protected )?}}constant [[INT]] {{52|80}}
@@ -103,6 +105,14 @@
   public let field: Int32 = 0
 }
 
+// Superclass is resilient, but the class is fixed-layout.
+// This simulates a user app subclassing a class in a resilient
+// framework. In this case, we still want to emit a base offset
+// global.
+
+@_fixed_layout public class FixedLayoutChild : ResilientOutsideParent {
+  public let field: Int32 = 0
+}
 
 // Superclass is resilient, so the number of fields and their
 // offsets is not known at compile time
@@ -303,6 +313,27 @@
 
 // CHECK:              ret void
 
+// CHECK-LABEL: define private void @initialize_metadata_FixedLayoutChild(i8*)
+
+// Get the superclass...
+
+// CHECK:              [[SUPER:%.*]] = call %swift.type* @_T015resilient_class22ResilientOutsideParentCMa()
+// CHECK:              [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
+// CHECK:              [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
+// CHECK:              [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
+// CHECK:              [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
+
+// Initialize class metadata base offset...
+// CHECK:              store [[INT]] {{.*}}, [[INT]]* @_T016class_resilience16FixedLayoutChildCMo
+
+// Initialize the superclass field...
+// CHECK:              store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
+
+// Relocate metadata if necessary...
+// CHECK:              call %swift.type* @swift_relocateClassMetadata(%swift.type* {{.*}}, [[INT]] {{60|96}}, [[INT]] 1)
+
+// CHECK:              ret void
+
 // CHECK-LABEL: define private %swift.type* @create_generic_metadata_ResilientGenericChild(%swift.type_pattern*, i8**)
 
 // Get the superclass...
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index 142114c..ef5ddd7 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -105,6 +105,11 @@
 //    implementations which are used if the instance has extra inhabitants.
 //    FIXME: Strings should be unnamed_addr. rdar://problem/22674524
 // CHECK: [[DYNAMICSINGLETON_FIELD_NAMES:@.*]] = private constant [7 x i8] c"value\00\00"
+// CHECK: @_T04enum16DynamicSingletonOWV =
+// CHECK-SAME:   i8* null
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum16DynamicSingletonOwxs to i8*)
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum16DynamicSingletonOwxg to i8*)
+
 // CHECK: [[DYNAMICSINGLETON_NAME:@.*]] = private constant [25 x i8] c"4enum16DynamicSingletonO\00"
 // CHECK: @_T04enum16DynamicSingletonOMn = hidden constant <{ {{.*}} i32 }> <{
 // CHECK-SAME:   [25 x i8]* [[DYNAMICSINGLETON_NAME]]
@@ -128,12 +133,10 @@
 // CHECK-SAME:   i32 1
 // CHECK-SAME: }>
 
-// CHECK: @_T04enum16DynamicSingletonOMP = internal global <{ {{.*}}, [18 x i8*] }> <{
+// CHECK: @_T04enum16DynamicSingletonOMP = internal global <{ {{.*}}, %swift.type* }> <{
 // CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSingleton
+// CHECK-SAME:   [18 x i8*]* @_T04enum16DynamicSingletonOWV
 // CHECK-SAME:   @_T04enum16DynamicSingletonOMn
-// CHECK-SAME:   i8* null
-// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum16DynamicSingletonOwxs to i8*)
-// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum16DynamicSingletonOwxg to i8*)
 
 // -- No-payload enums have extra inhabitants in
 //    their value witness table.
@@ -171,13 +174,15 @@
 // CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum19SinglePayloadNestedOwxg to i8*)
 // CHECK-SAME: ]
 
-
-// CHECK: @_T04enum20DynamicSinglePayloadOMP = internal global <{ {{.*}}, [18 x i8*] }> <{
-// CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSinglePayload
+// CHECK: @_T04enum20DynamicSinglePayloadOWV = internal constant [18 x i8*] [
 // CHECK-SAME:   i8* null
 // CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum20DynamicSinglePayloadOwxs to i8*)
 // CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum20DynamicSinglePayloadOwxg to i8*)
 
+// CHECK: @_T04enum20DynamicSinglePayloadOMP = internal global <{ {{.*}}, %swift.type* }> <{
+// CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSinglePayload
+// CHECK-SAME:   [18 x i8*]* @_T04enum20DynamicSinglePayloadOWV
+
 // CHECK: @_T04enum18MultiPayloadNestedOWV = internal constant [18 x i8*] [
 // -- size
 // CHECK-32-SAME:   i8* inttoptr ([[WORD]] 5 to i8*),
@@ -2682,8 +2687,7 @@
  return %tuple : $()
 }
 
-// -- Fill function for dynamic singleton. The value witness table flags just
-//    get copied over from the element.
+// -- Fill function for dynamic singleton.
 // CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_DynamicSingleton(%swift.type_pattern*, i8**) {{.*}} {
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   [[T:%T]] = load %swift.type*, %swift.type** [[T0]],
@@ -2692,48 +2696,17 @@
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 2
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* [[T]] to i8*
 // CHECK:   store i8* [[T0]], i8** [[T1]]
-// CHECK:   [[VWT:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 3
-// CHECK:   [[T0:%.*]] = bitcast i8** [[VWT]] to i8*
-// CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -1
-// CHECK:   store i8* [[T0]], i8** [[T1]]
 // CHECK:   [[T_VWTS:%.*]] = bitcast %swift.type* [[T]] to i8***
 // CHECK:   [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
 // CHECK:   [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
 // CHECK:   [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
-// CHECK:   [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
-// CHECK:   [[T_SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[T_LAYOUT]], i32 0
-// CHECK:   [[T_SIZE:%.*]] = load i8*, i8** [[T_SIZE_ADDR]]
-// CHECK:   store i8* [[T_SIZE]], i8** [[SIZE_ADDR]]
-// CHECK:   [[STRIDE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 11
-// CHECK:   [[T_STRIDE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[T_LAYOUT]], i32 2
-// CHECK:   [[T_STRIDE:%.*]] = load i8*, i8** [[T_STRIDE_ADDR]]
-// CHECK:   store i8* [[T_STRIDE]], i8** [[STRIDE_ADDR]]
-// CHECK:   [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
-// CHECK:   [[T_FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[T_LAYOUT]], i32 1
-// CHECK:   [[T_FLAGS:%.*]] = load i8*, i8** [[T_FLAGS_ADDR]]
-// CHECK:   [[T_FLAGS_INT:%.*]] = ptrtoint i8* [[T_FLAGS]] to [[WORD]]
-// CHECK:   [[T_FLAGS_INT_2:%.*]] = or [[WORD]] [[T_FLAGS_INT]], 2097152
-// CHECK:   [[T_FLAGS_2:%.*]] = inttoptr [[WORD]] [[T_FLAGS_INT_2]] to i8*
-// CHECK:   store i8* [[T_FLAGS_2]], i8** [[FLAGS_ADDR]]
-// -- Test the 'has extra inhabitants' bit and carry over the extra inhabitants
-//    flag if set.
-// CHECK:   [[T_FLAGS_VAL:%.*]] = ptrtoint i8* [[T_FLAGS]] to [[WORD]]
-// CHECK:   [[XI_FLAG:%.*]] = and [[WORD]] [[T_FLAGS_VAL]], 262144
-// CHECK:   [[XI_BIT:%.*]] = icmp ne [[WORD]] [[XI_FLAG]], 0
-// CHECK:   br i1 [[XI_BIT]], label %[[HAS_XI:[0-9]+]], label %[[HAS_NO_XI:[0-9]+]]
-// CHECK: ; <label>:[[HAS_XI]]
-// CHECK:   [[XI_FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 12
-// CHECK:   [[T_XI_FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[T_LAYOUT]], i32 3
-// CHECK:   [[T_XI_FLAGS:%.*]] = load i8*, i8** [[T_XI_FLAGS_ADDR]]
-// CHECK:   store i8* [[T_XI_FLAGS]], i8** [[XI_FLAGS_ADDR]]
-// CHECK:   br label %[[HAS_NO_XI]]
-// CHECK: ; <label>:[[HAS_NO_XI]]
+// CHECK:   call void @swift_initEnumMetadataSingleCase(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]])
 // CHECK:   ret %swift.type* [[METADATA]]
 
 // -- Fill function for dynamic single-payload. Call into the runtime to
 //    calculate the size.
 // CHECK-LABEL: define{{( protected)?}} private %swift.type* @create_generic_metadata_DynamicSinglePayload(%swift.type_pattern*, i8**) {{.*}} {
-// CHECK:   call void @swift_initEnumValueWitnessTableSinglePayload
+// CHECK:   call void @swift_initEnumMetadataSinglePayload(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]], i32 3)
 
 // CHECK-64-LABEL: define linkonce_odr hidden void @_T04enum17StructWithWeakVarVwxs(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
 // -- TODO: some pointless masking here.
diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil
index 53f5215..fea6b26 100644
--- a/test/IRGen/enum_dynamic_multi_payload.sil
+++ b/test/IRGen/enum_dynamic_multi_payload.sil
@@ -437,4 +437,4 @@
 // CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
 // CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF1]]
 
-// CHECK:   call void @swift_initEnumMetadataMultiPayload(i8** {{%.*}}, %swift.type* [[METADATA]], {{i(32|64)}} 2, i8*** [[BUF0]])
+// CHECK:   call void @swift_initEnumMetadataMultiPayload(%swift.type* [[METADATA]], {{i(32|64)}} 0, {{i(32|64)}} 2, i8*** [[BUF0]])
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index f82ffc3..14eb805 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -262,3 +262,4 @@
 }
 
 // CHECK-LABEL: define{{( protected)?}} private void @initialize_metadata_EnumWithResilientPayload(i8*)
+// CHECK: call void @swift_initEnumMetadataMultiPayload(%swift.type* {{.*}}, [[INT]] 256, [[INT]] 2, i8*** {{.*}})
diff --git a/test/IRGen/foreign_types.sil b/test/IRGen/foreign_types.sil
index 64d9669..89ef81f 100644
--- a/test/IRGen/foreign_types.sil
+++ b/test/IRGen/foreign_types.sil
@@ -4,9 +4,8 @@
 import c_layout
 
 // CHECK-LABEL: @_T0SC14HasNestedUnionV18__Unnamed_struct_sVN = linkonce_odr hidden global
-// CHECK-SAME:  i8* getelementptr inbounds
-// CHECK-SAME:  %swift.type* null,
-// CHECK-SAME:  [[INT:i[0-9]+]] 0,
+// CHECK-SAME:  [[INT:i[0-9]+]] sub ([[INT]] ptrtoint
+// CHECK-SAME:  [[INT]] 0,
 // CHECK-SAME:  @_T0SC14HasNestedUnionV18__Unnamed_struct_sVWV
 // CHECK-SAME:  [[INT]] 1,
 // CHECK-SAME:  @_T0SC14HasNestedUnionV18__Unnamed_struct_sVMn
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 6234bd8..6006411 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -6,7 +6,16 @@
 
 // -- Generic structs with dynamic layout contain the vwtable pattern as part
 //    of the metadata pattern, and no independent vwtable symbol
-// CHECK-NOT: @_T015generic_structs13SingleDynamicVWV
+// CHECK: @_T015generic_structs13SingleDynamicVWV = internal constant
+// CHECK-SAME:   i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_T015generic_structs13SingleDynamicVwCP to i8*),
+// -- ...
+// -- placeholder for size, flags, stride
+// CHECK-SAME:   i8* null, i8* null, i8* null
+// -- extra inhabitants
+// CHECK-SAME:   i8* null,
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T015generic_structs13SingleDynamicVwxs to i8*),
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T015generic_structs13SingleDynamicVwxg to i8*)]
+
 //    FIXME: Strings should be unnamed_addr. rdar://problem/22674524
 // CHECK: [[SINGLEDYNAMIC_NAME:@.*]] = private constant [34 x i8] c"15generic_structs13SingleDynamicV\00"
 // CHECK: [[SINGLEDYNAMIC_FIELDS:@.*]] = private constant [3 x i8] c"x\00\00"
@@ -35,23 +44,13 @@
 // CHECK: @_T015generic_structs13SingleDynamicVMP = internal global <{ {{.*}} }> <{
 // -- template header
 // CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_SingleDynamic,
-// CHECK-SAME:   i32 168, i16 1, i16 16, [{{[0-9]+}} x i8*] zeroinitializer,
-// -- placeholder for vwtable pointer
-// CHECK-SAME:   i8* null,
+// CHECK-SAME:   i32 48, i16 1, i16 16, [{{[0-9]+}} x i8*] zeroinitializer,
+// -- vwtable pointer
+// CHECK-SAME:   @_T015generic_structs13SingleDynamicVWV
 // -- address point
 // CHECK-SAME:   i64 1, {{.*}}* @_T015generic_structs13SingleDynamicVMn
 // -- field offset vector; generic parameter vector
-// CHECK-SAME:   i64 0, %swift.type* null,
-// -- tail-allocated vwtable pattern
-// CHECK-SAME:   i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_T015generic_structs13SingleDynamicVwCP to i8*),
-// -- ...
-// -- placeholder for size, flags, stride
-// CHECK-SAME:   i8* null, i8* null, i8* null
-// -- extra inhabitants
-// CHECK-SAME:   i8* null,
-// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T015generic_structs13SingleDynamicVwxs to i8*),
-// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T015generic_structs13SingleDynamicVwxg to i8*)] }>
-// CHECK-NOT: @_T015generic_structs13SingleDynamicVWV
+// CHECK-SAME:   i64 0, %swift.type* null }>
 
 // -- Nominal type descriptor for generic struct with protocol requirements
 //    FIXME: Strings should be unnamed_addr. rdar://problem/22674524
@@ -82,8 +81,7 @@
 
 // CHECK: @_T015generic_structs23DynamicWithRequirementsVMP = internal global <{ {{.*}} }> <{
 // -- field offset vector; generic parameter vector
-// CHECK:   i64 0, i64 0, %swift.type* null, %swift.type* null, i8** null, i8** null,
-// CHECK: }>
+// CHECK:   i64 0, i64 0, %swift.type* null, %swift.type* null, i8** null, i8** null }>
 
 // -- Fixed-layout struct metadata contains fixed field offsets
 // CHECK: @_T015generic_structs6IntishVMf = internal constant <{ {{.*}} i64 }> <{
@@ -219,16 +217,11 @@
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 3
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %T to i8*
 // CHECK:   store i8* [[T0]], i8** [[T1]], align 8
-//   Fill vwtable reference.
-// CHECK:   [[VWTABLE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 4
-// CHECK:   [[VWTABLE_VAL:%.*]] = bitcast i8** [[VWTABLE_ADDR]] to i8*
-// CHECK:   [[VWTABLE_SLOT_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 -1
-// CHECK:   store i8* [[VWTABLE_VAL]], i8** [[VWTABLE_SLOT_ADDR]], align 8
 //   Lay out fields.
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i64*
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i64, i64* [[T0]], i64 2
 // CHECK:   [[T2:%.*]] = getelementptr inbounds i8**, i8*** [[TYPES:%.*]], i32 0
-// CHECK:   call void @swift_initStructMetadata_UniversalStrategy(i64 1, i8*** [[TYPES]], i64* [[T1]], i8** [[VWTABLE_ADDR]])
+// CHECK:   call void @swift_initStructMetadata(%swift.type* [[METADATA]], i64 0, i64 1, i8*** [[TYPES]], i64* [[T1]])
 // CHECK:   ret %swift.type* [[METADATA]]
 // CHECK: }
 
diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift
index bf3eb6f..8a28b8f 100644
--- a/test/IRGen/generic_types.swift
+++ b/test/IRGen/generic_types.swift
@@ -23,8 +23,8 @@
 // CHECK-native-SAME: %swift.opaque* null,
 // CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
 // CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 1,
-// CHECK-SAME:   i32 3,
+// CHECK-SAME:   i64 {{1|2}},
+// CHECK-SAME:   i32 2,
 // CHECK-SAME:   i32 0,
 // CHECK-SAME:   i32 24,
 // CHECK-SAME:   i16 7,
@@ -52,8 +52,8 @@
 // CHECK-native-SAME: %swift.opaque* null,
 // CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
 // CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 1,
-// CHECK-SAME:   i32 3,
+// CHECK-SAME:   i64 {{1|2}},
+// CHECK-SAME:   i32 2,
 // CHECK-SAME:   i32 0,
 // CHECK-SAME:   i32 24,
 // CHECK-SAME:   i16 7,
@@ -74,8 +74,8 @@
 // CHECK-native-SAME: %swift.opaque* null,
 // CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
 // CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 1,
-// CHECK-SAME:   i32 3,
+// CHECK-SAME:   i64 {{1|2}},
+// CHECK-SAME:   i32 2,
 // CHECK-SAME:   i32 0,
 // CHECK-SAME:   i32 24,
 // CHECK-SAME:   i16 7,
@@ -96,8 +96,8 @@
 // CHECK-native-SAME: %swift.opaque* null,
 // CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
 // CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 1,
-// CHECK-SAME:   i32 3,
+// CHECK-SAME:   i64 {{1|2}},
+// CHECK-SAME:   i32 2,
 // CHECK-SAME:   i32 0,
 // CHECK-SAME:   i32 24,
 // CHECK-SAME:   i16 7,
diff --git a/test/IRGen/indirect_return.swift b/test/IRGen/indirect_return.swift
index 1633bd5..147df3a 100644
--- a/test/IRGen/indirect_return.swift
+++ b/test/IRGen/indirect_return.swift
@@ -9,3 +9,18 @@
   // CHECK: call %swift.opaque* {{%.*}}(%swift.opaque* noalias %0, %swift.opaque* noalias [[T1]], %swift.type* %T)
   return p.pointee
 }
+
+
+protocol Number {}
+extension Int: Number {}
+
+// Make sure that the absence of the sret attribute matches.
+// CHECK: define hidden swiftcc void @_T015indirect_return3fooSS_S2SAA6Number_pAaC_ptyF(<{ %TSS, %TSS, %TSS }>* noalias nocapture
+func foo() -> (String, String, String, Number, Number) {
+    return ("1", "2", "3", 42, 7)
+}
+// CHECK-LABEL: define{{.*}}testCall
+func testCall() {
+// CHECK: call swiftcc void @_T015indirect_return3fooSS_S2SAA6Number_pAaC_ptyF(<{ %TSS, %TSS, %TSS }>* noalias nocapture %{{.*}}
+  print(foo())
+}
diff --git a/test/IRGen/ivar_destroyer.sil b/test/IRGen/ivar_destroyer.sil
index d26c81c..e8014e8 100644
--- a/test/IRGen/ivar_destroyer.sil
+++ b/test/IRGen/ivar_destroyer.sil
@@ -14,8 +14,8 @@
 // \ CHECK:   [[TYPE]]* bitcast (i64* getelementptr inbounds (<{ {{.*}} }>, <{ {{.*}} }>* @_T014ivar_destroyer11TrivialBaseCMf, i32 0, i32 2) to [[TYPE]]*),
 // \ CHECK:   [[OPAQUE]]* @_objc_empty_cache,
 // \ CHECK:   [[OPAQUE]]* null,
-// \ CHECK:   i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC14ivar_destroyer17NonTrivialDerived to i64), i64 1),
-// \ CHECK:   i32 3,
+// \ CHECK:   i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC14ivar_destroyer17NonTrivialDerived to i64), i64 {{1|2}}),
+// \ CHECK:   i32 2,
 // \ CHECK:   i32 0,
 // \ CHECK:   i32 24,
 // \ CHECK:   i16 7,
diff --git a/test/IRGen/objc_attr_NSManaged.sil b/test/IRGen/objc_attr_NSManaged.sil
index 98c08c2..cafd182 100644
--- a/test/IRGen/objc_attr_NSManaged.sil
+++ b/test/IRGen/objc_attr_NSManaged.sil
@@ -27,7 +27,7 @@
 // The getter/setter should not show up in the Swift metadata.
 /* FIXME: sil_vtable parser picks the wrong 'init' overload. Both vtable entries
    ought to be nonnull here. rdar://problem/19572342 */
-// CHECK: @_T019objc_attr_NSManaged10SwiftGizmoCMf = internal global <{ {{.*}} }> <{ void (%T19objc_attr_NSManaged10SwiftGizmoC*)* @_T019objc_attr_NSManaged10SwiftGizmoCfD, i8** @_T0BOWV, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC19objc_attr_NSManaged10SwiftGizmo" to i64), %objc_class* @"OBJC_CLASS_$_Gizmo", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [2 x { i8*, i8*, i8* }] }*, i8*, i8*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC19objc_attr_NSManaged10SwiftGizmo to i64), i64 1), i32 1, i32 0, i32 8, i16 7, i16 0, i32 112, i32 16, {{.*}}* @_T019objc_attr_NSManaged10SwiftGizmoCMn, i8* null, %T19objc_attr_NSManaged10SwiftGizmoC* (i64, %T19objc_attr_NSManaged10SwiftGizmoC*)* @_T019objc_attr_NSManaged10SwiftGizmoC7bellsOnACSi_tcfc, i8* bitcast (void ()* @swift_deletedMethodError to i8*) }>
+// CHECK: @_T019objc_attr_NSManaged10SwiftGizmoCMf = internal global <{ {{.*}} }> <{ void (%T19objc_attr_NSManaged10SwiftGizmoC*)* @_T019objc_attr_NSManaged10SwiftGizmoCfD, i8** @_T0BOWV, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC19objc_attr_NSManaged10SwiftGizmo" to i64), %objc_class* @"OBJC_CLASS_$_Gizmo", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [2 x { i8*, i8*, i8* }] }*, i8*, i8*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC19objc_attr_NSManaged10SwiftGizmo to i64), i64 {{1|2}}), i32 0, i32 0, i32 8, i16 7, i16 0, i32 112, i32 16, {{.*}}* @_T019objc_attr_NSManaged10SwiftGizmoCMn, i8* null, %T19objc_attr_NSManaged10SwiftGizmoC* (i64, %T19objc_attr_NSManaged10SwiftGizmoC*)* @_T019objc_attr_NSManaged10SwiftGizmoC7bellsOnACSi_tcfc, i8* bitcast (void ()* @swift_deletedMethodError to i8*) }>
 
 @objc class SwiftGizmo : Gizmo {
   @objc @NSManaged var x: X
diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift
index 85105ca..a06fbd6 100644
--- a/test/IRGen/struct_resilience.swift
+++ b/test/IRGen/struct_resilience.swift
@@ -170,7 +170,6 @@
 
 // CHECK-LABEL: define{{( protected)?}} private void @initialize_metadata_StructWithResilientStorage(i8*)
 // CHECK: [[FIELDS:%.*]] = alloca [4 x i8**]
-// CHECK: [[VWT:%.*]] = load i8**, i8*** getelementptr inbounds ({{.*}} @_T017struct_resilience26StructWithResilientStorageVMf{{.*}}, [[INT]] -1)
 
 // CHECK: [[FIELDS_ADDR:%.*]] = getelementptr inbounds [4 x i8**], [4 x i8**]* [[FIELDS]], i32 0, i32 0
 
@@ -195,6 +194,6 @@
 // CHECK: [[FIELD_4:%.*]] = getelementptr inbounds i8**, i8*** [[FIELDS_ADDR]], i32 3
 // CHECK: store i8** [[SIZE_AND_ALIGNMENT:%.*]], i8*** [[FIELD_4]]
 
-// CHECK: call void @swift_initStructMetadata_UniversalStrategy([[INT]] 4, i8*** [[FIELDS_ADDR]], [[INT]]* {{.*}}, i8** [[VWT]])
+// CHECK: call void @swift_initStructMetadata(%swift.type* {{.*}}, [[INT]] 256, [[INT]] 4, i8*** [[FIELDS_ADDR]], [[INT]]* {{.*}})
 // CHECK: store atomic %swift.type* {{.*}} @_T017struct_resilience26StructWithResilientStorageVMf{{.*}}, %swift.type** @_T017struct_resilience26StructWithResilientStorageVML release,
 // CHECK: ret void
diff --git a/test/IRGen/vtable.sil b/test/IRGen/vtable.sil
index 3234030..dc451a0 100644
--- a/test/IRGen/vtable.sil
+++ b/test/IRGen/vtable.sil
@@ -26,8 +26,8 @@
 // CHECK-objc: %objc_class* @"OBJC_CLASS_$_SwiftObject",
 // CHECK-objc: %swift.opaque* @_objc_empty_cache,
 // CHECK-objc: %swift.opaque* null,
-// CHECK-objc: i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_DATA__TtC6vtable1C to i64), i64 1),
-// CHECK-objc: i32 3, i32 0, i32 16, i16 7, i16 0,
+// CHECK-objc: i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_DATA__TtC6vtable1C to i64), i64 {{1|2}}),
+// CHECK-objc: i32 2, i32 0, i32 16, i16 7, i16 0,
 // CHECK-objc: i32 112, i32 16,
 // CHECK-objc: @_T06vtable1CCMn
 // CHECK-objc: [[C]]* (%swift.type*)* @_T06vtable1CCACycACmcfC,
@@ -42,7 +42,7 @@
 // CHECK-native: %swift.opaque* null,
 // CHECK-native: %swift.opaque* null,
 // CHECK-native: i64 1,
-// CHECK-native: i32 3, i32 0, i32 16, i16 7, i16 0,
+// CHECK-native: i32 2, i32 0, i32 16, i16 7, i16 0,
 // CHECK-native: i32 112, i32 16,
 // CHECK-native: @_T06vtable1CCMn
 // CHECK-native: [[C]]* (%swift.type*)* @_T06vtable1CCACycACmcfC,
diff --git a/test/IRGen/witness_method.sil b/test/IRGen/witness_method.sil
index 3669da7..09cd5e3 100644
--- a/test/IRGen/witness_method.sil
+++ b/test/IRGen/witness_method.sil
@@ -110,7 +110,7 @@
   func disrupt() -> GrowthHack
 }
 
-// CHECK-LABEL: define{{( protected)?}} swiftcc void @classArchetypeWitnessMethod(%swift.type* %CoverSheet, %T14witness_method9TPSReportC** noalias nocapture swiftself dereferenceable({{4|8}}), %swift.type* %Self, i8** %SelfWitnessTable)
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @classArchetypeWitnessMethod(%T14witness_method9TPSReportC** noalias nocapture swiftself dereferenceable({{4|8}}), %swift.type* %Self, i8** %SelfWitnessTable)
 
 sil @classArchetypeWitnessMethod : $@convention(witness_method: Strategy) <T><CoverSheet where T : TPSReport<CoverSheet>> (@in_guaranteed T) -> () {
 entry(%self : $*T):
diff --git a/test/Interpreter/enforce_exclusive_access.swift b/test/Interpreter/enforce_exclusive_access.swift
index 40fd5bf..3d17b75 100644
--- a/test/Interpreter/enforce_exclusive_access.swift
+++ b/test/Interpreter/enforce_exclusive_access.swift
@@ -104,66 +104,6 @@
   globalX = X() // no-trap
 }
 
-// FIXME: This should be covered by static diagnostics.
-// Once this radar is fixed, confirm that a it is covered by a static diagnostic
-// (-verify) test in exclusivity_static_diagnostics.sil.
-// <rdar://problem/32061282> Enforce exclusive access in noescape closures.
-//
-//ExclusiveAccessTestSuite.test("ClosureCaptureModifyModify")
-//.skip(.custom(
-//    { _isFastAssertConfiguration() },
-//    reason: "this trap is not guaranteed to happen in -Ounchecked"))
-//  .crashOutputMatches("Previous access (a modification) started at")
-//  .crashOutputMatches("Current access (a modification) started at")
-//  .code
-//{
-//  var x = X()
-//  modifyAndPerform(&x) {
-//    expectCrashLater()
-//    x.i = 12
-//  }
-//}
-
-// FIXME: This should be covered by static diagnostics.
-// Once this radar is fixed, confirm that a it is covered by a static diagnostic
-// (-verify) test in exclusivity_static_diagnostics.sil.
-// <rdar://problem/32061282> Enforce exclusive access in noescape closures.
-//
-//ExclusiveAccessTestSuite.test("ClosureCaptureReadModify")
-//.skip(.custom(
-//    { _isFastAssertConfiguration() },
-//    reason: "this trap is not guaranteed to happen in -Ounchecked"))
-//  .crashOutputMatches("Previous access (a read) started at")
-//  .crashOutputMatches("Current access (a modification) started at")
-//  .code
-//{
-//  var x = X()
-//  modifyAndPerform(&x) {
-//    expectCrashLater()
-//    _blackHole(x.i)
-//  }
-//}
-
-// FIXME: This should be covered by static diagnostics.
-// Once this radar is fixed, confirm that a it is covered by a static diagnostic
-// (-verify) test in exclusivity_static_diagnostics.sil.
-// <rdar://problem/32061282> Enforce exclusive access in noescape closures.
-//
-//ExclusiveAccessTestSuite.test("ClosureCaptureModifyRead")
-//.skip(.custom(
-//    { _isFastAssertConfiguration() },
-//    reason: "this trap is not guaranteed to happen in -Ounchecked"))
-//  .crashOutputMatches("Previous access (a modification) started at")
-//  .crashOutputMatches("Current access (a read) started at")
-//  .code
-//{
-//  var x = X()
-//  readAndPerform(&x) {
-//    expectCrashLater()
-//    x.i = 12
-//  }
-//}
-
 ExclusiveAccessTestSuite.test("ClosureCaptureReadRead") {
   var x = X()
   readAndPerform(&x) {
@@ -301,4 +241,27 @@
   doOne { modifyAndPerform(&x, closure: c) }
 }
 
+class ClassWithStoredProperty {
+  var f = 7
+}
+
+// FIXME: This should trap with a modify/modify violation at run time.
+ExclusiveAccessTestSuite.test("KeyPathClassStoredProp")
+  .skip(.custom(
+    { _isFastAssertConfiguration() },
+    reason: "this trap is not guaranteed to happen in -Ounchecked"))
+//  .crashOutputMatches("Previous access (a modification) started at")
+//  .crashOutputMatches("Current access (a modification) started at")
+  .code
+{
+  let getF = \ClassWithStoredProperty.f
+  let c = ClassWithStoredProperty()
+
+//  expectCrashLater()
+  modifyAndPerform(&c[keyPath: getF]) {
+    c[keyPath: getF] = 12
+  }
+}
+
+
 runAllTests()
diff --git a/test/Interpreter/functions.swift b/test/Interpreter/functions.swift
index 891948b..9238a20 100644
--- a/test/Interpreter/functions.swift
+++ b/test/Interpreter/functions.swift
@@ -42,3 +42,13 @@
 foo(D())
 // CHECK: Right
 bar(D())
+
+protocol Number {}
+extension Int: Number {}
+
+func foo() -> (String, String, String, Number, Number) {
+    return ("1", "2", "3", 42, 7)
+}
+
+// CHECK: ("1", "2", "3", 42, 7)
+print(foo())
diff --git a/test/Interpreter/protocol_extensions.swift b/test/Interpreter/protocol_extensions.swift
index ab001b7..1b15052 100644
--- a/test/Interpreter/protocol_extensions.swift
+++ b/test/Interpreter/protocol_extensions.swift
@@ -315,6 +315,8 @@
 
 class SelfMetadataDerived : SelfMetadataBase {}
 
+class SelfMetadataGeneric<T> : SelfMetadataTest {}
+
 func testSelfMetadata<T : SelfMetadataTest>(_ x: T, _ t: T.T) -> [Any.Type] {
   return [x.staticTypeOfSelf(),
           x.staticTypeOfSelfTakesT(t),
@@ -348,6 +350,16 @@
     expectTrue(SelfMetadataDerived.self == result[2])
     expectTrue(SelfMetadataDerived.self == result[3])
   }
+
+  // Make sure the calling convention works out if 'Self' is a generic
+  // class too.
+  do {
+    let result = testSelfMetadata(SelfMetadataGeneric<Int>(), 0)
+    expectTrue(SelfMetadataGeneric<Int>.self == result[0])
+    expectTrue(SelfMetadataGeneric<Int>.self == result[1])
+    expectTrue(SelfMetadataGeneric<Int>.self == result[2])
+    expectTrue(SelfMetadataGeneric<Int>.self == result[3])
+  }
 }
 
 runAllTests()
diff --git a/test/SILGen/default_arguments.swift b/test/SILGen/default_arguments.swift
index e6c6408..41e7f26 100644
--- a/test/SILGen/default_arguments.swift
+++ b/test/SILGen/default_arguments.swift
@@ -12,7 +12,7 @@
 // CHECK-LABEL: sil hidden @_T017default_arguments7defarg11i1d1sySi_SdSStFfA_ : $@convention(thin) () -> Int
 // CHECK: [[INT:%[0-9]+]] = metatype $@thin Int.Type
 // CHECK: [[LIT:%[0-9]+]] = integer_literal $Builtin.Int2048, 17
-// CHECK: [[CVT:%[0-9]+]] = function_ref @_T0Si22_builtinIntegerLiteralSiBi2048__tcfC
+// CHECK: [[CVT:%[0-9]+]] = function_ref @_T0Si22_builtinIntegerLiteralSiBi{{[_0-9]*}}__tcfC
 // CHECK: [[RESULT:%[0-9]+]] = apply [[CVT]]([[LIT]], [[INT]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
 // CHECK: return [[RESULT]] : $Int
 
@@ -30,7 +30,7 @@
 func testDefaultArg1() {
   // CHECK: [[FLOAT64:%[0-9]+]] = metatype $@thin Double.Type
   // CHECK: [[FLOATLIT:%[0-9]+]] = float_literal $Builtin.FPIEEE{{64|80}}, {{0x4009000000000000|0x4000C800000000000000}}
-  // CHECK: [[LITFN:%[0-9]+]] = function_ref @_T0Sd20_builtinFloatLiteralSdBf80__tcfC
+  // CHECK: [[LITFN:%[0-9]+]] = function_ref @_T0Sd20_builtinFloatLiteralSdBf{{[_0-9]*}}__tcfC
   // CHECK: [[FLOATVAL:%[0-9]+]] = apply [[LITFN]]([[FLOATLIT]], [[FLOAT64]])
   // CHECK: [[DEF0FN:%[0-9]+]] = function_ref @_T017default_arguments7defarg1{{.*}}A_
   // CHECK: [[DEF0:%[0-9]+]] = apply [[DEF0FN]]()
@@ -47,7 +47,7 @@
 func testDefaultArg2() {
 // CHECK:  [[INT64:%[0-9]+]] = metatype $@thin Int.Type
 // CHECK:  [[INTLIT:%[0-9]+]] = integer_literal $Builtin.Int2048, 5
-// CHECK:  [[LITFN:%[0-9]+]] = function_ref @_T0Si22_builtinIntegerLiteralSiBi2048__tcfC
+// CHECK:  [[LITFN:%[0-9]+]] = function_ref @_T0Si22_builtinIntegerLiteralSiBi{{[_0-9]*}}__tcfC
 // CHECK:  [[I:%[0-9]+]] = apply [[LITFN]]([[INTLIT]], [[INT64]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
 // CHECK:  [[DFN:%[0-9]+]] = function_ref @_T017default_arguments7defarg2{{.*}}A0_ : $@convention(thin) () -> Double
 // CHECK:  [[D:%[0-9]+]] = apply [[DFN]]() : $@convention(thin) () -> Double
diff --git a/test/SILOptimizer/exclusivity_static_diagnostics.swift b/test/SILOptimizer/exclusivity_static_diagnostics.swift
index 6c0a94c..99a0d25 100644
--- a/test/SILOptimizer/exclusivity_static_diagnostics.swift
+++ b/test/SILOptimizer/exclusivity_static_diagnostics.swift
@@ -64,6 +64,7 @@
 class ClassWithFinalStoredProp {
   final var s1: StructWithMutatingMethodThatTakesSelfInout = StructWithMutatingMethodThatTakesSelfInout()
   final var s2: StructWithMutatingMethodThatTakesSelfInout = StructWithMutatingMethodThatTakesSelfInout()
+  final var i = 7
 
   func callMutatingMethodThatTakesClassStoredPropInout() {
     s1.mutate(&s2.f) // no-warning
@@ -195,6 +196,13 @@
   }
 }
 
+func callsTakesInoutAndNoEscapeClosureWithRead() {
+  var local = 5
+  takesInoutAndNoEscapeClosure(&local) { // expected-error {{overlapping accesses to 'local', but modification requires exclusive access; consider copying to a local variable}}
+    _ = local  // expected-note {{conflicting access is here}}
+  }
+}
+
 func takesInoutAndNoEscapeClosureThatThrows<T>(_ p: inout T, _ c: () throws -> ()) { }
 
 func callsTakesInoutAndNoEscapeClosureThatThrowsWithNonThrowingClosure() {
@@ -252,8 +260,15 @@
 }
 
 
+// Calling this with an inout expression for the first parameter performs a
+// read access for the duration of a call
 func takesUnsafePointerAndNoEscapeClosure<T>(_ p: UnsafePointer<T>, _ c: () -> ()) { }
 
+// Calling this with an inout expression for the first parameter performs a
+// modify access for the duration of a call
+func takesUnsafeMutablePointerAndNoEscapeClosure<T>(_ p: UnsafeMutablePointer<T>, _ c: () -> ()) { }
+
+
 func callsTakesUnsafePointerAndNoEscapeClosure() {
   var local = 1
   takesUnsafePointerAndNoEscapeClosure(&local) { // expected-note {{conflicting access is here}}
@@ -261,6 +276,24 @@
   }
 }
 
+func callsTakesUnsafePointerAndNoEscapeClosureThatReads() {
+  var local = 1
+
+  // Overlapping reads
+  takesUnsafePointerAndNoEscapeClosure(&local) {
+     _ = local // no-error
+  }
+}
+
+func callsTakesUnsafeMutablePointerAndNoEscapeClosureThatReads() {
+  var local = 1
+
+  // Overlapping modify and read
+  takesUnsafeMutablePointerAndNoEscapeClosure(&local) { // expected-error {{overlapping accesses to 'local', but modification requires exclusive access; consider copying to a local variable}}
+     _ = local  // expected-note {{conflicting access is here}}
+  }
+
+}
 func takesThrowingAutoClosureReturningGeneric<T: Equatable>(_ : @autoclosure () throws -> T) { }
 func takesInoutAndClosure<T>(_: inout T, _ : () -> ()) { }
 
@@ -468,3 +501,29 @@
     // expected-note@-2{{conflicting access is here}}
   }
 }
+
+
+func testForLoopCausesReadAccess() {
+  var a: [Int] = [1]
+  takesInoutAndNoEscapeClosure(&a) { // expected-error {{overlapping accesses to 'a', but modification requires exclusive access; consider copying to a local variable}}
+    for _ in a { // expected-note {{conflicting access is here}}
+    }
+  }
+}
+
+func testKeyPathStructField() {
+  let getF = \StructWithField.f
+  var local = StructWithField()
+  takesInoutAndNoEscapeClosure(&local[keyPath: getF]) { // expected-error {{overlapping accesses to 'local', but modification requires exclusive access; consider copying to a local variable}}
+    local.f = 17 // expected-note {{conflicting access is here}}
+  }
+}
+
+func testKeyPathWithClassFinalStoredProperty() {
+  let getI = \ClassWithFinalStoredProp.i
+  let local = ClassWithFinalStoredProp()
+
+  // Ideally we would diagnose statically here, but it is not required by the
+  // model.
+  takesTwoInouts(&local[keyPath: getI], &local[keyPath: getI])
+}
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 0a0f4ce..394bf76 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -34,6 +34,7 @@
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>bar2</IdentifierExpr>(<FunctionCallArgument>a : <IdentifierExpr>bar2</IdentifierExpr>(<FunctionCallArgument>a: <IntegerLiteralExpr>1</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>b: <IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c: <IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>), </FunctionCallArgument><FunctionCallArgument>b: <IntegerLiteralExpr>2</IntegerLiteralExpr>, </FunctionCallArgument><FunctionCallArgument>c: <IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>)</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a : <IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a: <IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a: <IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallArgument>)</FunctionCallArgument>)</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>bar4</IdentifierExpr>(<FunctionCallArgument><IdentifierExpr>bar4</IdentifierExpr>(<FunctionCallArgument><IdentifierExpr>bar4</IdentifierExpr>(<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallArgument>)</FunctionCallArgument>)</SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><DictionaryExpr>[:]</DictionaryExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ArrayExpr>[<ArrayElement><IntegerLiteralExpr>1</IntegerLiteralExpr>, </ArrayElement><ArrayElement><IntegerLiteralExpr>2</IntegerLiteralExpr>, </ArrayElement><ArrayElement><IntegerLiteralExpr>3</IntegerLiteralExpr>, </ArrayElement><ArrayElement><IntegerLiteralExpr>4</IntegerLiteralExpr></ArrayElement>]</ArrayExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><DictionaryExpr>[<DictionaryElement><IntegerLiteralExpr>1</IntegerLiteralExpr>:<IntegerLiteralExpr>1</IntegerLiteralExpr>, </DictionaryElement><DictionaryElement><IntegerLiteralExpr>2</IntegerLiteralExpr>:<IntegerLiteralExpr>2</IntegerLiteralExpr>, </DictionaryElement><DictionaryElement><IntegerLiteralExpr>3</IntegerLiteralExpr>:<IntegerLiteralExpr>3</IntegerLiteralExpr>, </DictionaryElement><DictionaryElement><IntegerLiteralExpr>4</IntegerLiteralExpr>:<IntegerLiteralExpr>4</IntegerLiteralExpr></DictionaryElement>]</DictionaryExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ArrayExpr>[<ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </ArrayElement><ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </ArrayElement><ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>), </ArrayElement><ArrayElement><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</ArrayElement>]</ArrayExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
@@ -49,10 +50,10 @@
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TupleExpr>(<TupleElement><IntegerLiteralExpr>1</IntegerLiteralExpr>, </TupleElement><TupleElement><IntegerLiteralExpr>2</IntegerLiteralExpr></TupleElement>)</TupleExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TupleExpr>(<TupleElement>first: <IntegerLiteralExpr>1</IntegerLiteralExpr>, </TupleElement><TupleElement>second: <IntegerLiteralExpr>2</IntegerLiteralExpr></TupleElement>)</TupleExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TupleExpr>(<TupleElement><IntegerLiteralExpr>1</IntegerLiteralExpr></TupleElement>)</TupleExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TupleExpr>(<TupleElement>first: <IntegerLiteralExpr>1</IntegerLiteralExpr></TupleElement>)</TupleExpr></SequenceExpr>
-    if <PrefixOperatorExpr>!<BooleanLiteralExpr>true </BooleanLiteralExpr></PrefixOperatorExpr><CodeBlock>{<ReturnStmt>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><TupleExpr>(<TupleElement>first: <IntegerLiteralExpr>1</IntegerLiteralExpr></TupleElement>)</TupleExpr></SequenceExpr><IfStmt>
+    if <ConditionElement><PrefixOperatorExpr>!<BooleanLiteralExpr>true </BooleanLiteralExpr></PrefixOperatorExpr></ConditionElement><CodeBlock>{<ReturnStmt>
       return</ReturnStmt>
-    }</CodeBlock>
+    }</CodeBlock></IfStmt>
   }</CodeBlock></FunctionDecl><FunctionDecl>
 
   func foo3<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
@@ -213,6 +214,71 @@
 
 class C <MemberDeclBlock>{<VariableDecl><Attribute>
   @objc</Attribute><DeclModifier>
-  static </DeclModifier><DeclModifier>private </DeclModifier>var <PatternBinding><IdentifierPattern>a</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><InitializerClause>= <IntegerLiteralExpr>3 </IntegerLiteralExpr></InitializerClause><AccessorBlock>{ <ReturnStmt>return <IntegerLiteralExpr>3 </IntegerLiteralExpr></ReturnStmt>}</AccessorBlock>, </PatternBinding><PatternBinding><IdentifierPattern>b</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TypeAnnotation>, </PatternBinding><PatternBinding><IdentifierPattern>c </IdentifierPattern><InitializerClause>= <IntegerLiteralExpr>4</IntegerLiteralExpr></InitializerClause>, </PatternBinding><PatternBinding><IdentifierPattern>d </IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><AccessorBlock>{ <AccessorDecl>get <CodeBlock>{} </CodeBlock></AccessorDecl><AccessorDecl>get <CodeBlock>{}</CodeBlock></AccessorDecl>}</AccessorBlock>, </PatternBinding><PatternBinding>(<IdentifierPattern>a</IdentifierPattern>, <IdentifierPattern>b</IdentifierPattern>)<TypeAnnotation>: <TupleType>(<TupleTypeElement><SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </TupleTypeElement><TupleTypeElement><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TupleTypeElement>)</TupleType></TypeAnnotation></PatternBinding></VariableDecl><VariableDecl>
-  let <PatternBinding>(<IdentifierPattern>a</IdentifierPattern>, <IdentifierPattern>b</IdentifierPattern>) <InitializerClause>= <TupleExpr>(<TupleElement><IntegerLiteralExpr>1</IntegerLiteralExpr>,</TupleElement><TupleElement><IntegerLiteralExpr>2</IntegerLiteralExpr></TupleElement>)</TupleExpr></InitializerClause>, </PatternBinding><PatternBinding>_ <InitializerClause>= <IntegerLiteralExpr>4 </IntegerLiteralExpr></InitializerClause><AccessorBlock>{}</AccessorBlock></PatternBinding></VariableDecl>
-}</MemberDeclBlock></ClassDecl>
+  static </DeclModifier><DeclModifier>private </DeclModifier>var <PatternBinding><IdentifierPattern>a</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><InitializerClause>= <IntegerLiteralExpr>3 </IntegerLiteralExpr></InitializerClause><AccessorBlock>{ <ReturnStmt>return <IntegerLiteralExpr>3 </IntegerLiteralExpr></ReturnStmt>}</AccessorBlock>, </PatternBinding><PatternBinding><IdentifierPattern>b</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TypeAnnotation>, </PatternBinding><PatternBinding><IdentifierPattern>c </IdentifierPattern><InitializerClause>= <IntegerLiteralExpr>4</IntegerLiteralExpr></InitializerClause>, </PatternBinding><PatternBinding><IdentifierPattern>d </IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><AccessorBlock>{ <AccessorDecl>get <CodeBlock>{} </CodeBlock></AccessorDecl><AccessorDecl>get <CodeBlock>{}</CodeBlock></AccessorDecl>}</AccessorBlock>, </PatternBinding><PatternBinding><TuplePattern>(<TuplePatternElement><IdentifierPattern>a</IdentifierPattern>, </TuplePatternElement><TuplePatternElement><IdentifierPattern>b</IdentifierPattern></TuplePatternElement>)</TuplePattern><TypeAnnotation>: <TupleType>(<TupleTypeElement><SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </TupleTypeElement><TupleTypeElement><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TupleTypeElement>)</TupleType></TypeAnnotation></PatternBinding></VariableDecl><VariableDecl>
+  let <PatternBinding><TuplePattern>(<TuplePatternElement><IdentifierPattern>a</IdentifierPattern>, </TuplePatternElement><TuplePatternElement><IdentifierPattern>b</IdentifierPattern></TuplePatternElement>) </TuplePattern><InitializerClause>= <TupleExpr>(<TupleElement><IntegerLiteralExpr>1</IntegerLiteralExpr>,</TupleElement><TupleElement><IntegerLiteralExpr>2</IntegerLiteralExpr></TupleElement>)</TupleExpr></InitializerClause>, </PatternBinding><PatternBinding><WildcardPattern>_ </WildcardPattern><InitializerClause>= <IntegerLiteralExpr>4 </IntegerLiteralExpr></InitializerClause><AccessorBlock>{}</AccessorBlock></PatternBinding></VariableDecl><FunctionDecl>
+
+  func patternTests<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<ForInStmt>
+    for <ValueBindingPattern>let <TuplePattern>(<TuplePatternElement><IdentifierPattern>x</IdentifierPattern>, </TuplePatternElement><TuplePatternElement><WildcardPattern>_</WildcardPattern></TuplePatternElement>) </TuplePattern></ValueBindingPattern>in <IdentifierExpr>foo </IdentifierExpr><CodeBlock>{}</CodeBlock></ForInStmt><ForInStmt>
+    for <ValueBindingPattern>var <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation>in <IdentifierExpr>foo </IdentifierExpr><CodeBlock>{}</CodeBlock></ForInStmt>
+  }</CodeBlock></FunctionDecl>
+}</MemberDeclBlock></ClassDecl><DoStmt>
+
+do <CodeBlock>{
+  switch <IdentifierExpr>foo </IdentifierExpr>{
+    case <ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
+    case <ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
+    case <ValueBindingPattern>let <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><IdentifierPattern>b</IdentifierPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
+    case <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>b</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern>: <BreakStmt>break</BreakStmt>
+    case <IsTypePattern>is <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></IsTypePattern>: <BreakStmt>break</BreakStmt>
+    case <ValueBindingPattern>let <ExpressionPattern>.bar(<FunctionCallArgument><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr></FunctionCallArgument>)</ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
+    case <ExpressionPattern><MemberAccessExpr><IdentifierExpr>MyEnum</IdentifierExpr>.foo</MemberAccessExpr></ExpressionPattern>: <BreakStmt>break</BreakStmt>
+    case <ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
+    case <ValueBindingPattern>let <ExpressionPattern><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>?</ExpressionPattern></ValueBindingPattern>: <BreakStmt>break</BreakStmt>
+  }
+}</CodeBlock></DoStmt><FunctionDecl>
+
+func statementTests<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<DoStmt>
+  do <CodeBlock>{
+  } </CodeBlock><CatchClause>catch <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>y</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleElement>) </TupleExpr></ExpressionPattern><CodeBlock>{
+  } </CodeBlock></CatchClause><CatchClause>catch <WhereClause>where <BooleanLiteralExpr>false </BooleanLiteralExpr></WhereClause><CodeBlock>{
+  } </CodeBlock></CatchClause><CatchClause>catch <ValueBindingPattern>let <IdentifierPattern>e </IdentifierPattern></ValueBindingPattern><WhereClause>where <SequenceExpr><MemberAccessExpr><IdentifierExpr>e</IdentifierExpr>.foo </MemberAccessExpr><BinaryOperatorExpr>== </BinaryOperatorExpr><IdentifierExpr>bar </IdentifierExpr></SequenceExpr></WhereClause><CodeBlock>{
+  } </CodeBlock></CatchClause><CatchClause>catch <CodeBlock>{
+  }</CodeBlock></CatchClause></DoStmt><RepeatWhileStmt>
+  repeat <CodeBlock>{ } </CodeBlock>while <BooleanLiteralExpr>true</BooleanLiteralExpr></RepeatWhileStmt><RepeatWhileStmt>
+  LABEL: repeat <CodeBlock>{ } </CodeBlock>while <BooleanLiteralExpr>false</BooleanLiteralExpr></RepeatWhileStmt><DoStmt>
+  LABEL: do <CodeBlock>{}</CodeBlock></DoStmt>
+  LABEL: switch <IdentifierExpr>foo </IdentifierExpr>{
+    case <ExpressionPattern><IntegerLiteralExpr>1</IntegerLiteralExpr></ExpressionPattern>:<FallthroughStmt>
+      fallthrough</FallthroughStmt>
+    case <ExpressionPattern><IntegerLiteralExpr>2</IntegerLiteralExpr></ExpressionPattern>:<BreakStmt>
+      break LABEL</BreakStmt>
+    case <ExpressionPattern><IntegerLiteralExpr>3</IntegerLiteralExpr></ExpressionPattern>:<BreakStmt>
+      break</BreakStmt>
+  }<ForInStmt>
+
+  for <IdentifierPattern>a </IdentifierPattern>in <IdentifierExpr>b </IdentifierExpr><CodeBlock>{<DeferStmt>
+    defer <CodeBlock>{ <TupleExpr>() </TupleExpr>}</CodeBlock></DeferStmt><IfStmt>
+    if <ConditionElement><IdentifierExpr>c </IdentifierExpr></ConditionElement><CodeBlock>{<ThrowStmt>
+      throw <IdentifierExpr>MyError</IdentifierExpr>()</ThrowStmt><ContinueStmt>
+      continue</ContinueStmt>
+    } </CodeBlock>else <CodeBlock>{<ContinueStmt>
+      continue LABEL</ContinueStmt>
+    }</CodeBlock></IfStmt>
+  }</CodeBlock></ForInStmt><IfStmt>
+
+  if<ConditionElement><IdentifierExpr>
+    foo</IdentifierExpr>,</ConditionElement><ConditionElement><OptionalBindingCondition>
+    let <IdentifierPattern>a </IdentifierPattern><InitializerClause>= <IdentifierExpr>foo</IdentifierExpr></InitializerClause></OptionalBindingCondition>,</ConditionElement><ConditionElement><OptionalBindingCondition>
+    let <IdentifierPattern>b</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><InitializerClause>= <IdentifierExpr>foo</IdentifierExpr></InitializerClause></OptionalBindingCondition>,</ConditionElement><ConditionElement><OptionalBindingCondition>
+    var <IdentifierPattern>c </IdentifierPattern><InitializerClause>= <IdentifierExpr>foo</IdentifierExpr></InitializerClause></OptionalBindingCondition>,</ConditionElement><ConditionElement><MatchingPatternCondition>
+    case <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>v</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><DiscardAssignmentExpr>_</DiscardAssignmentExpr></TupleElement>) </TupleExpr></ExpressionPattern><InitializerClause>= <IdentifierExpr>foo</IdentifierExpr></InitializerClause></MatchingPatternCondition>,</ConditionElement><ConditionElement><MatchingPatternCondition>
+    case <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>v</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><DiscardAssignmentExpr>_</DiscardAssignmentExpr></TupleElement>)</TupleExpr></ExpressionPattern><TypeAnnotation>: <TupleType>(<TupleTypeElement><SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </TupleTypeElement><TupleTypeElement><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TupleTypeElement>) </TupleType></TypeAnnotation><InitializerClause>= <IdentifierExpr>foo </IdentifierExpr></InitializerClause></MatchingPatternCondition></ConditionElement><CodeBlock>{
+  } </CodeBlock>else <IfStmt>if <ConditionElement><IdentifierExpr>foo </IdentifierExpr></ConditionElement><CodeBlock>{
+  } </CodeBlock>else <CodeBlock>{
+  }</CodeBlock></IfStmt></IfStmt><GuardStmt>
+
+  guard <ConditionElement><OptionalBindingCondition>let <IdentifierPattern>a </IdentifierPattern><InitializerClause>= <IdentifierExpr>b </IdentifierExpr></InitializerClause></OptionalBindingCondition></ConditionElement>else <CodeBlock>{}</CodeBlock></GuardStmt><ForInStmt>
+
+  for <ValueBindingPattern>var <IdentifierPattern>i </IdentifierPattern></ValueBindingPattern>in <IdentifierExpr>foo </IdentifierExpr><WhereClause>where <MemberAccessExpr><IdentifierExpr>i</IdentifierExpr>.foo </MemberAccessExpr></WhereClause><CodeBlock>{}</CodeBlock></ForInStmt><ForInStmt>
+  for case <IsTypePattern>is <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></IsTypePattern>in <IdentifierExpr>foo </IdentifierExpr><CodeBlock>{}</CodeBlock></ForInStmt>
+}</CodeBlock></FunctionDecl>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 9f1329d..c8734c3 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -34,6 +34,7 @@
     _ = bar2(a : bar2(a: 1, b: 2, c: 3), b: 2, c: 3)
     _ = bar3(a : bar3(a: bar3(a: 1)))
     _ = bar4(bar4(bar4(1)))
+    _ = [:]
     _ = [1, 2, 3, 4]
     _ = [1:1, 2:2, 3:3, 4:4]
     _ = [bar3(a:1), bar3(a:1), bar3(a:1), bar3(a:1)]
@@ -215,4 +216,69 @@
   @objc
   static private var a: Int = 3 { return 3 }, b: Int, c = 4, d : Int { get {} get {}}, (a, b): (Int, Int)
   let (a, b) = (1,2), _ = 4 {}
+
+  func patternTests() {
+    for let (x, _) in foo {}
+    for var x: Int in foo {}
+  }
+}
+
+do {
+  switch foo {
+    case let a: break
+    case let a as Int: break
+    case let (a, b): break
+    case (let a, var b): break
+    case is Int: break
+    case let .bar(x): break
+    case MyEnum.foo: break
+    case let a as Int: break
+    case let a?: break
+  }
+}
+
+func statementTests() {
+  do {
+  } catch (var x, let y) {
+  } catch where false {
+  } catch let e where e.foo == bar {
+  } catch {
+  }
+  repeat { } while true
+  LABEL: repeat { } while false
+  LABEL: do {}
+  LABEL: switch foo {
+    case 1:
+      fallthrough
+    case 2:
+      break LABEL
+    case 3:
+      break
+  }
+
+  for a in b {
+    defer { () }
+    if c {
+      throw MyError()
+      continue
+    } else {
+      continue LABEL
+    }
+  }
+
+  if
+    foo,
+    let a = foo,
+    let b: Int = foo,
+    var c = foo,
+    case (let v, _) = foo,
+    case (let v, _): (Int, Int) = foo {
+  } else if foo {
+  } else {
+  }
+
+  guard let a = b else {}
+
+  for var i in foo where i.foo {}
+  for case is Int in foo {}
 }
diff --git a/test/decl/protocol/req/associated_type_typealias_implements.swift b/test/decl/protocol/req/associated_type_typealias_implements.swift
new file mode 100644
index 0000000..8c85bef
--- /dev/null
+++ b/test/decl/protocol/req/associated_type_typealias_implements.swift
@@ -0,0 +1,38 @@
+// RUN: %target-typecheck-verify-swift
+
+protocol P { }
+
+protocol Q {
+  associatedtype T
+  associatedtype U // expected-note 2{{protocol requires nested type 'U'; do you want to add it?}}
+}
+
+protocol R: Q {
+}
+
+struct XT: P { }
+struct XTWithoutP { }
+
+struct XU { }
+
+extension R where T: P {
+  @_implements(Q, U)
+  typealias _Default_U = XU
+}
+
+struct Y1: R {
+  typealias T = XT
+  // okay: infers U = XU
+}
+
+struct Y2: R { // expected-error{{type 'Y2' does not conform to protocol 'Q'}}
+  typealias T = XTWithoutP
+
+  // FIXME: More detail from diagnostic.
+  // error: T: P fails
+}
+
+struct Y3: Q { // expected-error{{type 'Y3' does not conform to protocol 'Q'}}
+  typealias T = XT
+  // FIXME: More detail from diagnostic.
+}
diff --git a/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L14-3.swift.expected b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L14-3.swift.expected
new file mode 100644
index 0000000..edaa618
--- /dev/null
+++ b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L14-3.swift.expected
@@ -0,0 +1,20 @@
+func testConvertToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  if a < 5 {
+    x = a
+  } else {
+    x = b
+  }
+}
+func testConvertTupleToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y): (Int, Int) = a < 5 ? (a, b) : (b, a)
+}
+
+
+
+
+
diff --git a/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L15-3.swift.expected b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L15-3.swift.expected
new file mode 100644
index 0000000..0b67708
--- /dev/null
+++ b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L15-3.swift.expected
@@ -0,0 +1,21 @@
+func testConvertToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  if a < 5 {
+    x = a
+  } else {
+    x = b
+  }
+}
+func testConvertTupleToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y): (Int, Int)
+  (x, y) = a < 5 ? (a, b) : (b, a)
+}
+
+
+
+
+
diff --git a/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L4-3.swift.expected b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L4-3.swift.expected
new file mode 100644
index 0000000..bef8f6a
--- /dev/null
+++ b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L4-3.swift.expected
@@ -0,0 +1,20 @@
+func testConvertToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int = a < 5 ? a : b
+}
+func testConvertTupleToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y): (Int, Int)
+  if a < 5 {
+    (x, y) = (a, b)
+  } else {
+    (x, y) = (b, a)
+  }
+}
+
+
+
+
+
diff --git a/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L5-3.swift.expected b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L5-3.swift.expected
new file mode 100644
index 0000000..e4bf3f6
--- /dev/null
+++ b/test/refactoring/ConvertToTernaryExpr/Outputs/basic/L5-3.swift.expected
@@ -0,0 +1,21 @@
+func testConvertToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  x = a < 5 ? a : b
+}
+func testConvertTupleToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y): (Int, Int)
+  if a < 5 {
+    (x, y) = (a, b)
+  } else {
+    (x, y) = (b, a)
+  }
+}
+
+
+
+
+
diff --git a/test/refactoring/ConvertToTernaryExpr/basic.swift b/test/refactoring/ConvertToTernaryExpr/basic.swift
new file mode 100644
index 0000000..e94cb0d
--- /dev/null
+++ b/test/refactoring/ConvertToTernaryExpr/basic.swift
@@ -0,0 +1,34 @@
+func testConvertToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  if a < 5 {
+    x = a
+  } else {
+    x = b
+  }
+}
+func testConvertTupleToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y): (Int, Int)
+  if a < 5 {
+    (x, y) = (a, b)
+  } else {
+    (x, y) = (b, a)
+  }
+}
+
+// RUN: rm -rf %t.result && mkdir -p %t.result
+
+// RUN: %refactor -convert-to-ternary-expr -source-filename %s -pos=4:3 -end-pos=9:4 > %t.result/L4-3.swift
+// RUN: diff -u %S/Outputs/basic/L4-3.swift.expected %t.result/L4-3.swift
+
+// RUN: %refactor -convert-to-ternary-expr -source-filename %s -pos=5:3 -end-pos=9:4 > %t.result/L5-3.swift
+// RUN: diff -u %S/Outputs/basic/L5-3.swift.expected %t.result/L5-3.swift
+
+// RUN: %refactor -convert-to-ternary-expr -source-filename %s -pos=14:3 -end-pos=19:4 > %t.result/L14-3.swift
+// RUN: diff -u %S/Outputs/basic/L14-3.swift.expected %t.result/L14-3.swift
+
+// RUN: %refactor -convert-to-ternary-expr -source-filename %s -pos=15:3 -end-pos=19:4 > %t.result/L15-3.swift
+// RUN: diff -u %S/Outputs/basic/L15-3.swift.expected %t.result/L15-3.swift
diff --git a/test/refactoring/ExpandTernaryExpr/Outputs/basic/L17-3.swift.expected b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L17-3.swift.expected
new file mode 100644
index 0000000..abdfda6
--- /dev/null
+++ b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L17-3.swift.expected
@@ -0,0 +1,34 @@
+func testExpandBasicTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x = a < 5 ? a : b
+}
+func testExpandMultilineTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y) = a < 5
+    ? (a, b)
+    : (b, a)
+}
+func testExpandAssignOnlyTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  if a < 5 {
+x = a
+} else {
+x = b
+}
+}
+func testExpandAssignOnlyTupleTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  let y: Int
+  (x, y) = a < 5 ? (a, b) : (b, a)
+}
+
+
+
+
+
diff --git a/test/refactoring/ExpandTernaryExpr/Outputs/basic/L24-3.swift.expected b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L24-3.swift.expected
new file mode 100644
index 0000000..449eaeb
--- /dev/null
+++ b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L24-3.swift.expected
@@ -0,0 +1,34 @@
+func testExpandBasicTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x = a < 5 ? a : b
+}
+func testExpandMultilineTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y) = a < 5
+    ? (a, b)
+    : (b, a)
+}
+func testExpandAssignOnlyTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  x = a < 5 ? a : b
+}
+func testExpandAssignOnlyTupleTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  let y: Int
+  if a < 5 {
+(x, y) = (a, b)
+} else {
+(x, y) = (b, a)
+}
+}
+
+
+
+
+
diff --git a/test/refactoring/ExpandTernaryExpr/Outputs/basic/L4-3.swift.expected b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L4-3.swift.expected
new file mode 100644
index 0000000..147e3be
--- /dev/null
+++ b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L4-3.swift.expected
@@ -0,0 +1,35 @@
+func testExpandBasicTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+if a < 5 {
+x = a
+} else {
+x = b
+}
+}
+func testExpandMultilineTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y) = a < 5
+    ? (a, b)
+    : (b, a)
+}
+func testExpandAssignOnlyTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  x = a < 5 ? a : b
+}
+func testExpandAssignOnlyTupleTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  let y: Int
+  (x, y) = a < 5 ? (a, b) : (b, a)
+}
+
+
+
+
+
diff --git a/test/refactoring/ExpandTernaryExpr/Outputs/basic/L9-3.swift.expected b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L9-3.swift.expected
new file mode 100644
index 0000000..fc308b7
--- /dev/null
+++ b/test/refactoring/ExpandTernaryExpr/Outputs/basic/L9-3.swift.expected
@@ -0,0 +1,33 @@
+func testExpandBasicTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x = a < 5 ? a : b
+}
+func testExpandMultilineTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y): (Int, Int)
+if a < 5 {
+(x, y) = (a, b)
+} else {
+(x, y) = (b, a)
+}
+}
+func testExpandAssignOnlyTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  x = a < 5 ? a : b
+}
+func testExpandAssignOnlyTupleTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  let y: Int
+  (x, y) = a < 5 ? (a, b) : (b, a)
+}
+
+
+
+
+
diff --git a/test/refactoring/ExpandTernaryExpr/basic.swift b/test/refactoring/ExpandTernaryExpr/basic.swift
new file mode 100644
index 0000000..3cc55f9
--- /dev/null
+++ b/test/refactoring/ExpandTernaryExpr/basic.swift
@@ -0,0 +1,39 @@
+func testExpandBasicTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x = a < 5 ? a : b
+}
+func testExpandMultilineTernaryExpr() {
+  let a = 3
+  let b = 5
+  let (x, y) = a < 5
+    ? (a, b)
+    : (b, a)
+}
+func testExpandAssignOnlyTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  x = a < 5 ? a : b
+}
+func testExpandAssignOnlyTupleTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  let y: Int
+  (x, y) = a < 5 ? (a, b) : (b, a)
+}
+
+// RUN: rm -rf %t.result && mkdir -p %t.result
+
+// RUN: %refactor -expand-ternary-expr -source-filename %s -pos=4:3 -end-pos=4:24 > %t.result/L4-3.swift
+// RUN: diff -u %S/Outputs/basic/L4-3.swift.expected %t.result/L4-3.swift
+
+// RUN: %refactor -expand-ternary-expr -source-filename %s -pos=9:3 -end-pos=11:13 > %t.result/L9-3.swift
+// RUN: diff -u %S/Outputs/basic/L9-3.swift.expected %t.result/L9-3.swift
+
+// RUN: %refactor -expand-ternary-expr -source-filename %s -pos=17:3 -end-pos=17:20 > %t.result/L17-3.swift
+// RUN: diff -u %S/Outputs/basic/L17-3.swift.expected %t.result/L17-3.swift
+
+// RUN: %refactor -expand-ternary-expr -source-filename %s -pos=24:3 -end-pos=24:35 > %t.result/L24-3.swift
+// RUN: diff -u %S/Outputs/basic/L24-3.swift.expected %t.result/L24-3.swift
diff --git a/test/refactoring/RefactoringKind/basic.swift b/test/refactoring/RefactoringKind/basic.swift
index 15912dc..436c4f9 100644
--- a/test/refactoring/RefactoringKind/basic.swift
+++ b/test/refactoring/RefactoringKind/basic.swift
@@ -224,6 +224,24 @@
   let account: AccountType = .savings
   switch account { }
 }
+
+func testExpandTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x = a < 5 ? a : b
+}
+
+func testConvertToTernaryExpr() {
+  let a = 3
+  let b = 5
+  let x: Int
+  if a < 5 {
+    x = a
+  } else {
+    x = b
+  }
+}
+
 // RUN: %refactor -source-filename %s -pos=2:1 -end-pos=5:13 | %FileCheck %s -check-prefix=CHECK1
 // RUN: %refactor -source-filename %s -pos=3:1 -end-pos=5:13 | %FileCheck %s -check-prefix=CHECK1
 // RUN: %refactor -source-filename %s -pos=4:1 -end-pos=5:13 | %FileCheck %s -check-prefix=CHECK1
@@ -311,6 +329,9 @@
 
 // RUN: %refactor -source-filename %s -pos=225:3 | %FileCheck %s -check-prefix=CHECK-EXPAND-SWITCH
 
+// RUN: %refactor -source-filename %s -pos=231:3 -end-pos=231:24 | %FileCheck %s -check-prefix=CHECK-EXPAND-TERNARY-EXPRESSEXPRESSION
+
+// RUN: %refactor -source-filename %s -pos=237:3 -end-pos=242:4 | %FileCheck %s -check-prefix=CHECK-CONVERT-TO-TERNARY-EXPRESSEXPRESSION
 
 // CHECK1: Action begins
 // CHECK1-NEXT: Extract Method
@@ -354,3 +375,7 @@
 // CHECK-TRY-CATCH: Convert To Do/Catch
 
 // CHECK-EXPAND-SWITCH: Expand Switch Cases
+
+// CHECK-EXPAND-TERNARY-EXPRESSEXPRESSION: Expand Ternary Expression
+
+// CHECK-CONVERT-TO-TERNARY-EXPRESSEXPRESSION: Convert To Ternary Expression
diff --git a/test/stmt/if_while_var.swift b/test/stmt/if_while_var.swift
index c35399a..750c190 100644
--- a/test/stmt/if_while_var.swift
+++ b/test/stmt/if_while_var.swift
@@ -95,7 +95,7 @@
 
 // Test that these don't cause the parser to crash.
 if true { if a == 0; {} }   // expected-error {{use of unresolved identifier 'a'}} expected-error {{expected '{' after 'if' condition}}
-if a == 0, where b == 0 {}  // expected-error 3{{}} expected-note {{}} {{25-25=do }}
+if a == 0, where b == 0 {}  // expected-error 4{{}} expected-note {{}} {{25-25=do }}
 
 
 
diff --git a/tools/SwiftSyntax/Trivia.swift b/tools/SwiftSyntax/Trivia.swift
index 6986b1f..1a78a40 100644
--- a/tools/SwiftSyntax/Trivia.swift
+++ b/tools/SwiftSyntax/Trivia.swift
@@ -46,6 +46,9 @@
     case "CarriageReturn":
       let value = try container.decode(Int.self, forKey: .value)
       self = .carriageReturns(value)
+    case "CarriageReturnLineFeed":
+      let value = try container.decode(Int.self, forKey: .value)
+      self = .carriageReturnLineFeeds(value)
     case "Backtick":
       let value = try container.decode(Int.self, forKey: .value)
       self = .backticks(value)
@@ -102,6 +105,9 @@
     case .carriageReturns(let count):
       try container.encode("CarriageReturn", forKey: .kind)
       try container.encode(count, forKey: .value)
+    case .carriageReturnLineFeeds(let count):
+      try container.encode("CarriageReturnLineFeeds", forKey: .kind)
+      try container.encode(count, forKey: .value)
     case .spaces(let count):
       try container.encode("Space", forKey: .kind)
       try container.encode(count, forKey: .value)
@@ -132,6 +138,9 @@
 
   /// A carriage-return '\r' character.
   case carriageReturns(Int)
+  
+  /// A newline two bytes sequence consists of '\r' and '\n' characters.
+  case carriageReturnLineFeeds(Int)
 
   /// A backtick '`' character, used to escape identifiers.
   case backticks(Int)
@@ -168,6 +177,7 @@
     case let .formfeeds(count): printRepeated("\u{240C}", count: count)
     case let .newlines(count): printRepeated("\n", count: count)
     case let .carriageReturns(count): printRepeated("\r", count: count)
+    case let .carriageReturnLineFeeds(count): printRepeated("\r\n", count: count)
     case let .backticks(count): printRepeated("`", count: count)
     case let .lineComment(text),
          let .blockComment(text),
@@ -195,6 +205,8 @@
       return (lines: n, lastColumn: 0, utf8Length: n)
     case .carriageReturns(let n):
       return (lines: n, lastColumn: 0, utf8Length: n)
+    case .carriageReturnLineFeeds(let n):
+      return (lines: n, lastColumn: 0, utf8Length: n * 2)
     case .lineComment(let text),
          .docLineComment(let text):
       let length = text.utf8.count
@@ -205,15 +217,29 @@
       var lines = 0
       var col = 0
       var total = 0
+      var prevChar: UInt8? = nil
+      // TODO: CR + LF should be regarded as one newline
       for char in text.utf8 {
         total += 1
-        if char == 0x0a /* ASCII newline */
-          || char == 0x0d /* ASCII carriage-return */{
+        switch char {
+        case 0x0a:
+          if prevChar == 0x0d {
+            /* ASCII CR LF */
+            assert(col == 0)
+          } else {
+            /* ASCII newline */
+            col = 0
+            lines += 1
+          }
+        /* ASCII carriage-return */
+        case 0x0d:
           col = 0
           lines += 1
-        } else {
+        
+        default:
           col += 1
         }
+        prevChar = char
       }
       return (lines: lines, lastColumn: col, utf8Length: total)
     }
@@ -290,6 +316,12 @@
     return [.carriageReturns(count)]
   }
 
+  /// Return a piece of trivia for some number of two bytes sequence
+  /// consists of CR and LF in a row.
+  public static func carriageReturnLineFeeds(_ count: Int) -> Trivia {
+    return [.carriageReturnLineFeeds(count)]
+  }
+
   /// Return a piece of trivia for some number of backtick '`' characters
   /// in a row.
   public static func backticks(_ count: Int) -> Trivia {
diff --git a/tools/swift-refactor/swift-refactor.cpp b/tools/swift-refactor/swift-refactor.cpp
index e40c7a1..ecf7f3b 100644
--- a/tools/swift-refactor/swift-refactor.cpp
+++ b/tools/swift-refactor/swift-refactor.cpp
@@ -48,6 +48,10 @@
                       "simplify-long-number", "Perform simplify long number literal refactoring"),
            clEnumValN(RefactoringKind::ConvertStringsConcatenationToInterpolation,
                       "strings-concatenation-to-interpolation", "Perform strings concatenation to interpolation refactoring"),
+           clEnumValN(RefactoringKind::ExpandTernaryExpr,
+                     "expand-ternary-expr", "Perform expand ternary expression"),
+           clEnumValN(RefactoringKind::ConvertToTernaryExpr,
+                      "convert-to-ternary-expr", "Perform convert to ternary expression"),
            clEnumValN(RefactoringKind::ExtractFunction,
                       "extract-function", "Perform extract function refactoring"),
            clEnumValN(RefactoringKind::MoveMembersToExtension,
diff --git a/unittests/Parse/LexerTriviaTests.cpp b/unittests/Parse/LexerTriviaTests.cpp
index 23eaf31..e1c7d08 100644
--- a/unittests/Parse/LexerTriviaTests.cpp
+++ b/unittests/Parse/LexerTriviaTests.cpp
@@ -184,3 +184,64 @@
   ASSERT_EQ(LeadingTrivia, (Trivia{{TriviaPiece::carriageReturns(1)}}));
   ASSERT_EQ(TrailingTrivia, Trivia());
 }
+
+TEST_F(LexerTriviaTest, TriviaNewLines) {
+  using namespace swift::syntax;
+  StringRef SourceStr = "\n\r\r\n\r\r\r\n\r\n\n\n"
+                        "aaa"
+                        "\n\r\r\n\r\r\r\n\r\n\n\n"
+                        "bbb"
+                        "\n\r\r\n\r\r\r\n\r\n\n\n";
+
+  LangOptions LangOpts;
+  SourceManager SourceMgr;
+  unsigned BufferID = SourceMgr.addMemBufferCopy(SourceStr);
+
+  Lexer L(LangOpts, SourceMgr, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+          CommentRetentionMode::AttachToNextToken,
+          TriviaRetentionMode::WithTrivia);
+
+  Token Tok;
+  Trivia LeadingTrivia, TrailingTrivia;
+
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("aaa", Tok.getText());
+  ASSERT_TRUE(Tok.isAtStartOfLine());
+  ASSERT_EQ((Trivia{{
+    TriviaPiece::newlines(1),
+    TriviaPiece::carriageReturns(1),
+    TriviaPiece::carriageReturnLineFeeds(1),
+    TriviaPiece::carriageReturns(2),
+    TriviaPiece::carriageReturnLineFeeds(2),
+    TriviaPiece::newlines(2)
+  }}), LeadingTrivia);
+  ASSERT_EQ(Trivia(), TrailingTrivia);
+
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::identifier, Tok.getKind());
+  ASSERT_EQ("bbb", Tok.getText());
+  ASSERT_TRUE(Tok.isAtStartOfLine());
+  ASSERT_EQ((Trivia{{
+    TriviaPiece::newlines(1),
+    TriviaPiece::carriageReturns(1),
+    TriviaPiece::carriageReturnLineFeeds(1),
+    TriviaPiece::carriageReturns(2),
+    TriviaPiece::carriageReturnLineFeeds(2),
+    TriviaPiece::newlines(2)
+  }}), LeadingTrivia);
+  ASSERT_EQ(Trivia(), TrailingTrivia);
+
+  L.lex(Tok, LeadingTrivia, TrailingTrivia);
+  ASSERT_EQ(tok::eof, Tok.getKind());
+  ASSERT_TRUE(Tok.isAtStartOfLine());
+  ASSERT_EQ((Trivia{{
+    TriviaPiece::newlines(1),
+    TriviaPiece::carriageReturns(1),
+    TriviaPiece::carriageReturnLineFeeds(1),
+    TriviaPiece::carriageReturns(2),
+    TriviaPiece::carriageReturnLineFeeds(2),
+    TriviaPiece::newlines(2)
+  }}), LeadingTrivia);
+  ASSERT_EQ(Trivia(), TrailingTrivia);
+}
diff --git a/unittests/Syntax/RawSyntaxTests.cpp b/unittests/Syntax/RawSyntaxTests.cpp
index 71cdfc9..4fb98de 100644
--- a/unittests/Syntax/RawSyntaxTests.cpp
+++ b/unittests/Syntax/RawSyntaxTests.cpp
@@ -1,5 +1,6 @@
 #include "swift/Parse/Token.h"
 #include "swift/Syntax/RawSyntax.h"
+#include "swift/Syntax/RawTokenSyntax.h"
 #include "swift/Syntax/SyntaxFactory.h"
 #include "llvm/ADT/SmallString.h"
 #include "gtest/gtest.h"
@@ -8,3 +9,33 @@
 using namespace swift::syntax;
 
 // TODO
+
+TEST(RawSyntaxTests, accumulateAbsolutePosition1) {
+  auto Token = RawTokenSyntax::make(tok::identifier,
+                                    OwnedString("aaa"),
+                                    SourcePresence::Present,
+                                    Trivia {{
+                                      TriviaPiece::newlines(2),
+                                      TriviaPiece::carriageReturns(2),
+                                      TriviaPiece::carriageReturnLineFeeds(2) }},
+                                    Trivia {{  }});
+  AbsolutePosition Pos;
+  Token->accumulateAbsolutePosition(Pos);
+  ASSERT_EQ(7u, Pos.getLine());
+  ASSERT_EQ(4u, Pos.getColumn());
+  ASSERT_EQ(11u, Pos.getOffset());
+}
+
+TEST(RawSyntaxTests, accumulateAbsolutePosition2) {
+  auto Token = RawTokenSyntax::make(tok::identifier,
+                                    OwnedString("aaa"),
+                                    SourcePresence::Present,
+                                    Trivia {{
+                                      TriviaPiece::blockComment("/* \n\r\r\n */") }},
+                                    Trivia {{  }});
+  AbsolutePosition Pos;
+  Token->accumulateAbsolutePosition(Pos);
+  ASSERT_EQ(4u, Pos.getLine());
+  ASSERT_EQ(7u, Pos.getColumn());
+  ASSERT_EQ(13u, Pos.getOffset());
+}
diff --git a/unittests/runtime/Array.cpp b/unittests/runtime/Array.cpp
index ce56bbc..40c8023 100644
--- a/unittests/runtime/Array.cpp
+++ b/unittests/runtime/Array.cpp
@@ -80,8 +80,8 @@
 
 static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
   { { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, 0, /*rodata*/ 1,
-  ClassFlags::UsesSwift1Refcounting, 0, 0, 0, 0, 0, 0 }
+  { { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK,
+  ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
 };
 
 /// Create an object that, when deallocated, stores the given value to
diff --git a/unittests/runtime/LongTests/LongRefcounting.cpp b/unittests/runtime/LongTests/LongRefcounting.cpp
index bd3d710..ba5da09 100644
--- a/unittests/runtime/LongTests/LongRefcounting.cpp
+++ b/unittests/runtime/LongTests/LongRefcounting.cpp
@@ -98,8 +98,8 @@
 
 static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
   { { &deinitTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, 0, /*rodata*/ 1,
-  ClassFlags::UsesSwift1Refcounting, 0, 0, 0, 0, 0, 0 }
+  { { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK,
+  ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
 };
 
 /// Create an object that, when deinited, stores the given value to
diff --git a/unittests/runtime/Refcounting.cpp b/unittests/runtime/Refcounting.cpp
index e1b6bf9..e6f60a3 100644
--- a/unittests/runtime/Refcounting.cpp
+++ b/unittests/runtime/Refcounting.cpp
@@ -31,8 +31,8 @@
 
 static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
   { { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, 0, /*rodata*/ 1,
-  ClassFlags::UsesSwift1Refcounting, 0, 0, 0, 0, 0, 0 }
+  { { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK,
+  ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
 };
 
 /// Create an object that, when deallocated, stores the given value to
diff --git a/utils/gyb_syntax_support/Child.py b/utils/gyb_syntax_support/Child.py
index 9a0eb74..c28be20 100644
--- a/utils/gyb_syntax_support/Child.py
+++ b/utils/gyb_syntax_support/Child.py
@@ -9,7 +9,7 @@
     restricted subset of acceptable kinds or texts.
     """
     def __init__(self, name, kind, is_optional=False,
-                 token_choices=None, text_choices=None):
+                 token_choices=None, text_choices=None, node_choices=None):
         self.name = name
         self.swift_name = lowercase_first_word(name)
         self.syntax_kind = kind
@@ -39,6 +39,19 @@
         # token against the choices.
         self.text_choices = text_choices or []
 
+        # A list of valid choices for a child
+        self.node_choices = node_choices or []
+
+        # Check the choices are either empty or multiple
+        assert len(self.node_choices) != 1
+
+        # Check node choices are well-formed
+        for choice in self.node_choices:
+            assert not choice.is_optional, \
+                "node choice %s cannot be optional" % choice.name
+            assert not choice.node_choices, \
+                "node choice %s cannot have further choices" % choice.name
+
     def is_token(self):
         """
         Returns true if this child has a token kind.
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index a7af33f..782f167 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -358,9 +358,10 @@
     Node('AccessorBlock', kind="Syntax",
          children=[
              Child('LeftBrace', kind='LeftBraceToken'),
-             # one of the following children should be required.
-             Child('Accessors', kind='AccessorList', is_optional=True),
-             Child('Statements', kind='StmtList', is_optional=True),
+             Child('AccessorListOrStmtList', kind='Syntax',
+                   node_choices=[
+                      Child('Accessors', kind='AccessorList'),
+                      Child('Statements', kind='StmtList')]),
              Child('RightBrace', kind='RightBraceToken'),
          ]),
 
diff --git a/utils/gyb_syntax_support/ExprNodes.py b/utils/gyb_syntax_support/ExprNodes.py
index 1f47df3..e3ebe08 100644
--- a/utils/gyb_syntax_support/ExprNodes.py
+++ b/utils/gyb_syntax_support/ExprNodes.py
@@ -74,6 +74,10 @@
              Child('Elements', kind='ExprList'),
          ]),
 
+    Node('ExprList', kind='SyntaxCollection',
+         element='Expr',
+         element_name='Expression'),
+
     # A #line expression.
     Node('PoundLineExpr', kind='Expr',
          children=[
@@ -152,7 +156,11 @@
     Node('DictionaryExpr', kind='Expr',
          children=[
              Child('LeftSquare', kind='LeftSquareToken'),
-             Child('Elements', kind='DictionaryElementList'),
+             Child('Content', kind='Syntax',
+                   node_choices=[
+                       Child('Colon', kind='ColonToken'),
+                       Child('Elements', kind='DictionaryElementList'),
+                   ]),
              Child('RightSquare', kind='RightSquareToken'),
          ]),
 
@@ -300,9 +308,11 @@
          children=[
              Child('Capture', kind='ClosureCaptureSignature',
                    is_optional=True),
-             # FIXME: one and only one of these two children is required
-             Child('SimpleInput', kind='ClosureParamList', is_optional=True),
-             Child('Input', kind='ParameterClause', is_optional=True),
+             Child('Input', kind='Syntax', is_optional=True,
+                   node_choices=[
+                       Child('SimpleInput', kind='ClosureParamList'),
+                       Child('Input', kind='ParameterClause'),
+                   ]),
              Child('ThrowsTok', kind='ThrowsToken', is_optional=True),
              Child('Output', kind='ReturnClause', is_optional=True),
              Child('InTok', kind='InToken'),
@@ -315,4 +325,10 @@
              Child('Statements', kind='StmtList'),
              Child('RightBrace', kind='RightBraceToken'),
          ]),
+
+    # unresolved-pattern-expr -> pattern
+    Node('UnresolvedPatternExpr', kind='Expr',
+         children=[
+             Child('Pattern', kind='Pattern'),
+         ]),
 ]
diff --git a/utils/gyb_syntax_support/PatternNodes.py b/utils/gyb_syntax_support/PatternNodes.py
index eb962ae..f8ebb5b 100644
--- a/utils/gyb_syntax_support/PatternNodes.py
+++ b/utils/gyb_syntax_support/PatternNodes.py
@@ -28,10 +28,10 @@
              Child('Type', kind='Type'),
          ]),
 
-    # optional-pattern -> identifier '?'
+    # optional-pattern -> pattern '?'
     Node('OptionalPattern', kind='Pattern',
          children=[
-             Child('Identifier', kind='IdentifierToken'),
+             Child('SubPattern', kind='Pattern'),
              Child('QuestionMark', kind='PostfixQuestionMarkToken'),
          ]),
 
@@ -49,14 +49,12 @@
              Child('Type', kind='Type'),
          ]),
 
-    # tuple-pattern -> '(' tuple-pattern-element-list ')' type-annotation?
+    # tuple-pattern -> '(' tuple-pattern-element-list ')'
     Node('TuplePattern', kind='Pattern',
          children=[
              Child('OpenParen', kind='LeftParenToken'),
              Child('Elements', kind='TuplePatternElementList'),
              Child('CloseParen', kind='RightParenToken'),
-             Child('TypeAnnotation', kind='TypeAnnotation',
-                   is_optional=True),
          ]),
 
     # wildcard-pattern -> '_' type-annotation?
@@ -72,7 +70,7 @@
          children=[
              Child('LabelName', kind='IdentifierToken',
                    is_optional=True),
-             Child('LabelColon', kind='ColonToken',
+             Child('Colon', kind='ColonToken',
                    is_optional=True),
              Child('Pattern', kind='Pattern'),
              Child('Comma', kind='CommaToken',
diff --git a/utils/gyb_syntax_support/StmtNodes.py b/utils/gyb_syntax_support/StmtNodes.py
index 34049bc..844e0e6 100644
--- a/utils/gyb_syntax_support/StmtNodes.py
+++ b/utils/gyb_syntax_support/StmtNodes.py
@@ -20,7 +20,7 @@
              Child('LabelColon', kind='ColonToken',
                    is_optional=True),
              Child('WhileKeyword', kind='WhileToken'),
-             Child('Conditions', kind='ConditionList'),
+             Child('Conditions', kind='ConditionElementList'),
              Child('Body', kind='CodeBlock'),
              Child('Semicolon', kind='SemicolonToken',
                    is_optional=True),
@@ -66,21 +66,17 @@
     Node('GuardStmt', kind='Stmt',
          children=[
              Child('GuardKeyword', kind='GuardToken'),
-             Child('Conditions', kind='ConditionList'),
+             Child('Conditions', kind='ConditionElementList'),
              Child('ElseKeyword', kind='ElseToken'),
              Child('Body', kind='CodeBlock'),
              Child('Semicolon', kind='SemicolonToken',
                    is_optional=True),
          ]),
 
-    Node('ExprList', kind='SyntaxCollection',
-         element='Expr',
-         element_name='Expression'),
-
     Node('WhereClause', kind='Syntax',
          children=[
              Child('WhereKeyword', kind='WhereToken'),
-             Child('Expressions', kind='ExprList'),
+             Child('GuardResult', kind='Expr'),
          ]),
 
     # for-in-stmt -> label? ':'? 'for' 'case'? pattern 'in' expr 'where'?
@@ -94,9 +90,11 @@
              Child('ForKeyword', kind='ForToken'),
              Child('CaseKeyword', kind='CaseToken',
                    is_optional=True),
-             Child('ItemPattern', kind='Pattern'),
+             Child('Pattern', kind='Pattern'),
+             Child('TypeAnnotation', kind='TypeAnnotation',
+                   is_optional=True),
              Child('InKeyword', kind='InToken'),
-             Child('CollectionExpr', kind='Expr'),
+             Child('SequenceExpr', kind='Expr'),
              Child('WhereClause', kind='WhereClause',
                    is_optional=True),
              Child('Body', kind='CodeBlock'),
@@ -134,7 +132,8 @@
                    is_optional=True),
              Child('DoKeyword', kind='DoToken'),
              Child('Body', kind='CodeBlock'),
-             Child('CatchClauses', kind='CatchClauseList'),
+             Child('CatchClauses', kind='CatchClauseList',
+                   is_optional=True),
              Child('Semicolon', kind='SemicolonToken',
                    is_optional=True),
          ]),
@@ -179,21 +178,53 @@
     Node('CaseItemList', kind='SyntaxCollection',
          element='CaseItem'),
 
-    Node('Condition', kind='Syntax',
-         children=[
-             Child('Condition', kind='Syntax'),
-             Child('TrailingComma', kind='CommaToken',
-                   is_optional=True),
-         ]),
-
-    # condition-list -> condition
-    #                 | condition ','? condition-list
     # condition -> expression
     #            | availability-condition
     #            | case-condition
     #            | optional-binding-condition
-    Node('ConditionList', kind='SyntaxCollection',
-         element='Condition'),
+    Node('ConditionElement', kind='Syntax',
+         children=[
+             Child('Condition', kind='Syntax',
+                   node_choices=[
+                       Child('Expression', kind='Expr'),
+                       Child('Availablity', kind='AvailabilityCondition'),
+                       Child('MatchingPattern',
+                             kind='MatchingPatternCondition'),
+                       Child('OptionalBinding',
+                             kind='OptionalBindingCondition'),
+                   ]),
+             Child('TrailingComma', kind='CommaToken',
+                   is_optional=True),
+         ]),
+    Node('AvailabilityCondition', kind='Syntax',
+         children=[
+             Child('PoundAvailableKeyword', kind='PoundAvailableToken'),
+             Child('Arguments', kind='TokenList'),
+         ]),
+    Node('MatchingPatternCondition', kind='Syntax',
+         children=[
+             Child('CaseKeyword', kind='CaseToken'),
+             Child('Pattern', kind='Pattern'),
+             Child('TypeAnnotation', kind='TypeAnnotation',
+                   is_optional=True),
+             Child('Initializer', kind='InitializerClause'),
+         ]),
+    Node('OptionalBindingCondition', kind='Syntax',
+         children=[
+             Child('LetOrVarKeyword', kind='Token',
+                   token_choices=[
+                       'LetToken', 'VarToken',
+                   ]),
+             Child('Pattern', kind='Pattern'),
+             Child('TypeAnnotation', kind='TypeAnnotation',
+                   is_optional=True),
+             Child('Initializer', kind='InitializerClause'),
+         ]),
+
+    # condition-list -> condition
+    #                 | condition ','? condition-list
+    Node('ConditionElementList', kind='SyntaxCollection',
+         element='ConditionElement'),
 
     # A declaration in statement position.
     # struct Foo {};
@@ -222,9 +253,15 @@
              Child('LabelColon', kind='ColonToken',
                    is_optional=True),
              Child('IfKeyword', kind='IfToken'),
-             Child('Conditions', kind='ConditionList'),
+             Child('Conditions', kind='ConditionElementList'),
              Child('Body', kind='CodeBlock'),
-             Child('ElseClause', kind='Syntax',
+             Child('ElseKeyword', kind='ElseToken',
+                   is_optional=True),
+             Child('ElseBody', kind='Syntax',
+                   node_choices=[
+                       Child('IfStmt', kind='IfStmt'),
+                       Child('CodeBlock', kind='CodeBlock'),
+                   ],
                    is_optional=True),
              Child('Semicolon', kind='SemicolonToken',
                    is_optional=True),
diff --git a/utils/gyb_syntax_support/__init__.py b/utils/gyb_syntax_support/__init__.py
index 36ded62..44d625c 100644
--- a/utils/gyb_syntax_support/__init__.py
+++ b/utils/gyb_syntax_support/__init__.py
@@ -28,9 +28,54 @@
     else:
         missing_kind = "Unknown" if child.syntax_kind == "Syntax" \
                        else child.syntax_kind
+        if child.node_choices:
+            return make_missing_child(child.node_choices[0])
         return 'RawSyntax::missing(SyntaxKind::%s)' % missing_kind
 
 
+def check_child_condition(child):
+    """
+    Generates a C++ closure to check whether a given syntax node S can satisfy
+    the requirements of child.
+    """
+    result = '[](const Syntax &S) {\n'
+    result += '  // check %s\n' % child.name
+    if child.token_choices:
+        # Check token kind choices are met.
+        result += 'if (auto Tok = S.getAs<TokenSyntax>()) {\n'
+        result += '  auto Kind = Tok->getTokenKind();\n'
+        tok_checks = []
+        for choice in child.token_choices:
+            tok_checks.append("Kind == tok::%s" % choice.kind)
+        all_checks = ' || '.join(tok_checks)
+        result += '  return %s;\n' % all_checks
+        result += '}\n'
+        result += 'return false;\n'
+    elif child.text_choices:
+        # Check token text choices are met.
+        result += 'if (auto Tok = S.getAs<TokenSyntax>()) {\n'
+        result += '  auto Text = Tok->getText();\n'
+        tok_checks = []
+        for choice in child.text_choices:
+            tok_checks.append("Text == \"%s\"" % choice)
+        all_checks = ' || '.join(tok_checks)
+        result += '  return %s;\n' % all_checks
+        result += '}\n'
+        result += 'return false;\n'
+    elif child.node_choices:
+        # Recursively, check one of the node choices' conditions are met.
+        node_checks = []
+        for choice in child.node_choices:
+            node_checks.append(check_child_condition(choice) + '(S)')
+        all_checks = ' || '.join(node_checks)
+        result += 'return %s;\n' % all_checks
+    else:
+        # For remaining children, simply check the syntax kind.
+        result += 'return S.getAs<%s>().hasValue();\n' % child.type_name
+    result += '}'
+    return result
+
+
 def make_missing_swift_child(child):
     """
     Generates a Swift call to make the raw syntax for a given Child object.
diff --git a/validation-test/compiler_crashers/28865-void-lookupinmodule-llvm-smallset-swift-cantype-4u-anonymous-namespace-sortcanty.swift b/validation-test/compiler_crashers/28865-void-lookupinmodule-llvm-smallset-swift-cantype-4u-anonymous-namespace-sortcanty.swift
new file mode 100644
index 0000000..a0fdccf
--- /dev/null
+++ b/validation-test/compiler_crashers/28865-void-lookupinmodule-llvm-smallset-swift-cantype-4u-anonymous-namespace-sortcanty.swift
@@ -0,0 +1,9 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A:a{}typealias a:A&
diff --git a/validation-test/compiler_crashers/28866-unreachable-executed-at-swift-include-swift-ast-cantypevisitor-h-41.swift b/validation-test/compiler_crashers/28866-unreachable-executed-at-swift-include-swift-ast-cantypevisitor-h-41.swift
new file mode 100644
index 0000000..5c7f26e
--- /dev/null
+++ b/validation-test/compiler_crashers/28866-unreachable-executed-at-swift-include-swift-ast-cantypevisitor-h-41.swift
@@ -0,0 +1,11 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+[.a
+[Int?as?Int
+nil?
diff --git a/validation-test/compiler_crashers/28867-swift-iterativetypechecker-issatisfied-swift-typecheckrequest.swift b/validation-test/compiler_crashers/28867-swift-iterativetypechecker-issatisfied-swift-typecheckrequest.swift
new file mode 100644
index 0000000..71b51ec
--- /dev/null
+++ b/validation-test/compiler_crashers/28867-swift-iterativetypechecker-issatisfied-swift-typecheckrequest.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A:a
+& {}typealias a:A
diff --git a/validation-test/compiler_crashers/28868-known-typebindings-end.swift b/validation-test/compiler_crashers/28868-known-typebindings-end.swift
new file mode 100644
index 0000000..711219e
--- /dev/null
+++ b/validation-test/compiler_crashers/28868-known-typebindings-end.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+struct B{func a{a(Int?as?ManagedBuffer{
diff --git a/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift b/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
new file mode 100644
index 0000000..641a444
--- /dev/null
+++ b/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
@@ -0,0 +1,9 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A:A&CLong
diff --git a/validation-test/compiler_crashers/28870-swift-associatedtypedecl-getoverriddendecls-const.swift b/validation-test/compiler_crashers/28870-swift-associatedtypedecl-getoverriddendecls-const.swift
new file mode 100644
index 0000000..61a157f
--- /dev/null
+++ b/validation-test/compiler_crashers/28870-swift-associatedtypedecl-getoverriddendecls-const.swift
@@ -0,0 +1,10 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A:a{typealias a}protocol a:A{typealias a
+class a
diff --git a/validation-test/compiler_crashers/28871-nested-second-nested-second-isequal-result-nested-second-haserror-result-haserro.swift b/validation-test/compiler_crashers/28871-nested-second-nested-second-isequal-result-nested-second-haserror-result-haserro.swift
new file mode 100644
index 0000000..c7d21fb
--- /dev/null
+++ b/validation-test/compiler_crashers/28871-nested-second-nested-second-isequal-result-nested-second-haserror-result-haserro.swift
@@ -0,0 +1,11 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// REQUIRES: asserts
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+class a:A
+protocol A:a{typealias a:=a
diff --git a/validation-test/stdlib/CollectionType.swift.gyb b/validation-test/stdlib/CollectionType.swift.gyb
index f826161..0f287a3 100644
--- a/validation-test/stdlib/CollectionType.swift.gyb
+++ b/validation-test/stdlib/CollectionType.swift.gyb
@@ -853,4 +853,28 @@
 % end
 
 
+struct RACollectionWithIntIndex<T> {
+  var contents: [T]
+}
+
+extension RACollectionWithIntIndex: RandomAccessCollection {
+  var startIndex: Int { return contents.startIndex }
+  var endIndex: Int { return contents.endIndex }
+  subscript(index: Int) -> T {
+    get { return contents[index] }
+    set { }
+  }
+}
+
+CollectionTypeTests.test("AssociatedTypes/RACollectionWithIntIndex") {
+  typealias C = RACollectionWithIntIndex<Void>
+  expectCollectionAssociatedTypes(
+    collectionType: C.self,
+    iteratorType: IndexingIterator<C>.self,
+    subSequenceType: Slice<C>.self,
+    indexType: Int.self,
+    indicesType: CountableRange<Int>.self)
+}
+
+
 runAllTests()
diff --git a/validation-test/stdlib/Lazy.swift.gyb b/validation-test/stdlib/Lazy.swift.gyb
index 9518334..44b29ac 100644
--- a/validation-test/stdlib/Lazy.swift.gyb
+++ b/validation-test/stdlib/Lazy.swift.gyb
@@ -1291,6 +1291,11 @@
   }
 }
 
+struct TryFlattenIndex<C: Collection> where C.Element: Collection {
+  typealias FlattenedIndex = FlattenCollectionIndex<C>
+}
+
+
 //===--- LazyPrefixWhile --------------------------------------------------===//
 
 let prefixDropWhileTests: [(data: [Int], value: Int, pivot: Int)] = [
diff --git a/validation-test/stdlib/MicroStdlib/Inputs/RuntimeStubs.c b/validation-test/stdlib/MicroStdlib/Inputs/RuntimeStubs.c
index 74cc302..f4fe6cd 100644
--- a/validation-test/stdlib/MicroStdlib/Inputs/RuntimeStubs.c
+++ b/validation-test/stdlib/MicroStdlib/Inputs/RuntimeStubs.c
@@ -7,6 +7,6 @@
 void _swift_slowDealloc(void) {}
 void _swift_storeEnumTagSinglePayload(void) {}
 void swift_allocateGenericValueMetadata(void) {}
-void swift_initEnumValueWitnessTableSinglePayload(void) {}
+void swift_initEnumMetadataSinglePayload(void) {}
 void _swift_retain(){}
 void swift_allocBox(){}