Merge pull request #15257 from rintaro/parse-eliminate-square_lit

[Parse] Eliminate {l,r}_square_lit tokens.
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 66d360e..a7bbc35 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -5340,6 +5340,8 @@
       StaticLoc(StaticLoc), FuncLoc(FuncLoc),
       OverriddenOrBehaviorParamDecl(),
       Operator(nullptr) {
+    assert(!Name.getBaseName().isSpecial());
+
     Bits.FuncDecl.IsStatic =
       StaticLoc.isValid() || StaticSpelling != StaticSpellingKind::None;
     Bits.FuncDecl.StaticSpelling = static_cast<unsigned>(StaticSpelling);
@@ -5915,8 +5917,6 @@
                   GenericParamList *GenericParams, 
                   DeclContext *Parent);
 
-  Identifier getName() const { return getFullName().getBaseIdentifier(); }
-
   void setParameterLists(ParamDecl *selfParam, ParameterList *bodyParams);
 
   SourceLoc getConstructorLoc() const { return getNameLoc(); }
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index b1288df..592481b 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -600,6 +600,9 @@
 ERROR(sil_keypath_computed_property_missing_part,none,
       "keypath %select{gettable|settable}0_property component needs an "
       "%select{id and getter|id, getter, and setter}0", (bool))
+ERROR(sil_keypath_external_missing_part,none,
+      "keypath external component with indices needs an indices_equals and "
+      "indices_hash function", ())
 ERROR(sil_keypath_no_components,none,
       "keypath must have at least one component", ())
 ERROR(sil_keypath_no_root,none,
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 744a3e1..7481d69 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -631,7 +631,7 @@
       "ambiguous type name %0 in module %1", (Identifier, Identifier))
 ERROR(use_nonmatching_operator,none,
       "%0 is not a %select{binary|prefix unary|postfix unary}1 operator",
-      (Identifier, unsigned))
+      (DeclName, unsigned))
 ERROR(broken_associated_type_witness,none,
       "reference to invalid associated type %0 of type %1", (DeclName, Type))
 
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index c46fba2..34306db 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -148,14 +148,14 @@
 
     // The docs say "not all sections may be present." We'll succeed if ANY of
     // them are present. Not sure if that's the right thing to do.
-    auto FieldMd = findSection<FieldSection>(Header, "__swift5_fieldmd");
+    auto FieldMd = findSection<FieldSection>(Header, "__swift4_fieldmd");
     auto AssocTyMd =
-        findSection<AssociatedTypeSection>(Header, "__swift5_assocty");
+        findSection<AssociatedTypeSection>(Header, "__swift4_assocty");
     auto BuiltinTyMd =
-        findSection<BuiltinTypeSection>(Header, "__swift5_builtin");
-    auto CaptureMd = findSection<CaptureSection>(Header, "__swift5_capture");
-    auto TyperefMd = findSection<GenericSection>(Header, "__swift5_typeref");
-    auto ReflStrMd = findSection<GenericSection>(Header, "__swift5_reflstr");
+        findSection<BuiltinTypeSection>(Header, "__swift4_builtin");
+    auto CaptureMd = findSection<CaptureSection>(Header, "__swift4_capture");
+    auto TyperefMd = findSection<GenericSection>(Header, "__swift4_typeref");
+    auto ReflStrMd = findSection<GenericSection>(Header, "__swift4_reflstr");
 
     bool success = FieldMd.second || AssocTyMd.second || BuiltinTyMd.second ||
                    CaptureMd.second || TyperefMd.second || ReflStrMd.second;
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 29b5d64..5450faf 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -2276,17 +2276,15 @@
       return Value.DeclRef;
     }
   };
-
+  
   enum class Kind: unsigned {
     StoredProperty,
     GettableProperty,
     SettableProperty,
-    Last_Packed = SettableProperty, // Last enum value that can be packed in
-                                    // a PointerIntPair
+    External,
     OptionalChain,
     OptionalForce,
     OptionalWrap,
-    External,
   };
   
   // Description of a captured index value and its Hashable conformance for a
@@ -2299,73 +2297,93 @@
   };
   
 private:
-  static constexpr const unsigned KindPackingBits = 2;
-  static constexpr const unsigned UnpackedKind = (1u << KindPackingBits) - 1;
-  static_assert((unsigned)Kind::Last_Packed < UnpackedKind,
-                "too many kinds to pack");
-                
+  enum PackedKind: unsigned {
+    PackedStored,
+    PackedComputed,
+    PackedExternal,
+    Unpacked,
+  };
+  
+  static const unsigned KindPackingBits = 2;
+  
+  static unsigned getPackedKind(Kind k) {
+    switch (k) {
+    case Kind::StoredProperty:
+      return PackedStored;
+    case Kind::GettableProperty:
+    case Kind::SettableProperty:
+      return PackedComputed;
+    case Kind::External:
+      return PackedExternal;
+    case Kind::OptionalChain:
+    case Kind::OptionalForce:
+    case Kind::OptionalWrap:
+      return Unpacked;
+    }
+  }
+  
   // Value is the VarDecl* for StoredProperty, the SILFunction* of the
   // Getter for computed properties, or the Kind for other kinds
   llvm::PointerIntPair<void *, KindPackingBits, unsigned> ValueAndKind;
-  llvm::PointerIntPair<SILFunction *, 2,
-                       ComputedPropertyId::KindType> SetterAndIdKind;
-  ComputedPropertyId::ValueType IdValue;
-  ArrayRef<Index> Indices;
   union {
-    // Valid if Kind == GettableProperty || Value == SettableProperty
+    // Valid if Kind == GettableProperty || Kind == SettableProperty
     struct {
-      SILFunction *Equal;
-      SILFunction *Hash;
-    } IndexEquality;
+      llvm::PointerIntPair<SILFunction *, 2,
+                           ComputedPropertyId::KindType> SetterAndIdKind;
+      ComputedPropertyId::ValueType IdValue;
+    } Computed;
     // Valid if Kind == External
     ArrayRef<Substitution> ExternalSubstitutions;
   };
+  ArrayRef<Index> Indices;
+  struct {
+    SILFunction *Equal;
+    SILFunction *Hash;
+  } IndexEquality;
   CanType ComponentType;
   
-  unsigned kindForPacking(Kind k) {
-    auto value = (unsigned)k;
-    assert(value <= (unsigned)Kind::Last_Packed);
-    return value;
-  }
-  
-  KeyPathPatternComponent(Kind kind, CanType ComponentType)
-    : ValueAndKind((void*)((uintptr_t)kind << KindPackingBits), UnpackedKind),
-      ComponentType(ComponentType)
-  {
-    assert(kind > Kind::Last_Packed && "wrong initializer");
-  }
-  
-  KeyPathPatternComponent(VarDecl *storedProp, Kind kind,
+  /// Constructor for stored components
+  KeyPathPatternComponent(VarDecl *storedProp,
                           CanType ComponentType)
-    : ValueAndKind(storedProp, kindForPacking(kind)),
+    : ValueAndKind(storedProp, PackedStored),
       ComponentType(ComponentType) {}
 
-  KeyPathPatternComponent(ComputedPropertyId id, Kind kind,
+  /// Constructor for computed components
+  KeyPathPatternComponent(ComputedPropertyId id,
                           SILFunction *getter,
                           SILFunction *setter,
                           ArrayRef<Index> indices,
                           SILFunction *indicesEqual,
                           SILFunction *indicesHash,
                           CanType ComponentType)
-    : ValueAndKind(getter, kindForPacking(kind)),
-      SetterAndIdKind(setter, id.Kind),
-      IdValue(id.Value),
+    : ValueAndKind(getter, PackedComputed),
+      Computed{{setter, id.Kind}, {id.Value}},
       Indices(indices),
       IndexEquality{indicesEqual, indicesHash},
       ComponentType(ComponentType) {
   }
   
+  /// Constructor for external components
   KeyPathPatternComponent(AbstractStorageDecl *externalStorage,
                           ArrayRef<Substitution> substitutions,
                           ArrayRef<Index> indices,
+                          SILFunction *indicesEqual,
+                          SILFunction *indicesHash,
                           CanType componentType)
-    : ValueAndKind((void*)((uintptr_t)Kind::External << KindPackingBits),
-                   UnpackedKind),
-      IdValue(externalStorage),
-      Indices(indices),
+    : ValueAndKind(externalStorage, PackedExternal),
       ExternalSubstitutions(substitutions),
+      Indices(indices),
+      IndexEquality{indicesEqual, indicesHash},
       ComponentType(componentType) {
   }
+  
+  /// Constructor for optional components.
+  KeyPathPatternComponent(Kind kind, CanType componentType)
+    : ValueAndKind((void*)((uintptr_t)kind << KindPackingBits), Unpacked),
+      ComponentType(componentType) {
+    assert((unsigned)kind >= (unsigned)Kind::OptionalChain
+           && "not an optional component");
+  }
 
 public:
   KeyPathPatternComponent() : ValueAndKind(nullptr, 0) {}
@@ -2376,9 +2394,17 @@
 
   Kind getKind() const {
     auto packedKind = ValueAndKind.getInt();
-    if (packedKind != UnpackedKind)
-      return (Kind)packedKind;
-    return (Kind)((uintptr_t)ValueAndKind.getPointer() >> KindPackingBits);
+    switch ((PackedKind)packedKind) {
+    case PackedStored:
+      return Kind::StoredProperty;
+    case PackedComputed:
+      return Computed.SetterAndIdKind.getPointer()
+        ? Kind::SettableProperty : Kind::GettableProperty;
+    case PackedExternal:
+      return Kind::External;
+    case Unpacked:
+      return (Kind)((uintptr_t)ValueAndKind.getPointer() >> KindPackingBits);
+    }
   }
   
   CanType getComponentType() const {
@@ -2410,7 +2436,8 @@
       llvm_unreachable("not a computed property");
     case Kind::GettableProperty:
     case Kind::SettableProperty:
-      return ComputedPropertyId(IdValue, SetterAndIdKind.getInt());
+      return ComputedPropertyId(Computed.IdValue,
+                                Computed.SetterAndIdKind.getInt());
     }
     llvm_unreachable("unhandled kind");
   }
@@ -2440,7 +2467,7 @@
     case Kind::External:
       llvm_unreachable("not a settable computed property");
     case Kind::SettableProperty:
-      return SetterAndIdKind.getPointer();
+      return Computed.SetterAndIdKind.getPointer();
     }
     llvm_unreachable("unhandled kind");
   }
@@ -2465,8 +2492,8 @@
     case Kind::OptionalChain:
     case Kind::OptionalForce:
     case Kind::OptionalWrap:
-    case Kind::External:
       llvm_unreachable("not a computed property");
+    case Kind::External:
     case Kind::GettableProperty:
     case Kind::SettableProperty:
       return IndexEquality.Equal;
@@ -2478,8 +2505,8 @@
     case Kind::OptionalChain:
     case Kind::OptionalForce:
     case Kind::OptionalWrap:
-    case Kind::External:
       llvm_unreachable("not a computed property");
+    case Kind::External:
     case Kind::GettableProperty:
     case Kind::SettableProperty:
       return IndexEquality.Hash;
@@ -2490,13 +2517,13 @@
   
   static KeyPathPatternComponent forStoredProperty(VarDecl *property,
                                                    CanType ty) {
-    return KeyPathPatternComponent(property, Kind::StoredProperty, ty);
+    return KeyPathPatternComponent(property, ty);
   }
   
   AbstractStorageDecl *getExternalDecl() const {
     assert(getKind() == Kind::External
            && "not an external property");
-    return IdValue.Property;
+    return (AbstractStorageDecl*)ValueAndKind.getPointer();
   }
   
   ArrayRef<Substitution> getExternalSubstitutions() const {
@@ -2512,7 +2539,7 @@
                               SILFunction *indicesEquals,
                               SILFunction *indicesHash,
                               CanType ty) {
-    return KeyPathPatternComponent(identifier, Kind::GettableProperty,
+    return KeyPathPatternComponent(identifier,
                                    getter, nullptr, indices,
                                    indicesEquals, indicesHash, ty);
   }
@@ -2525,7 +2552,7 @@
                               SILFunction *indicesEquals,
                               SILFunction *indicesHash,
                               CanType ty) {
-    return KeyPathPatternComponent(identifier, Kind::SettableProperty,
+    return KeyPathPatternComponent(identifier,
                                    getter, setter, indices,
                                    indicesEquals, indicesHash, ty);
   }
@@ -2553,8 +2580,11 @@
   forExternal(AbstractStorageDecl *externalDecl,
               ArrayRef<Substitution> substitutions,
               ArrayRef<Index> indices,
+              SILFunction *indicesEquals,
+              SILFunction *indicesHash,
               CanType ty) {
-    return KeyPathPatternComponent(externalDecl, substitutions, indices, ty);
+    return KeyPathPatternComponent(externalDecl, substitutions,
+                                   indices, indicesEquals, indicesHash, ty);
   }
   
   void incrementRefCounts() const;
diff --git a/include/swift/SIL/SILProperty.h b/include/swift/SIL/SILProperty.h
index c3f1dfe..a59c3f4 100644
--- a/include/swift/SIL/SILProperty.h
+++ b/include/swift/SIL/SILProperty.h
@@ -63,6 +63,9 @@
   const KeyPathPatternComponent &getComponent() const { return Component; }
   
   void print(SILPrintContext &Ctx) const;
+  void dump() const;
+  
+  void verify(const SILModule &M) const;
 };
   
 } // end namespace swift
diff --git a/include/swift/Syntax/Serialization/SyntaxSerialization.h b/include/swift/Syntax/Serialization/SyntaxSerialization.h
index 265fe3f..63938fd 100644
--- a/include/swift/Syntax/Serialization/SyntaxSerialization.h
+++ b/include/swift/Syntax/Serialization/SyntaxSerialization.h
@@ -93,25 +93,8 @@
 struct ObjectTraits<TokenDescription> {
   static void mapping(Output &out, TokenDescription &value) {
     out.mapRequired("kind", value.Kind);
-    switch (value.Kind) {
-      case tok::contextual_keyword:
-      case tok::integer_literal:
-      case tok::floating_literal:
-      case tok::string_literal:
-      case tok::unknown:
-      case tok::code_complete:
-      case tok::identifier:
-      case tok::oper_binary_unspaced:
-      case tok::oper_binary_spaced:
-      case tok::oper_postfix:
-      case tok::oper_prefix:
-      case tok::dollarident:
-      case tok::comment:
-      case tok::string_segment:
-        out.mapRequired("text", value.Text);
-        break;
-      default:
-        break;
+    if (!isTokenTextDetermined(value.Kind)) {
+      out.mapRequired("text", value.Text);
     }
   }
 };
diff --git a/include/swift/Syntax/TokenKinds.h b/include/swift/Syntax/TokenKinds.h
index 9e7717f..03c5599 100644
--- a/include/swift/Syntax/TokenKinds.h
+++ b/include/swift/Syntax/TokenKinds.h
@@ -24,6 +24,13 @@
 
   NUM_TOKENS
 };
+
+/// Check whether a token kind is known to have any specific text content.
+/// e.g., tol::l_paren has determined text however tok::identifier doesn't.
+bool isTokenTextDetermined(tok kind);
+
+/// If a token kind has determined text, return the text; otherwise assert.
+StringRef getTokenText(tok kind);
 } // end namespace swift
 
 #endif // SWIFT_TOKENKINDS_H
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 03773f9..557d595 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2224,7 +2224,7 @@
 
   // Fix the name of the function itself.
   if (name.getBaseName() != targetName.getBaseName()) {
-    diag.fixItReplace(func->getLoc(), targetName.getBaseIdentifier().str());
+    diag.fixItReplace(func->getLoc(), targetName.getBaseName().userFacingName());
   }
 
   // Fix the argument names that need fixing.
@@ -4086,6 +4086,7 @@
 
 DependentMemberType *DependentMemberType::get(Type base,
                                               AssociatedTypeDecl *assocType) {
+  assert(assocType && "Missing associated type");
   auto properties = base->getRecursiveProperties();
   properties |= RecursiveTypeProperties::HasDependentMember;
   auto arena = getArena(properties);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index b48a3bc..44ff15a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -4773,15 +4773,15 @@
 
   auto &ctx = getASTContext();
 
-  Identifier baseName;
+  StringRef baseNameStr;
   if (isa<DestructorDecl>(this)) {
     // Deinitializers are always called "dealloc".
     return ObjCSelector(ctx, 0, ctx.Id_dealloc);
   } else if (auto func = dyn_cast<FuncDecl>(this)) {
     // Otherwise cast this to be able to access getName()
-    baseName = func->getName();
+    baseNameStr = func->getName().str();
   } else if (auto ctor = dyn_cast<ConstructorDecl>(this)) {
-    baseName = ctor->getName();
+    baseNameStr = "init";
   } else {
     llvm_unreachable("Unknown subclass of AbstractFunctionDecl");
   }
@@ -4794,10 +4794,12 @@
     if (argNames.size() != preferredName.getArgumentNames().size()) {
       return ObjCSelector();
     }
-    baseName = preferredName.getBaseIdentifier();
+    baseNameStr = preferredName.getBaseName().userFacingName();
     argNames = preferredName.getArgumentNames();
   }
 
+  auto baseName = ctx.getIdentifier(baseNameStr);
+
   if (auto accessor = dyn_cast<AccessorDecl>(this)) {
     // For a getter or setter, go through the variable or subscript decl.
     auto asd = accessor->getStorage();
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index cf25a28..e8f1ff9 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -912,18 +912,15 @@
 }
 
 /// Replace 'Self' in the given dependent type (\c depTy) with the given
-/// potential archetype, producing a new potential archetype that refers to
+/// dependent type, producing a type that refers to
 /// the nested type. This limited operation makes sure that it does not
 /// create any new potential archetypes along the way, so it should only be
 /// used in cases where we're reconstructing something that we know exists.
 static Type replaceSelfWithType(Type selfType, Type depTy) {
   if (auto depMemTy = depTy->getAs<DependentMemberType>()) {
     Type baseType = replaceSelfWithType(selfType, depMemTy->getBase());
-
-    if (auto assocType = depMemTy->getAssocType())
-      return DependentMemberType::get(baseType, assocType);
-
-    return DependentMemberType::get(baseType, depMemTy->getName());
+    assert(depMemTy->getAssocType() && "Missing associated type");
+    return DependentMemberType::get(baseType, depMemTy->getAssocType());
   }
 
   assert(depTy->is<GenericTypeParamType>() && "missing Self?");
@@ -1098,14 +1095,15 @@
   // If we haven't seen a protocol requirement, we're done.
   if (!sawProtocolRequirement) return this;
 
-  // The root archetype might be a nested type, which implies constraints
+  // The root might be a nested type, which implies constraints
   // for each of the protocols of the associated types referenced (if any).
   for (auto depMemTy = rootType->getAs<DependentMemberType>(); depMemTy;
        depMemTy = depMemTy->getBase()->getAs<DependentMemberType>()) {
-    if (auto assocType = depMemTy->getAssocType()) {
-      if (addTypeConstraint(depMemTy->getBase(), assocType->getProtocol(), nullptr))
-        return nullptr;
-    }
+    auto assocType = depMemTy->getAssocType();
+    assert(assocType);
+    if (addTypeConstraint(depMemTy->getBase(), assocType->getProtocol(),
+                          nullptr))
+      return nullptr;
   }
 
   return this;
@@ -1634,10 +1632,8 @@
   auto depMemTy = type->castTo<DependentMemberType>();
   Type newBaseType = formProtocolRelativeType(proto, baseType,
                                               depMemTy->getBase());
-  if (auto assocType = depMemTy->getAssocType())
-    return DependentMemberType::get(newBaseType, assocType);
-
-  return DependentMemberType::get(newBaseType, depMemTy->getName());
+  auto assocType = depMemTy->getAssocType();
+  return DependentMemberType::get(newBaseType, assocType);
 }
 
 const RequirementSource *FloatingRequirementSource::getSource(
@@ -2310,15 +2306,7 @@
 #endif
   }
 
-  // FIXME: Once we are no longer constructing potential archetypes with
-  // concrete nested types, we can turn this into assert(updatedAnchor);
-  if (!updatedAnchor) {
-    ++NumArchetypeAnchorCacheMisses;
-    archetypeAnchorCache.anchor =
-      builder.getCanonicalTypeParameter(members.front()->getDependentType({ }));
-    archetypeAnchorCache.lastGeneration = builder.Impl->Generation;
-  }
-
+  assert(updatedAnchor && "Couldn't update anchor?");
   return substAnchor();
 }
 
@@ -2726,8 +2714,8 @@
   if (auto depMemTy =
         nested.getDependentType(builder)->getAs<DependentMemberType>())
     assocType = depMemTy->getAssocType();
-
-  if (!assocType) return;
+  else
+    return;
 
   // Dig out the type witness.
   auto superConformance = superSource->getProtocolConformance().getConcrete();
@@ -2820,19 +2808,10 @@
                                                   depMemTy2->getName().str()))
     return compareNames;
 
-  if (auto *assocType1 = depMemTy1->getAssocType()) {
-    if (auto *assocType2 = depMemTy2->getAssocType()) {
-      if (int result = compareAssociatedTypes(assocType1, assocType2))
-        return result;
-    } else {
-      // A resolved archetype is always ordered before an unresolved one.
-      return -1;
-    }
-  } else {
-    // A resolved archetype is always ordered before an unresolved one.
-    if (depMemTy2->getAssocType())
-      return +1;
-  }
+  auto *assocType1 = depMemTy1->getAssocType();
+  auto *assocType2 = depMemTy2->getAssocType();
+  if (int result = compareAssociatedTypes(assocType1, assocType2))
+    return result;
 
   return 0;
 }
@@ -4994,8 +4973,12 @@
 
   // Recursively merge the associated types of T2 into T1.
   auto dependentT1 = T1->getDependentType(getGenericParams());
+  SmallPtrSet<Identifier, 4> visited;
   for (auto equivT2 : equivClass2Members) {
     for (auto T2Nested : equivT2->NestedTypes) {
+      // Only visit each name once.
+      if (!visited.insert(T2Nested.first).second) continue;
+
       // If T1 is concrete but T2 is not, concretize the nested types of T2.
       if (t1IsConcrete && !t2IsConcrete) {
         concretizeNestedTypeFromConcreteParent(T1, T2Nested.second.front(),
@@ -5024,9 +5007,13 @@
   }
 
   // If T2 is concrete but T1 was not, concretize the nested types of T1.
+  visited.clear();
   if (t2IsConcrete && !t1IsConcrete) {
     for (auto equivT1 : equivClass1Members) {
       for (auto T1Nested : equivT1->NestedTypes) {
+        // Only visit each name once.
+        if (!visited.insert(T1Nested.first).second) continue;
+
         concretizeNestedTypeFromConcreteParent(T2, T1Nested.second.front(),
                                                *this);
       }
diff --git a/lib/AST/SwiftNameTranslation.cpp b/lib/AST/SwiftNameTranslation.cpp
index 4996f2a..4aba091 100644
--- a/lib/AST/SwiftNameTranslation.cpp
+++ b/lib/AST/SwiftNameTranslation.cpp
@@ -73,11 +73,16 @@
 std::pair<Identifier, ObjCSelector> swift::objc_translation::
 getObjCNameForSwiftDecl(const ValueDecl *VD, DeclName PreferredName){
   ASTContext &Ctx = VD->getASTContext();
+  Identifier BaseName;
+  if (PreferredName) {
+    auto BaseNameStr = PreferredName.getBaseName().userFacingName();
+    BaseName = Ctx.getIdentifier(BaseNameStr);
+  }
   if (auto *FD = dyn_cast<AbstractFunctionDecl>(VD)) {
     return {Identifier(), FD->getObjCSelector(PreferredName)};
   } else if (auto *VAD = dyn_cast<VarDecl>(VD)) {
     if (PreferredName)
-      return {PreferredName.getBaseIdentifier(), ObjCSelector()};
+      return {BaseName, ObjCSelector()};
     return {VAD->getObjCPropertyName(), ObjCSelector()};
   } else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
     return getObjCNameForSwiftDecl(SD->getGetter(), PreferredName);
@@ -85,7 +90,7 @@
     SmallString<64> Buffer;
     {
       llvm::raw_svector_ostream OS(Buffer);
-      printSwiftEnumElemNameInObjC(EL, OS, PreferredName.getBaseIdentifier());
+      printSwiftEnumElemNameInObjC(EL, OS, BaseName);
     }
     return {Ctx.getIdentifier(Buffer.str()), ObjCSelector()};
   } else {
@@ -93,8 +98,8 @@
     StringRef Name = getNameForObjC(VD, CustomNamesOnly);
     if (!Name.empty())
       return {Ctx.getIdentifier(Name), ObjCSelector()};
-    if (!PreferredName.getBaseName().empty())
-      return {PreferredName.getBaseIdentifier(), ObjCSelector()};
+    if (PreferredName)
+      return {BaseName, ObjCSelector()};
     return {Ctx.getIdentifier(getNameForObjC(VD)), ObjCSelector()};
   }
 }
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 9f022db..e740303 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -3068,6 +3068,23 @@
         return nullptr;
       }
 
+      // FIXME: We should actually support strong ARC references and similar in
+      // C structs. That'll require some SIL and IRGen work, though.
+      if (decl->isNonTrivialToPrimitiveCopy() ||
+          decl->isNonTrivialToPrimitiveDestroy()) {
+        // Note that there is a third predicate related to these,
+        // isNonTrivialToPrimitiveDefaultInitialize. That one's not important
+        // for us because Swift never "trivially default-initializes" a struct
+        // (i.e. uses whatever bits were lying around as an initial value).
+
+        // FIXME: It would be nice to instead import the declaration but mark
+        // it as unavailable, but then it might get used as a type for an
+        // imported function and the developer would be able to use it without
+        // referencing the name, which would sidestep our availability
+        // diagnostics.
+        return nullptr;
+      }
+
       // Import the name.
       Optional<ImportedName> correctSwiftName;
       auto importedName = getClangDeclName(decl, correctSwiftName);
@@ -3921,12 +3938,14 @@
 
       // Normal case applies when we're importing an older name, or when we're
       // not an init
-      if (!isActiveSwiftVersion() || !isFactoryInit(importedName)) {
+      if (!isFactoryInit(importedName)) {
         auto result = importNonInitObjCMethodDecl(decl, dc, importedName,
                                                   selector, forceClassMethod,
                                                   accessorInfo);
+
         if (!isActiveSwiftVersion() && result)
           markAsVariant(result, *correctSwiftName);
+
         return result;
       }
 
@@ -3946,6 +3965,9 @@
                             {decl->param_begin(), decl->param_size()},
                             decl->isVariadic(), redundant);
 
+      if (!isActiveSwiftVersion() && result)
+        markAsVariant(result, *correctSwiftName);
+
       return result;
     }
 
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index d2c6249..c6788e5 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -1704,11 +1704,13 @@
 
 DefaultArgumentKind ClangImporter::Implementation::inferDefaultArgument(
     clang::QualType type, OptionalTypeKind clangOptionality,
-    Identifier baseName, unsigned numParams, StringRef argumentLabel,
+    DeclBaseName baseName, unsigned numParams, StringRef argumentLabel,
     bool isFirstParameter, bool isLastParameter, NameImporter &nameImporter) {
+  auto baseNameStr = baseName.userFacingName();
+
   // Don't introduce a default argument for setters with only a single
   // parameter.
-  if (numParams == 1 && camel_case::getFirstWord(baseName.str()) == "set")
+  if (numParams == 1 && camel_case::getFirstWord(baseNameStr) == "set")
     return DefaultArgumentKind::None;
 
   // Some nullable parameters default to 'nil'.
@@ -1730,7 +1732,7 @@
   }
 
   // Don't introduce an empty options default arguments for setters.
-  if (isFirstParameter && camel_case::getFirstWord(baseName.str()) == "set")
+  if (isFirstParameter && camel_case::getFirstWord(baseNameStr) == "set")
     return DefaultArgumentKind::None;
 
   // Option sets default to "[]" if they have "Options" in their name.
@@ -1752,8 +1754,8 @@
     if (auto objcClass = objcPtrTy->getInterfaceDecl()) {
       if (objcClass->getName() == "NSDictionary") {
         StringRef searchStr = argumentLabel;
-        if (searchStr.empty() && !baseName.empty())
-          searchStr = baseName.str();
+        if (searchStr.empty() && !baseNameStr.empty())
+          searchStr = baseNameStr;
 
         auto emptyDictionaryKind = DefaultArgumentKind::EmptyDictionary;
         if (clangOptionality == OTK_Optional)
@@ -2125,7 +2127,7 @@
 
       auto defaultArg = inferDefaultArgument(
           param->getType(), optionalityOfParam,
-          importedName.getDeclName().getBaseIdentifier(), numEffectiveParams,
+          importedName.getDeclName().getBaseName(), numEffectiveParams,
           name.empty() ? StringRef() : name.str(), paramIndex == 0,
           isLastParameter, getNameImporter());
       if (defaultArg != DefaultArgumentKind::None)
diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h
index de1aa88..290ea3b 100644
--- a/lib/ClangImporter/ImporterImpl.h
+++ b/lib/ClangImporter/ImporterImpl.h
@@ -1111,7 +1111,7 @@
   /// given Clang \c type, \c baseName, and optionality.
   static DefaultArgumentKind
   inferDefaultArgument(clang::QualType type, OptionalTypeKind clangOptionality,
-                       Identifier baseName, unsigned numParams,
+                       DeclBaseName baseName, unsigned numParams,
                        StringRef argumentLabel, bool isFirstParameter,
                        bool isLastParameter, importer::NameImporter &);
 
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 1dad16c..f89c677 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -2851,7 +2851,7 @@
 
     // Base name
     addLeadingDot(Builder);
-    Builder.addTextChunk(AFD->getBaseName().getIdentifier().str());
+    Builder.addTextChunk(AFD->getBaseName().userFacingName());
 
     // Add the argument labels.
     auto ArgLabels = AFD->getFullName().getArgumentNames();
diff --git a/lib/IDE/TypeReconstruction.cpp b/lib/IDE/TypeReconstruction.cpp
index 906a27d..0d318f4 100644
--- a/lib/IDE/TypeReconstruction.cpp
+++ b/lib/IDE/TypeReconstruction.cpp
@@ -1191,6 +1191,24 @@
   }
 }
 
+static void VisitLocalDeclVariableName(ASTContext *ast,
+                                       Demangle::NodePointer child,
+                                       VisitNodeResult &result) {
+  if (child->getNumChildren() != 2 || !child->getChild(1)->hasText()) {
+    if (result._error.empty())
+      result._error =
+          "unable to retrieve content for Node::Kind::LocalDeclName";
+    return;
+  }
+
+  auto name = child->getChild(1);
+  FindNamedDecls(ast, ast->getIdentifier(name->getText()), result);
+  if (result._decls.empty())
+    result._error = stringWithFormat(
+      "demangled identifier '%s' could not be found by name lookup",
+      name->getText());
+}
+
 // VisitNodeFunction gets used for Function, Variable and Allocator:
 static void VisitNodeFunction(
     ASTContext *ast,
@@ -1256,22 +1274,9 @@
     }
 
     case Demangle::Node::Kind::LocalDeclName: {
-      if (child->getNumChildren() != 2 || !child->getChild(1)->hasText()) {
-        if (result._error.empty())
-          result._error =
-              "unable to retrieve content for Node::Kind::LocalDeclName";
+      VisitLocalDeclVariableName(ast, child, decl_scope_result);
+      if (decl_scope_result._decls.empty())
         break;
-      }
-
-      auto name = child->getChild(1); // First child is number.
-      FindNamedDecls(ast, ast->getIdentifier(name->getText()),
-                     decl_scope_result);
-      if (decl_scope_result._decls.empty()) {
-        llvm::raw_string_ostream OS(result._error);
-        OS << "demangled identifier " << name->getText()
-           << " could not be found by name lookup";
-        break;
-      }
       std::copy(decl_scope_result._decls.begin(),
                 decl_scope_result._decls.end(),
                 back_inserter(identifier_result._decls));
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 2286fc6..e946b0d 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2631,10 +2631,10 @@
   StringRef sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift5_protos, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift4_protos, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift5_protocols";
+    sectionName = "swift4_protocols";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5prt$B";
@@ -2820,10 +2820,10 @@
   StringRef sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift5_proto, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift4_proto, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift5_protocol_conformances";
+    sectionName = "swift4_protocol_conformances";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5prtc$B";
@@ -2845,10 +2845,10 @@
   std::string sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift5_types, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift4_types, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift5_type_metadata";
+    sectionName = "swift4_type_metadata";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5tymd$B";
@@ -2910,13 +2910,13 @@
   std::string sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift5_fieldmd, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift4_fieldmd, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift5_fieldmd";
+    sectionName = "swift4_fieldmd";
     break;
   case llvm::Triple::COFF:
-    sectionName = ".swift5_fieldmd";
+    sectionName = ".swift4_fieldmd";
     break;
   default:
     llvm_unreachable("Don't know how to emit field records table for "
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index fffc48a..8314bb2 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -842,22 +842,30 @@
       // instantiation more likely to avoid needing an allocation.
       unsigned argSize = descriptorArgs.size();
       if (isInstantiableInPlace) {
-        argSize = std::max(argSize, 5u);
+        argSize = std::max(argSize, 3u);
       }
       
       fields.addInt32(argSize);
       fields.add(getAddrOfPropertyDescriptor(component.getExternalDecl()));
       
       // Add an initializer function that copies generic arguments out of the
-      // pattern argument buffer into the instantiated object, or null if there
-      // are no arguments.
-      if (component.getSubscriptIndices().empty())
+      // pattern argument buffer into the instantiated object, along with the
+      // index equality/hash operations we have from our perspective, or null
+      // if there are no arguments.
+      if (component.getSubscriptIndices().empty()) {
         fields.addInt(IntPtrTy, 0);
-      else
+        fields.addInt(IntPtrTy, 0);
+        fields.addInt(IntPtrTy, 0);
+      } else {
         fields.add(getInitializerForComputedComponent(*this, component,
                                                       operands,
                                                       genericEnv,
                                                       requirements));
+        fields.add(getAddrOfSILFunction(component.getSubscriptIndexEquals(),
+                                        NotForDefinition));
+        fields.add(getAddrOfSILFunction(component.getSubscriptIndexHash(),
+                                        NotForDefinition));
+      }
       
       // Add the generic arguments for the external context.
       for (auto arg : descriptorArgs)
diff --git a/lib/IRGen/GenRecord.h b/lib/IRGen/GenRecord.h
index 4511c46..2a467b8 100644
--- a/lib/IRGen/GenRecord.h
+++ b/lib/IRGen/GenRecord.h
@@ -267,8 +267,6 @@
       llvm::MapVector<CanType, llvm::Value *> &typeToMetadataVec,
       SILType T) const override {
     auto canType = T.getSwiftRValueType();
-    // get the size before insertions
-    auto SZ = typeToMetadataVec.size();
     for (auto &field : getFields()) {
       if (field.isEmpty())
         continue;
@@ -277,7 +275,7 @@
                                                    fType);
     }
     if (typeToMetadataVec.find(canType) == typeToMetadataVec.end() &&
-        typeToMetadataVec.size() != SZ) {
+        typeToMetadataVec.size() != 0) {
       auto *metadata = IGF.emitTypeMetadataRefForLayout(T);
       assert(metadata && "Expected Type Metadata Ref");
       typeToMetadataVec.insert(std::make_pair(canType, metadata));
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index 2b209cc..57d9cb7 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -264,7 +264,7 @@
 
     // Others, such as capture descriptors, do not have a name.
     } else {
-      var = B.finishAndCreateGlobal("\x01l__swift5_reflection_descriptor",
+      var = B.finishAndCreateGlobal("\x01l__swift4_reflection_descriptor",
                                     Alignment(4), /*isConstant*/ true,
                                     llvm::GlobalValue::PrivateLinkage);
     }
@@ -788,12 +788,12 @@
     OS << ".sw5" << FourCC << "$B";
     break;
   case llvm::Triple::ELF:
-    OS << "swift5_" << LongName;
+    OS << "swift4_" << LongName;
     break;
   case llvm::Triple::MachO:
     assert(LongName.size() <= 7 &&
            "Mach-O section name length must be <= 16 characters");
-    OS << "__TEXT,__swift5_" << LongName << ", regular, no_dead_strip";
+    OS << "__TEXT,__swift4_" << LongName << ", regular, no_dead_strip";
     break;
   case llvm::Triple::Wasm:
     llvm_unreachable("web assembly object format is not supported.");
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 4025619..e0cfc32 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -1952,7 +1952,36 @@
                         diag::expected_tok_in_sil_instr, "$")
         || parseASTType(ty, patternEnv))
       return true;
-    
+
+    SILFunction *equals = nullptr;
+    SILFunction *hash = nullptr;
+
+    while (P.consumeIf(tok::comma)) {
+      Identifier subKind;
+      SourceLoc subKindLoc;
+      if (parseSILIdentifier(subKind, subKindLoc,
+                             diag::sil_keypath_expected_component_kind))
+        return true;
+
+      if (subKind.str() == "indices_equals") {
+        if (parseSILFunctionRef(InstLoc, equals))
+          return true;
+      } else if (subKind.str() == "indices_hash") {
+        if (parseSILFunctionRef(InstLoc, hash))
+          return true;
+      } else {
+        P.diagnose(subKindLoc, diag::sil_keypath_unknown_component_kind,
+                   subKind);
+        return true;
+      }
+    }
+
+    if (!indexes.empty() != (equals && hash)) {
+      P.diagnose(componentLoc,
+                 diag::sil_keypath_external_missing_part);
+      return true;
+    }
+
     if (!parsedSubs.empty()) {
       auto genericEnv = externalDecl->getInnermostDeclContext()
                                     ->getGenericEnvironmentOfContext();
@@ -1977,12 +2006,13 @@
         sub = sub.getCanonicalSubstitution();
     }
     
+
     auto indexesCopy = P.Context.AllocateCopy(indexes);
     auto subsCopy = P.Context.AllocateCopy(subs);
     
     component = KeyPathPatternComponent::forExternal(
         cast<AbstractStorageDecl>(externalDecl),
-        subsCopy, indexesCopy, ty);
+        subsCopy, indexesCopy, equals, hash, ty);
     return false;
   } else if (componentKind.str() == "gettable_property"
              || componentKind.str() == "settable_property") {
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index b46bce7..ff229f6 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -285,19 +285,29 @@
 
   // Stored property initializers get the linkage of their containing type.
   if (isStoredPropertyInitializer()) {
-    // If the type is public, the property initializer is referenced from
-    // inlinable initializers, and has PublicNonABI linkage.
+    // Three cases:
     //
-    // Note that we don't serialize the presence of an initializer, so there's
-    // no way to reference one from another module except for this case.
+    // 1) Type is formally @_fixed_layout. Root initializers can be declared
+    //    @_inlineable. The property initializer must only reference
+    //    public symbols, and is serialized, so we give it PublicNonABI linkage.
+    //
+    // 2) Type is not formally @_fixed_layout and the module is not resilient.
+    //    Root initializers can be declared @_inlineable. This is the annoying
+    //    case. We give the initializer public linkage if the type is public.
+    //
+    // 3) Type is resilient. The property initializer is never public because
+    //    root initializers cannot be @_inlineable.
+    //
+    // FIXME: Get rid of case 2 somehow.
     if (isSerialized())
       return maybeAddExternal(SILLinkage::PublicNonABI);
 
-    // Otherwise, use the visibility of the type itself, because even if the
-    // property is private, we might reference the initializer from another
-    // file.
     d = cast<NominalTypeDecl>(d->getDeclContext());
-    neverPublic = true;
+
+    // FIXME: This should always be true.
+    if (d->getDeclContext()->getParentModule()->getResilienceStrategy() ==
+        ResilienceStrategy::Resilient)
+      neverPublic = true;
   }
 
   // The global addressor is never public for resilient globals.
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index df9f1d0..726611d 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -2152,6 +2152,17 @@
       }
       
       *this << " : $" << component.getComponentType();
+      
+      if (!component.getSubscriptIndices().empty()) {
+        *this << ", indices_equals ";
+        component.getSubscriptIndexEquals()->printName(PrintState.OS);
+        *this << " : "
+              << component.getSubscriptIndexEquals()->getLoweredType();
+        *this << ", indices_hash ";
+        component.getSubscriptIndexHash()->printName(PrintState.OS);
+        *this << " : "
+              << component.getSubscriptIndexHash()->getLoweredType();
+      }
     }
     }
   }
@@ -2614,6 +2625,11 @@
   OS << ")\n";
 }
 
+void SILProperty::dump() const {
+  SILPrintContext context(llvm::errs());
+  print(context);
+}
+
 static void printSILProperties(SILPrintContext &Ctx,
                                const SILModule::PropertyListType &Properties) {
   for (const SILProperty &P : Properties) {
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 2ac2bff..2d97c2a 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -111,6 +111,318 @@
 
 namespace {
 
+/// Verify invariants on a key path component.
+void verifyKeyPathComponent(SILModule &M,
+                            llvm::function_ref<void(bool, StringRef)> require,
+                            CanType &baseTy,
+                            CanType leafTy,
+                            const KeyPathPatternComponent &component,
+                            ArrayRef<Operand> operands,
+                            CanGenericSignature patternSig,
+                            SubstitutionList patternSubList,
+                            bool forPropertyDescriptor,
+                            bool hasIndices) {
+  auto &C = M.getASTContext();
+  
+  SubstitutionMap patternSubs;
+  if (patternSig)
+    patternSubs  = patternSig->getSubstitutionMap(patternSubList);
+  
+  auto loweredBaseTy =
+    M.Types.getLoweredType(AbstractionPattern::getOpaque(), baseTy);
+  auto componentTy = component.getComponentType().subst(patternSubs)
+    ->getCanonicalType();
+  auto loweredComponentTy =
+    M.Types.getLoweredType(AbstractionPattern::getOpaque(), componentTy);
+
+  auto checkIndexEqualsAndHash = [&]{
+    if (!component.getSubscriptIndices().empty()) {
+      // Equals should be
+      // <Sig...> @convention(thin) (RawPointer, RawPointer) -> Bool
+      {
+        auto equals = component.getSubscriptIndexEquals();
+        require(equals, "key path pattern with indexes must have equals "
+                        "operator");
+        
+        auto substEqualsType = equals->getLoweredFunctionType()
+          ->substGenericArgs(M, patternSubList);
+        
+        require(substEqualsType->getParameters().size() == 2,
+                "must have two arguments");
+        for (unsigned i = 0; i < 2; ++i) {
+          auto param = substEqualsType->getParameters()[i];
+          require(param.getConvention()
+                    == ParameterConvention::Direct_Unowned,
+                  "indices pointer should be trivial");
+          require(param.getType()->getAnyNominal()
+                    == C.getUnsafeRawPointerDecl(),
+                  "indices pointer should be an UnsafeRawPointer");
+        }
+        
+        require(substEqualsType->getResults().size() == 1,
+                "must have one result");
+        
+        require(substEqualsType->getResults()[0].getConvention()
+                  == ResultConvention::Unowned,
+                "result should be unowned");
+        require(substEqualsType->getResults()[0].getType()->getAnyNominal()
+                  == C.getBoolDecl(),
+                "result should be Bool");
+      }
+      {
+        // Hash should be
+        // <Sig...> @convention(thin) (RawPointer) -> Int
+        auto hash = component.getSubscriptIndexHash();
+        require(hash, "key path pattern with indexes must have hash "
+                      "operator");
+        
+        auto substHashType = hash->getLoweredFunctionType()
+          ->substGenericArgs(M, patternSubList);
+        
+        require(substHashType->getParameters().size() == 1,
+                "must have two arguments");
+        auto param = substHashType->getParameters()[0];
+        require(param.getConvention()
+                  == ParameterConvention::Direct_Unowned,
+                "indices pointer should be trivial");
+        require(param.getType()->getAnyNominal()
+                  == C.getUnsafeRawPointerDecl(),
+                "indices pointer should be an UnsafeRawPointer");
+        
+        require(substHashType->getResults().size() == 1,
+                "must have one result");
+        
+        require(substHashType->getResults()[0].getConvention()
+                  == ResultConvention::Unowned,
+                "result should be unowned");
+        require(substHashType->getResults()[0].getType()->getAnyNominal()
+                  == C.getIntDecl(),
+                "result should be Int");
+      }
+    } else {
+      require(!component.getSubscriptIndexEquals()
+              && !component.getSubscriptIndexHash(),
+              "component without indexes must not have equals/hash");
+    }
+  };
+
+  switch (auto kind = component.getKind()) {
+  case KeyPathPatternComponent::Kind::StoredProperty: {
+    auto property = component.getStoredPropertyDecl();
+    require(property->getDeclContext()
+             == baseTy->getAnyNominal(),
+            "property decl should be a member of the component base type");
+    switch (property->getStorageKind()) {
+    case AbstractStorageDecl::Stored:
+    case AbstractStorageDecl::StoredWithObservers:
+    case AbstractStorageDecl::StoredWithTrivialAccessors:
+      break;
+    case AbstractStorageDecl::Addressed:
+    case AbstractStorageDecl::AddressedWithObservers:
+    case AbstractStorageDecl::AddressedWithTrivialAccessors:
+    case AbstractStorageDecl::Computed:
+    case AbstractStorageDecl::ComputedWithMutableAddress:
+    case AbstractStorageDecl::InheritedWithObservers:
+      require(false, "property must be stored");
+    }
+    auto propertyTy = loweredBaseTy.getFieldType(property, M);
+    require(propertyTy.getObjectType()
+              == loweredComponentTy.getObjectType(),
+            "component type should match the maximal abstraction of the "
+            "formal type");
+    break;
+  }
+    
+  case KeyPathPatternComponent::Kind::GettableProperty:
+  case KeyPathPatternComponent::Kind::SettableProperty: {
+    if (forPropertyDescriptor) {
+      require(component.getSubscriptIndices().empty()
+              && !component.getSubscriptIndexEquals()
+              && !component.getSubscriptIndexHash(),
+              "property descriptor should not have index information");
+    } else {
+      require(hasIndices == !component.getSubscriptIndices().empty(),
+              "component for subscript should have indices");
+    }
+  
+    ParameterConvention normalArgConvention;
+    if (M.getOptions().EnableGuaranteedNormalArguments)
+      normalArgConvention = ParameterConvention::Indirect_In_Guaranteed;
+    else
+      normalArgConvention = ParameterConvention::Indirect_In;
+  
+    // Getter should be <Sig...> @convention(thin) (@in_guaranteed Base) -> @out Result
+    {
+      auto getter = component.getComputedPropertyGetter();
+      auto substGetterType = getter->getLoweredFunctionType()
+        ->substGenericArgs(M, patternSubList);
+      require(substGetterType->getRepresentation() ==
+                SILFunctionTypeRepresentation::Thin,
+              "getter should be a thin function");
+      
+      require(substGetterType->getNumParameters() == 1 + hasIndices,
+              "getter should have one parameter");
+      auto baseParam = substGetterType->getParameters()[0];
+      require(baseParam.getConvention() == normalArgConvention,
+              "getter base parameter should have normal arg convention");
+      require(baseParam.getType() == loweredBaseTy.getSwiftRValueType(),
+              "getter base parameter should match base of component");
+      
+      if (hasIndices) {
+        auto indicesParam = substGetterType->getParameters()[1];
+        require(indicesParam.getConvention()
+                  == ParameterConvention::Direct_Unowned,
+                "indices pointer should be trivial");
+        require(indicesParam.getType()->getAnyNominal()
+                  == C.getUnsafeRawPointerDecl(),
+                "indices pointer should be an UnsafeRawPointer");
+      }
+
+      require(substGetterType->getNumResults() == 1,
+              "getter should have one result");
+      auto result = substGetterType->getResults()[0];
+      require(result.getConvention() == ResultConvention::Indirect,
+              "getter result should be @out");
+      require(result.getType() == loweredComponentTy.getSwiftRValueType(),
+              "getter result should match the maximal abstraction of the "
+              "formal component type");
+    }
+    
+    if (kind == KeyPathPatternComponent::Kind::SettableProperty) {
+      // Setter should be
+      // <Sig...> @convention(thin) (@in_guaranteed Result, @in Base) -> ()
+      
+      auto setter = component.getComputedPropertySetter();
+      auto substSetterType = setter->getLoweredFunctionType()
+        ->substGenericArgs(M, patternSubList);
+      
+      require(substSetterType->getRepresentation() ==
+                SILFunctionTypeRepresentation::Thin,
+              "setter should be a thin function");
+      
+      require(substSetterType->getNumParameters() == 2 + hasIndices,
+              "setter should have two parameters");
+
+      auto newValueParam = substSetterType->getParameters()[0];
+      // TODO: This should probably be unconditionally +1 when we
+      // can represent that.
+      require(newValueParam.getConvention() == normalArgConvention,
+              "setter value parameter should havee normal arg convention");
+
+      auto baseParam = substSetterType->getParameters()[1];
+      require(baseParam.getConvention() == normalArgConvention
+              || baseParam.getConvention() ==
+                  ParameterConvention::Indirect_Inout,
+              "setter base parameter should be normal arg convention "
+              "or @inout");
+      
+      if (hasIndices) {
+        auto indicesParam = substSetterType->getParameters()[2];
+        require(indicesParam.getConvention()
+                  == ParameterConvention::Direct_Unowned,
+                "indices pointer should be trivial");
+        require(indicesParam.getType()->getAnyNominal()
+                  == C.getUnsafeRawPointerDecl(),
+                "indices pointer should be an UnsafeRawPointer");
+      }
+
+      require(newValueParam.getType() ==
+                loweredComponentTy.getSwiftRValueType(),
+              "setter value should match the maximal abstraction of the "
+              "formal component type");
+      
+      require(substSetterType->getNumResults() == 0,
+              "setter should have no results");
+    }
+    
+    if (!forPropertyDescriptor) {
+      for (auto &index : component.getSubscriptIndices()) {
+        auto opIndex = index.Operand;
+        auto contextType =
+          index.LoweredType.subst(M, patternSubs);
+        require(contextType == operands[opIndex].get()->getType(),
+                "operand must match type required by pattern");
+        SILType loweredType = index.LoweredType;
+        require(loweredType.isLoweringOf(M, index.FormalType),
+                "pattern index formal type doesn't match lowered type");
+      }
+
+      checkIndexEqualsAndHash();
+    }
+    
+    break;
+  }
+  case KeyPathPatternComponent::Kind::External: {
+    // The component type should match the substituted type of the
+    // referenced property.
+    auto decl = component.getExternalDecl();
+    auto sig = decl->getInnermostDeclContext()
+                   ->getGenericSignatureOfContext();
+    SubstitutionMap subs;
+    CanGenericSignature canSig = nullptr;
+    if (sig) {
+      canSig = sig->getCanonicalSignature();
+      subs = sig->getSubstitutionMap(component.getExternalSubstitutions());
+    }
+    auto substType = component.getExternalDecl()->getStorageInterfaceType()
+      .subst(subs);
+    require(substType->isEqual(component.getComponentType()),
+            "component type should match storage type of referenced "
+            "declaration");
+
+    // Index types should match the lowered index types expected by the
+    // external declaration.
+    if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
+      auto indexParams = sub->getIndices();
+      require(indexParams->size() == component.getSubscriptIndices().size(),
+              "number of subscript indices should match referenced decl");
+      for (unsigned i : indices(*indexParams)) {
+        auto param = (*indexParams)[i];
+        auto &index = component.getSubscriptIndices()[i];
+        auto paramTy = param->getInterfaceType()->getCanonicalType();
+        auto substParamTy = paramTy.subst(subs);
+        auto loweredTy = M.Types.getLoweredType(
+          AbstractionPattern(canSig, paramTy), substParamTy);
+        require(index.LoweredType == loweredTy,
+                "index lowered types should match referenced decl");
+        require(index.FormalType == substParamTy->getCanonicalType(),
+                "index formal types should match referenced decl");
+      }
+      
+      checkIndexEqualsAndHash();
+    } else {
+      require(component.getSubscriptIndices().empty(),
+              "external var reference should not apply indices");
+      require(!component.getSubscriptIndexEquals()
+              && !component.getSubscriptIndexHash(),
+              "external var reference should not apply hash");
+    }
+    
+    break;
+  }
+  case KeyPathPatternComponent::Kind::OptionalChain: {
+    require(baseTy->getOptionalObjectType()->isEqual(componentTy),
+            "chaining component should unwrap optional");
+    require((bool)leafTy->getOptionalObjectType(),
+            "key path with chaining component should have optional "
+            "result");
+    break;
+  }
+  case KeyPathPatternComponent::Kind::OptionalForce: {
+    require(baseTy->getOptionalObjectType()->isEqual(componentTy),
+            "forcing component should unwrap optional");
+    break;
+  }
+  case KeyPathPatternComponent::Kind::OptionalWrap: {
+    require(componentTy->getOptionalObjectType()->isEqual(baseTy),
+            "wrapping component should wrap optional");
+    break;
+  }
+  }
+  
+  baseTy = componentTy;
+}
+
 /// The SIL verifier walks over a SIL function / basic block / instruction,
 /// checking and enforcing its invariants.
 class SILVerifier : public SILVerifierBase<SILVerifier> {
@@ -3801,279 +4113,39 @@
                                           pattern->getGenericSignature());
       
       for (auto &component : pattern->getComponents()) {
-        auto loweredBaseTy =
-          F.getModule().Types.getLoweredType(AbstractionPattern::getOpaque(),
-                                             baseTy);
-        auto componentTy = component.getComponentType().subst(patternSubs)
-          ->getCanonicalType();
-        auto loweredComponentTy =
-          F.getModule().Types.getLoweredType(AbstractionPattern::getOpaque(),
-                                             componentTy);
-        
-        switch (auto kind = component.getKind()) {
-        case KeyPathPatternComponent::Kind::StoredProperty: {
-          auto property = component.getStoredPropertyDecl();
-          require(property->getDeclContext()
-                   == baseTy->getAnyNominal(),
-                  "property decl should be a member of the component base type");
-          switch (property->getStorageKind()) {
-          case AbstractStorageDecl::Stored:
-          case AbstractStorageDecl::StoredWithObservers:
-          case AbstractStorageDecl::StoredWithTrivialAccessors:
-            break;
-          case AbstractStorageDecl::Addressed:
-          case AbstractStorageDecl::AddressedWithObservers:
-          case AbstractStorageDecl::AddressedWithTrivialAccessors:
-          case AbstractStorageDecl::Computed:
-          case AbstractStorageDecl::ComputedWithMutableAddress:
-          case AbstractStorageDecl::InheritedWithObservers:
-            require(false, "property must be stored");
-          }
-          auto propertyTy = loweredBaseTy.getFieldType(property, F.getModule());
-          require(propertyTy.getObjectType()
-                    == loweredComponentTy.getObjectType(),
-                  "component type should match the maximal abstraction of the "
-                  "formal type");
-          break;
-        }
-          
-        case KeyPathPatternComponent::Kind::GettableProperty:
-        case KeyPathPatternComponent::Kind::SettableProperty: {
-          bool hasIndices = !component.getSubscriptIndices().empty();
-        
-          ParameterConvention normalArgConvention;
-          if (F.getModule().getOptions().EnableGuaranteedNormalArguments)
-            normalArgConvention = ParameterConvention::Indirect_In_Guaranteed;
+        bool hasIndices;
+        switch (component.getKind()) {
+        case KeyPathPatternComponent::Kind::External:
+          if (auto subscript =
+                           dyn_cast<SubscriptDecl>(component.getExternalDecl()))
+            hasIndices = subscript->getIndices()->size() != 0;
           else
-            normalArgConvention = ParameterConvention::Indirect_In;
+            hasIndices = false;
+          break;
         
-          // Getter should be <Sig...> @convention(thin) (@in_guaranteed Base) -> @out Result
-          {
-            auto getter = component.getComputedPropertyGetter();
-            auto substGetterType = getter->getLoweredFunctionType()
-              ->substGenericArgs(F.getModule(), KPI->getSubstitutions());
-            require(substGetterType->getRepresentation() ==
-                      SILFunctionTypeRepresentation::Thin,
-                    "getter should be a thin function");
-            
-            require(substGetterType->getNumParameters() == 1 + hasIndices,
-                    "getter should have one parameter");
-            auto baseParam = substGetterType->getParameters()[0];
-            require(baseParam.getConvention() == normalArgConvention,
-                    "getter base parameter should have normal arg convention");
-            require(baseParam.getType() == loweredBaseTy.getSwiftRValueType(),
-                    "getter base parameter should match base of component");
-            
-            if (hasIndices) {
-              auto indicesParam = substGetterType->getParameters()[1];
-              require(indicesParam.getConvention()
-                        == ParameterConvention::Direct_Unowned,
-                      "indices pointer should be trivial");
-              require(indicesParam.getType()->getAnyNominal()
-                        == C.getUnsafeRawPointerDecl(),
-                      "indices pointer should be an UnsafeRawPointer");
-            }
-
-            require(substGetterType->getNumResults() == 1,
-                    "getter should have one result");
-            auto result = substGetterType->getResults()[0];
-            require(result.getConvention() == ResultConvention::Indirect,
-                    "getter result should be @out");
-            require(result.getType() == loweredComponentTy.getSwiftRValueType(),
-                    "getter result should match the maximal abstraction of the "
-                    "formal component type");
-          }
-          
-          if (kind == KeyPathPatternComponent::Kind::SettableProperty) {
-            // Setter should be
-            // <Sig...> @convention(thin) (@in_guaranteed Result, @in Base) -> ()
-            
-            auto setter = component.getComputedPropertySetter();
-            auto substSetterType = setter->getLoweredFunctionType()
-              ->substGenericArgs(F.getModule(), KPI->getSubstitutions());
-            
-            require(substSetterType->getRepresentation() ==
-                      SILFunctionTypeRepresentation::Thin,
-                    "setter should be a thin function");
-            
-            require(substSetterType->getNumParameters() == 2 + hasIndices,
-                    "setter should have two parameters");
-
-            auto newValueParam = substSetterType->getParameters()[0];
-            // TODO: This should probably be unconditionally +1 when we
-            // can represent that.
-            require(newValueParam.getConvention() == normalArgConvention,
-                    "setter value parameter should havee normal arg convention");
-
-            auto baseParam = substSetterType->getParameters()[1];
-            require(baseParam.getConvention() == normalArgConvention
-                    || baseParam.getConvention() ==
-                        ParameterConvention::Indirect_Inout,
-                    "setter base parameter should be normal arg convention "
-                    "or @inout");
-            
-            if (hasIndices) {
-              auto indicesParam = substSetterType->getParameters()[2];
-              require(indicesParam.getConvention()
-                        == ParameterConvention::Direct_Unowned,
-                      "indices pointer should be trivial");
-              require(indicesParam.getType()->getAnyNominal()
-                        == C.getUnsafeRawPointerDecl(),
-                      "indices pointer should be an UnsafeRawPointer");
-            }
-
-            require(newValueParam.getType() ==
-                      loweredComponentTy.getSwiftRValueType(),
-                    "setter value should match the maximal abstraction of the "
-                    "formal component type");
-            
-            require(substSetterType->getNumResults() == 0,
-                    "setter should have no results");
-          }
-          
-          for (auto &index : component.getSubscriptIndices()) {
-            auto opIndex = index.Operand;
-            auto contextType =
-              index.LoweredType.subst(F.getModule(), patternSubs);
-            requireSameType(contextType,
-                            KPI->getAllOperands()[opIndex].get()->getType(),
-                            "operand must match type required by pattern");
-            require(isLoweringOf(index.LoweredType, index.FormalType),
-                    "pattern index formal type doesn't match lowered type");
-          }
-          
-          if (!component.getSubscriptIndices().empty()) {
-            // Equals should be
-            // <Sig...> @convention(thin) (RawPointer, RawPointer) -> Bool
-            {
-              auto equals = component.getSubscriptIndexEquals();
-              require(equals, "key path pattern with indexes must have equals "
-                              "operator");
-              
-              auto substEqualsType = equals->getLoweredFunctionType()
-                ->substGenericArgs(F.getModule(), KPI->getSubstitutions());
-              
-              require(substEqualsType->getParameters().size() == 2,
-                      "must have two arguments");
-              for (unsigned i = 0; i < 2; ++i) {
-                auto param = substEqualsType->getParameters()[i];
-                require(param.getConvention()
-                          == ParameterConvention::Direct_Unowned,
-                        "indices pointer should be trivial");
-                require(param.getType()->getAnyNominal()
-                          == C.getUnsafeRawPointerDecl(),
-                        "indices pointer should be an UnsafeRawPointer");
-              }
-              
-              require(substEqualsType->getResults().size() == 1,
-                      "must have one result");
-              
-              require(substEqualsType->getResults()[0].getConvention()
-                        == ResultConvention::Unowned,
-                      "result should be unowned");
-              require(substEqualsType->getResults()[0].getType()->getAnyNominal()
-                        == C.getBoolDecl(),
-                      "result should be Bool");
-            }
-            {
-              // Hash should be
-              // <Sig...> @convention(thin) (RawPointer) -> Int
-              auto hash = component.getSubscriptIndexHash();
-              require(hash, "key path pattern with indexes must have hash "
-                            "operator");
-              
-              auto substHashType = hash->getLoweredFunctionType()
-                ->substGenericArgs(F.getModule(), KPI->getSubstitutions());
-              
-              require(substHashType->getParameters().size() == 1,
-                      "must have two arguments");
-              auto param = substHashType->getParameters()[0];
-              require(param.getConvention()
-                        == ParameterConvention::Direct_Unowned,
-                      "indices pointer should be trivial");
-              require(param.getType()->getAnyNominal()
-                        == C.getUnsafeRawPointerDecl(),
-                      "indices pointer should be an UnsafeRawPointer");
-              
-              require(substHashType->getResults().size() == 1,
-                      "must have one result");
-              
-              require(substHashType->getResults()[0].getConvention()
-                        == ResultConvention::Unowned,
-                      "result should be unowned");
-              require(substHashType->getResults()[0].getType()->getAnyNominal()
-                        == C.getIntDecl(),
-                      "result should be Int");
-            }
-          } else {
-            require(!component.getSubscriptIndexEquals()
-                    && !component.getSubscriptIndexHash(),
-                    "component without indexes must not have equals/hash");
-          }
-
+        case KeyPathPatternComponent::Kind::GettableProperty:
+        case KeyPathPatternComponent::Kind::SettableProperty:
+          hasIndices = !component.getSubscriptIndices().empty();
           break;
-        }
-        case KeyPathPatternComponent::Kind::External: {
-          // The component type should match the substituted type of the
-          // referenced property.
-          auto decl = component.getExternalDecl();
-          auto sig = decl->getInnermostDeclContext()
-                         ->getGenericSignatureOfContext()
-                         ->getCanonicalSignature();
-          auto subs =
-                sig->getSubstitutionMap(component.getExternalSubstitutions());
-          auto substType = component.getExternalDecl()->getStorageInterfaceType()
-            .subst(subs);
-          require(substType->isEqual(component.getComponentType()),
-                  "component type should match storage type of referenced "
-                  "declaration");
-
-          // Index types should match the lowered index types expected by the
-          // external declaration.
-          if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
-            auto indexParams = sub->getIndices();
-            require(indexParams->size() == component.getSubscriptIndices().size(),
-                    "number of subscript indices should match referenced decl");
-            for (unsigned i : indices(*indexParams)) {
-              auto param = (*indexParams)[i];
-              auto &index = component.getSubscriptIndices()[i];
-              auto paramTy = param->getInterfaceType()->getCanonicalType();
-              auto substParamTy = paramTy.subst(subs);
-              auto loweredTy = F.getModule().Types.getLoweredType(
-                AbstractionPattern(sig, paramTy), substParamTy);
-              requireSameType(index.LoweredType, loweredTy,
-                            "index lowered types should match referenced decl");
-              require(index.FormalType == substParamTy->getCanonicalType(),
-                      "index formal types should match referenced decl");
-            }
-          } else {
-            require(component.getSubscriptIndices().empty(),
-                    "external var reference should not apply indices");
-          }
-          
-          break;
-        }
-        case KeyPathPatternComponent::Kind::OptionalChain: {
-          require(baseTy->getOptionalObjectType()->isEqual(componentTy),
-                  "chaining component should unwrap optional");
-          require(leafTy->getOptionalObjectType(),
-                  "key path with chaining component should have optional "
-                  "result");
-          break;
-        }
-        case KeyPathPatternComponent::Kind::OptionalForce: {
-          require(baseTy->getOptionalObjectType()->isEqual(componentTy),
-                  "forcing component should unwrap optional");
-          break;
-        }
-        case KeyPathPatternComponent::Kind::OptionalWrap: {
-          require(componentTy->getOptionalObjectType()->isEqual(baseTy),
-                  "wrapping component should wrap optional");
-          break;
-        }
-        }
         
-        baseTy = componentTy;
+        case KeyPathPatternComponent::Kind::StoredProperty:
+        case KeyPathPatternComponent::Kind::OptionalChain:
+        case KeyPathPatternComponent::Kind::OptionalWrap:
+        case KeyPathPatternComponent::Kind::OptionalForce:
+          hasIndices = false;
+          break;
+        }
+      
+        verifyKeyPathComponent(F.getModule(),
+          [&](bool reqt, StringRef message) { _require(reqt, message); },
+          baseTy,
+          leafTy,
+          component,
+          KPI->getAllOperands(),
+          KPI->getPattern()->getGenericSignature(),
+          KPI->getSubstitutions(),
+          /*property descriptor*/false,
+          hasIndices);
       }
     }
     require(CanType(baseTy) == CanType(leafTy),
@@ -4645,6 +4717,62 @@
   SILVerifier(*this, SingleFunction).verify();
 }
 
+/// Verify that a property descriptor follows invariants.
+void SILProperty::verify(const SILModule &M) const {
+#ifdef NDEBUG
+  if (!M.getOptions().VerifyAll)
+    return;
+#endif
+
+  auto *decl = getDecl();
+  auto *dc = decl->getInnermostDeclContext();
+  auto &component = getComponent();
+  
+  // TODO: base type for global/static descriptors
+  auto sig = dc->getGenericSignatureOfContext();
+  auto baseTy = dc->getInnermostTypeContext()->getSelfInterfaceType()
+                  ->getCanonicalType(sig);
+  auto leafTy = decl->getStorageInterfaceType()->getReferenceStorageReferent()
+                    ->getCanonicalType(sig);
+  SubstitutionList subs;
+  if (sig) {
+    auto env = dc->getGenericEnvironmentOfContext();
+    subs = env->getForwardingSubstitutions();
+    baseTy = env->mapTypeIntoContext(baseTy)->getCanonicalType();
+    leafTy = env->mapTypeIntoContext(leafTy)->getCanonicalType();
+  }
+  bool hasIndices = false;
+  if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
+    hasIndices = subscript->getIndices()->size() != 0;
+  }
+
+  auto canSig = sig ? sig->getCanonicalSignature() : nullptr;
+  Lowering::GenericContextScope scope(M.Types, canSig);
+
+  auto require = [&](bool reqt, StringRef message) {
+      if (!reqt) {
+        llvm::errs() << message << "\n";
+        assert(false && "invoking standard assertion failure");
+      }
+    };
+
+  verifyKeyPathComponent(const_cast<SILModule&>(M),
+    require,
+    baseTy,
+    leafTy,
+    component,
+    {},
+    canSig,
+    subs,
+    /*property descriptor*/true,
+    hasIndices);
+  
+  // verifyKeyPathComponent updates baseTy to be the projected type of the
+  // component, which should be the same as the type of the declared storage
+  require(baseTy == leafTy,
+          "component type of property descriptor should match type of storage");
+}
+
 /// Verify that a vtable follows invariants.
 void SILVTable::verify(const SILModule &M) const {
 #ifdef NDEBUG
@@ -4879,6 +5007,12 @@
     }
     wt.verify(*this);
   }
+  
+  // Check property descriptors.
+  DEBUG(llvm::dbgs() << "*** Checking property descriptors ***\n");
+  for (auto &prop : getPropertyList()) {
+    prop.verify(*this);
+  }
 }
 
 /// Determine whether an instruction may not have a SILDebugScope.
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 6702ccf..b167e74 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -1172,6 +1172,10 @@
   if (!decl->getGetter())
     return false;
 
+  // If the getter is mutating, we cannot form a keypath to it at all.
+  if (decl->isGetterMutating())
+    return false;
+
   // TODO: If previous versions of an ABI-stable binary needed the descriptor,
   // then we still do.
 
@@ -1219,7 +1223,9 @@
   
   Type baseTy;
   if (decl->getDeclContext()->isTypeContext()) {
-    baseTy = decl->getDeclContext()->getSelfInterfaceType();
+    baseTy = decl->getDeclContext()->getSelfInterfaceType()
+                 ->getCanonicalType(decl->getInnermostDeclContext()
+                                        ->getGenericSignatureOfContext());
     if (decl->isStatic()) {
       // TODO: Static properties should eventually be referenceable as
       // keypaths from T.Type -> Element
@@ -1237,35 +1243,39 @@
   if (genericEnv)
     subs = genericEnv->getForwardingSubstitutions();
   
-  // TODO: The hashable conformances for the indices need to be provided by the
-  // client, since they may be post-hoc conformances, or a generic subscript
-  // may be invoked with hashable substitutions. We may eventually allow for
-  // non-hashable keypaths as well.
-  SmallVector<ProtocolConformanceRef, 4> indexHashables;
   if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
-    auto hashable = getASTContext().getProtocol(KnownProtocolKind::Hashable);
     for (auto *index : *sub->getIndices()) {
+      // Keypaths can't capture inout indices.
       if (index->isInOut())
         return;
+
+      // TODO: Handle reabstraction and tuple explosion in thunk generation.
+      // This wasn't previously a concern because anything that was Hashable
+      // had only one abstraction level and no explosion.
       auto indexTy = index->getInterfaceType();
+      
+      if (isa<TupleType>(indexTy->getCanonicalType(sub->getGenericSignature())))
+        return;
+      
       if (genericEnv)
         indexTy = genericEnv->mapTypeIntoContext(indexTy);
       
-      auto conformance = sub->getModuleContext()
-                            ->lookupConformance(indexTy, hashable);
-      if (!conformance)
+      auto indexLoweredTy = Types.getLoweredType(indexTy);
+      auto indexOpaqueLoweredTy =
+        Types.getLoweredType(AbstractionPattern::getOpaque(), indexTy);
+      
+      if (indexOpaqueLoweredTy.getAddressType()
+             != indexLoweredTy.getAddressType())
         return;
-      if (!conformance->getConditionalRequirements().empty())
-        return;
-      indexHashables.push_back(*conformance);
     }
   }
-  
+
   auto component = emitKeyPathComponentForDecl(SILLocation(decl),
                                                genericEnv,
                                                baseOperand, needsGenericContext,
-                                               subs, decl, indexHashables,
-                                               baseTy->getCanonicalType());
+                                               subs, decl, {},
+                                               baseTy->getCanonicalType(),
+                                               /*property descriptor*/ true);
   
   (void)SILProperty::create(M, /*serialized*/ false, decl, component);
 }
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index 7ae1bf7..e388aba 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -347,7 +347,8 @@
                               SubstitutionList subs,
                               AbstractStorageDecl *storage,
                               ArrayRef<ProtocolConformanceRef> indexHashables,
-                              CanType baseTy);
+                              CanType baseTy,
+                              bool forPropertyDescriptor);
 
   /// Known functions for bridging.
   SILDeclRef getStringToNSStringFn();
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index aa265e3..06be890 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -4945,35 +4945,16 @@
   // If the parameter is indirect, we need to drop the value into
   // temporary memory.
   if (SGF.silConv.isSILIndirect(selfParam)) {
-    // It's usually a really bad idea to materialize when we're
-    // about to pass a value to an inout argument, because it's a
-    // really easy way to silently drop modifications (e.g. from a
-    // mutating getter in a writeback pair).  Our caller should
-    // always take responsibility for that decision (by doing the
-    // materialization itself).
-    //
-    // However, when the base is a reference type and the target is
-    // a non-class protocol, this is innocuous.
-#ifndef NDEBUG
-    auto isNonClassProtocolMember = [](Decl *d) {
-      auto p = d->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
-      return (p && !p->requiresClass());
-    };
-#endif
-    assert((!selfParam.isIndirectMutating() ||
-            (baseFormalType->isAnyClassReferenceType() &&
-             isNonClassProtocolMember(accessor.getDecl()))) &&
+    // It's a really bad idea to materialize when we're about to
+    // pass a value to an inout argument, because it's a really easy
+    // way to silently drop modifications (e.g. from a mutating
+    // getter in a writeback pair).  Our caller should always take
+    // responsibility for that decision (by doing the materialization
+    // itself).
+    assert(!selfParam.isIndirectMutating() &&
            "passing unmaterialized r-value as inout argument");
 
     base = base.materialize(SGF, loc);
-    if (selfParam.isIndirectInOut()) {
-      // Drop the cleanup if we have one.
-      auto baseLV = ManagedValue::forLValue(base.getValue());
-      return ArgumentSource(
-          loc, LValue::forAddress(baseLV, None,
-                                  AbstractionPattern(baseFormalType),
-                                  baseFormalType));
-    }
   }
 
   return ArgumentSource(loc, RValue(SGF, loc, baseFormalType, base));
@@ -5301,23 +5282,6 @@
 }
 
 
-RValue SILGenFunction::emitApplyConversionFunction(SILLocation loc,
-                                                   Expr *funcExpr,
-                                                   Type resultType,
-                                                   RValue &&operand) {
-  // Walk the function expression, which should produce a reference to the
-  // callee, leaving the final curry level unapplied.
-  CallEmission emission = CallEmission::forApplyExpr(*this, funcExpr);
-  // Rewrite the operand type to the expected argument type, to handle tuple
-  // conversions etc.
-  auto funcTy = cast<FunctionType>(funcExpr->getType()->getCanonicalType());
-  operand.rewriteType(funcTy.getInput());
-  // Add the operand as the final callsite.
-  emission.addCallSite(loc, ArgumentSource(loc, std::move(operand)),
-                       resultType->getCanonicalType(), funcTy->throws());
-  return emission.apply();
-}
-
 // Create a partial application of a dynamic method, applying bridging thunks
 // if necessary.
 static ManagedValue emitDynamicPartialApply(SILGenFunction &SGF,
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 16affcc..cdaa12b 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -3050,22 +3050,24 @@
   return paramSubstValue;
 }
 
+using IndexTypePair = std::pair<CanType, SILType>;
+
 /// Helper function to load the captured indexes out of a key path component
 /// in order to invoke the accessors on that key path. A component with captured
 /// indexes passes down a pointer to those captures to the accessor thunks,
 /// which we can copy out of to produce values we can pass to the real
 /// accessor functions.
 static RValue loadIndexValuesForKeyPathComponent(SILGenFunction &SGF,
-                         SILLocation loc,
-                         ArrayRef<KeyPathPatternComponent::Index> indexes,
-                         SILValue pointer) {
+                                               SILLocation loc,
+                                               ArrayRef<IndexTypePair> indexes,
+                                               SILValue pointer) {
   // If no indexes, do nothing.
   if (indexes.empty())
     return RValue();
   
   SmallVector<TupleTypeElt, 2> indexElts;
   for (auto &elt : indexes) {
-    indexElts.push_back(SGF.F.mapTypeIntoContext(elt.FormalType));
+    indexElts.push_back(SGF.F.mapTypeIntoContext(elt.first));
   }
   
   auto indexTupleTy = TupleType::get(indexElts, SGF.getASTContext())
@@ -3082,11 +3084,11 @@
     if (indexes.size() > 1) {
       eltAddr = SGF.B.createTupleElementAddr(loc, eltAddr, i);
     }
-    auto ty = SGF.F.mapTypeIntoContext(indexes[i].LoweredType);
+    auto ty = SGF.F.mapTypeIntoContext(indexes[i].second);
     auto value = SGF.emitLoad(loc, eltAddr,
                               SGF.getTypeLowering(ty),
                               SGFContext(), IsNotTake);
-    indexValue.addElement(SGF, value, indexes[i].FormalType, loc);
+    indexValue.addElement(SGF, value, indexes[i].first, loc);
   }
   
   return indexValue;
@@ -3098,7 +3100,7 @@
                          SubstitutionList subs,
                          AccessStrategy strategy,
                          GenericEnvironment *genericEnv,
-                         ArrayRef<KeyPathPatternComponent::Index> indexes,
+                         ArrayRef<IndexTypePair> indexes,
                          CanType baseType,
                          CanType propertyType) {
   auto genericSig = genericEnv
@@ -3219,7 +3221,7 @@
                           SubstitutionList subs,
                           AccessStrategy strategy,
                           GenericEnvironment *genericEnv,
-                          ArrayRef<KeyPathPatternComponent::Index> indexes,
+                          ArrayRef<IndexTypePair> indexes,
                           CanType baseType,
                           CanType propertyType) {
   auto genericSig = genericEnv
@@ -3734,13 +3736,11 @@
 }
 
 static void
-lowerKeyPathSubscriptIndexPatterns(
+lowerKeyPathSubscriptIndexTypes(
                  SILGenModule &SGM,
-                 SmallVectorImpl<KeyPathPatternComponent::Index> &indexPatterns,
+                 SmallVectorImpl<IndexTypePair> &indexPatterns,
                  SubscriptDecl *subscript,
                  SubstitutionList subscriptSubs,
-                 ArrayRef<ProtocolConformanceRef> indexHashables,
-                 unsigned &baseOperand,
                  bool &needsGenericContext) {
   // Capturing an index value dependent on the generic context means we
   // need the generic context captured in the key path.
@@ -3753,16 +3753,11 @@
   }
   needsGenericContext |= subscriptSubstTy->hasArchetype();
 
-  unsigned i = 0;
   for (auto *index : *subscript->getIndices()) {
     auto indexTy = index->getInterfaceType();
     if (sig) {
       indexTy = indexTy.subst(subMap);
     }
-    auto hashable = indexHashables[i++];
-    assert(hashable.isAbstract() ||
-           hashable.getConcrete()->getType()->isEqual(indexTy));
-
     auto indexLoweredTy = SGM.Types.getLoweredType(
                                                 AbstractionPattern::getOpaque(),
                                                 indexTy);
@@ -3770,11 +3765,28 @@
                      indexLoweredTy.getSwiftRValueType()->mapTypeOutOfContext()
                                                         ->getCanonicalType(),
                      indexLoweredTy.getCategory());
-    indexPatterns.push_back({baseOperand++,
-                             indexTy->mapTypeOutOfContext()
+    indexPatterns.push_back({indexTy->mapTypeOutOfContext()
                                     ->getCanonicalType(),
-                             indexLoweredTy,
-                             hashable});
+                             indexLoweredTy});
+  }
+};
+
+static void
+lowerKeyPathSubscriptIndexPatterns(
+                 SmallVectorImpl<KeyPathPatternComponent::Index> &indexPatterns,
+                 ArrayRef<IndexTypePair> indexTypes,
+                 ArrayRef<ProtocolConformanceRef> indexHashables,
+                 unsigned &baseOperand) {
+  for (unsigned i : indices(indexTypes)) {
+    CanType formalTy;
+    SILType loweredTy;
+    std::tie(formalTy, loweredTy) = indexTypes[i];
+    auto hashable = indexHashables[i];
+    assert(hashable.isAbstract() ||
+           hashable.getConcrete()->getType()->mapTypeOutOfContext()
+                                 ->isEqual(formalTy));
+
+    indexPatterns.push_back({baseOperand++, formalTy, loweredTy, hashable});
   }
 };
 
@@ -3786,7 +3798,8 @@
                                 SubstitutionList subs,
                                 AbstractStorageDecl *storage,
                                 ArrayRef<ProtocolConformanceRef> indexHashables,
-                                CanType baseTy) {
+                                CanType baseTy,
+                                bool forPropertyDescriptor) {
   if (auto var = dyn_cast<VarDecl>(storage)) {
     CanType componentTy;
     if (!var->getDeclContext()->isTypeContext()) {
@@ -3794,7 +3807,8 @@
     } else {
       componentTy = baseTy->getTypeOfMember(SwiftModule, var)
         ->getReferenceStorageReferent()
-        ->getCanonicalType();
+        ->getCanonicalType(genericEnv ? genericEnv->getGenericSignature()
+                                      : nullptr);
     }
   
     switch (auto strategy = var->getAccessStrategy(AccessSemantics::Ordinary,
@@ -3859,26 +3873,31 @@
       baseSubscriptTy->mapTypeOutOfContext()->getCanonicalType());
     auto componentTy = baseSubscriptInterfaceTy.getResult();
   
-    SmallVector<KeyPathPatternComponent::Index, 4> indexPatterns;
-    lowerKeyPathSubscriptIndexPatterns(*this, indexPatterns,
-                                       decl, subs, indexHashables,
-                                       baseOperand,
-                                       needsGenericContext);
+    SmallVector<IndexTypePair, 4> indexTypes;
+    lowerKeyPathSubscriptIndexTypes(*this, indexTypes,
+                                    decl, subs,
+                                    needsGenericContext);
     
+    SmallVector<KeyPathPatternComponent::Index, 4> indexPatterns;
     SILFunction *indexEquals = nullptr, *indexHash = nullptr;
-    // TODO: Property descriptors for external key paths should get their
-    // equality and hashing from the client.
-    getOrCreateKeyPathEqualsAndHash(*this, loc,
-             needsGenericContext ? genericEnv : nullptr,
-             indexPatterns,
-             indexEquals, indexHash);
-
+    // Property descriptors get their index information from the client.
+    if (!forPropertyDescriptor) {
+      lowerKeyPathSubscriptIndexPatterns(indexPatterns,
+                                         indexTypes, indexHashables,
+                                         baseOperand);
+      
+      getOrCreateKeyPathEqualsAndHash(*this, loc,
+               needsGenericContext ? genericEnv : nullptr,
+               indexPatterns,
+               indexEquals, indexHash);
+    }
+    
     auto id = getIdForKeyPathComponentComputedProperty(*this, decl, strategy);
     auto getter = getOrCreateKeyPathGetter(*this, loc,
              decl, subs,
              strategy,
              needsGenericContext ? genericEnv : nullptr,
-             indexPatterns,
+             indexTypes,
              baseTy, componentTy);
   
     auto indexPatternsCopy = getASTContext().AllocateCopy(indexPatterns);
@@ -3887,7 +3906,7 @@
              decl, subs,
              strategy,
              needsGenericContext ? genericEnv : nullptr,
-             indexPatterns,
+             indexTypes,
              baseTy, componentTy);
       return KeyPathPatternComponent::forComputedSettableProperty(id,
                                                            getter, setter,
@@ -3987,23 +4006,30 @@
         ty = ty.subst(subMap);
       }
       
+      SILFunction *indexEquals = nullptr, *indexHash = nullptr;
       if (component.getKind() ==  KeyPathExpr::Component::Kind::Subscript) {
         unsigned numOperands = operands.size();
-        lowerKeyPathSubscriptIndexPatterns(SGF.SGM,
-             indices,
-             cast<SubscriptDecl>(component.getDeclRef().getDecl()),
-             component.getDeclRef().getSubstitutions(),
+        SmallVector<IndexTypePair, 4> indexTypes;
+        auto sub = cast<SubscriptDecl>(component.getDeclRef().getDecl());
+        lowerKeyPathSubscriptIndexTypes(SGF.SGM, indexTypes,
+                                sub, component.getDeclRef().getSubstitutions(),
+                                needsGenericContext);
+        lowerKeyPathSubscriptIndexPatterns(indices, indexTypes,
              component.getSubscriptIndexHashableConformances(),
-             numOperands,
-             needsGenericContext);
+             numOperands);
         
         lowerSubscriptOperands(component);
         
         assert(numOperands == operands.size()
                && "operand count out of sync");
+        getOrCreateKeyPathEqualsAndHash(SGF.SGM, SILLocation(E),
+                 needsGenericContext ? SGF.F.getGenericEnvironment() : nullptr,
+                 indices,
+                 indexEquals, indexHash);
       }
       return KeyPathPatternComponent::forExternal(
         decl, subs, SGF.getASTContext().AllocateCopy(indices),
+        indexEquals, indexHash,
         ty->getCanonicalType());
     };
   
@@ -4025,7 +4051,8 @@
                               component.getDeclRef().getSubstitutions(),
                               decl,
                               component.getSubscriptIndexHashableConformances(),
-                              baseTy));
+                              baseTy,
+                              /*for descriptor*/ false));
         lowerSubscriptOperands(component);
       
         assert(numOperands == operands.size()
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index df5f9aa..052a2be 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -1147,11 +1147,6 @@
                         RValue &&optionalSubscripts,
                         SILType addressType);
 
-  RValue emitApplyConversionFunction(SILLocation loc,
-                                     Expr *funcExpr,
-                                     Type resultType,
-                                     RValue &&operand);
-
   ManagedValue emitManagedRetain(SILLocation loc, SILValue v);
   ManagedValue emitManagedRetain(SILLocation loc, SILValue v,
                                  const TypeLowering &lowering);
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index e1aa7e4..5e42978 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -597,7 +597,9 @@
         SGF.B.createRefElementAddr(loc, base.getUnmanagedValue(),
                                    Field, SubstFieldType);
 
-      if (!IsNonAccessing) {
+      // Avoid emitting access markers completely for non-accesses or immutable
+      // declarations. Access marker verification is aware of these cases.
+      if (!IsNonAccessing && !Field->isLet()) {
         if (auto enforcement = SGF.getDynamicEnforcement(Field)) {
           result = enterAccessScope(SGF, loc, result, getTypeData(),
                                     accessKind, *enforcement);
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 497f0ce..099d8c4 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1456,10 +1456,9 @@
         // The result type of the function must be convertible to the base type.
         // TODO: we definitely want this to include ImplicitlyUnwrappedOptional; does it
         // need to include everything else in the world?
-        auto outputTy
-          = CS.createTypeVariable(
-              CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction),
-              TVO_CanBindToInOut);
+        auto outputTy = CS.createTypeVariable(
+            CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
+            TVO_CanBindToInOut);
         CS.addConstraint(ConstraintKind::Conversion, outputTy, baseTy,
           CS.getConstraintLocator(expr, ConstraintLocator::RvalueAdjustment));
 
@@ -2419,9 +2418,8 @@
       // variables T1 and T2.
       if (outputTy.isNull()) {
         outputTy = CS.createTypeVariable(
-                     CS.getConstraintLocator(expr,
-                                             ConstraintLocator::ApplyFunction),
-                                             TVO_CanBindToInOut);
+            CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
+            TVO_CanBindToInOut);
       } else {
         // Since we know what the output type is, we can set it as the favored
         // type of this expression.
diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp
index 4bf61f3..3406fbc 100644
--- a/lib/Sema/CalleeCandidateInfo.cpp
+++ b/lib/Sema/CalleeCandidateInfo.cpp
@@ -663,7 +663,7 @@
   // base uncurried by one level, and we refer to the name of the member, not to
   // the name of any base.
   if (auto UDE = dyn_cast<UnresolvedDotExpr>(fn)) {
-    declName = UDE->getName().getBaseIdentifier().str();
+    declName = UDE->getName().getBaseName().userFacingName();
     uncurryLevel = 1;
     
     // If we actually resolved the member to use, return it.
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index 548bbe7..f3beaaf 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -3910,7 +3910,7 @@
     return None;
 
   // String'ify the arguments.
-  StringRef baseNameStr = name.getBaseIdentifier().str();
+  StringRef baseNameStr = name.getBaseName().userFacingName();
   SmallVector<StringRef, 4> argNameStrs;
   for (auto arg : name.getArgumentNames()) {
     if (arg.empty())
diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp
index abb988d..21388ba 100644
--- a/lib/Sema/TypeCheckAvailability.cpp
+++ b/lib/Sema/TypeCheckAvailability.cpp
@@ -1890,14 +1890,7 @@
     name << parsed.ContextName << '.';
 
   if (parsed.IsFunctionName) {
-    // FIXME: duplicated from above.
-    SmallVector<Identifier, 4> argumentLabelIDs;
-    std::transform(parsed.ArgumentLabels.begin(), parsed.ArgumentLabels.end(),
-                   std::back_inserter(argumentLabelIDs),
-                   [&ctx](StringRef labelStr) -> Identifier {
-      return labelStr.empty() ? Identifier() : ctx.getIdentifier(labelStr);
-    });
-    name << DeclName(ctx, ctx.getIdentifier(parsed.BaseName), argumentLabelIDs);
+    name << parsed.formDeclName(ctx);
   } else {
     name << parsed.BaseName;
   }
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index d97a6bd..af2387a 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -553,7 +553,7 @@
     if (ResultValues.empty()) {
       assert(UDRE->getRefKind() != DeclRefKind::Ordinary);
       diagnose(Loc, diag::use_nonmatching_operator,
-               Name.getBaseName().getIdentifier(),
+               Name,
                UDRE->getRefKind() == DeclRefKind::BinaryOperator ? 0 :
                UDRE->getRefKind() == DeclRefKind::PrefixOperator ? 1 : 2);
       return new (Context) ErrorExpr(UDRE->getSourceRange());
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index aa8533a..3eedfe9 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -499,8 +499,8 @@
   }
   assert(argName.getBaseName().getKind() == DeclBaseName::Kind::Normal);
 
-  StringRef argBase = argName.getBaseIdentifier().str();
-  StringRef paramBase = paramName.getBaseIdentifier().str();
+  StringRef argBase = argName.getBaseName().userFacingName();
+  StringRef paramBase = paramName.getBaseName().userFacingName();
 
   unsigned distance = argBase.edit_distance(paramBase, maxEditDistance);
 
@@ -644,12 +644,12 @@
                         "member");
 
       return tc.diagnose(parentDecl, diag::note_typo_candidate_implicit_member,
-                         decl->getBaseName().getIdentifier().str(), kind);
+                         decl->getBaseName().userFacingName(), kind);
     }
   }
 
   return tc.diagnose(decl, diag::note_typo_candidate,
-                     decl->getBaseName().getIdentifier().str());
+                     decl->getBaseName().userFacingName());
 }
 
 void TypeChecker::noteTypoCorrection(DeclName writtenName, DeclNameLoc loc,
@@ -660,7 +660,7 @@
 
   if (writtenName.getBaseName() != declName.getBaseName())
     diagnostic.fixItReplace(loc.getBaseNameLoc(),
-                            declName.getBaseIdentifier().str());
+                            declName.getBaseName().userFacingName());
 
   // TODO: add fix-its for typo'ed argument labels.  This is trickier
   // because of the reordering rules.
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 414f497..5e205c5 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -437,6 +437,9 @@
       subPattern = getSubExprPattern(arg);
     }
     
+    if (ume->getName().getBaseName().isSpecial())
+      return nullptr;
+
     // FIXME: Compound names.
     return new (TC.Context) EnumElementPattern(
                               ume->getDotLoc(),
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index 215a8f2..015d456 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -1347,15 +1347,12 @@
         switch (IP->getCastKind()) {
         case CheckedCastKind::Coercion:
         case CheckedCastKind::BridgingCoercion: {
-          // If the pattern and subpattern types are identical than this is a
-          // non-useful cast that we've already warned about, but it also means
-          // this pattern itself is a no-op and we should examine the subpattern.
           auto *subPattern = IP->getSubPattern();
-          if (subPattern && IP->getType()->isEqual(subPattern->getType()))
+          if (subPattern)
             return projectPattern(TC, subPattern, sawDowngradablePattern);
 
-          // These coercions are irrefutable.  Project with the original type
-          // instead of the cast's target type to maintain consistency with the
+          // With no subpattern coercions are irrefutable.  Project with the original
+          // type instead of the cast's target type to maintain consistency with the
           // scrutinee's type.
           return Space(IP->getType(), Identifier());
         }
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 4fe2d87..b4d07b3 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -798,8 +798,7 @@
     }
     
     indices = MF->getContext().AllocateCopy(indicesBuf);
-    if (!indices.empty() &&
-        kind != KeyPathComponentKindEncoding::External) {
+    if (!indices.empty()) {
       auto indicesEqualsName = MF->getIdentifier(ListOfValues[nextValue++]);
       auto indicesHashName = MF->getIdentifier(ListOfValues[nextValue++]);
       indicesEquals = getFuncForReference(indicesEqualsName.str());
@@ -851,7 +850,8 @@
     }
     handleComputedIndices();
     return KeyPathPatternComponent::forExternal(decl,
-        MF->getContext().AllocateCopy(subs), indices, type);
+        MF->getContext().AllocateCopy(subs),
+        indices, indicesEquals, indicesHash, type);
   }
   }
 }
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index cd0d181..34c65b5 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -626,8 +626,7 @@
         ListOfValues.push_back((unsigned)index.LoweredType.getCategory());
         serializeAfter.push_back(index.Hashable);
       }
-      if (!indices.empty() &&
-          component.getKind() != KeyPathPatternComponent::Kind::External) {
+      if (!indices.empty()) {
         ListOfValues.push_back(
           addSILFunctionRef(component.getSubscriptIndexEquals()));
         ListOfValues.push_back(
diff --git a/lib/Syntax/SyntaxKind.cpp.gyb b/lib/Syntax/SyntaxKind.cpp.gyb
index b7e09ad..d4c2965 100644
--- a/lib/Syntax/SyntaxKind.cpp.gyb
+++ b/lib/Syntax/SyntaxKind.cpp.gyb
@@ -18,8 +18,31 @@
 //===----------------------------------------------------------------------===//
 
 #include "swift/Syntax/SyntaxKind.h"
+#include "swift/Syntax/TokenKinds.h"
 
 namespace swift {
+
+static StringRef getTokenTextInternal(tok kind) {
+  switch(kind) {
+% for token in SYNTAX_TOKENS:
+%   if token.text:
+  case tok::${token.kind}: return "${token.text}";
+%   end
+% end
+  default: return StringRef();
+  }
+}
+
+bool isTokenTextDetermined(tok kind) {
+  return !getTokenTextInternal(kind).empty();
+}
+
+StringRef getTokenText(tok kind) {
+  auto text = getTokenTextInternal(kind);
+  assert(!text.empty() && "token kind cannot be determined");
+  return text;
+}
+
 namespace syntax {
 
 void dumpSyntaxKind(llvm::raw_ostream &os, const SyntaxKind kind) {
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index a147612..2b55d9b 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -40,6 +40,21 @@
   return VD->isStatic() || VD->getDeclContext()->isModuleScopeContext();
 }
 
+void TBDGenVisitor::visitPatternBindingDecl(PatternBindingDecl *PBD) {
+  for (auto &entry : PBD->getPatternList()) {
+    auto *var = entry.getAnchoringVarDecl();
+
+    // Non-global variables might have an explicit initializer symbol.
+    if (entry.getInit() && !isGlobalOrStaticVar(var)) {
+      auto declRef =
+          SILDeclRef(var, SILDeclRef::Kind::StoredPropertyInitializer);
+      // Stored property initializers for public properties are currently
+      // public.
+      addSymbol(declRef);
+    }
+  }
+}
+
 void TBDGenVisitor::addSymbol(SILDeclRef declRef) {
   auto linkage = effectiveLinkageForClassMember(
     declRef.getLinkage(ForDefinition),
diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h
index ddd11b0..5c57bb5 100644
--- a/lib/TBDGen/TBDGenVisitor.h
+++ b/lib/TBDGen/TBDGenVisitor.h
@@ -84,6 +84,8 @@
       addSymbol("main");
   }
 
+  void visitPatternBindingDecl(PatternBindingDecl *PBD);
+
   void visitAbstractFunctionDecl(AbstractFunctionDecl *AFD);
 
   void visitNominalTypeDecl(NominalTypeDecl *NTD);
diff --git a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
index ecb24b6..2a717b1 100644
--- a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
+++ b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
@@ -107,12 +107,12 @@
 ///
 /// An image of interest must have the following sections in the __DATA
 /// segment:
-/// - __swift5_fieldmd
-/// - __swift5_assocty
-/// - __swift5_builtin
-/// - __swift5_capture
-/// - __swift5_typeref
-/// - __swift5_reflstr (optional, may have been stripped out)
+/// - __swift4_fieldmd
+/// - __swift4_assocty
+/// - __swift4_builtin
+/// - __swift4_capture
+/// - __swift4_typeref
+/// - __swift4_reflstr (optional, may have been stripped out)
 ///
 /// - Parameter i: The index of the loaded image as reported by Dyld.
 /// - Returns: A `ReflectionInfo` containing the locations of all of the
@@ -123,12 +123,12 @@
     to: UnsafePointer<MachHeader>.self)
 
   let imageName = _dyld_get_image_name(i)!
-  let fieldmd = getSectionInfo("__swift5_fieldmd", header)
-  let assocty = getSectionInfo("__swift5_assocty", header)
-  let builtin = getSectionInfo("__swift5_builtin", header)
-  let capture = getSectionInfo("__swift5_capture", header)
-  let typeref = getSectionInfo("__swift5_typeref", header)
-  let reflstr = getSectionInfo("__swift5_reflstr", header)
+  let fieldmd = getSectionInfo("__swift4_fieldmd", header)
+  let assocty = getSectionInfo("__swift4_assocty", header)
+  let builtin = getSectionInfo("__swift4_builtin", header)
+  let capture = getSectionInfo("__swift4_capture", header)
+  let typeref = getSectionInfo("__swift4_typeref", header)
+  let reflstr = getSectionInfo("__swift4_reflstr", header)
   return ReflectionInfo(imageName: String(validatingUTF8: imageName)!,
                         fieldmd: fieldmd,
                         assocty: assocty,
diff --git a/stdlib/public/SDK/Accelerate/BNNS.swift.gyb b/stdlib/public/SDK/Accelerate/BNNS.swift.gyb
index c2be935..7552db1 100644
--- a/stdlib/public/SDK/Accelerate/BNNS.swift.gyb
+++ b/stdlib/public/SDK/Accelerate/BNNS.swift.gyb
@@ -172,7 +172,7 @@
   public init(function: BNNSActivationFunction,
               alpha: Float = .nan,
               beta: Float = .nan) {
-    if #available(OSX 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {
+    if #available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {
       _precondition(function != .integerLinearSaturate,
                     "This initializer cannot be used with the integerLinearSaturate activation function; use BNNSActivation.integerLinearSaturate(scale:Int32, offset:Int32, shift:Int32) instead.")
       _precondition(function != .integerLinearSaturatePerChannel,
diff --git a/stdlib/public/SDK/Dispatch/Dispatch.swift b/stdlib/public/SDK/Dispatch/Dispatch.swift
index b507306..188a09f 100644
--- a/stdlib/public/SDK/Dispatch/Dispatch.swift
+++ b/stdlib/public/SDK/Dispatch/Dispatch.swift
@@ -131,7 +131,7 @@
 
 public extension DispatchGroup {
 	public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @escaping @convention(block) () -> Void) {
-		if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
+		if #available(macOS 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
 			let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
 			_swift_dispatch_group_notify(self, queue, item._block)
 		} else {
diff --git a/stdlib/public/SDK/Dispatch/Queue.swift b/stdlib/public/SDK/Dispatch/Queue.swift
index 545a638..4e5f5b9 100644
--- a/stdlib/public/SDK/Dispatch/Queue.swift
+++ b/stdlib/public/SDK/Dispatch/Queue.swift
@@ -39,7 +39,7 @@
 			if self.contains(.concurrent) {
 				attr = _swift_dispatch_queue_concurrent()
 			}
-			if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
+			if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
 				if self.contains(.initiallyInactive) {
 					attr = __dispatch_queue_attr_make_initially_inactive(attr)
 				}
@@ -93,7 +93,7 @@
 		case never
 
 		internal func _attr(attr: __OS_dispatch_queue_attr?) -> __OS_dispatch_queue_attr? {
-			if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
+			if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
 				switch self {
 				case .inherit:
 					// DISPATCH_AUTORELEASE_FREQUENCY_INHERIT
@@ -154,11 +154,11 @@
 		if autoreleaseFrequency != .inherit {
 			attr = autoreleaseFrequency._attr(attr: attr)
 		}
-		if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified {
+		if #available(macOS 10.10, iOS 8.0, *), qos != .unspecified {
 			attr = __dispatch_queue_attr_make_with_qos_class(attr, qos.qosClass.rawValue, Int32(qos.relativePriority))
 		}
 
-		if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
+		if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
 			self.init(__label: label, attr: attr, queue: target)
 		} else {
 			self.init(__label: label, attr: attr)
@@ -209,7 +209,7 @@
 		}
 
 		var block: @convention(block) () -> Void = work
-		if #available(OSX 10.10, iOS 8.0, *), (qos != .unspecified || !flags.isEmpty) {
+		if #available(macOS 10.10, iOS 8.0, *), (qos != .unspecified || !flags.isEmpty) {
 			let workItem = DispatchWorkItem(qos: qos, flags: flags, block: work)
 			block = workItem._block
 		}
@@ -279,7 +279,7 @@
 	public func sync<T>(flags: DispatchWorkItemFlags, execute work: () throws -> T) rethrows -> T {
 		if flags == .barrier {
 			return try self._syncHelper(fn: _syncBarrier, execute: work, rescue: { throw $0 })
-		} else if #available(OSX 10.10, iOS 8.0, *), !flags.isEmpty {
+		} else if #available(macOS 10.10, iOS 8.0, *), !flags.isEmpty {
 			return try self._syncHelper(fn: sync, flags: flags, execute: work, rescue: { throw $0 })
 		} else {
 			return try self._syncHelper(fn: sync, execute: work, rescue: { throw $0 })
@@ -292,7 +292,7 @@
 		flags: DispatchWorkItemFlags = [],
 		execute work: @escaping @convention(block) () -> Void)
 	{
-		if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
+		if #available(macOS 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
 			let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
 			_swift_dispatch_after(deadline.rawValue, self, item._block)
 		} else {
@@ -306,7 +306,7 @@
 		flags: DispatchWorkItemFlags = [],
 		execute work: @escaping @convention(block) () -> Void)
 	{
-		if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
+		if #available(macOS 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
 			let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
 			_swift_dispatch_after(wallDeadline.rawValue, self, item._block)
 		} else {
diff --git a/stdlib/public/SDK/Dispatch/Source.swift b/stdlib/public/SDK/Dispatch/Source.swift
index 2fab3ea..b6ee590 100644
--- a/stdlib/public/SDK/Dispatch/Source.swift
+++ b/stdlib/public/SDK/Dispatch/Source.swift
@@ -17,7 +17,7 @@
 	typealias DispatchSourceHandler = @convention(block) () -> Void
 
 	public func setEventHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) {
-		if #available(OSX 10.10, iOS 8.0, *),
+		if #available(macOS 10.10, iOS 8.0, *),
                    let h = handler,
                    qos != .unspecified || !flags.isEmpty {
 			let item = DispatchWorkItem(qos: qos, flags: flags, block: h)
@@ -33,7 +33,7 @@
 	}
 
 	public func setCancelHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) {
-		if #available(OSX 10.10, iOS 8.0, *),
+		if #available(macOS 10.10, iOS 8.0, *),
                    let h = handler,
                    qos != .unspecified || !flags.isEmpty {
 			let item = DispatchWorkItem(qos: qos, flags: flags, block: h)
@@ -49,7 +49,7 @@
 	}
 
 	public func setRegistrationHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) {
-		if #available(OSX 10.10, iOS 8.0, *),
+		if #available(macOS 10.10, iOS 8.0, *),
                    let h = handler,
                    qos != .unspecified || !flags.isEmpty {
 			let item = DispatchWorkItem(qos: qos, flags: flags, block: h)
diff --git a/stdlib/public/SDK/Foundation/Calendar.swift b/stdlib/public/SDK/Foundation/Calendar.swift
index 7208d85..f7a5c8d 100644
--- a/stdlib/public/SDK/Foundation/Calendar.swift
+++ b/stdlib/public/SDK/Foundation/Calendar.swift
@@ -970,7 +970,7 @@
     }
     
     internal static func _toNSCalendarIdentifier(_ identifier : Identifier) -> NSCalendar.Identifier {
-        if #available(OSX 10.10, iOS 8.0, *) {
+        if #available(macOS 10.10, iOS 8.0, *) {
             let identifierMap : [Identifier : NSCalendar.Identifier] =
                 [.gregorian : .gregorian,
                  .buddhist : .buddhist,
@@ -1010,7 +1010,7 @@
     }
     
     internal static func _fromNSCalendarIdentifier(_ identifier : NSCalendar.Identifier) -> Identifier {
-        if #available(OSX 10.10, iOS 8.0, *) {
+        if #available(macOS 10.10, iOS 8.0, *) {
             let identifierMap : [NSCalendar.Identifier : Identifier] =
                 [.gregorian : .gregorian,
                  .buddhist : .buddhist,
diff --git a/stdlib/public/SDK/Foundation/CharacterSet.swift b/stdlib/public/SDK/Foundation/CharacterSet.swift
index 5bb2088..6bc8c57 100644
--- a/stdlib/public/SDK/Foundation/CharacterSet.swift
+++ b/stdlib/public/SDK/Foundation/CharacterSet.swift
@@ -517,7 +517,7 @@
 
     /// Returns the character set for characters allowed in a user URL subcomponent.
     public static var urlUserAllowed : CharacterSet {
-        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
             return CharacterSet(_uncopiedImmutableReference: _CFURLComponentsGetURLUserAllowedCharacterSet() as NSCharacterSet)
         } else {
             return CharacterSet(_uncopiedImmutableReference: _NSURLComponentsGetURLUserAllowedCharacterSet() as! NSCharacterSet)
@@ -526,7 +526,7 @@
     
     /// Returns the character set for characters allowed in a password URL subcomponent.
     public static var urlPasswordAllowed : CharacterSet {
-        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
             return CharacterSet(_uncopiedImmutableReference: _CFURLComponentsGetURLPasswordAllowedCharacterSet() as NSCharacterSet)
         } else {
             return CharacterSet(_uncopiedImmutableReference: _NSURLComponentsGetURLPasswordAllowedCharacterSet() as! NSCharacterSet)
@@ -535,7 +535,7 @@
     
     /// Returns the character set for characters allowed in a host URL subcomponent.
     public static var urlHostAllowed : CharacterSet {
-        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
             return CharacterSet(_uncopiedImmutableReference: _CFURLComponentsGetURLHostAllowedCharacterSet() as NSCharacterSet)
         } else {
             return CharacterSet(_uncopiedImmutableReference: _NSURLComponentsGetURLHostAllowedCharacterSet() as! NSCharacterSet)
@@ -544,7 +544,7 @@
     
     /// Returns the character set for characters allowed in a path URL component.
     public static var urlPathAllowed : CharacterSet {
-        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
             return CharacterSet(_uncopiedImmutableReference: _CFURLComponentsGetURLPathAllowedCharacterSet() as NSCharacterSet)
         } else {
             return CharacterSet(_uncopiedImmutableReference: _NSURLComponentsGetURLPathAllowedCharacterSet() as! NSCharacterSet)
@@ -553,7 +553,7 @@
     
     /// Returns the character set for characters allowed in a query URL component.
     public static var urlQueryAllowed : CharacterSet {
-        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
             return CharacterSet(_uncopiedImmutableReference: _CFURLComponentsGetURLQueryAllowedCharacterSet() as NSCharacterSet)
         } else {
             return CharacterSet(_uncopiedImmutableReference: _NSURLComponentsGetURLQueryAllowedCharacterSet() as! NSCharacterSet)
@@ -562,7 +562,7 @@
     
     /// Returns the character set for characters allowed in a fragment URL component.
     public static var urlFragmentAllowed : CharacterSet {
-        if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
             return CharacterSet(_uncopiedImmutableReference: _CFURLComponentsGetURLFragmentAllowedCharacterSet() as NSCharacterSet)
         } else {
             return CharacterSet(_uncopiedImmutableReference: _NSURLComponentsGetURLFragmentAllowedCharacterSet() as! NSCharacterSet)
diff --git a/stdlib/public/SDK/Foundation/Date.swift b/stdlib/public/SDK/Foundation/Date.swift
index d11270f..967b158 100644
--- a/stdlib/public/SDK/Foundation/Date.swift
+++ b/stdlib/public/SDK/Foundation/Date.swift
@@ -143,7 +143,7 @@
     public static let distantPast = Date(timeIntervalSinceReferenceDate: -63114076800.0)
     
     public var hashValue: Int {
-        if #available(OSX 10.12, iOS 10.0, *) {
+        if #available(macOS 10.12, iOS 10.0, *) {
             return Int(bitPattern: __CFHashDouble(_time))
         } else { // 10.11 and previous behavior fallback; this must allocate a date to reference the hash value and then throw away the reference
             return NSDate(timeIntervalSinceReferenceDate: _time).hash
diff --git a/stdlib/public/SDK/Foundation/JSONEncoder.swift b/stdlib/public/SDK/Foundation/JSONEncoder.swift
index 269551e..42c6081 100644
--- a/stdlib/public/SDK/Foundation/JSONEncoder.swift
+++ b/stdlib/public/SDK/Foundation/JSONEncoder.swift
@@ -733,7 +733,7 @@
             return NSNumber(value: 1000.0 * date.timeIntervalSince1970)
 
         case .iso8601:
-            if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+            if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
                 return NSString(string: _iso8601Formatter.string(from: date))
             } else {
                 fatalError("ISO8601DateFormatter is unavailable on this platform.")
@@ -2289,7 +2289,7 @@
             return Date(timeIntervalSince1970: double / 1000.0)
 
         case .iso8601:
-            if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+            if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
                 let string = try self.unbox(value, as: String.self)!
                 guard let date = _iso8601Formatter.date(from: string) else {
                     throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Expected date string to be ISO8601-formatted."))
diff --git a/stdlib/public/SDK/Foundation/NSError.swift b/stdlib/public/SDK/Foundation/NSError.swift
index 6c864bd..ec32c9e 100644
--- a/stdlib/public/SDK/Foundation/NSError.swift
+++ b/stdlib/public/SDK/Foundation/NSError.swift
@@ -205,7 +205,7 @@
 
   // If the OS supports user info value providers, use those
   // to lazily populate the user-info dictionary for this domain.
-  if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
+  if #available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
     // Note: the Cocoa error domain specifically excluded from
     // user-info value providers.
     let domain = error._domain
diff --git a/stdlib/public/SDK/Foundation/NSStringAPI.swift b/stdlib/public/SDK/Foundation/NSStringAPI.swift
index 65870c0..976e3c7 100644
--- a/stdlib/public/SDK/Foundation/NSStringAPI.swift
+++ b/stdlib/public/SDK/Foundation/NSStringAPI.swift
@@ -1638,7 +1638,7 @@
   /// Equivalent to `self.rangeOfString(other) != nil`
   public func contains<T : StringProtocol>(_ other: T) -> Bool {
     let r = self.range(of: other) != nil
-    if #available(OSX 10.10, iOS 8.0, *) {
+    if #available(macOS 10.10, iOS 8.0, *) {
       _sanityCheck(r == _ns.contains(other._ephemeralString))
     }
     return r
@@ -1661,7 +1661,7 @@
     let r = self.range(
       of: other, options: .caseInsensitive, locale: Locale.current
     ) != nil
-    if #available(OSX 10.10, iOS 8.0, *) {
+    if #available(macOS 10.10, iOS 8.0, *) {
       _sanityCheck(r ==
         _ns.localizedCaseInsensitiveContains(other._ephemeralString))
     }
diff --git a/stdlib/public/SDK/Foundation/URLComponents.swift b/stdlib/public/SDK/Foundation/URLComponents.swift
index acf8f09..760a640 100644
--- a/stdlib/public/SDK/Foundation/URLComponents.swift
+++ b/stdlib/public/SDK/Foundation/URLComponents.swift
@@ -333,7 +333,7 @@
         if let p = self.port { c.append((label: "port", value: p)) }
         
         c.append((label: "path", value: self.path))
-        if #available(OSX 10.10, iOS 8.0, *) {
+        if #available(macOS 10.10, iOS 8.0, *) {
             if let qi = self.queryItems { c.append((label: "queryItems", value: qi)) }
         }
         if let f = self.fragment { c.append((label: "fragment", value: f)) }
diff --git a/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift b/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
index 8966c21..e7c0853 100644
--- a/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
+++ b/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
@@ -18,7 +18,7 @@
 internal enum _Prespecialize {
   // Create specializations for the arrays of most
   // popular builtin integer and floating point types.
-  static internal func _specializeArrays() {
+  internal static func _specializeArrays() {
     func _createArrayUser<Element : Comparable>(_ sampleValue: Element) {
       // Initializers.
       let _: [Element] = [sampleValue]
@@ -158,7 +158,7 @@
 
   // Force pre-specialization of Range<Int>
   @discardableResult
-  static internal func _specializeRanges() -> Int {
+  internal static func _specializeRanges() -> Int {
     let a = [Int](repeating: 1, count: 10)
     var count = 0
     // Specialize Range for integers
diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift
index 99b2a09..3997a52 100644
--- a/stdlib/public/core/Collection.swift
+++ b/stdlib/public/core/Collection.swift
@@ -604,7 +604,7 @@
   ///     } else {
   ///         print("Hi ho, \(horseName)!")
   ///     }
-  ///     // Prints "Hi ho, Silver!")
+  ///     // Prints "Hi ho, Silver!"
   ///
   /// - Complexity: O(1)
   var isEmpty: Bool { get }
diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift
index 4359787..cf9ad6e 100644
--- a/stdlib/public/core/Mirror.swift
+++ b/stdlib/public/core/Mirror.swift
@@ -487,15 +487,21 @@
 
 /// The sum of types that can be used as a Quick Look representation.
 ///
-/// - note: `PlaygroundQuickLook` is deprecated, and will be removed from the
-/// standard library in a future Swift release. Customizing display for in a
-/// playground is now done using the `CustomPlaygroundDisplayConvertible`
-/// protocol, which does not use the `PlaygroundQuickLook` enum. Please remove
-/// your uses of `PlaygroundQuickLook`, or conditionalize your use such that it
-/// is only present when compiling with Swift 4.0 or Swift 3.2 or earlier:
+/// The `PlaygroundQuickLook` protocol is deprecated, and will be removed from
+/// the standard library in a future Swift release. To customize the logging of
+/// your type in a playground, conform to the
+/// `CustomPlaygroundDisplayConvertible` protocol, which does not use the
+/// `PlaygroundQuickLook` enum.
 ///
-///     #if !(swift(>=4.1) || swift(>=3.3) && !swift(>=4.0))
-///       /* OK to use PlaygroundQuickLook */
+/// If you need to provide a customized playground representation in Swift 4.0
+/// or Swift 3.2 or earlier, use a conditional compilation block:
+///
+///     #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
+///         // With Swift 4.1 and later (including Swift 3.3 and later), use
+///         // the CustomPlaygroundDisplayConvertible protocol.
+///     #else
+///         // With Swift 4.0 and Swift 3.2 and earlier, use PlaygroundQuickLook
+///         // and the CustomPlaygroundQuickLookable protocol.
 ///     #endif
 @_fixed_layout // FIXME(sil-serialize-all)
 @available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
@@ -606,26 +612,22 @@
 
 /// A type that explicitly supplies its own playground Quick Look.
 ///
-/// A Quick Look can be created for an instance of any type by using the
-/// `PlaygroundQuickLook(reflecting:)` initializer. If you are not satisfied
-/// with the representation supplied for your type by default, you can make it
-/// conform to the `CustomPlaygroundQuickLookable` protocol and provide a
-/// custom `PlaygroundQuickLook` instance.
+/// The `CustomPlaygroundQuickLookable` protocol is deprecated, and will be
+/// removed from the standard library in a future Swift release. To customize
+/// the logging of your type in a playground, conform to the
+/// `CustomPlaygroundDisplayConvertible` protocol.
 ///
-/// - note: `CustomPlaygroundQuickLookable` is deprecated, and will be removed
-/// from the standard library in a future Swift release. Please migrate to the
-/// `CustomPlaygroundDisplayConvertible` protocol instead, or conditionalize
-/// your conformance such that it is only present when compiling with Swift 4.0
-/// or Swift 3.2 or earlier:
+/// If you need to provide a customized playground representation in Swift 4.0
+/// or Swift 3.2 or earlier, use a conditional compilation block:
 ///
-///     #if swift(>=4.1) || swift(>=3.3) && !swift(>=4.0)
-///       // With Swift 4.1 and later (including Swift 3.3 and later), implement
-///       // CustomPlaygroundDisplayConvertible.
-///       extension MyType: CustomPlaygroundDisplayConvertible { /*...*/ }
+///     #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
+///         // With Swift 4.1 and later (including Swift 3.3 and later),
+///         // conform to CustomPlaygroundDisplayConvertible.
+///         extension MyType: CustomPlaygroundDisplayConvertible { /*...*/ }
 ///     #else
-///       // Otherwise, on Swift 4.0 and Swift 3.2 and earlier,
-///       // implement CustomPlaygroundQuickLookable.
-///       extension MyType: CustomPlaygroundQuickLookable { /*...*/ }
+///         // Otherwise, on Swift 4.0 and Swift 3.2 and earlier,
+///         // conform to CustomPlaygroundQuickLookable.
+///         extension MyType: CustomPlaygroundQuickLookable { /*...*/ }
 ///     #endif
 @available(*, deprecated, message: "CustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
 public protocol CustomPlaygroundQuickLookable {
diff --git a/stdlib/public/core/PlaygroundDisplay.swift b/stdlib/public/core/PlaygroundDisplay.swift
index ef5dd66..846cedc 100644
--- a/stdlib/public/core/PlaygroundDisplay.swift
+++ b/stdlib/public/core/PlaygroundDisplay.swift
@@ -12,21 +12,19 @@
 
 /// A type that supplies a custom description for playground logging.
 ///
-/// All types have a default description for playgrounds. This protocol
-/// allows types to provide custom descriptions which are then logged in
-/// place of the original instance.
-///
 /// Playground logging can generate, at a minimum, a structured description
-/// of any type. Playground logging is also capable of generating a richer,
-/// more specialized description of core types -- for instance, the contents
-/// of a `String` are logged, as are the components of an `NSColor` or
-/// `UIColor`.
+/// of any type. If you want to provide a custom description of your type to be
+/// logged in place of the default description, conform to the
+/// `CustomPlaygroundDisplayConvertible` protocol.
 ///
-/// The current playground logging implementation logs specialized
-/// descriptions of at least the following types:
+/// Playground logging generates a richer, more specialized description of core
+/// types. For example, the contents of a `String` are logged, as are the
+/// components of an `NSColor` or `UIColor`. The current playground logging
+/// implementation logs specialized descriptions of at least the following
+/// types:
 ///
 /// - `String` and `NSString`
-/// - `Int` and `UInt` (including the sized variants)
+/// - `Int`, `UInt`, and the other standard library integer types
 /// - `Float` and `Double`
 /// - `Bool`
 /// - `Date` and `NSDate`
@@ -43,21 +41,24 @@
 /// Playground logging may also be able to support specialized descriptions
 /// of other types.
 ///
-/// Implementors of `CustomPlaygroundDisplayConvertible` may return a value of
-/// one of the above types to also receive a specialized log description.
-/// Implementors may also return any other type, and playground logging will
-/// generated structured logging for the returned value.
+/// Conforming to the CustomPlaygroundDisplayConvertible Protocol
+/// -------------------------------------------------------------
 ///
-/// - note: `CustomPlaygroundDisplayConvertible` conformances chain -- that is,
-///   if `playgroundDescription` returns an instance which itself conforms to
-///   `CustomPlaygroundDisplayConvertible`, then playground logging will ask for
-///   that instance's `playgroundDescription` and so on. It is permissible for
-///   playground logging implementations to place a reasonable limit on this
-///   kind of chaining to prevent infinite loops.
+/// To add `CustomPlaygroundDisplayConvertible` conformance to your custom type,
+/// implement the `playgroundDescription` property. If your implementation
+/// returns an instance of one of the types above, that type's specialized
+/// description is used. If you return any other type, a structured description
+/// is generated.
+///
+/// If your type has value semantics, the `playgroundDescription` should be
+/// unaffected by subsequent mutations, if possible.
+///
+/// If your type's `playgroundDescription` returns an instance which itself
+/// conforms to `CustomPlaygroundDisplayConvertible`, then that type's
+/// `playgroundDescription` will be used, and so on. To prevent infinite loops,
+/// playground logging implementations can place a reasonable limit on this
+/// kind of chaining.
 public protocol CustomPlaygroundDisplayConvertible {
-  /// Returns the custom playground description for this instance.
-  ///
-  /// If this type has value semantics, the instance returned should be
-  /// unaffected by subsequent mutations if possible.
+  /// A custom playground description for this instance.
   var playgroundDescription: Any { get }
-}
\ No newline at end of file
+}
diff --git a/stdlib/public/core/RuntimeFunctionCounters.swift b/stdlib/public/core/RuntimeFunctionCounters.swift
index 0efb2a682..0ac2626 100644
--- a/stdlib/public/core/RuntimeFunctionCounters.swift
+++ b/stdlib/public/core/RuntimeFunctionCounters.swift
@@ -163,7 +163,7 @@
   }
 
   /// Build a map from counter name to counter index inside the state struct.
-  static internal func getRuntimeFunctionNameToIndex() -> [String : Int] {
+  internal static func getRuntimeFunctionNameToIndex() -> [String : Int] {
     let runtimeFunctionNames = _RuntimeFunctionCounters.getRuntimeFunctionNames()
     let numRuntimeFunctionCounters =
       _RuntimeFunctionCounters.getNumRuntimeFunctionCounters()
@@ -317,19 +317,19 @@
 
 extension _RuntimeFunctionCounters {
   @_silgen_name("_swift_getObjectRuntimeFunctionCounters")
-  static internal func getObjectRuntimeFunctionCounters(
+  internal static func getObjectRuntimeFunctionCounters(
     _ object: UnsafeRawPointer, _ result: inout _RuntimeFunctionCountersState)
 
   @_silgen_name("_swift_getGlobalRuntimeFunctionCounters")
-  static internal func getGlobalRuntimeFunctionCounters(
+  internal static func getGlobalRuntimeFunctionCounters(
     _ result: inout _RuntimeFunctionCountersState)
 
   @_silgen_name("_swift_setGlobalRuntimeFunctionCounters")
-  static internal func setGlobalRuntimeFunctionCounters(
+  internal static func setGlobalRuntimeFunctionCounters(
     _ state: inout _RuntimeFunctionCountersState)
 
   @_silgen_name("_swift_setObjectRuntimeFunctionCounters")
-  static internal func setObjectRuntimeFunctionCounters(
+  internal static func setObjectRuntimeFunctionCounters(
     _ object: UnsafeRawPointer,
     _ state: inout _RuntimeFunctionCountersState)
 
diff --git a/stdlib/public/core/StringComparison.swift b/stdlib/public/core/StringComparison.swift
index 680130d..7dbd1f5 100644
--- a/stdlib/public/core/StringComparison.swift
+++ b/stdlib/public/core/StringComparison.swift
@@ -680,7 +680,7 @@
     return impl(&inBuffer, count: inLength, into: outputBuffer)
   }
 
-  static internal let maxValue = 0x0010_FFFF
+  internal static let maxValue = 0x0010_FFFF
 }
 
 private struct _UnicodeScalarExceptions {
diff --git a/stdlib/public/core/ThreadLocalStorage.swift b/stdlib/public/core/ThreadLocalStorage.swift
index 8689317..11f176d 100644
--- a/stdlib/public/core/ThreadLocalStorage.swift
+++ b/stdlib/public/core/ThreadLocalStorage.swift
@@ -68,7 +68,7 @@
   // creates and initializes a new one.
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
-  static internal func getPointer()
+  internal static func getPointer()
     -> UnsafeMutablePointer<_ThreadLocalStorage>
   {
     let tlsRawPtr = _stdlib_thread_getspecific(_tlsKey)
@@ -82,7 +82,7 @@
 
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
-  static internal func getUBreakIterator(
+  internal static func getUBreakIterator(
     start: UnsafePointer<UTF16.CodeUnit>,
     count: Int32
   ) -> OpaquePointer {
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.cpp b/stdlib/public/runtime/ImageInspectionCOFF.cpp
index 2b60233..2228cc1 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.cpp
+++ b/stdlib/public/runtime/ImageInspectionCOFF.cpp
@@ -41,7 +41,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &protocols =
-      sections->swift5_protocols;
+      sections->swift4_protocols;
     if (protocols.length)
       addImageProtocolsBlockCallback(reinterpret_cast<void *>(protocols.start),
                                      protocols.length);
@@ -56,7 +56,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &conformances =
-        sections->swift5_protocol_conformances;
+        sections->swift4_protocol_conformances;
     if (conformances.length)
       addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
                                                conformances.length);
@@ -71,7 +71,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &type_metadata =
-        sections->swift5_type_metadata;
+        sections->swift4_type_metadata;
     if (type_metadata.length)
       addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
                                               type_metadata.length);
@@ -85,7 +85,7 @@
 void swift::initializeTypeFieldLookup() {
   const swift::MetadataSections *sections = registered;
   while (true) {
-    const swift::MetadataSections::Range &fields = sections->swift5_fieldmd;
+    const swift::MetadataSections::Range &fields = sections->swift4_fieldmd;
     if (fields.length)
       addImageTypeFieldDescriptorBlockCallback(
           reinterpret_cast<void *>(fields.start), fields.length);
@@ -103,20 +103,20 @@
 
   record(sections);
 
-  const auto &protocols_section = sections->swift5_protocols;
+  const auto &protocols_section = sections->swift4_protocols;
   const void *protocols =
       reinterpret_cast<void *>(protocols_section.start);
   if (protocols_section.length)
     addImageProtocolsBlockCallback(protocols, protocols_section.length);
 
-  const auto &protocol_conformances = sections->swift5_protocol_conformances;
+  const auto &protocol_conformances = sections->swift4_protocol_conformances;
   const void *conformances =
       reinterpret_cast<void *>(protocol_conformances.start);
   if (protocol_conformances.length)
     addImageProtocolConformanceBlockCallback(conformances,
                                              protocol_conformances.length);
 
-  const auto &type_metadata = sections->swift5_type_metadata;
+  const auto &type_metadata = sections->swift4_type_metadata;
   const void *metadata = reinterpret_cast<void *>(type_metadata.start);
   if (type_metadata.length)
     addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.h b/stdlib/public/runtime/ImageInspectionCOFF.h
index 75e0266..2ce5fa6 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.h
+++ b/stdlib/public/runtime/ImageInspectionCOFF.h
@@ -45,13 +45,13 @@
     size_t length;
   };
 
-  Range swift5_protocols;
-  Range swift5_protocol_conformances;
-  Range swift5_type_metadata;
-  Range swift5_typeref;
-  Range swift5_reflstr;
-  Range swift5_fieldmd;
-  Range swift5_assocty;
+  Range swift4_protocols;
+  Range swift4_protocol_conformances;
+  Range swift4_type_metadata;
+  Range swift4_typeref;
+  Range swift4_reflstr;
+  Range swift4_fieldmd;
+  Range swift4_assocty;
 };
 } // namespace swift
 
diff --git a/stdlib/public/runtime/ImageInspectionELF.cpp b/stdlib/public/runtime/ImageInspectionELF.cpp
index 16064ab..02c4f42 100644
--- a/stdlib/public/runtime/ImageInspectionELF.cpp
+++ b/stdlib/public/runtime/ImageInspectionELF.cpp
@@ -46,7 +46,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &protocols =
-        sections->swift5_protocols;
+        sections->swift4_protocols;
     if (protocols.length)
       addImageProtocolsBlockCallback(reinterpret_cast<void *>(protocols.start),
                                      protocols.length);
@@ -60,7 +60,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &conformances =
-        sections->swift5_protocol_conformances;
+        sections->swift4_protocol_conformances;
     if (conformances.length)
       addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
                                                conformances.length);
@@ -75,7 +75,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &type_metadata =
-        sections->swift5_type_metadata;
+        sections->swift4_type_metadata;
     if (type_metadata.length)
       addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
                                               type_metadata.length);
@@ -89,7 +89,7 @@
 void swift::initializeTypeFieldLookup() {
   const swift::MetadataSections *sections = registered;
   while (true) {
-    const swift::MetadataSections::Range &fields = sections->swift5_fieldmd;
+    const swift::MetadataSections::Range &fields = sections->swift4_fieldmd;
     if (fields.length)
       addImageTypeFieldDescriptorBlockCallback(
           reinterpret_cast<void *>(fields.start), fields.length);
@@ -111,20 +111,20 @@
 
   record(sections);
 
-  const auto &protocols_section = sections->swift5_protocol_conformances;
+  const auto &protocols_section = sections->swift4_protocol_conformances;
   const void *protocols =
       reinterpret_cast<void *>(protocols_section.start);
   if (protocols_section.length)
     addImageProtocolsBlockCallback(protocols, protocols_section.length);
 
-  const auto &protocol_conformances = sections->swift5_protocol_conformances;
+  const auto &protocol_conformances = sections->swift4_protocol_conformances;
   const void *conformances =
       reinterpret_cast<void *>(protocol_conformances.start);
   if (protocol_conformances.length)
     addImageProtocolConformanceBlockCallback(conformances,
                                              protocol_conformances.length);
 
-  const auto &type_metadata = sections->swift5_type_metadata;
+  const auto &type_metadata = sections->swift4_type_metadata;
   const void *metadata = reinterpret_cast<void *>(type_metadata.start);
   if (type_metadata.length)
     addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
diff --git a/stdlib/public/runtime/ImageInspectionELF.h b/stdlib/public/runtime/ImageInspectionELF.h
index 9505360..b88be22 100644
--- a/stdlib/public/runtime/ImageInspectionELF.h
+++ b/stdlib/public/runtime/ImageInspectionELF.h
@@ -45,13 +45,13 @@
     size_t length;
   };
 
-  Range swift5_protocols;
-  Range swift5_protocol_conformances;
-  Range swift5_type_metadata;
-  Range swift5_typeref;
-  Range swift5_reflstr;
-  Range swift5_fieldmd;
-  Range swift5_assocty;
+  Range swift4_protocols;
+  Range swift4_protocol_conformances;
+  Range swift4_type_metadata;
+  Range swift4_typeref;
+  Range swift4_reflstr;
+  Range swift4_fieldmd;
+  Range swift4_assocty;
 };
 } // namespace swift
 
diff --git a/stdlib/public/runtime/ImageInspectionMachO.cpp b/stdlib/public/runtime/ImageInspectionMachO.cpp
index c7d556c..778d6b0 100644
--- a/stdlib/public/runtime/ImageInspectionMachO.cpp
+++ b/stdlib/public/runtime/ImageInspectionMachO.cpp
@@ -31,16 +31,16 @@
 namespace {
 /// The Mach-O section name for the section containing protocol descriptor
 /// references. This lives within SEG_TEXT.
-constexpr const char ProtocolsSection[] = "__swift5_protos";
+constexpr const char ProtocolsSection[] = "__swift4_protos";
 /// The Mach-O section name for the section containing protocol conformances.
 /// This lives within SEG_TEXT.
-constexpr const char ProtocolConformancesSection[] = "__swift5_proto";
+constexpr const char ProtocolConformancesSection[] = "__swift4_proto";
 /// The Mach-O section name for the section containing type references.
 /// This lives within SEG_TEXT.
-constexpr const char TypeMetadataRecordSection[] = "__swift5_types";
+constexpr const char TypeMetadataRecordSection[] = "__swift4_types";
 /// The Mach-O section name for the section containing type field references.
 /// This lives within SEG_TEXT.
-constexpr const char TypeFieldRecordSection[] = "__swift5_fieldmd";
+constexpr const char TypeFieldRecordSection[] = "__swift4_fieldmd";
 
 template<const char *SECTION_NAME,
          void CONSUME_BLOCK(const void *start, uintptr_t size)>
@@ -52,7 +52,7 @@
   using mach_header_platform = mach_header;
 #endif
   
-  // Look for a __swift5_proto section.
+  // Look for a __swift4_proto section.
   unsigned long size;
   const uint8_t *section =
   getsectiondata(reinterpret_cast<const mach_header_platform *>(mh),
diff --git a/stdlib/public/runtime/SwiftRT-ELF.cpp b/stdlib/public/runtime/SwiftRT-ELF.cpp
index 56074d2..47ba9a7 100644
--- a/stdlib/public/runtime/SwiftRT-ELF.cpp
+++ b/stdlib/public/runtime/SwiftRT-ELF.cpp
@@ -24,14 +24,14 @@
   __attribute__((__visibility__("hidden"))) extern const char __stop_##name;
 
 extern "C" {
-DECLARE_SWIFT_SECTION(swift5_protocols)
-DECLARE_SWIFT_SECTION(swift5_protocol_conformances)
-DECLARE_SWIFT_SECTION(swift5_type_metadata)
+DECLARE_SWIFT_SECTION(swift4_protocols)
+DECLARE_SWIFT_SECTION(swift4_protocol_conformances)
+DECLARE_SWIFT_SECTION(swift4_type_metadata)
 
-DECLARE_SWIFT_SECTION(swift5_typeref)
-DECLARE_SWIFT_SECTION(swift5_reflstr)
-DECLARE_SWIFT_SECTION(swift5_fieldmd)
-DECLARE_SWIFT_SECTION(swift5_assocty)
+DECLARE_SWIFT_SECTION(swift4_typeref)
+DECLARE_SWIFT_SECTION(swift4_reflstr)
+DECLARE_SWIFT_SECTION(swift4_fieldmd)
+DECLARE_SWIFT_SECTION(swift4_assocty)
 }
 
 #undef DECLARE_SWIFT_SECTION
@@ -53,14 +53,14 @@
       nullptr,
       nullptr,
 
-      SWIFT_SECTION_RANGE(swift5_protocols),
-      SWIFT_SECTION_RANGE(swift5_protocol_conformances),
-      SWIFT_SECTION_RANGE(swift5_type_metadata),
+      SWIFT_SECTION_RANGE(swift4_protocols),
+      SWIFT_SECTION_RANGE(swift4_protocol_conformances),
+      SWIFT_SECTION_RANGE(swift4_type_metadata),
 
-      SWIFT_SECTION_RANGE(swift5_typeref),
-      SWIFT_SECTION_RANGE(swift5_reflstr),
-      SWIFT_SECTION_RANGE(swift5_fieldmd),
-      SWIFT_SECTION_RANGE(swift5_assocty),
+      SWIFT_SECTION_RANGE(swift4_typeref),
+      SWIFT_SECTION_RANGE(swift4_reflstr),
+      SWIFT_SECTION_RANGE(swift4_fieldmd),
+      SWIFT_SECTION_RANGE(swift4_assocty),
   };
 
 #undef SWIFT_SECTION_RANGE
diff --git a/test/APINotes/versioned-objc.swift b/test/APINotes/versioned-objc.swift
index 42aac2a..647d092 100644
--- a/test/APINotes/versioned-objc.swift
+++ b/test/APINotes/versioned-objc.swift
@@ -48,15 +48,15 @@
   _ = ClassWithManyRenames.classWithManyRenamesForInt(0)
   // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'classWithManyRenamesForInt' has been replaced by 'init(for:)'
 
-  // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(forInt:)' has been replaced by 'init(swift3Factory:)'
+  // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(forInt:)' has been renamed to 'init(swift3Factory:)'
   _ = ClassWithManyRenames(forInt: 0)
-  // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(forInt:)' has been replaced by 'init(for:)'
+  // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(forInt:)' has been renamed to 'init(for:)'
 
   // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
   _ = ClassWithManyRenames(swift3Factory: 0)
-  // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(swift3Factory:)' has been replaced by 'init(for:)'
+  // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(swift3Factory:)' has been renamed to 'init(for:)'
 
-  // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(for:)' has been replaced by 'init(swift3Factory:)'
+  // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(for:)' has been renamed to 'init(swift3Factory:)'
   _ = ClassWithManyRenames(for: 0)
   // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
 
diff --git a/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h b/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h
index 320e4ab..b5b83a6 100644
--- a/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h
+++ b/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h
@@ -212,3 +212,19 @@
 
 typedef NSString * _Nonnull (*FPTypedef)(NSString * _Nonnull);
 extern FPTypedef _Nonnull getFP(void);
+
+
+#if !__has_feature(objc_arc_fields)
+# error "Your Clang is not new enough"
+#endif
+struct NonTrivialToCopy {
+  __strong id field;
+};
+
+struct NonTrivialToCopyWrapper {
+  struct NonTrivialToCopy inner;
+};
+
+struct TrivialToCopy {
+  __unsafe_unretained id field;
+};
diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift
index 554dde0..35ea85c 100644
--- a/test/ClangImporter/objc_parse.swift
+++ b/test/ClangImporter/objc_parse.swift
@@ -671,3 +671,9 @@
   let _: Int = fptrTypedef // expected-error{{'@convention(c) (String) -> String'}}
   let _: Int = getFP() // expected-error{{'@convention(c) (String) -> String'}}
 }
+
+func testNonTrivialStructs() {
+  _ = NonTrivialToCopy() // expected-error {{use of unresolved identifier 'NonTrivialToCopy'}}
+  _ = NonTrivialToCopyWrapper() // expected-error {{use of unresolved identifier 'NonTrivialToCopyWrapper'}}
+  _ = TrivialToCopy() // okay
+}
\ No newline at end of file
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index 80e0a07..e040b4a 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -196,10 +196,8 @@
 // CHECK-NEXT: [[PTR:%.*]] = bitcast %T16class_resilience26ClassWithResilientPropertyC* %0 to i8*
 // CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[PTR]], [[INT]] [[OFFSET]]
 // CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Ts5Int32V*
-// CHECK:      call void @swift_beginAccess
 // CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Ts5Int32V, %Ts5Int32V* [[FIELD_PTR]], i32 0, i32 0
 // CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]]
-// CHECK-NEXT: call void @swift_endAccess
 // CHECK: ret i32 [[FIELD_VALUE]]
 
 // ClassWithResilientProperty metadata accessor
@@ -225,10 +223,8 @@
 // CHECK-NEXT: [[PTR:%.*]] = bitcast %T16class_resilience33ClassWithResilientlySizedPropertyC* %0 to i8*
 // CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[PTR]], [[INT]] [[OFFSET]]
 // CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Ts5Int32V*
-// CHECK:      call void @swift_beginAccess
 // CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Ts5Int32V, %Ts5Int32V* [[FIELD_PTR]], i32 0, i32 0
 // CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]]
-// CHECK-NEXT: call void @swift_endAccess
 // CHECK:      ret i32 [[FIELD_VALUE]]
 
 // ClassWithResilientlySizedProperty metadata accessor
@@ -252,10 +248,8 @@
 
 // CHECK-LABEL: define{{( protected)?}} swiftcc i32 @"$S16class_resilience30ClassWithIndirectResilientEnumC5colors5Int32Vvg"(%T16class_resilience30ClassWithIndirectResilientEnumC* swiftself)
 // CHECK:      [[FIELD_PTR:%.*]] = getelementptr inbounds %T16class_resilience30ClassWithIndirectResilientEnumC, %T16class_resilience30ClassWithIndirectResilientEnumC* %0, i32 0, i32 2
-// CHECK: call void @swift_beginAccess
 // CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Ts5Int32V, %Ts5Int32V* [[FIELD_PTR]], i32 0, i32 0
 // CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]]
-// CHECK-NEXT: call void @swift_endAccess
 // CHECK: ret i32 [[FIELD_VALUE]]
 
 
@@ -303,10 +297,8 @@
 
 // CHECK-LABEL: define{{( protected)?}} swiftcc i32 @"$S16class_resilience16MyResilientChildC5fields5Int32Vvg"(%T16class_resilience16MyResilientChildC* swiftself)
 // CHECK:      [[FIELD_ADDR:%.*]] = getelementptr inbounds %T16class_resilience16MyResilientChildC, %T16class_resilience16MyResilientChildC* %0, i32 0, i32 2
-// CHECK:      call void @swift_beginAccess
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Ts5Int32V, %Ts5Int32V* [[FIELD_ADDR]], i32 0, i32 0
 // CHECK-NEXT: [[RESULT:%.*]] = load i32, i32* [[PAYLOAD_ADDR]]
-// CHECK-NEXT: call void @swift_endAccess
 // CHECK:      ret i32 [[RESULT]]
 
 
diff --git a/test/IRGen/closure.swift b/test/IRGen/closure.swift
index 3558748..a9daccf 100644
--- a/test/IRGen/closure.swift
+++ b/test/IRGen/closure.swift
@@ -4,7 +4,7 @@
 
 // -- partial_apply context metadata
 
-// CHECK: [[METADATA:@.*]] = private constant %swift.full_boxmetadata { void (%swift.refcounted*)* @objectdestroy, i8** null, %swift.type { i64 64 }, i32 16, i8* bitcast ({ i32, i32, i32, i32 }* @"\01l__swift5_reflection_descriptor" to i8*) }
+// CHECK: [[METADATA:@.*]] = private constant %swift.full_boxmetadata { void (%swift.refcounted*)* @objectdestroy, i8** null, %swift.type { i64 64 }, i32 16, i8* bitcast ({ i32, i32, i32, i32 }* @"\01l__swift4_reflection_descriptor" to i8*) }
 
 func a(i i: Int) -> (Int) -> Int {
   return { x in i }
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index b4cf071..2628a66 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -418,13 +418,19 @@
 
   %u = keypath $KeyPath<G<A>, A>, <X: Hashable, Y: Hashable> (
     root $G<Y>;
-    external #G.subscript<Y, X> [%$0 : $X : $*X] : $Y
+    external #G.subscript<Y, X> [%$0 : $X : $*X] : $Y,
+      indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
+      indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int
   ) <B, A> (%1)
 
   %v = keypath $KeyPath<G<G<B>>, B>, <X: Hashable, Y: Hashable> (
     root $G<G<X>>;
-    external #G.subscript<G<X>, Y> [%$1 : $Y : $*Y] : $G<X>;
-    external #G.subscript<X, X> [%$0 : $X : $*X] : $X
+    external #G.subscript<G<X>, Y> [%$1 : $Y : $*Y] : $G<X>,
+      indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
+      indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int;
+    external #G.subscript<X, X> [%$0 : $X : $*X] : $X,
+      indices_equals @s_equals : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
+      indices_hash @s_hash : $@convention(thin) <A: Hashable, B: Hashable> (UnsafeRawPointer) -> Int
   ) <B, A> (%3, %4)
 
   return undef : $()
diff --git a/test/IRGen/outlined_copy_addr.swift b/test/IRGen/outlined_copy_addr.swift
new file mode 100644
index 0000000..80653a6
--- /dev/null
+++ b/test/IRGen/outlined_copy_addr.swift
@@ -0,0 +1,26 @@
+// RUN: %target-swift-frontend -emit-ir  -module-name outcopyaddr -primary-file %s | %FileCheck %s
+
+public protocol BaseProt {
+}
+
+public protocol ChildProt: BaseProt {
+}
+
+public struct BaseStruct<T: BaseProt> {
+    public typealias Element = T
+    public var elem1: Element
+    public var elem2: Element
+}
+
+public struct StructWithBaseStruct<T: BaseProt> {
+    public typealias Element = T
+    var elem1: Element
+    var elem2: BaseStruct<Element>
+}
+
+// CHECK-LABEL: define hidden swiftcc void @"$S11outcopyaddr010StructWithbc4BaseB0V4elemAA0bcdB0VyxGvg"(%T11outcopyaddr014StructWithBaseB0V.0* noalias nocapture sret, %swift.type* %"StructWithStructWithBaseStruct<T>", %T11outcopyaddr010StructWithbc4BaseB0V* noalias nocapture swiftself)
+// CHECK: call %T11outcopyaddr014StructWithBaseB0V.0* @"$S11outcopyaddrytWc3_"
+public struct StructWithStructWithBaseStruct<T: ChildProt> {
+    public typealias Element = T
+    let elem: StructWithBaseStruct<Element>
+}
diff --git a/test/IRGen/reflection_metadata.swift b/test/IRGen/reflection_metadata.swift
index 0664561..0065eae 100644
--- a/test/IRGen/reflection_metadata.swift
+++ b/test/IRGen/reflection_metadata.swift
@@ -2,51 +2,51 @@
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-reflection-names -emit-ir %s | %FileCheck %s --check-prefix=STRIP_REFLECTION_NAMES
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-reflection-metadata -emit-ir %s | %FileCheck %s --check-prefix=STRIP_REFLECTION_METADATA
 
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_reflect
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_fieldmd
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_assocty
-// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift5_capture
-// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift5_typeref
-// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift5_reflstr
-// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift5_builtin
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_reflect
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_fieldmd
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_assocty
+// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift4_capture
+// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift4_typeref
+// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift4_reflstr
+// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift4_builtin
 
-// STRIP_REFLECTION_NAMES-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift5_fieldmd
+// STRIP_REFLECTION_NAMES-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift4_fieldmd
 
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_reflect
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_fieldmd
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_assocty
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_capture
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_typeref
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_reflstr
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_builtin
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_reflect
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_fieldmd
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_assocty
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_capture
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_typeref
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_reflstr
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_builtin
 
 // CHECK-DAG: @__swift_reflection_version = linkonce_odr hidden constant i16 {{[0-9]+}}
-// CHECK-DAG: private constant [2 x i8] c"i\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"ms\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"me\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"mc\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"C\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"S\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"E\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"I\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"t\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mgs\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mge\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mgc\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GC\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GS\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GE\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"i\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"ms\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"me\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"mc\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"C\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"S\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"E\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"I\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"t\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mgs\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mge\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mgc\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GC\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GS\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GE\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
 
-// CHECK-DAG: @"\01l__swift5_reflection_descriptor" = private constant { {{.*}} } { i32 1, i32 1, i32 2, {{.*}} }
+// CHECK-DAG: @"\01l__swift4_reflection_descriptor" = private constant { {{.*}} } { i32 1, i32 1, i32 2, {{.*}} }
 
-// CHECK-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata7MyClassCMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata11ConformanceVAA10MyProtocolAAMA" = internal constant {{.*}}swift5_assocty
-// CHECK-DAG: @"$S19reflection_metadata8MyStructVMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata6MyEnumOMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata14MyGenericClassCMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata15MyGenericStructVMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata13MyGenericEnumOMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata7MyClassCMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata11ConformanceVAA10MyProtocolAAMA" = internal constant {{.*}}swift4_assocty
+// CHECK-DAG: @"$S19reflection_metadata8MyStructVMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata6MyEnumOMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata14MyGenericClassCMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata15MyGenericStructVMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata13MyGenericEnumOMF" = internal constant {{.*}}swift4_fieldmd
 
 public protocol MyProtocol {
   associatedtype Inner
diff --git a/test/IRGen/reflection_metadata_imported.swift b/test/IRGen/reflection_metadata_imported.swift
index f8a61b1..4af3fd7 100644
--- a/test/IRGen/reflection_metadata_imported.swift
+++ b/test/IRGen/reflection_metadata_imported.swift
@@ -4,10 +4,10 @@
 
 // CHECK-DAG: @__swift_reflection_version = linkonce_odr hidden constant i16 {{[0-9]+}}
 
-// CHECK-DAG: @"$S28reflection_metadata_imported15HasImportedTypeVMF" = internal constant {{.*}}swift5_fieldmd
-// CHECK-DAG: @"$SSo1AVMB" = linkonce_odr hidden constant {{.*}}swift5_builtin
-// CHECK-DAG: @"$SSo11CrappyColorVMB" = linkonce_odr hidden constant {{.*}}swift5_builtin
-// CHECK-DAG: @"$SSo11CrappyColorVs16RawRepresentableSCMA" = linkonce_odr hidden constant {{.*}}swift5_assocty
+// CHECK-DAG: @"$S28reflection_metadata_imported15HasImportedTypeVMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$SSo1AVMB" = linkonce_odr hidden constant {{.*}}swift4_builtin
+// CHECK-DAG: @"$SSo11CrappyColorVMB" = linkonce_odr hidden constant {{.*}}swift4_builtin
+// CHECK-DAG: @"$SSo11CrappyColorVs16RawRepresentableSCMA" = linkonce_odr hidden constant {{.*}}swift4_assocty
 
 struct HasImportedType {
   let a: A
diff --git a/test/IRGen/swift3-metadata-coff.swift b/test/IRGen/swift3-metadata-coff.swift
index 15441b7..38d0887 100644
--- a/test/IRGen/swift3-metadata-coff.swift
+++ b/test/IRGen/swift3-metadata-coff.swift
@@ -25,7 +25,7 @@
   return { gg = s }
 }
 
-// CHECK-DAG: @"\01l__swift5_reflection_descriptor" = private constant {{.*}}, section ".sw5cptr$B"
+// CHECK-DAG: @"\01l__swift4_reflection_descriptor" = private constant {{.*}}, section ".sw5cptr$B"
 // CHECK-DAG: @"{{.*}}" = {{.*}} c"Sq", {{.*}} section ".sw5tyrf$B"
 // CHECK-DAG: @{{[0-9]+}} = {{.*}} c"none\00", section ".sw5rfst$B"
 // CHECK-DAG: @{{[0-9]+}} = {{.*}} c"some\00", section ".sw5rfst$B"
diff --git a/test/SIL/Parser/keypath.sil b/test/SIL/Parser/keypath.sil
index 6c90dec..e5b153a 100644
--- a/test/SIL/Parser/keypath.sil
+++ b/test/SIL/Parser/keypath.sil
@@ -156,30 +156,32 @@
   // CHECK: %3 = keypath $KeyPath<External<Int>, Int>, <τ_0_0> (root $External<τ_0_0>; external #External.ro<τ_0_0> : $τ_0_0) <Int>
   %c = keypath $KeyPath<External<Int>, Int>, <F> (root $External<F>; external #External.ro <F> : $F) <Int>
 
-  // CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1) <B, A> (%0)
-  %d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (root $External<H>; external #External.subscript <H, G> [%$0 : $G : $*G] : $H) <B, A> (%z)
+  // CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
+  // CHECK-SAME: root $External<τ_0_1>;
+  // CHECK-SAME: external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1,
+  // CHECK-SAME: indices_equals @equals_external_subscript
+  // CHECK-SAME: indices_hash @hash_external_subscript
+  // CHECK-SAME: ) <B, A> (%0)
+  %d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (
+    root $External<H>;
+    external #External.subscript <H, G> [%$0 : $G : $*G] : $H,
+      indices_equals @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
+      indices_hash @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int) <B, A> (%z)
 
   return undef : $()
 }
 
 sil @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in External<T>, UnsafeRawPointer) -> @out T
-sil @equals_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
-sil @hash_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer) -> Int
+sil @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
+sil  @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int
 
 // CHECK-LABEL: sil_property #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0)
 sil_property #External.ro <T> (stored_property #External.ro : $T)
 
 // CHECK-LABEL: sil_property #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0,
 // CHECK-SAME:   id @id_a : $@convention(thin) () -> (),
-// CHECK-SAME:   getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0,
-// CHECK-SAME:   indices [%$0 : $τ_1_0 : $*τ_1_0],
-// CHECK-SAME:   indices_equals @equals_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
-// CHECK-SAME:   indices_hash @hash_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (UnsafeRawPointer) -> Int)
+// CHECK-SAME:   getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0)
 sil_property #External.subscript <T><U: Hashable> (gettable_property $T,
   id @id_a : $@convention(thin) () -> (),
-  getter @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in External<T>, UnsafeRawPointer) -> @out T,
-  indices [%$0 : $U : $*U],
-  indices_equals @equals_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
-  indices_hash @hash_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer) -> Int)
-
+  getter @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in External<T>, UnsafeRawPointer) -> @out T)
 
diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil
index 0a5a404..264b32d 100644
--- a/test/SIL/Serialization/keypath.sil
+++ b/test/SIL/Serialization/keypath.sil
@@ -43,9 +43,11 @@
 }
 
 public struct External<T> {
-  var ro: T { get }
+  var ro: T
 
   subscript<U: Hashable>(ro _: U) -> T { get }
+
+  init()
 }
 
 // CHECK-LABEL: sil shared [serialized] @stored_properties
@@ -159,8 +161,17 @@
   // CHECK: %3 = keypath $KeyPath<External<Int>, Int>, <τ_0_0> (root $External<τ_0_0>; external #External.ro<τ_0_0> : $τ_0_0) <Int>
   %c = keypath $KeyPath<External<Int>, Int>, <F> (root $External<F>; external #External.ro <F> : $F) <Int>
 
-  // CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1) <B, A> (%0)
-  %d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (root $External<H>; external #External.subscript <H, G> [%$0 : $G : $*G] : $H) <B, A> (%z)
+  // CHECK: %4 = keypath $KeyPath<External<A>, A>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
+  // CHECK-SAME: root $External<τ_0_1>;
+  // CHECK-SAME: external #External.subscript<τ_0_1, τ_0_0>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1,
+  // CHECK-SAME: indices_equals @equals_external_subscript
+  // CHECK-SAME: indices_hash @hash_external_subscript
+  // CHECK-SAME: ) <B, A> (%0)
+  %d = keypath $KeyPath<External<A>, A>, <G: Hashable, H> (
+    root $External<H>;
+    external #External.subscript <H, G> [%$0 : $G : $*G] : $H,
+      indices_equals @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
+      indices_hash @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int) <B, A> (%z)
 
   return undef : $()
 }
@@ -179,23 +190,17 @@
 }
 
 sil [serialized] @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in External<T>, UnsafeRawPointer) -> @out T
-sil [serialized] @equals_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
-sil [serialized] @hash_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer) -> Int
+sil [serialized] @equals_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
+sil [serialized] @hash_external_subscript : $@convention(thin) <U: Hashable, T> (UnsafeRawPointer) -> Int
 
 // CHECK-LABEL: sil_property [serialized] #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0)
 sil_property [serialized] #External.ro <T> (stored_property #External.ro : $T)
 
 // CHECK-LABEL: sil_property [serialized] #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0,
 // CHECK-SAME:   id @id_a : $@convention(thin) () -> (),
-// CHECK-SAME:   getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0,
-// CHECK-SAME:   indices [%$0 : $τ_1_0 : $*τ_1_0],
-// CHECK-SAME:   indices_equals @equals_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
-// CHECK-SAME:   indices_hash @hash_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (UnsafeRawPointer) -> Int)
+// CHECK-SAME:   getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0)
 sil_property [serialized] #External.subscript <T><U: Hashable> (gettable_property $T,
   id @id_a : $@convention(thin) () -> (),
-  getter @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in External<T>, UnsafeRawPointer) -> @out T,
-  indices [%$0 : $U : $*U],
-  indices_equals @equals_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool,
-  indices_hash @hash_external_subscript : $@convention(thin) <T, U: Hashable> (UnsafeRawPointer) -> Int)
+  getter @get_external_subscript : $@convention(thin) <T, U: Hashable> (@in External<T>, UnsafeRawPointer) -> @out T)
 
 
diff --git a/test/SILGen/Inputs/ExternalKeyPaths.swift b/test/SILGen/Inputs/ExternalKeyPaths.swift
index 23d4f30..a191274 100644
--- a/test/SILGen/Inputs/ExternalKeyPaths.swift
+++ b/test/SILGen/Inputs/ExternalKeyPaths.swift
@@ -3,3 +3,7 @@
   public var intProperty: Int
   public subscript<B: Hashable>(index: B) -> A { return property }
 }
+
+public struct ExternalEmptySubscript {
+  public subscript() -> Int { return 0 }
+}
diff --git a/test/SILGen/access_marker_gen.swift b/test/SILGen/access_marker_gen.swift
index ed41275..205cbca 100644
--- a/test/SILGen/access_marker_gen.swift
+++ b/test/SILGen/access_marker_gen.swift
@@ -98,6 +98,7 @@
 
 class C {
   final var x: Int = 0
+  let z: Int = 0
 }
 
 func testClassInstanceProperties(c: C) {
@@ -116,6 +117,20 @@
 // CHECK-NEXT:  assign [[Y]] to [[ACCESS]]
 // CHECK-NEXT:  end_access [[ACCESS]]
 
+func testClassLetProperty(c: C) -> Int {
+  return c.z
+}
+
+// CHECK-LABEL: sil hidden @$S17access_marker_gen20testClassLetProperty1cSiAA1CC_tF : $@convention(thin) (@owned C) -> Int {
+// CHECK: bb0(%0 : @owned $C):
+// CHECK:   [[ADR:%.*]] = ref_element_addr %{{.*}} : $C, #C.z
+// CHECK-NOT: begin_access
+// CHECK:   %{{.*}} = load [trivial] [[ADR]] : $*Int
+// CHECK-NOT: end_access
+// CHECK:   destroy_value %0 : $C
+// CHECK:   return %{{.*}} : $Int
+// CHECK-LABEL: } // end sil function '$S17access_marker_gen20testClassLetProperty1cSiAA1CC_tF'
+
 class D {
   var x: Int = 0
 }
diff --git a/test/SILGen/extensions_multifile.swift b/test/SILGen/extensions_multifile.swift
index 3c8d81f..e5b6550 100644
--- a/test/SILGen/extensions_multifile.swift
+++ b/test/SILGen/extensions_multifile.swift
@@ -1,4 +1,5 @@
-// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/struct_with_initializer.swift -module-name extensions_multifile -enable-sil-ownership | %FileCheck %s
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/struct_with_initializer.swift -module-name extensions_multifile -enable-sil-ownership | %FileCheck %s --check-prefix=FRAGILE --check-prefix=CHECK
+// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/struct_with_initializer.swift -module-name extensions_multifile -enable-sil-ownership -enable-resilience | %FileCheck %s --check-prefix=RESILIENT --check-prefix=CHECK
 
 // CHECK-LABEL: sil hidden @$S20extensions_multifile12HasInitValueV1zACSi_tcfC : $@convention(method) (Int, @thin HasInitValue.Type) -> @owned HasInitValue {
 // CHECK: function_ref @$S20extensions_multifile12HasInitValueV1xSivpfi : $@convention(thin) () -> Int
@@ -15,7 +16,9 @@
   init(z: Int) {}
 }
 
-// CHECK-LABEL: sil hidden_external [transparent] @$S20extensions_multifile24PublicStructHasInitValueV1xSivpfi : $@convention(thin) () -> Int
+// FRAGILE-LABEL: sil [transparent] @$S20extensions_multifile24PublicStructHasInitValueV1xSivpfi : $@convention(thin) () -> Int
+
+// RESILIENT-LABEL: sil hidden_external [transparent] @$S20extensions_multifile24PublicStructHasInitValueV1xSivpfi : $@convention(thin) () -> Int
 
 extension PublicStructHasInitValue {
   init(z: Int) {}
diff --git a/test/SILGen/external-keypath.swift b/test/SILGen/external-keypath.swift
index cf51664..401c221 100644
--- a/test/SILGen/external-keypath.swift
+++ b/test/SILGen/external-keypath.swift
@@ -29,24 +29,29 @@
   // CHECK: keypath $WritableKeyPath<External<U>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.intProperty<U> : $Int) <T, U>
   _ = \External<U>.intProperty
 
-  // CHECK: keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.subscript<Int, Int>[%$0 : $Int : $Int] : $Int) (%2)
+  // CHECK: keypath $KeyPath<External<Int>, Int>, (root $External<Int>; external #External.subscript<Int, Int>[%$0 : $Int : $Int] : $Int, indices_equals @{{.*}}) (%2)
   _ = \External<Int>.[z]
 
-  // CHECK: keypath $KeyPath<External<T>, T>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; external #External.subscript<T, T>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_0) <T, U> ({{.*}})
+  // CHECK: keypath $KeyPath<External<T>, T>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_0>; external #External.subscript<T, T>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_0, indices_equals @{{.*}}) <T, U> ({{.*}})
   _ = \External<T>.[x]
 
-  // CHECK: keypath $KeyPath<External<U>, U>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.subscript<U, T>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1) <T, U> ({{.*}})
+  // CHECK: keypath $KeyPath<External<U>, U>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (root $External<τ_0_1>; external #External.subscript<U, T>[%$0 : $τ_0_0 : $*τ_0_0] : $τ_0_1, indices_equals @{{.*}}) <T, U> ({{.*}})
   _ = \External<U>.[x]
 
   // CHECK: keypath $KeyPath<External<Local>, Int>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
   // CHECK-SAME: root $External<Local>;
-  // CHECK-SAME: external #External.subscript<Local, T>[%$0 : $τ_0_0 : $*τ_0_0] : $Local;
+  // CHECK-SAME: external #External.subscript<Local, T>[%$0 : $τ_0_0 : $*τ_0_0] : $Local, indices_equals @{{.*}};
   // CHECK-SAME: stored_property #Local.x : $Int) <T, U> ({{.*}})
   _ = \External<Local>.[x].x
 
   // CHECK: keypath $KeyPath<External<Local>, String>, <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (
   // CHECK-SAME: root $External<Local>;
-  // CHECK-SAME: external #External.subscript<Local, T>[%$0 : $τ_0_0 : $*τ_0_0] : $Local;
+  // CHECK-SAME: external #External.subscript<Local, T>[%$0 : $τ_0_0 : $*τ_0_0] : $Local, indices_equals @{{.*}};
   // CHECK-SAME: stored_property #Local.y : $String) <T, U> ({{.*}})
   _ = \External<Local>.[x].y
+
+  // CHECK: keypath $KeyPath<ExternalEmptySubscript, Int>, (
+  // CHECK-SAME: root $ExternalEmptySubscript;
+  // CHECK-SAME: external #ExternalEmptySubscript.subscript : $Int)
+  _ = \ExternalEmptySubscript.[]
 }
diff --git a/test/SILGen/fixed_layout_attribute.swift b/test/SILGen/fixed_layout_attribute.swift
index 75a14c4..b8777ff 100644
--- a/test/SILGen/fixed_layout_attribute.swift
+++ b/test/SILGen/fixed_layout_attribute.swift
@@ -20,7 +20,8 @@
   public var storedProperty = global
 }
 
-// CHECK-LABEL: sil hidden [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int
+// FRAGILE-LABEL: sil [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int
+// RESILIENT-LABEL: sil hidden [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int
 //
 //    ... okay to directly reference the addressor here:
 // CHECK: function_ref @$S22fixed_layout_attribute6globalSivau
diff --git a/test/SILGen/guaranteed_self.swift b/test/SILGen/guaranteed_self.swift
index efa45ba..ab193e7 100644
--- a/test/SILGen/guaranteed_self.swift
+++ b/test/SILGen/guaranteed_self.swift
@@ -452,16 +452,11 @@
   // CHECK-LABEL: sil hidden @$S15guaranteed_self13LetFieldClassC10letkMethod{{[_0-9a-zA-Z]*}}F : $@convention(method) (@guaranteed LetFieldClass) -> () {
   // CHECK: bb0([[CLS:%.*]] : @guaranteed $LetFieldClass):
   // CHECK: [[KRAKEN_ADDR:%.*]] = ref_element_addr [[CLS]] : $LetFieldClass, #LetFieldClass.letk
-  // CHECK-NEXT: [[WRITE:%.*]] = begin_access [read] [dynamic] [[KRAKEN_ADDR]] : $*Kraken
-  // CHECK-NEXT: [[KRAKEN:%.*]] = load_borrow [[WRITE]]
-  // CHECK-NEXT: end_access [[WRITE]] : $*Kraken
+  // CHECK-NEXT: [[KRAKEN:%.*]] = load_borrow [[KRAKEN_ADDR]]
   // CHECK-NEXT: [[KRAKEN_METH:%.*]] = class_method [[KRAKEN]]
   // CHECK-NEXT: apply [[KRAKEN_METH]]([[KRAKEN]])
-  // CHECK-NEXT: end_borrow [[KRAKEN]] from [[WRITE]]
-  // CHECK-NEXT: [[KRAKEN_ADDR:%.*]] = ref_element_addr [[CLS]] : $LetFieldClass, #LetFieldClass.letk
-  // CHECK: [[READ:%.*]] = begin_access [read] [dynamic] [[KRAKEN_ADDR]] : $*Kraken
-  // CHECK-NEXT: [[KRAKEN:%.*]] = load [copy] [[READ]]
-  // CHECK-NEXT: end_access [[READ]] : $*Kraken
+  // CHECK: [[KRAKEN_ADDR:%.*]] = ref_element_addr [[CLS]] : $LetFieldClass, #LetFieldClass.letk
+  // CHECK-NEXT: [[KRAKEN:%.*]] = load [copy] [[KRAKEN_ADDR]]
   // CHECK:      [[BORROWED_KRAKEN:%.*]] = begin_borrow [[KRAKEN]]
   // CHECK-NEXT: [[KRAKEN_COPY:%.*]] = copy_value [[BORROWED_KRAKEN]]
   // CHECK: [[DESTROY_SHIP_FUN:%.*]] = function_ref @$S15guaranteed_self11destroyShipyyAA6KrakenCF : $@convention(thin) (@owned Kraken) -> ()
@@ -470,9 +465,7 @@
   // CHECK-NEXT: [[KRAKEN_BOX:%.*]] = alloc_box ${ var Kraken }
   // CHECK-NEXT: [[PB:%.*]] = project_box [[KRAKEN_BOX]]
   // CHECK-NEXT: [[KRAKEN_ADDR:%.*]] = ref_element_addr [[CLS]] : $LetFieldClass, #LetFieldClass.letk
-  // CHECK-NEXT: [[READ:%.*]] = begin_access [read] [dynamic] [[KRAKEN_ADDR]] : $*Kraken
-  // CHECK-NEXT: [[KRAKEN2:%.*]] = load [copy] [[READ]]
-  // CHECK-NEXT: end_access [[READ]] : $*Kraken
+  // CHECK-NEXT: [[KRAKEN2:%.*]] = load [copy] [[KRAKEN_ADDR]]
   // CHECK-NEXT: store [[KRAKEN2]] to [init] [[PB]]
   // CHECK-NEXT: [[READ:%.*]] = begin_access [read] [unknown] [[PB]] : $*Kraken
   // CHECK-NEXT: [[KRAKEN_COPY:%.*]] = load [copy] [[READ]]
diff --git a/test/SILGen/keypath_property_descriptors.swift b/test/SILGen/keypath_property_descriptors.swift
index 61f306d..ee63e8e 100644
--- a/test/SILGen/keypath_property_descriptors.swift
+++ b/test/SILGen/keypath_property_descriptors.swift
@@ -50,12 +50,12 @@
   // CHECK-NOT: sil_property #A.f
   private static var f: Int = 0
 
-  // CHECK-LABEL: sil_property #A.subscript
+  // CHECK-LABEL: sil_property #A.subscript{{.*}} id @{{.*}}1a
   public subscript(a x: Int) -> Int { return x }
-  // CHECK-LABEL: sil_property #A.subscript
+  // CHECK-LABEL: sil_property #A.subscript{{.*}} id @{{.*}}1b
   @_inlineable
   public subscript(b x: Int) -> Int { return x }
-  // CHECK-LABEL: sil_property #A.subscript
+  // CHECK-LABEL: sil_property #A.subscript{{.*}} id @{{.*}}1c
   @_versioned
   internal subscript(c x: Int) -> Int { return x }
   
@@ -65,16 +65,32 @@
   fileprivate subscript(e x: Int) -> Int { return x }
   private subscript(f x: Int) -> Int { return x }
 
-  // TODO: Subscripts with non-hashable subscripts should get descriptors
+  // CHECK-LABEL: sil_property #A.subscript{{.*}} id @{{.*}}1a
   public subscript<T>(a x: T) -> T { return x }
+  // CHECK-LABEL: sil_property #A.subscript{{.*}} id @{{.*}}1b
   @_inlineable
   public subscript<T>(b x: T) -> T { return x }
+  // CHECK-LABEL: sil_property #A.subscript{{.*}} id @{{.*}}1c
   @_versioned
   internal subscript<T>(c x: T) -> T { return x }
   
   // no descriptor
+  // CHECK-NOT: sil_property #A.subscript
   internal subscript<T>(d x: T) -> T { return x }
   fileprivate subscript<T>(e x: T) -> T { return x }
   private subscript<T>(f x: T) -> T { return x }
+
+  // no descriptor
+  public var count: Int {
+    mutating get {
+      _count += 1
+      return _count
+    }
+    set {
+      _count = newValue
+    }
+  }
+
+  private var _count: Int = 0
 }
 
diff --git a/test/SILGen/properties.swift b/test/SILGen/properties.swift
index d8b80e9..b719200 100644
--- a/test/SILGen/properties.swift
+++ b/test/SILGen/properties.swift
@@ -947,8 +947,7 @@
   let _ = x.y
   // CHECK:   [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
   // CHECK:   [[Z:%.*]] = ref_element_addr [[BORROWED_ARG]] : $GenericClass<String>, #GenericClass.z
-  // CHECK:   [[READ:%.*]] = begin_access [read] [dynamic] [[Z]] : $*String
-  // CHECK:   [[LOADED_Z:%.*]] = load [copy] [[READ]] : $*String
+  // CHECK:   [[LOADED_Z:%.*]] = load [copy] [[Z]] : $*String
   // CHECK:   destroy_value [[LOADED_Z]]
   // CHECK:   end_borrow [[BORROWED_ARG]] from [[ARG]]
   // CHECK:   destroy_value [[ARG]]
@@ -960,8 +959,7 @@
   // CHECK: bb0([[ARG:%.*]] : $GenericClass<U>):
   // CHECK:   [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
   // CHECK:   [[Z:%.*]] = ref_element_addr [[BORROWED_ARG]] : $GenericClass<U>, #GenericClass.z
-  // CHECK:   [[READ:%.*]] = begin_access [read] [dynamic] [[Z]] : $*U
-  // CHECK:   copy_addr [[READ]] {{.*}} : $*U
+  // CHECK:   copy_addr [[Z]] {{.*}} : $*U
   // CHECK:   end_borrow [[BORROWED_ARG]] from [[ARG]]
   let _ = x.z
 }
@@ -978,9 +976,7 @@
 // CHECK:       bb0([[ARG:%.*]] : $ClassWithLetProperty):
 // CHECK-NEXT:    debug_value
 // CHECK-NEXT:    [[PTR:%[0-9]+]] = ref_element_addr [[ARG]] : $ClassWithLetProperty, #ClassWithLetProperty.p
-// CHECK-NEXT:    [[READ:%.*]] = begin_access [read] [dynamic] [[PTR]] : $*Int
-// CHECK-NEXT:    [[VAL:%[0-9]+]] = load [trivial] [[READ]] : $*Int
-// CHECK-NEXT:    end_access [[READ]] : $*Int
+// CHECK-NEXT:    [[VAL:%[0-9]+]] = load [trivial] [[PTR]] : $*Int
 // CHECK-NEXT:   return [[VAL]] : $Int
 
 
@@ -1008,8 +1004,7 @@
 // Initialization of the pi field: no copy_values/releases.
 // CHECK:  [[SELF:%[0-9]+]] = load_borrow [[PB_BOX]] : $*r19254812Derived
 // CHECK-NEXT:  [[PIPTR:%[0-9]+]] = ref_element_addr [[SELF]] : $r19254812Derived, #r19254812Derived.pi
-// CHECK-NEXT:  [[WRITE:%.*]] = begin_access [modify] [dynamic] [[PIPTR]] : $*Double
-// CHECK-NEXT:  assign {{.*}} to [[WRITE]] : $*Double
+// CHECK-NEXT:  assign {{.*}} to [[PIPTR]] : $*Double
 
 // CHECK-NOT: destroy_value
 // CHECK-NOT: copy_value
@@ -1017,9 +1012,7 @@
 // Load of the pi field: no copy_values/releases.
 // CHECK:  [[SELF:%[0-9]+]] = load_borrow [[PB_BOX]] : $*r19254812Derived
 // CHECK-NEXT:  [[PIPTR:%[0-9]+]] = ref_element_addr [[SELF]] : $r19254812Derived, #r19254812Derived.pi
-// CHECK-NEXT:  [[READ:%.*]] = begin_access [read] [dynamic] [[PIPTR]] : $*Double
-// CHECK-NEXT:  {{.*}} = load [trivial] [[READ]] : $*Double
-// CHECK-NEXT:  end_access [[READ]] : $*Double
+// CHECK-NEXT:  {{.*}} = load [trivial] [[PIPTR]] : $*Double
 // CHECK: return
 }
 
diff --git a/test/SILGen/reabstract-tuple.swift b/test/SILGen/reabstract-tuple.swift
index 4e5d0c7..7d98c63 100644
--- a/test/SILGen/reabstract-tuple.swift
+++ b/test/SILGen/reabstract-tuple.swift
@@ -33,15 +33,13 @@
 // CHECK:   destroy_value [[TUPLEB]] : $(Int, @callee_guaranteed (@in ()) -> @out ())
 // CHECK:   [[BORROW_CALL:%.*]] = begin_borrow [[CALL]] : $Box<(Int, () -> ())> 
 // CHECK:   [[REF:%.*]] = ref_element_addr [[BORROW_CALL]] : $Box<(Int, () -> ())>, #Box.value
-// CHECK:   [[READ:%.*]] = begin_access [read] [dynamic] [[REF]] : $*(Int, @callee_guaranteed (@in ()) -> @out ())
-// CHECK:   [[TUPLEC:%.*]] = load [copy] [[READ]] : $*(Int, @callee_guaranteed (@in ()) -> @out ())
+// CHECK:   [[TUPLEC:%.*]] = load [copy] [[REF]] : $*(Int, @callee_guaranteed (@in ()) -> @out ())
 // CHECK:   [[BORROW_TUPLEC:%.*]] = begin_borrow [[TUPLEC]] : $(Int, @callee_guaranteed (@in ()) -> @out ())
 // CHECK:   [[TUPLEC_0:%.*]] = tuple_extract [[BORROW_TUPLEC]] : $(Int, @callee_guaranteed (@in ()) -> @out ()), 0
 // CHECK:   [[TUPLEC_1:%.*]] = tuple_extract [[BORROW_TUPLEC]] : $(Int, @callee_guaranteed (@in ()) -> @out ()), 1
 // CHECK:   [[COPYC_1:%.*]] = copy_value [[TUPLEC_1]] : $@callee_guaranteed (@in ()) -> @out ()
 // CHECK:   [[THUNK2:%.*]] = function_ref @$SytytIegir_Ieg_TR : $@convention(thin) (@guaranteed @callee_guaranteed (@in ()) -> @out ()) -> ()
 // CHECK:   [[PA2:%.*]] = partial_apply [callee_guaranteed] [[THUNK2]]([[COPYC_1]]) : $@convention(thin) (@guaranteed @callee_guaranteed (@in ()) -> @out ()) -> ()
-// CHECK:   end_access [[READ]] : $*(Int, @callee_guaranteed (@in ()) -> @out ())
 // CHECK:   destroy_value [[PA2]] : $@callee_guaranteed () -> ()    
 // CHECK:   end_borrow [[BORROW_TUPLEC]] from %{{.*}} : $(Int, @callee_guaranteed (@in ()) -> @out ()), $(Int, @callee_guaranteed (@in ()) -> @out ())
 // CHECK:   destroy_value [[TUPLEC]] : $(Int, @callee_guaranteed (@in ()) -> @out ())
diff --git a/test/SILGen/super_init_refcounting.swift b/test/SILGen/super_init_refcounting.swift
index c3608b7..411f054 100644
--- a/test/SILGen/super_init_refcounting.swift
+++ b/test/SILGen/super_init_refcounting.swift
@@ -80,15 +80,13 @@
   // CHECK:         store %0 to [init] [[PB_SELF_BOX]]
   // CHECK:         [[SELF_OBJ:%.*]] = load_borrow [[PB_SELF_BOX]]
   // CHECK:         [[X_ADDR:%.*]] = ref_element_addr [[SELF_OBJ]] : $Good, #Good.x
-  // CHECK:         [[WRITE:%.*]] = begin_access [modify] [dynamic] [[X_ADDR]] : $*Int
-  // CHECK:         assign {{.*}} to [[WRITE]] : $*Int
+  // CHECK:         assign {{.*}} to [[X_ADDR]] : $*Int
   // CHECK:         [[SELF_OBJ:%.*]] = load [take] [[PB_SELF_BOX]] : $*Good
   // CHECK:         [[SUPER_OBJ:%.*]] = upcast [[SELF_OBJ]] : $Good to $Foo
   // CHECK:         [[BORROWED_SUPER:%.*]] = begin_borrow [[SUPER_OBJ]]
   // CHECK:         [[DOWNCAST_BORROWED_SUPER:%.*]] = unchecked_ref_cast [[BORROWED_SUPER]] : $Foo to $Good
   // CHECK:         [[X_ADDR:%.*]] = ref_element_addr [[DOWNCAST_BORROWED_SUPER]] : $Good, #Good.x
-  // CHECK:         [[READ:%.*]] = begin_access [read] [dynamic] [[X_ADDR]] : $*Int
-  // CHECK:         [[X:%.*]] = load [trivial] [[READ]] : $*Int
+  // CHECK:         [[X:%.*]] = load [trivial] [[X_ADDR]] : $*Int
   // CHECK:         end_borrow [[BORROWED_SUPER]] from [[SUPER_OBJ]]
   // CHECK:         [[SUPER_INIT:%.*]] = function_ref @$S22super_init_refcounting3FooCyACSicfc : $@convention(method) (Int, @owned Foo) -> @owned Foo
   // CHECK:         apply [[SUPER_INIT]]([[X]], [[SUPER_OBJ]])
diff --git a/test/SILGen/unowned.swift b/test/SILGen/unowned.swift
index 0c2853e..804ded7 100644
--- a/test/SILGen/unowned.swift
+++ b/test/SILGen/unowned.swift
@@ -146,10 +146,9 @@
 // CHECK:   [[BORROWED_ARG1:%.*]] = begin_borrow [[ARG1]]
 // CHECK:   [[ARG1_COPY:%.*]] = copy_value [[BORROWED_ARG1]]
 // CHECK:   [[FIELDPTR:%.*]] = ref_element_addr [[BORROWED_SELF]] : $TestUnownedMember, #TestUnownedMember.member
-// CHECK:   [[WRITE:%.*]] = begin_access [modify] [dynamic] [[FIELDPTR]] : $*@sil_unowned C
 // CHECK:   [[INVAL:%.*]] = ref_to_unowned [[ARG1_COPY]] : $C to $@sil_unowned C
 // CHECK:   [[INVAL_COPY:%.*]] = copy_value [[INVAL]] : $@sil_unowned C
-// CHECK:   assign [[INVAL_COPY]] to [[WRITE]] : $*@sil_unowned C
+// CHECK:   assign [[INVAL_COPY]] to [[FIELDPTR]] : $*@sil_unowned C
 // CHECK:   destroy_value [[ARG1_COPY]] : $C
 // CHECK:   end_borrow [[BORROWED_ARG1]] from [[ARG1]]
 // CHECK:   end_borrow [[BORROWED_SELF]] from [[SELF]]
diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift
index d7dee50..9b93faf 100644
--- a/test/SILOptimizer/access_marker_verify.swift
+++ b/test/SILOptimizer/access_marker_verify.swift
@@ -162,15 +162,11 @@
   let x = 3
 }
 
-// FIXME: should be a [unknown] access.
-//
 // CHECK-LABEL: sil hidden @$S20access_marker_verify10testGetLet1cSiAA0F5ClassC_tF : $@convention(thin) (@owned LetClass) -> Int {
 // CHECK: bb0(%0 : @owned $LetClass):
 // CHECK:   begin_borrow %0 : $LetClass
 // CHECK:   ref_element_addr
-// CHECK:   begin_access [read] [dynamic]
 // CHECK:   load [trivial]
-// CHECK:   end_access
 // CHECK:   end_borrow
 // CHECK:   destroy_value %0 : $LetClass
 // CHECK:   return
@@ -202,9 +198,7 @@
 // CHECK-NOT: begin_access
 // CHECK:   load_borrow
 // CHECK:   ref_element_addr
-// CHECK:   begin_access [modify] [dynamic]
 // CHECK:   assign %0 to
-// CHECK:   end_access
 // CHECK:   end_borrow
 // CHECK-NOT: begin_access
 // CHECK:   load [take]
diff --git a/test/SILOptimizer/definite-init-wrongscope.swift b/test/SILOptimizer/definite-init-wrongscope.swift
index 97846af..aeabae3 100644
--- a/test/SILOptimizer/definite-init-wrongscope.swift
+++ b/test/SILOptimizer/definite-init-wrongscope.swift
@@ -28,16 +28,14 @@
 
 // Make sure the expanded sequence gets the right scope.
 
-// CHECK:   %49 = begin_access [modify] [dynamic] %48 : $*C, loc{{.*}}:23:20, scope 2
-// CHECK:   %50 = integer_literal $Builtin.Int2, 1, loc {{.*}}:20:12, scope 2
-// CHECK:   %51 = load [trivial] %2 : $*Builtin.Int2, loc {{.*}}:20:12, scope 2
-// CHECK:   %52 = builtin "or_Int2"(%51 : $Builtin.Int2, %50 : $Builtin.Int2) : $Builtin.Int2, loc {{.*}}:20:12, scope 2
-// CHECK:   store %52 to [trivial] %2 : $*Builtin.Int2, loc {{.*}}:20:12, scope 2
-// CHECK:   store %47 to [init] %49 : $*C, loc {{.*}}:23:20, scope 2
-// CHECK:   end_access %49 : $*C, loc {{.*}}:23:20, scope 2
+// CHECK:   [[I:%.*]] = integer_literal $Builtin.Int2, 1, loc {{.*}}:20:12, scope 2
+// CHECK:   [[V:%.*]] = load [trivial] %2 : $*Builtin.Int2, loc {{.*}}:20:12, scope 2
+// CHECK:   [[OR:%.*]] = builtin "or_Int2"([[V]] : $Builtin.Int2, [[I]] : $Builtin.Int2) : $Builtin.Int2, loc {{.*}}:20:12, scope 2
+// CHECK:   store [[OR]] to [trivial] %2 : $*Builtin.Int2, loc {{.*}}:20:12, scope 2
+// CHECK:   store %{{.*}} to [init] %{{.*}} : $*C, loc {{.*}}:23:20, scope 2
 
 // Make sure the dealloc_stack gets the same scope of the instructions surrounding it.
 
 // CHECK:   destroy_addr %0 : $*WithDelegate, loc {{.*}}:26:5, scope 2
 // CHECK:   dealloc_stack %2 : $*Builtin.Int2, loc {{.*}}:20:12, scope 2
-// CHECK:   throw %92 : $Error, loc {{.*}}:20:12, scope 2
+// CHECK:   throw %{{.*}} : $Error, loc {{.*}}:20:12, scope 2
diff --git a/test/SILOptimizer/definite_init_failable_initializers_objc.swift b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
index 9e834c8..c7066ea 100644
--- a/test/SILOptimizer/definite_init_failable_initializers_objc.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers_objc.swift
@@ -34,9 +34,7 @@
     // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $Cat
     // CHECK:      store %2 to [[SELF_BOX]] : $*Cat
     // CHECK:      [[FIELD_ADDR:%.*]] = ref_element_addr %2 : $Cat, #Cat.x
-    // CHECK-NEXT: [[ACCESS:%.*]] = begin_access [modify] [dynamic] %12 : $*LifetimeTracked
-    // CHECK-NEXT: store {{%.*}} to [[ACCESS]] : $*LifetimeTracked
-    // CHECK-NEXT: end_access [[ACCESS]] : $*LifetimeTracked
+    // CHECK-NEXT: store {{%.*}} to [[FIELD_ADDR]] : $*LifetimeTracked
     // CHECK-NEXT: [[COND:%.*]] = struct_extract %1 : $Bool, #Bool._value
     // CHECK-NEXT: cond_br [[COND]], bb1, bb2
 
@@ -46,7 +44,7 @@
   // CHECK: bb2:
     // CHECK-NEXT: [[SUPER:%.*]] = upcast %2 : $Cat to $FakeNSObject
     // CHECK-NEXT: [[SUB:%.*]] = unchecked_ref_cast [[SUPER]] : $FakeNSObject to $Cat
-    // CHECK-NEXT: [[SUPER_FN:%.*]] = objc_super_method %20 : $Cat, #FakeNSObject.init!initializer.1.foreign : (FakeNSObject.Type) -> () -> FakeNSObject, $@convention(objc_method) (@owned FakeNSObject) -> @owned FakeNSObject
+    // CHECK-NEXT: [[SUPER_FN:%.*]] = objc_super_method [[SUB]] : $Cat, #FakeNSObject.init!initializer.1.foreign : (FakeNSObject.Type) -> () -> FakeNSObject, $@convention(objc_method) (@owned FakeNSObject) -> @owned FakeNSObject
     // CHECK-NEXT: [[NEW_SUPER_SELF:%.*]] = apply [[SUPER_FN]]([[SUPER]]) : $@convention(objc_method) (@owned FakeNSObject) -> @owned FakeNSObject
     // CHECK-NEXT: [[NEW_SELF:%.*]] = unchecked_ref_cast [[NEW_SUPER_SELF]] : $FakeNSObject to $Cat
     // CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] : $*Cat
diff --git a/test/SILOptimizer/di-conditional-destroy-scope.swift b/test/SILOptimizer/di-conditional-destroy-scope.swift
index 055d65d..4b6bee9 100644
--- a/test/SILOptimizer/di-conditional-destroy-scope.swift
+++ b/test/SILOptimizer/di-conditional-destroy-scope.swift
@@ -6,8 +6,8 @@
 // REQUIRES: objc_interop
 
 
-// CHECK: %49 = ref_element_addr %48 : $RecursibleDirectoryContentsGenerator, #RecursibleDirectoryContentsGenerator.fileSystem, loc {{.*}}:38:5, scope 2
-// CHECK:  destroy_addr %49 : $*FileSystem, loc {{.*}}:38:5, scope 2
+// CHECK: [[ADR:%.*]] = ref_element_addr %{{.*}} : $RecursibleDirectoryContentsGenerator, #RecursibleDirectoryContentsGenerator.fileSystem, loc {{.*}}:38:5, scope 2
+// CHECK:  destroy_addr [[ADR]] : $*FileSystem, loc {{.*}}:38:5, scope 2
 
 
 import Foundation
diff --git a/test/Sema/exhaustive_switch.swift b/test/Sema/exhaustive_switch.swift
index caa6469..660aff4 100644
--- a/test/Sema/exhaustive_switch.swift
+++ b/test/Sema/exhaustive_switch.swift
@@ -801,4 +801,13 @@
   case .a: // expected-warning {{case is already handled by previous patterns; consider removing it}}
     print("second a")
   }
+
+  func foo(_ str: String) -> Int {
+    switch str { // expected-error {{switch must be exhaustive}}
+    // expected-note@-1 {{do you want to add a default clause?}}
+    case let (x as Int) as Any:
+      return x
+    }
+  }
+  _ = foo("wtf")
 }
diff --git a/test/SwiftSyntax/AbsolutePosition.swift b/test/SwiftSyntax/AbsolutePosition.swift
index cb5f317..a0c1754 100644
--- a/test/SwiftSyntax/AbsolutePosition.swift
+++ b/test/SwiftSyntax/AbsolutePosition.swift
@@ -73,6 +73,10 @@
         _ = node.byteSize
         _ = node.positionAfterSkippingLeadingTrivia
       }
+      override func visit(_ node: TokenSyntax) {
+        expectEqual(node.position.byteOffset + node.leadingTrivia.byteSize,
+                    node.positionAfterSkippingLeadingTrivia.byteOffset)
+      }
     }
     Visitor().visit(parsed)
   })
diff --git a/test/SwiftSyntax/Inputs/visitor.swift b/test/SwiftSyntax/Inputs/visitor.swift
index 5084af6..3597e47 100644
--- a/test/SwiftSyntax/Inputs/visitor.swift
+++ b/test/SwiftSyntax/Inputs/visitor.swift
@@ -1,6 +1,7 @@
 func foo() {
   func foo() {
     func foo() {
+      /*Unknown token */0xG
     }
   }
 }
diff --git a/test/Syntax/Inputs/serialize_multiple_decls.json b/test/Syntax/Inputs/serialize_multiple_decls.json
index 931ea25..c7af058 100644
--- a/test/Syntax/Inputs/serialize_multiple_decls.json
+++ b/test/Syntax/Inputs/serialize_multiple_decls.json
@@ -185,7 +185,8 @@
     },
     {
       "tokenKind": {
-        "kind": "eof"
+        "kind": "eof",
+        "text": ""
       },
       "leadingTrivia": [
         {
diff --git a/test/Syntax/Inputs/serialize_struct_decl.json b/test/Syntax/Inputs/serialize_struct_decl.json
index 14d1da1..efa432a 100644
--- a/test/Syntax/Inputs/serialize_struct_decl.json
+++ b/test/Syntax/Inputs/serialize_struct_decl.json
@@ -373,7 +373,8 @@
     },
     {
       "tokenKind": {
-        "kind": "eof"
+        "kind": "eof",
+        "text": ""
       },
       "leadingTrivia": [
         {
diff --git a/test/stdlib/tgmath.swift b/test/stdlib/tgmath.swift
index 791d386..2dd538d 100644
--- a/test/stdlib/tgmath.swift
+++ b/test/stdlib/tgmath.swift
@@ -18,74 +18,31 @@
 
 let MathTests = TestSuite("TGMath")
 
-func print3(_ op: String, _ d: Double, _ f: Float, _ g: CGFloat) -> String {
-#if arch(i386) || arch(arm)
-  if (f != Float(g)  &&  f.isNaN != g.isNaN) {
-    return "\(op)(CGFloat) got \(g) instead of \(f)"
-  }
-#else
-  if (d != Double(g)  &&  d.isNaN != g.isNaN) {
-    return "\(op)(CGFloat) got \(g) instead of \(d)"
-  }
-#endif
-  return "\(op) \(d) \(f) \(op)"
+func expectEqualWithAccuracy(_ actualDouble: Double, _ expectedDouble: Double, ulps: Int, _ message: String = "", file: String = #file, line: UInt = #line) {
+    let epsilonDouble = Double(ulps) * expectedDouble.ulp
+    let minDouble = expectedDouble - epsilonDouble
+    let maxDouble = expectedDouble + epsilonDouble
+    let messageDouble = "Expected: \(expectedDouble) != Actual: \(actualDouble)"
+    expectTrue((actualDouble.isNaN && expectedDouble.isNaN) || (actualDouble >= minDouble && actualDouble <= maxDouble), messageDouble, file: file, line: line)
 }
 
-func print3(_ op: String, _ d: Bool, _ f: Bool, _ g: Bool) -> String {
-#if arch(i386) || arch(arm)
-  if (f != g) {
-    return "\(op)(CGFloat) got \(g) instead of \(f)"
-  }
-#else
-  if (d != g) {
-    return "\(op)(CGFloat) got \(g) instead of \(d)"
-  }
-#endif
-  return "\(op) \(d) \(f) \(op)"
+func expectEqualWithAccuracy(_ actualFloat: Float, _ expectedFloat: Float, ulps: Int, _ message: String = "", file: String = #file, line: UInt = #line) {
+    let epsilonFloat = Float(ulps) * expectedFloat.ulp
+    let minFloat = expectedFloat - epsilonFloat
+    let maxFloat = expectedFloat + epsilonFloat
+    let messageFloat = "Expected: \(expectedFloat) != Actual: \(actualFloat) (actualFloat.isNaN=\(actualFloat.isNaN) , expectedFloat.isNaN=\(expectedFloat.isNaN), minFloat=\(minFloat), maxFloat = \(maxFloat)"
+    expectTrue((actualFloat.isNaN && expectedFloat.isNaN) || (actualFloat >= minFloat && actualFloat <= maxFloat), messageFloat, file: file, line: line)
 }
 
-func print3(_ op: String, _ d: Int, _ f: Int, _ g: Int) -> String {
-#if arch(i386) || arch(arm)
-  if (f != g) {
-    return "\(op)(CGFloat) got \(g) instead of \(f)"
-  }
-#else
-  if (d != g) {
-    return "\(op)(CGFloat) got \(g) instead of \(d)"
-  }
-#endif
-  return "\(op) \(d) \(f) \(op)"
-}
+func expectEqualWithAccuracy(_ actualDouble: Double, _ actualFloat: Float, _ actualCGFloat: CGFloat, _ expected: Double, ulps: Int, _ message: String = "", file: String = #file, line: UInt = #line) {
+    expectEqualWithAccuracy(actualDouble, expected, ulps: ulps, message, file: file, line: line)
+    expectEqualWithAccuracy(actualFloat, Float(expected), ulps: ulps, message, file: file, line: line)
 
-
-func print6(_ op: String, _ d1: Double, _ d2: Double,
-  _ f1: Float, _ f2: Float, _ g1: CGFloat, _ g2: CGFloat)  -> String
-{
 #if arch(i386) || arch(arm)
-  if (f1 != Float(g1)  ||  f2 != Float(g2)) {
-    return "\(op)(CGFloat) got \(g1),\(g2) instead of \(f1),\(f2)"
-  }
+    expectEqualWithAccuracy(Float(actualCGFloat), Float(expected), ulps: ulps, message, file: file, line: line)
 #else
-  if (d1 != Double(g1)  ||  d2 != Double(g2)) {
-    return "\(op)(CGFloat) got \(g1),\(g2) instead of \(d1),\(d2)"
-  }
+    expectEqualWithAccuracy(Double(actualCGFloat), Double(expected), ulps: ulps, message, file: file, line: line)
 #endif
-  return "\(op) \(d1),\(d2) \(f1),\(f2) \(op)"
-}
-
-func print6(_ op: String, _ d1: Double, _ di: Int,
-  _ f1: Float, _ fi: Int, _ g1: CGFloat, _ gi: Int) -> String
-{
-#if arch(i386) || arch(arm)
-  if (f1 != Float(g1) || fi != gi) {
-    return "\(op)(CGFloat) got \(g1),\(gi) instead of \(f1),\(fi)"
-  }
-#else
-  if (d1 != Double(g1)  ||  di != gi) {
-    return "\(op)(CGFloat) got \(g1),\(gi) instead of \(d1),\(di)"
-  }
-#endif
-  return "\(op) \(d1),\(di) \(f1),\(fi) \(op)"
 }
 
 // inputs
@@ -103,200 +60,146 @@
 
 let ix = Int(11)
 
-// outputs
-var d1: Double = 0, d2: Double = 0
-var f1: Float = 0, f2: Float = 0
-var g1: CGFloat = 0, g2: CGFloat = 0
-var i1 = 0, i2 = 0, i3 = 0
-var b1 = false, b2 = false, b3 = false
 
+/*  Note on error tolerances:
+ *
+ *  These tests are *not* intended to test the underlying math library; rather,
+ *  they are only testing that the Swift wrappers call the right functions.
+ *  Because of this, there's nothing wrong with relaxing these tolerances
+ *  from 1 ulp to 3 or more, as needed to support platforms with less accurate
+ *  implementations.
+ *
+ *  The 0-ulp tolerances should be preserved, however, and XFAILED or #if'd
+ *  out for platforms that do not satisfy them.                               */
 MathTests.test("Unary functions") {
-  (d1, f1, g1) = (acos(dx), acos(fx), acos(gx))
-  expectEqual("acos 1.47062890563334 1.47063 acos", print3("acos", d1, f1, g1))
+  expectEqualWithAccuracy(acos(dx), acos(fx), acos(gx), 1.4706289056333368, ulps: 1)
 
-  (d1, f1, g1) = (asin(dx), asin(fx), asin(gx))
-  expectEqual("asin 0.10016742116156 0.100167 asin", print3("asin", d1, f1, g1))
+  expectEqualWithAccuracy(asin(dx), asin(fx), asin(gx), 0.1001674211615598, ulps: 1)
 
-  (d1, f1, g1) = (atan(dx), atan(fx), atan(gx))
-  expectEqual("atan 0.099668652491162 0.0996687 atan",
-    print3("atan", d1, f1, g1))
+  expectEqualWithAccuracy(atan(dx), atan(fx), atan(gx), 0.09966865249116204, ulps: 1)
 
-  (d1, f1, g1) = (cos(dx), cos(fx), cos(gx))
-  expectEqual("cos 0.995004165278026 0.995004 cos", print3("cos", d1, f1, g1))
+  expectEqualWithAccuracy(cos(dx), cos(fx), cos(gx), 0.9950041652780257, ulps: 1)
 
-  (d1, f1, g1) = (sin(dx), sin(fx), sin(gx))
-  expectEqual("sin 0.0998334166468282 0.0998334 sin", print3("sin", d1, f1, g1))
+  expectEqualWithAccuracy(sin(dx), sin(fx), sin(gx), 0.09983341664682815, ulps: 1)
 
-  (d1, f1, g1) = (tan(dx), tan(fx), tan(gx))
-  expectEqual("tan 0.100334672085451 0.100335 tan", print3("tan", d1, f1, g1))
+  expectEqualWithAccuracy(tan(dx), tan(fx), tan(gx), 0.10033467208545055, ulps: 1)
 
-  (d1, f1, g1) = (acosh(dx), acosh(fx), acosh(gx))
-  expectEqual("acosh nan nan acosh", print3("acosh", d1, f1, g1))
+  expectEqualWithAccuracy(acosh(dx), acosh(fx), acosh(gx), Double.nan, ulps: 1)
 
-  (d1, f1, g1) = (asinh(dx), asinh(fx), asinh(gx))
-  expectEqual("asinh 0.0998340788992076 0.0998341 asinh",
-    print3("asinh", d1, f1, g1))
+  expectEqualWithAccuracy(asinh(dx), asinh(fx), asinh(gx), 0.09983407889920758, ulps: 1)
 
-  (d1, f1, g1) = (atanh(dx), atanh(fx), atanh(gx))
-  expectEqual("atanh 0.100335347731076 0.100335 atanh",
-    print3("atanh", d1, f1, g1))
+  expectEqualWithAccuracy(atanh(dx), atanh(fx), atanh(gx), 0.10033534773107558, ulps: 1)
 
-  (d1, f1, g1) = (cosh(dx), cosh(fx), cosh(gx))
-  expectEqual("cosh 1.0050041680558 1.005 cosh", print3("cosh", d1, f1, g1))
+  expectEqualWithAccuracy(cosh(dx), cosh(fx), cosh(gx), 1.0050041680558035, ulps: 1)
 
-  (d1, f1, g1) = (sinh(dx), sinh(fx), sinh(gx))
-  expectEqual("sinh 0.100166750019844 0.100167 sinh", print3("sinh", d1, f1, g1))
+  expectEqualWithAccuracy(sinh(dx), sinh(fx), sinh(gx), 0.10016675001984403, ulps: 1)
 
-  (d1, f1, g1) = (tanh(dx), tanh(fx), tanh(gx))
-  expectEqual("tanh 0.0996679946249558 0.099668 tanh",
-    print3("tanh", d1, f1, g1))
+  expectEqualWithAccuracy(tanh(dx), tanh(fx), tanh(gx), 0.09966799462495582, ulps: 1)
 
-  (d1, f1, g1) = (exp(dx), exp(fx), exp(gx))
-  expectEqual("exp 1.10517091807565 1.10517 exp", print3("exp", d1, f1, g1))
+  expectEqualWithAccuracy(exp(dx), exp(fx), exp(gx), 1.1051709180756477, ulps: 1)
 
-  (d1, f1, g1) = (exp2(dx), exp2(fx), exp2(gx))
-  expectEqual("exp2 1.07177346253629 1.07177 exp2", print3("exp2", d1, f1, g1))
+  expectEqualWithAccuracy(exp2(dx), exp2(fx), exp2(gx), 1.0717734625362931, ulps: 1)
 
-  (d1, f1, g1) = (expm1(dx), expm1(fx), expm1(gx))
-  expectEqual("expm1 0.105170918075648 0.105171 expm1",
-    print3("expm1", d1, f1, g1))
+  expectEqualWithAccuracy(expm1(dx), expm1(fx), expm1(gx), 0.10517091807564763, ulps: 1)
 
-  (d1, f1, g1) = (log(dx), log(fx), log(gx))
-  expectEqual("log -2.30258509299405 -2.30259 log", print3("log", d1, f1, g1))
+  expectEqualWithAccuracy(log(dx), log(fx), log(gx), -2.3025850929940455, ulps: 1)
 
-  (d1, f1, g1) = (log10(dx), log10(fx), log10(gx))
-  expectEqual("log10 -1.0 -1.0 log10", print3("log10", d1, f1, g1))
+  expectEqualWithAccuracy(log10(dx), log10(fx), log10(gx), -1.0, ulps: 1)
 
-  (d1, f1, g1) = (log2(dx), log2(fx), log2(gx))
-  expectEqual("log2 -3.32192809488736 -3.32193 log2", print3("log2", d1, f1, g1))
+  expectEqualWithAccuracy(log2(dx), log2(fx), log2(gx), -3.321928094887362, ulps: 1)
 
-  (d1, f1, g1) = (log1p(dx), log1p(fx), log1p(gx))
-  expectEqual("log1p 0.0953101798043249 0.0953102 log1p",
-    print3("log1p", d1, f1, g1))
+  expectEqualWithAccuracy(log1p(dx), log1p(fx), log1p(gx), 0.09531017980432487, ulps: 1)
 
-  (d1, f1, g1) = (logb(dx), logb(fx), logb(gx))
-  expectEqual("logb -4.0 -4.0 logb", print3("logb", d1, f1, g1))
+  expectEqualWithAccuracy(logb(dx), logb(fx), logb(gx), -4.0, ulps: 1)
 
-  (d1, f1, g1) = (fabs(dx), fabs(fx), fabs(gx))
-  expectEqual("fabs 0.1 0.1 fabs", print3("fabs", d1, f1, g1))
+  expectEqualWithAccuracy(fabs(dx), fabs(fx), fabs(gx), 0.1, ulps: 1)
 
-  (d1, f1, g1) = (cbrt(dx), cbrt(fx), cbrt(gx))
-  expectEqual("cbrt 0.464158883361278 0.464159 cbrt", print3("cbrt", d1, f1, g1))
+  expectEqualWithAccuracy(cbrt(dx), cbrt(fx), cbrt(gx), 0.4641588833612779, ulps: 1)
 
-  (d1, f1, g1) = (sqrt(dx), sqrt(fx), sqrt(gx))
-  expectEqual("sqrt 0.316227766016838 0.316228 sqrt", print3("sqrt", d1, f1, g1))
+  expectEqualWithAccuracy(sqrt(dx), sqrt(fx), sqrt(gx), 0.31622776601683794, ulps: 1)
 
-  (d1, f1, g1) = (erf(dx), erf(fx), erf(gx))
-  expectEqual("erf 0.112462916018285 0.112463 erf", print3("erf", d1, f1, g1))
+  expectEqualWithAccuracy(erf(dx), erf(fx), erf(gx), 0.1124629160182849, ulps: 1)
 
-  (d1, f1, g1) = (erfc(dx), erfc(fx), erfc(gx))
-  expectEqual("erfc 0.887537083981715 0.887537 erfc", print3("erfc", d1, f1, g1))
+  expectEqualWithAccuracy(erfc(dx), erfc(fx), erfc(gx), 0.8875370839817152, ulps: 1)
 
-  (d1, f1, g1) = (tgamma(dx), tgamma(fx), tgamma(gx))
-  expectEqual("tgamma 9.51350769866873 9.51351 tgamma",
-    print3("tgamma", d1, f1, g1))
+  expectEqualWithAccuracy(tgamma(dx), tgamma(fx), tgamma(gx), 9.51350769866873, ulps: 1)
 
-  (d1, f1, g1) = (ceil(dx), ceil(fx), ceil(gx))
-  expectEqual("ceil 1.0 1.0 ceil", print3("ceil", d1, f1, g1))
+  expectEqualWithAccuracy(ceil(dx), ceil(fx), ceil(gx), 1.0, ulps: 0)
 
-  (d1, f1, g1) = (floor(dx), floor(fx), floor(gx))
-  expectEqual("floor 0.0 0.0 floor", print3("floor", d1, f1, g1))
+  expectEqualWithAccuracy(floor(dx), floor(fx), floor(gx), 0.0, ulps: 0)
 
-  (d1, f1, g1) = (nearbyint(dx), nearbyint(fx), nearbyint(gx))
-  expectEqual("nearbyint 0.0 0.0 nearbyint", print3("nearbyint", d1, f1, g1))
+  expectEqualWithAccuracy(nearbyint(dx), nearbyint(fx), nearbyint(gx), 0.0, ulps: 0)
 
-  (d1, f1, g1) = (rint(dx), rint(fx), rint(gx))
-  expectEqual("rint 0.0 0.0 rint", print3("rint", d1, f1, g1))
+  expectEqualWithAccuracy(rint(dx), rint(fx), rint(gx), 0.0, ulps: 0)
 
-  (d1, f1, g1) = (round(dx), round(fx), round(gx))
-  expectEqual("round 0.0 0.0 round", print3("round", d1, f1, g1))
+  expectEqualWithAccuracy(round(dx), round(fx), round(gx), 0.0, ulps: 0)
 
-  (d1, f1, g1) = (trunc(dx), trunc(fx), trunc(gx))
-  expectEqual("trunc 0.0 0.0 trunc", print3("trunc", d1, f1, g1))
+  expectEqualWithAccuracy(trunc(dx), trunc(fx), trunc(gx), 0.0, ulps: 0)
 }
 
 MathTests.test("Binary functions") {
+    expectEqualWithAccuracy(atan2(dx, dy), atan2(fx, fy), atan2(gx, gy), 0.04542327942157701, ulps: 1)
+    expectEqualWithAccuracy(hypot(dx, dy), hypot(fx, fy), hypot(gx, gy), 2.202271554554524, ulps: 1)
+    expectEqualWithAccuracy(pow(dx, dy), pow(fx, fy), pow(gx, gy), 0.00630957344480193, ulps: 1)
+    expectEqualWithAccuracy(fmod(dx, dy), fmod(fx, fy), fmod(gx, gy), 0.1, ulps: 0)
+    expectEqualWithAccuracy(remainder(dx, dy), remainder(fx, fy), remainder(gx, gy), 0.1, ulps: 0)
+    expectEqualWithAccuracy(copysign(dx, dy), copysign(fx, fy), copysign(gx, gy), 0.1, ulps: 0)
 
-  (d1, f1, g1) = (atan2(dx, dy), atan2(fx, fy), atan2(gx, gy))
-  expectEqual("atan2 0.045423279421577 0.0454233 atan2",
-    print3("atan2", d1, f1, g1))
+    expectEqual(nextafter(dx, dy), dx.nextUp)
+    expectEqual(nextafter(fx, fy), fx.nextUp)
+    expectEqual(nextafter(gx, gy), gx.nextUp)
+    expectEqual(nextafter(dx, dx - 1.0), dx.nextDown)
+    expectEqual(nextafter(fx, fx - 1.0), fx.nextDown)
+    expectEqual(nextafter(gx, gx - 1.0), gx.nextDown)
 
-  (d1, f1, g1) = (hypot(dx, dy), hypot(fx, fy), hypot(gx, gy))
-  expectEqual("hypot 2.20227155455452 2.20227 hypot",
-    print3("hypot", d1, f1, g1))
-
-  (d1, f1, g1) = (pow(dx, dy), pow(fx, fy), pow(gx, gy))
-  expectEqual("pow 0.00630957344480193 0.00630957 pow",
-    print3("pow", d1, f1, g1))
-
-  (d1, f1, g1) = (fmod(dx, dy), fmod(fx, fy), fmod(gx, gy))
-  expectEqual("fmod 0.1 0.1 fmod", print3("fmod", d1, f1, g1))
-
-  (d1, f1, g1) = (remainder(dx, dy), remainder(fx, fy), remainder(gx, gy))
-  expectEqual("remainder 0.1 0.1 remainder", print3("remainder", d1, f1, g1))
-
-  (d1, f1, g1) = (copysign(dx, dy), copysign(fx, fy), copysign(gx, gy))
-  expectEqual("copysign 0.1 0.1 copysign", print3("copysign", d1, f1, g1))
-
-  (d1, f1, g1) = (nextafter(dx, dy), nextafter(fx, fy), nextafter(gx, gy))
-  expectEqual("nextafter 0.1 0.1 nextafter", print3("nextafter", d1, f1, g1))
-
-  (d1, f1, g1) = (fdim(dx, dy), fdim(fx, fy), fdim(gx, gy))
-  expectEqual("fdim 0.0 0.0 fdim", print3("fdim", d1, f1, g1))
-
-  (d1, f1, g1) = (fmax(dx, dy), fmax(fx, fy), fmax(gx, gy))
-  expectEqual("fmax 2.2 2.2 fmax", print3("fmax", d1, f1, g1))
-
-  (d1, f1, g1) = (fmin(dx, dy), fmin(fx, fy), fmin(gx, gy))
-  expectEqual("fmin 0.1 0.1 fmin", print3("fmin", d1, f1, g1))
+    expectEqualWithAccuracy(fdim(dx, dy), fdim(fx, fy), fdim(gx, gy), 0.0, ulps: 0)
+    expectEqualWithAccuracy(fmax(dx, dy), fmax(fx, fy), fmax(gx, gy), 2.2, ulps: 0)
+    expectEqualWithAccuracy(fmin(dx, dy), fmin(fx, fy), fmin(gx, gy), 0.1, ulps: 0)
 }
 
 MathTests.test("Other functions") {
 
-  (d1, d2) = modf(dy)
-  (f1, f2) = modf(fy)
-  (g1, g2) = modf(gy)
-  expectEqual("modf 2.0,0.2 2.0,0.2 modf", print6("modf", d1,d2, f1,f2, g1,g2))
+  expectEqual(modf(dy), (2.0, 0.20000000000000018))
+  expectEqual(modf(fy), (2.0, 0.20000005))
+#if arch(i386) || arch(arm)
+  expectEqual(modf(gy), (2.0, 0.20000005))
+#else
+  expectEqual(modf(gy), (2.0, 0.20000000000000018))
+#endif
 
-  (d1, f1, g1) = (ldexp(dx, ix), ldexp(fx, ix), ldexp(gx, ix))
-  expectEqual("ldexp 204.8 204.8 ldexp", print3("ldexp", d1, f1, g1))
+  expectEqualWithAccuracy(ldexp(dx, ix), ldexp(fx, ix), ldexp(gx, ix), 204.8, ulps: 0)
 
-  (d1, i1) = frexp(dy)
-  (f1, i2) = frexp(fy)
-  (g1, i3) = frexp(gy)
-  expectEqual("frexp 0.55,2 0.55,2 frexp", print6("frexp", d1,i1, f1,i2, g1,i3))
+  expectEqual(frexp(dy), (0.55, 2))
+  expectEqual(frexp(fy), (0.55, 2))
+  expectEqual(frexp(gy), (0.55, 2))
 
-  (i1, i2, i3) = (ilogb(dy), ilogb(fy), ilogb(gy))
-  expectEqual("ilogb 1 1 ilogb", print3("ilogb", i1, i2, i3))
+  expectEqual(ilogb(dy), 1)
+  expectEqual(ilogb(fy), 1)
+  expectEqual(ilogb(gy), 1)
 
-  (d1, f1, g1) = (scalbn(dx, ix), scalbn(fx, ix), scalbn(gx, ix))
-  expectEqual("scalbn 204.8 204.8 scalbn", print3("scalbn", d1, f1, g1))
+  expectEqualWithAccuracy(scalbn(dx, ix), scalbn(fx, ix), scalbn(gx, ix), 204.8, ulps: 0)
 
-  (d1, i1) = lgamma(dx)
-  (f1, i2) = lgamma(fx)
-  (g1, i3) = lgamma(gx)
-  expectEqual("lgamma 2.25271265173421,1 2.25271,1 lgamma", print6("lgamma",
- d1,i1, f1,i2, g1,i3))
+  expectEqual(lgamma(dx).1, 1)
+  expectEqual(lgamma(fx).1, 1)
+  expectEqual(lgamma(gx).1, 1)
+  expectEqualWithAccuracy(lgamma(dx).0, lgamma(fx).0, lgamma(gx).0, 2.2527126517342055, ulps: 1)
 
-  (d1, i1) = remquo(dz, dy)
-  (f1, i2) = remquo(fz, fy)
-  (g1, i3) = remquo(gz, gy)
-  expectEqual("remquo 1.1,1 1.1,1 remquo", print6("remquo", d1,i1, f1,i2, g1,i3))
+  // ISO C only requires the last 3 bits to be correct
+  expectEqual(remquo(dz, dy).1 & 7, 1)
+  expectEqual(remquo(fz, fy).1 & 7, 1)
+  expectEqual(remquo(gz, gy).1 & 7, 1)
+  expectEqualWithAccuracy(remquo(dz, dy).0, remquo(fz, fy).0, remquo(gz, gy).0, 1.0999999999999996, ulps: 1)
 
-  (d1, f1, g1) = (nan("12345"), nan("12345"), nan("12345"))
-  expectEqual("nan nan nan nan", print3("nan", d1, f1, g1))
+  expectEqualWithAccuracy(nan("12345"), nan("12345"), nan("12345"), Double.nan, ulps: 0)
 
-  (d1, f1, g1) = (fma(dx, dy, dz), fma(fx, fy, fz), fma(gx, gy, gz))
-  expectEqual("fma 3.52 3.52 fma", print3("fma", d1, f1, g1))
+  expectEqualWithAccuracy(fma(dx, dy, dz), fma(fx, fy, fz), fma(gx, gy, gz), 3.52, ulps: 0)
 
-  expectEqual("j0 0.99750156206604 j0", "j0 \(j0(dx)) j0")
-  expectEqual("j1 0.049937526036242 j1", "j1 \(j1(dx)) j1")
-  expectEqual("jn 1.22299266103565e-22 jn", "jn \(jn(ix, dx)) jn")
-  expectEqual("y0 -1.53423865135037 y0", "y0 \(y0(dx)) y0")
-  expectEqual("y1 -6.45895109470203 y1", "y1 \(y1(dx)) y1")
-
-  d1 = yn(ix, dx)
-  expectEqual("yn -2.36620129448696e+20 yn", "yn \(d1) yn")
+  expectEqualWithAccuracy(j0(dx), 0.99750156206604, ulps: 1)
+  expectEqualWithAccuracy(j1(dx), 0.049937526036242, ulps: 1)
+  expectEqualWithAccuracy(jn(ix, dx), 1.2229926610356451e-22, ulps: 1)
+  expectEqualWithAccuracy(y0(dx), -1.5342386513503667, ulps: 1)
+  expectEqualWithAccuracy(y1(dx), -6.458951094702027, ulps: 1)
+  expectEqualWithAccuracy(yn(ix, dx), -2.3662012944869576e+20, ulps: 1)
 }
 
 runAllTests()
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
index 395e13d..1c9fd01 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
@@ -1097,7 +1097,7 @@
     DeclName Name = Importer->importName(Named, ObjCName);
     NameTranslatingInfo Result;
     Result.NameKind = SwiftLangSupport::getUIDForNameKind(NameKind::Swift);
-    Result.BaseName = Name.getBaseIdentifier().str();
+    Result.BaseName = Name.getBaseName().userFacingName();
     std::transform(Name.getArgumentNames().begin(),
                    Name.getArgumentNames().end(),
                    std::back_inserter(Result.ArgNames),
diff --git a/tools/SwiftSyntax/Syntax.swift b/tools/SwiftSyntax/Syntax.swift
index 9b936a8..7908213 100644
--- a/tools/SwiftSyntax/Syntax.swift
+++ b/tools/SwiftSyntax/Syntax.swift
@@ -120,7 +120,7 @@
     return data.indexInParent
   }
 
-  /// The absolute position of the starting point this node. If the first token
+  /// The absolute position of the starting point of this node. If the first token
   /// is with leading trivia, the position points to the start of the leading
   /// trivia.
   public var position: AbsolutePosition {
diff --git a/tools/SwiftSyntax/SyntaxBuilders.swift.gyb b/tools/SwiftSyntax/SyntaxBuilders.swift.gyb
index 207c8da..b5da75a 100644
--- a/tools/SwiftSyntax/SyntaxBuilders.swift.gyb
+++ b/tools/SwiftSyntax/SyntaxBuilders.swift.gyb
@@ -31,11 +31,9 @@
 %   if node.is_buildable():
 %     Builder = node.name + "Builder"
 public struct ${Builder} {
-  private var layout = [
-%     for child in node.children:
-    ${make_missing_swift_child(child)},
-%     end
-  ]
+  private var layout =
+    Array<RawSyntax?>(repeating: nil, count: ${len(node.children)})
+
   internal init() {}
 %     for child in node.children:
 %       child_node = NODE_MAP.get(child.syntax_kind)
@@ -45,7 +43,12 @@
 
   public mutating func add${child_elt}(_ elt: ${child_elt_type}) {
     let idx = ${node.name}.Cursor.${child.swift_name}.rawValue
-    layout[idx] = layout[idx].appending(elt.raw)
+    if let list = layout[idx] {
+      layout[idx] = list.appending(elt.raw)
+    } else {
+      layout[idx] = RawSyntax.node(
+        .${child.swift_syntax_kind}, [elt.raw], .present)
+    }
   }
 %       else:
 
@@ -56,7 +59,15 @@
 %       end
 %     end
 
-  internal func buildData() -> SyntaxData {
+  internal mutating func buildData() -> SyntaxData {
+%     for (idx, child) in enumerate(node.children):
+%       if not child.is_optional:
+    if (layout[${idx}] == nil) {
+      layout[${idx}] = ${make_missing_swift_child(child)}
+    }
+%       end
+%     end
+
     return SyntaxData(raw: .node(.${node.swift_syntax_kind},
                                  layout, .present))
   }
diff --git a/tools/SwiftSyntax/TokenKind.swift.gyb b/tools/SwiftSyntax/TokenKind.swift.gyb
index a71a8af..3f4fd33 100644
--- a/tools/SwiftSyntax/TokenKind.swift.gyb
+++ b/tools/SwiftSyntax/TokenKind.swift.gyb
@@ -19,7 +19,6 @@
 
 /// Enumerates the kinds of tokens in the Swift language.
 public enum TokenKind: Codable {
-  case unknown
   case eof
 % for token in SYNTAX_TOKENS:
 %   kind = token.swift_kind()
@@ -35,7 +34,6 @@
   /// The textual representation of this token kind.
   var text: String {
     switch self {
-    case .unknown: return "unknown"
     case .eof: return ""
 % for token in SYNTAX_TOKENS:
 %   if token.text:
@@ -60,7 +58,6 @@
     let container = try decoder.container(keyedBy: CodingKeys.self)
     let kind = try container.decode(String.self, forKey: .kind)
     switch kind {
-    case "unknown": self = .unknown
     case "eof": self = .eof
 % for token in SYNTAX_TOKENS:
     case "${token.kind}":
@@ -83,7 +80,6 @@
   
   var kind: String {
     switch self {
-    case .unknown: return "unknown"
     case .eof: return "eof"
 % for token in SYNTAX_TOKENS:
 %   kind = token.swift_kind()
@@ -99,7 +95,6 @@
 extension TokenKind: Equatable {
   public static func ==(lhs: TokenKind, rhs: TokenKind) -> Bool {
     switch (lhs, rhs) {
-    case (.unknown, .unknown): return true
     case (.eof, .eof): return true
 % for token in SYNTAX_TOKENS:
 %   kind = token.swift_kind()
diff --git a/tools/SwiftSyntax/Trivia.swift.gyb b/tools/SwiftSyntax/Trivia.swift.gyb
index 54406ea..d4a95c2 100644
--- a/tools/SwiftSyntax/Trivia.swift.gyb
+++ b/tools/SwiftSyntax/Trivia.swift.gyb
@@ -242,6 +242,15 @@
   public subscript(_ index: Int) -> TriviaPiece {
     return pieces[index]
   }
+
+  /// Get the byteSize of this trivia
+  public var byteSize: Int {
+    let pos = AbsolutePosition()
+    for piece in pieces {
+      piece.accumulateAbsolutePosition(pos)
+    }
+    return pos.byteOffset
+  }
 }
 
 
diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp
index c88912d..3e3579a 100644
--- a/tools/swift-reflection-dump/swift-reflection-dump.cpp
+++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp
@@ -122,17 +122,17 @@
 
 static ReflectionInfo findReflectionInfo(const ObjectFile *objectFile) {
   auto fieldSection = findReflectionSection<FieldSection>(
-      objectFile, {"__swift5_fieldmd", ".swift5_fieldmd", "swift5_fieldmd"});
+      objectFile, {"__swift4_fieldmd", ".swift4_fieldmd", "swift4_fieldmd"});
   auto associatedTypeSection = findReflectionSection<AssociatedTypeSection>(
-      objectFile, {"__swift5_assocty", ".swift5_assocty", "swift5_assocty"});
+      objectFile, {"__swift4_assocty", ".swift4_assocty", "swift4_assocty"});
   auto builtinTypeSection = findReflectionSection<BuiltinTypeSection>(
-      objectFile, {"__swift5_builtin", ".swift5_builtin", "swift5_builtin"});
+      objectFile, {"__swift4_builtin", ".swift4_builtin", "swift4_builtin"});
   auto captureSection = findReflectionSection<CaptureSection>(
-      objectFile, {"__swift5_capture", ".swift5_capture", "swift5_capture"});
+      objectFile, {"__swift4_capture", ".swift4_capture", "swift4_capture"});
   auto typeRefSection = findReflectionSection<GenericSection>(
-      objectFile, {"__swift5_typeref", ".swift5_typeref", "swift5_typeref"});
+      objectFile, {"__swift4_typeref", ".swift4_typeref", "swift4_typeref"});
   auto reflectionStringsSection = findReflectionSection<GenericSection>(
-      objectFile, {"__swift5_reflstr", ".swift5_reflstr", "swift5_reflstr"});
+      objectFile, {"__swift4_reflstr", ".swift4_reflstr", "swift4_reflstr"});
 
   // The entire object file is mapped into this process's memory, so the
   // local/remote mapping is identity.
diff --git a/utils/build-script-impl b/utils/build-script-impl
index b7e70e3..527cbc2 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -2790,7 +2790,7 @@
                 fi
 
                 # Handle test subdirectory clause
-                if [[ "${LLDB_TEST_SWIFT_ONLY}" ]]; then
+                if [[ "$(true_false ${LLDB_TEST_SWIFT_ONLY})" == "TRUE" ]]; then
                     LLDB_TEST_SUBDIR_CLAUSE="--test-subdir lang/swift"
                     LLDB_TEST_CATEGORIES="--skip-category=dwo --skip-category=dsym --skip-category=gmodules -G swiftpr"
                 else
@@ -2812,7 +2812,7 @@
 
                 # If we need to use the system debugserver, do so explicitly.
                 if [[ "$(uname -s)" == "Darwin" && "${LLDB_USE_SYSTEM_DEBUGSERVER}" ]] ; then
-                    LLDB_TEST_DEBUG_SERVER="--server $(xcode-select -p)/../SharedFrameworks/LLDB.framework/Resources/debugserver"
+                    LLDB_TEST_DEBUG_SERVER="--server $(xcode-select -p)/../SharedFrameworks/LLDB.framework/Resources/debugserver --out-of-tree-debugserver"
                 else
                     LLDB_TEST_DEBUG_SERVER=""
                 fi
diff --git a/utils/cmpcodesize/cmpcodesize/compare.py b/utils/cmpcodesize/cmpcodesize/compare.py
index 51ea7d7..598b353 100644
--- a/utils/cmpcodesize/cmpcodesize/compare.py
+++ b/utils/cmpcodesize/cmpcodesize/compare.py
@@ -232,7 +232,7 @@
         compare_sizes(old_sizes, new_sizes, "__objc_const", section_title,
                       csv=csv)
         compare_sizes(old_sizes, new_sizes, "__data", section_title, csv=csv)
-        compare_sizes(old_sizes, new_sizes, "__swift5_proto", section_title,
+        compare_sizes(old_sizes, new_sizes, "__swift4_proto", section_title,
                       csv=csv)
         compare_sizes(old_sizes, new_sizes, "__common", section_title, csv=csv)
         compare_sizes(old_sizes, new_sizes, "__bss", section_title, csv=csv)
diff --git a/utils/gyb_syntax_support/Token.py b/utils/gyb_syntax_support/Token.py
index 75b3dfc..8f1fdd8 100644
--- a/utils/gyb_syntax_support/Token.py
+++ b/utils/gyb_syntax_support/Token.py
@@ -157,6 +157,7 @@
     Token('FloatingLiteral', 'floating_literal'),
     Token('StringLiteral', 'string_literal'),
     Token('ContextualKeyword', 'contextual_keyword'),
+    Token('Unknown', 'unknown'),
 ]
 
 SYNTAX_TOKEN_MAP = {token.name + 'Token': token for token in SYNTAX_TOKENS}
diff --git a/utils/gyb_syntax_support/__init__.py b/utils/gyb_syntax_support/__init__.py
index ba62605..fcf1bb0 100644
--- a/utils/gyb_syntax_support/__init__.py
+++ b/utils/gyb_syntax_support/__init__.py
@@ -23,9 +23,9 @@
     """
     if child.is_token():
         token = child.main_token()
-        tok_kind = "tok::" + token.kind if token else "tok::unknown"
+        tok_kind = token.kind if token else "unknown"
         tok_text = token.text if token else ""
-        return 'RawSyntax::missing(%s, "%s")' % (tok_kind, tok_text)
+        return 'RawSyntax::missing(tok::%s, "%s")' % (tok_kind, tok_text)
     else:
         missing_kind = "Unknown" if child.syntax_kind == "Syntax" \
                        else child.syntax_kind
@@ -73,7 +73,7 @@
     if child.is_token():
         token = child.main_token()
         tok_kind = token.swift_kind() if token else "unknown"
-        if token and not token.text:
+        if not token or not token.text:
             tok_kind += '("")'
         return 'RawSyntax.missingToken(.%s)' % tok_kind
     else: