Merge pull request #35111 from nate-chandler/concurrency/irgen/for-now-async-is-not-simple

[Async CC] Never use simple partial apply for async functions.
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 7d72e56..9c084ad 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -493,6 +493,7 @@
   type ::= 'Bb'                              // Builtin.BridgeObject
   type ::= 'BB'                              // Builtin.UnsafeValueBuffer
   type ::= 'Bc'                              // Builtin.RawUnsafeContinuation
+  type ::= 'BD'                              // Builtin.DefaultActorStorage
   type ::= 'Bf' NATURAL '_'                  // Builtin.Float<n>
   type ::= 'Bi' NATURAL '_'                  // Builtin.Int<n>
   type ::= 'BI'                              // Builtin.IntLiteral
diff --git a/include/swift/AST/TypeNodes.def b/include/swift/AST/TypeNodes.def
index aea2a4a..0a3ff64 100644
--- a/include/swift/AST/TypeNodes.def
+++ b/include/swift/AST/TypeNodes.def
@@ -110,6 +110,7 @@
   BUILTIN_TYPE(BuiltinNativeObject, BuiltinType)
   BUILTIN_TYPE(BuiltinBridgeObject, BuiltinType)
   BUILTIN_TYPE(BuiltinUnsafeValueBuffer, BuiltinType)
+  BUILTIN_TYPE(BuiltinDefaultActorStorage, BuiltinType)
   BUILTIN_TYPE(BuiltinVector, BuiltinType)
   TYPE_RANGE(Builtin, BuiltinInteger, BuiltinVector)
 TYPE(Tuple, Type)
@@ -185,6 +186,7 @@
 SINGLETON_TYPE(NativeObject, BuiltinNativeObject)
 SINGLETON_TYPE(BridgeObject, BuiltinBridgeObject)
 SINGLETON_TYPE(UnsafeValueBuffer, BuiltinUnsafeValueBuffer)
+SINGLETON_TYPE(DefaultActorStorage, BuiltinDefaultActorStorage)
 SINGLETON_TYPE(SILToken, SILToken)
 #undef SINGLETON_TYPE
 #endif
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index a89e318..a44404d 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -1420,6 +1420,22 @@
 };
 DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinJobType, BuiltinType);
 
+/// BuiltinDefaultActorStorageType - The type of the stored property
+/// that's added implicitly to default actors.  No C equivalent because
+/// the C types all include a heap-object header.  Similarly, this type
+/// generally does not appear in the AST/SIL around default actors;
+/// it's purely a convenience in IRGen.
+class BuiltinDefaultActorStorageType : public BuiltinType {
+  friend class ASTContext;
+  BuiltinDefaultActorStorageType(const ASTContext &C)
+    : BuiltinType(TypeKind::BuiltinDefaultActorStorage, C) {}
+public:
+  static bool classof(const TypeBase *T) {
+    return T->getKind() == TypeKind::BuiltinDefaultActorStorage;
+  }
+};
+DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinDefaultActorStorageType, BuiltinType);
+
 /// BuiltinNativeObjectType - The builtin opaque object-pointer type.
 /// Useful for keeping an object alive when it is otherwise being
 /// manipulated via an unsafe pointer type.
diff --git a/include/swift/Basic/Fingerprint.h b/include/swift/Basic/Fingerprint.h
index 3caaa28..da18ef4 100644
--- a/include/swift/Basic/Fingerprint.h
+++ b/include/swift/Basic/Fingerprint.h
@@ -60,53 +60,51 @@
 class Fingerprint final {
 public:
   /// The size (in bytes) of the raw value of all fingerprints.
-  ///
-  /// This constant's value is justified by a static assertion in the
-  /// corresponding cpp file.
   constexpr static size_t DIGEST_LENGTH = 32;
 
+  using Core = std::pair<uint64_t, uint64_t>;
 private:
-  std::string Core;
+  Core core;
 
 public:
+  /// Creates a fingerprint value from a pair of 64-bit integers.
+  explicit Fingerprint(Fingerprint::Core value) : core(value) {}
+
   /// Creates a fingerprint value from the given input string that is known to
   /// be a 32-byte hash value.
   ///
   /// In +asserts builds, strings that violate this invariant will crash. If a
   /// fingerprint value is needed to represent an "invalid" state, use a
   /// vocabulary type like \c Optional<Fingerprint> instead.
-  explicit Fingerprint(std::string value) : Core(std::move(value)) {
-    assert(Core.size() == Fingerprint::DIGEST_LENGTH &&
-           "Only supports 32-byte hash values!");
-  }
+  static Fingerprint fromString(llvm::StringRef value);
 
   /// Creates a fingerprint value from the given input string literal.
   template <std::size_t N>
   explicit Fingerprint(const char (&literal)[N])
-    : Core{literal, N-1} {
+    : Fingerprint{Fingerprint::fromString({literal, N-1}).core} {
       static_assert(N == Fingerprint::DIGEST_LENGTH + 1,
                     "String literal must be 32 bytes in length!");
     }
 
   /// Creates a fingerprint value by consuming the given \c MD5Result from LLVM.
   explicit Fingerprint(llvm::MD5::MD5Result &&MD5Value)
-      : Core{MD5Value.digest().str()} {}
+      : core{MD5Value.words()} {}
 
 public:
   /// Retrieve the raw underlying bytes of this fingerprint.
-  llvm::StringRef getRawValue() const { return Core; }
+  llvm::SmallString<Fingerprint::DIGEST_LENGTH> getRawValue() const;
 
 public:
   friend bool operator==(const Fingerprint &lhs, const Fingerprint &rhs) {
-    return lhs.Core == rhs.Core;
+    return lhs.core == rhs.core;
   }
 
   friend bool operator!=(const Fingerprint &lhs, const Fingerprint &rhs) {
-    return lhs.Core != rhs.Core;
+    return lhs.core != rhs.core;
   }
 
   friend llvm::hash_code hash_value(const Fingerprint &fp) {
-    return llvm::hash_value(fp.Core);
+    return llvm::hash_value(fp.core);
   }
 
 public:
@@ -115,7 +113,7 @@
   /// This fingerprint is a perfectly fine value for an MD5 hash, but it is
   /// completely arbitrary.
   static Fingerprint ZERO() {
-    return Fingerprint("00000000000000000000000000000000");
+    return Fingerprint(Fingerprint::Core{0, 0});
   }
 
 private:
@@ -124,7 +122,7 @@
   ///
   /// Very well, LLVM. A default value you shall have.
   friend class llvm::yaml::IO;
-  Fingerprint() : Core(DIGEST_LENGTH, '0') {}
+  Fingerprint() : core{Fingerprint::Core{0, 0}} {}
 };
 
 void simple_display(llvm::raw_ostream &out, const Fingerprint &fp);
diff --git a/include/swift/Reflection/Records.h b/include/swift/Reflection/Records.h
index 80478cc..d24efae 100644
--- a/include/swift/Reflection/Records.h
+++ b/include/swift/Reflection/Records.h
@@ -37,6 +37,9 @@
     
     // Is this a mutable `var` property?
     IsVar = 0x2,
+
+    // Is this an artificial field?
+    IsArtificial = 0x4,
   };
   int_type Data = 0;
 
@@ -49,6 +52,10 @@
     return (Data & IsVar) == IsVar;
   }
 
+  bool isArtificial() const {
+    return (Data & IsArtificial) == IsArtificial;
+  }
+
   void setIsIndirectCase(bool IndirectCase=true) {
     if (IndirectCase)
       Data |= IsIndirectCase;
@@ -63,6 +70,13 @@
       Data &= ~IsVar;
   }
 
+  void setIsArtificial(bool artificial=true) {
+    if (artificial)
+      Data |= IsArtificial;
+    else
+      Data &= ~IsArtificial;
+  }
+
   int_type getRawValue() const {
     return Data;
   }
diff --git a/include/swift/Strings.h b/include/swift/Strings.h
index a869c42..b9c056d 100644
--- a/include/swift/Strings.h
+++ b/include/swift/Strings.h
@@ -47,6 +47,9 @@
 constexpr static const StringLiteral SEMANTICS_PROGRAMTERMINATION_POINT =
     "programtermination_point";
 
+constexpr static const StringLiteral DEFAULT_ACTOR_STORAGE_FIELD_NAME =
+    "$defaultActor";
+
 /// The name of the Builtin type prefix
 constexpr static const StringLiteral BUILTIN_TYPE_NAME_PREFIX = "Builtin.";
 
@@ -119,6 +122,9 @@
 /// The name of the Builtin type for Job
 constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_JOB = {
     "Builtin.Job"};
+/// The name of the Builtin type for DefaultActorStorage
+constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_DEFAULTACTORSTORAGE = {
+    "Builtin.DefaultActorStorage"};
 /// The name of the Builtin type for UnknownObject
 ///
 /// This no longer exists as an AST-accessible type, but it's still used for
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 2b529ac..52ba7f2 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -3561,6 +3561,7 @@
 
     TRIVIAL_TYPE_PRINTER(BuiltinIntegerLiteral, builtin_integer_literal)
     TRIVIAL_TYPE_PRINTER(BuiltinJob, builtin_job)
+    TRIVIAL_TYPE_PRINTER(BuiltinDefaultActorStorage, builtin_default_actor_storage)
     TRIVIAL_TYPE_PRINTER(BuiltinRawPointer, builtin_raw_pointer)
     TRIVIAL_TYPE_PRINTER(BuiltinRawUnsafeContinuation, builtin_raw_unsafe_continuation)
     TRIVIAL_TYPE_PRINTER(BuiltinNativeObject, builtin_native_object)
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 65f1e9a..df071a0 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -975,6 +975,8 @@
       return appendOperator("BI");
     case TypeKind::BuiltinJob:
       return appendOperator("Bj");
+    case TypeKind::BuiltinDefaultActorStorage:
+      return appendOperator("BD");
     case TypeKind::BuiltinRawPointer:
       return appendOperator("Bp");
     case TypeKind::BuiltinRawUnsafeContinuation:
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 5760581..091d708 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -3946,6 +3946,7 @@
   ASTPRINTER_PRINT_BUILTINTYPE(BuiltinRawPointerType)
   ASTPRINTER_PRINT_BUILTINTYPE(BuiltinRawUnsafeContinuationType)
   ASTPRINTER_PRINT_BUILTINTYPE(BuiltinJobType)
+  ASTPRINTER_PRINT_BUILTINTYPE(BuiltinDefaultActorStorageType)
   ASTPRINTER_PRINT_BUILTINTYPE(BuiltinNativeObjectType)
   ASTPRINTER_PRINT_BUILTINTYPE(BuiltinBridgeObjectType)
   ASTPRINTER_PRINT_BUILTINTYPE(BuiltinUnsafeValueBufferType)
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index af72df2..fa0ea2c 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -83,6 +83,8 @@
     return Context.TheRawUnsafeContinuationType;
   if (Name == "Job")
     return Context.TheJobType;
+  if (Name == "DefaultActorStorage")
+    return Context.TheDefaultActorStorageType;
   if (Name == "NativeObject")
     return Context.TheNativeObjectType;
   if (Name == "BridgeObject")
@@ -2733,6 +2735,9 @@
   case BuiltinTypeKind::BuiltinJob:
     printer << MAYBE_GET_NAMESPACED_BUILTIN(BUILTIN_TYPE_NAME_JOB);
     break;
+  case BuiltinTypeKind::BuiltinDefaultActorStorage:
+    printer << MAYBE_GET_NAMESPACED_BUILTIN(BUILTIN_TYPE_NAME_DEFAULTACTORSTORAGE);
+    break;
   case BuiltinTypeKind::BuiltinNativeObject:
     printer << MAYBE_GET_NAMESPACED_BUILTIN(BUILTIN_TYPE_NAME_NATIVEOBJECT);
     break;
diff --git a/lib/AST/FineGrainedDependencyFormat.cpp b/lib/AST/FineGrainedDependencyFormat.cpp
index 4294767..6842377 100644
--- a/lib/AST/FineGrainedDependencyFormat.cpp
+++ b/lib/AST/FineGrainedDependencyFormat.cpp
@@ -232,7 +232,7 @@
       if (node == nullptr)
         llvm::report_fatal_error("Unexpected FINGERPRINT_NODE record");
 
-      node->setFingerprint(Fingerprint{BlobData.str()});
+      node->setFingerprint(Fingerprint::fromString(BlobData));
       break;
     }
 
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 9535ab9..70fc6ac 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -210,6 +210,7 @@
   case TypeKind::BuiltinRawPointer:
   case TypeKind::BuiltinRawUnsafeContinuation:
   case TypeKind::BuiltinJob:
+  case TypeKind::BuiltinDefaultActorStorage:
   case TypeKind::BuiltinUnsafeValueBuffer:
   case TypeKind::BuiltinVector:
   case TypeKind::Tuple:
@@ -5007,6 +5008,7 @@
   case TypeKind::BuiltinRawPointer:
   case TypeKind::BuiltinRawUnsafeContinuation:
   case TypeKind::BuiltinJob:
+  case TypeKind::BuiltinDefaultActorStorage:
   case TypeKind::BuiltinUnsafeValueBuffer:
   case TypeKind::BuiltinVector:
   case TypeKind::Tuple:
diff --git a/lib/Basic/Fingerprint.cpp b/lib/Basic/Fingerprint.cpp
index 389ecd3..ec4ca98 100644
--- a/lib/Basic/Fingerprint.cpp
+++ b/lib/Basic/Fingerprint.cpp
@@ -12,8 +12,12 @@
 
 #include "swift/Basic/Fingerprint.h"
 #include "swift/Basic/STLExtras.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <inttypes.h>
+#include <sstream>
+
 using namespace swift;
 
 llvm::raw_ostream &llvm::operator<<(llvm::raw_ostream &OS,
@@ -25,19 +29,26 @@
   out << fp.getRawValue();
 }
 
-namespace {
-  template <class T> struct SmallStringBound;
-  template <size_t N> struct SmallStringBound<llvm::SmallString<N>> {
-    static constexpr size_t value = N;
-  };
-};
+Fingerprint Fingerprint::fromString(StringRef value) {
+  assert(value.size() == Fingerprint::DIGEST_LENGTH &&
+         "Only supports 32-byte hash values!");
+  auto fp = Fingerprint::ZERO();
+  {
+    std::istringstream s(value.drop_back(Fingerprint::DIGEST_LENGTH/2).str());
+    s >> std::hex >> fp.core.first;
+  }
+  {
+    std::istringstream s(value.drop_front(Fingerprint::DIGEST_LENGTH/2).str());
+    s >> std::hex >> fp.core.second;
+  }
+  return fp;
+}
 
-// Assert that the \c DIGEST_LENGTH value we export from the \c Fingerprint
-// has the right byte length. It's unlikely this value will change in LLVM,
-// but it's always good to have compile-time justification for a
-// magic constant - especially one that gets used for serialization.
-using MD5Digest_t =
-    decltype (&llvm::MD5::MD5Result::digest)(llvm::MD5::MD5Result);
-static_assert(SmallStringBound<std::result_of<MD5Digest_t>::type>::value ==
-                  Fingerprint::DIGEST_LENGTH,
-              "MD5 digest size does not match size expected by Fingerprint!");
+llvm::SmallString<Fingerprint::DIGEST_LENGTH> Fingerprint::getRawValue() const {
+  llvm::SmallString<Fingerprint::DIGEST_LENGTH> Str;
+  llvm::raw_svector_ostream Res(Str);
+  Res << llvm::format_hex_no_prefix(core.first, 16);
+  Res << llvm::format_hex_no_prefix(core.second, 16);
+  assert(*this == Fingerprint::fromString(Str));
+  return Str;
+}
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index 6e7b133..2811cf3 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -1184,6 +1184,10 @@
       Ty = createNode(Node::Kind::BuiltinTypeName,
                                BUILTIN_TYPE_NAME_JOB);
       break;
+    case 'D':
+      Ty = createNode(Node::Kind::BuiltinTypeName,
+                               BUILTIN_TYPE_NAME_DEFAULTACTORSTORAGE);
+      break;
     case 'c':
       Ty = createNode(Node::Kind::BuiltinTypeName,
                                BUILTIN_TYPE_NAME_RAWUNSAFECONTINUATION);
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index b29e8c8..c54a8a8 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -2177,8 +2177,8 @@
 }
 
 void Remangler::mangleCanonicalSpecializedGenericMetaclass(Node *node) {
-  Buffer << "MM";
   mangleSingleChildNode(node); // type
+  Buffer << "MM";
 }
 
 void Remangler::mangleCanonicalSpecializedGenericTypeMetadataAccessFunction(
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index 5fde0aa..ea90ba6 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -748,6 +748,8 @@
     Buffer << 'c';
   } else if (text == BUILTIN_TYPE_NAME_JOB) {
     Buffer << 'j';
+  } else if (text == BUILTIN_TYPE_NAME_DEFAULTACTORSTORAGE) {
+    Buffer << 'D';
   } else if (text == BUILTIN_TYPE_NAME_SILTOKEN) {
     Buffer << 't';
   } else if (text == BUILTIN_TYPE_NAME_INTLITERAL) {
diff --git a/lib/IRGen/ClassLayout.cpp b/lib/IRGen/ClassLayout.cpp
index 65adf4e..87bca56 100644
--- a/lib/IRGen/ClassLayout.cpp
+++ b/lib/IRGen/ClassLayout.cpp
@@ -27,7 +27,7 @@
 ClassLayout::ClassLayout(const StructLayoutBuilder &builder,
                          ClassMetadataOptions options,
                          llvm::Type *classTy,
-                         ArrayRef<VarDecl *> allStoredProps,
+                         ArrayRef<Field> allStoredProps,
                          ArrayRef<FieldAccess> allFieldAccesses,
                          ArrayRef<ElementLayout> allElements,
                          Size headerSize)
diff --git a/lib/IRGen/ClassLayout.h b/lib/IRGen/ClassLayout.h
index 014e518..19c8918 100644
--- a/lib/IRGen/ClassLayout.h
+++ b/lib/IRGen/ClassLayout.h
@@ -19,6 +19,7 @@
 #define SWIFT_IRGEN_CLASSLAYOUT_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "Field.h"
 #include "IRGen.h"
 #include "StructLayout.h"
 
@@ -119,7 +120,7 @@
 
   /// Lazily-initialized array of all fragile stored properties directly defined
   /// in the class itself.
-  ArrayRef<VarDecl *> AllStoredProperties;
+  ArrayRef<Field> AllStoredProperties;
 
   /// Lazily-initialized array of all field access methods.
   ArrayRef<FieldAccess> AllFieldAccesses;
@@ -132,7 +133,7 @@
   ClassLayout(const StructLayoutBuilder &builder,
               ClassMetadataOptions options,
               llvm::Type *classTy,
-              ArrayRef<VarDecl *> allStoredProps,
+              ArrayRef<Field> allStoredProps,
               ArrayRef<FieldAccess> allFieldAccesses,
               ArrayRef<ElementLayout> allElements,
               Size headerSize);
@@ -201,7 +202,7 @@
   }
 
   std::pair<FieldAccess, ElementLayout>
-  getFieldAccessAndElement(VarDecl *field) const {
+  getFieldAccessAndElement(Field field) const {
     // FIXME: This is algorithmically terrible.
     auto found = std::find(AllStoredProperties.begin(),
                            AllStoredProperties.end(), field);
diff --git a/lib/IRGen/ClassMetadataVisitor.h b/lib/IRGen/ClassMetadataVisitor.h
index 441eabf..ef11895 100644
--- a/lib/IRGen/ClassMetadataVisitor.h
+++ b/lib/IRGen/ClassMetadataVisitor.h
@@ -25,6 +25,7 @@
 #include "swift/SIL/SILVTable.h"
 #include "swift/SIL/SILVTableVisitor.h"
 #include "IRGen.h"
+#include "Field.h"
 #include "NominalMetadataVisitor.h"
 
 namespace swift {
@@ -157,10 +158,9 @@
     // But we currently always give classes field-offset vectors,
     // whether they need them or not.
     asImpl().noteStartOfFieldOffsets(theClass);
-    for (auto field :
-           theClass->getStoredPropertiesAndMissingMemberPlaceholders()) {
-      addFieldEntries(field);
-    }
+    forEachField(IGM, theClass, [&](Field field) {
+      asImpl().addFieldEntries(field);
+    });
     asImpl().noteEndOfFieldOffsets(theClass);
 
     // If the class has resilient metadata, we cannot make any assumptions
@@ -183,13 +183,16 @@
   }
   
         
-  void addFieldEntries(Decl *field) {
-    if (auto var = dyn_cast<VarDecl>(field)) {
-      asImpl().addFieldOffset(var);
+  void addFieldEntries(Field field) {
+    switch (field.getKind()) {
+    case Field::Var:
+      asImpl().addFieldOffset(field.getVarDecl());
       return;
-    }
-    if (auto placeholder = dyn_cast<MissingMemberDecl>(field)) {
-      asImpl().addFieldOffsetPlaceholders(placeholder);
+    case Field::MissingMember:
+      asImpl().addFieldOffsetPlaceholders(field.getMissingMemberDecl());
+      return;
+    case Field::DefaultActorStorage:
+      asImpl().addDefaultActorStorageFieldOffset();
       return;
     }
   }
@@ -227,6 +230,7 @@
     addPointer();
   }
   void addMethodOverride(SILDeclRef baseRef, SILDeclRef declRef) {}
+  void addDefaultActorStorageFieldOffset() { addPointer(); }
   void addFieldOffset(VarDecl *var) { addPointer(); }
   void addFieldOffsetPlaceholders(MissingMemberDecl *mmd) {
     for (unsigned i = 0, e = mmd->getNumberOfFieldOffsetVectorEntries();
diff --git a/lib/IRGen/Field.h b/lib/IRGen/Field.h
new file mode 100644
index 0000000..f2f6f5e
--- /dev/null
+++ b/lib/IRGen/Field.h
@@ -0,0 +1,107 @@
+//===--- Field.h - Abstract stored field ------------------------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides an abstraction for some sort of stored field
+//  in a type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_IRGEN_FIELD_H
+#define SWIFT_IRGEN_FIELD_H
+
+#include "swift/AST/Decl.h"
+
+namespace swift {
+class SILType;
+
+namespace irgen {
+class IRGenModule;
+
+/// Return the number of fields that will be visited by forEachField,
+/// which determines a number of things in the ABI, including the length
+/// of the field vector in the type metadata.
+///
+/// Generally this is the length of the stored properties, but 
+/// root default actors have an implicit field for their default-actor
+/// storage, and there may also be missing members.
+///
+/// Even if you're sure that you're in a case where only the stored
+/// properties are needed, calling this (and forEachField) instead of
+/// directly accessing the stored properties is good practice.
+unsigned getNumFields(const NominalTypeDecl *type);
+
+struct Field {
+public:
+  enum Kind: uintptr_t {
+    Var,
+    MissingMember,
+    DefaultActorStorage,
+    FirstArtificial = DefaultActorStorage
+  };
+  enum : uintptr_t { KindMask = 0x3 };
+private:
+  uintptr_t declOrKind;
+public:
+  Field(VarDecl *decl)
+      : declOrKind(reinterpret_cast<uintptr_t>(decl) | Var) {
+    assert(decl);
+    assert(getKind() == Var);
+  }
+  Field(MissingMemberDecl *decl)
+      : declOrKind(reinterpret_cast<uintptr_t>(decl) | MissingMember) {
+    assert(decl);
+    assert(getKind() == MissingMember);
+  }
+  Field(Kind kind) : declOrKind(kind) {
+    assert(kind >= FirstArtificial);
+  }
+
+  Kind getKind() const {
+    return Kind(declOrKind & KindMask);
+  }
+  VarDecl *getVarDecl() const {
+    assert(getKind() == Var);
+    return reinterpret_cast<VarDecl*>(declOrKind);
+  }
+  MissingMemberDecl *getMissingMemberDecl() const {
+    assert(getKind() == MissingMember);
+    return reinterpret_cast<MissingMemberDecl*>(declOrKind & ~KindMask);
+  }
+
+  /// Is this a concrete field?  When we're emitting a type, all the
+  /// fields should be concrete; non-concrete fields occur only with
+  /// imported declarations.
+  bool isConcrete() const { return getKind() != MissingMember; }
+
+  /// Return the type of this concrete field.
+  SILType getType(IRGenModule &IGM, SILType baseType) const;
+
+  /// Return the interface type of this concrete field.
+  Type getInterfaceType(IRGenModule &IGM) const;
+
+  /// Return the nam eof this concrete field.
+  llvm::StringRef getName() const;
+
+  bool operator==(Field other) const { return declOrKind == other.declOrKind; }
+  bool operator!=(Field other) const { return declOrKind != other.declOrKind; }
+};
+
+/// Iterate all the fields of the given struct or class type, including
+/// any implicit fields that might be accounted for in
+/// getFieldVectorLength.
+void forEachField(IRGenModule &IGM, const NominalTypeDecl *typeDecl,
+                  llvm::function_ref<void(Field field)> fn);
+
+} // end namespace irgen
+} // end namespace swift
+
+#endif
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index e90ea54..d6243e7 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -88,7 +88,7 @@
 namespace {
   class ClassLayoutBuilder : public StructLayoutBuilder {
     SmallVector<ElementLayout, 8> Elements;
-    SmallVector<VarDecl*, 8> AllStoredProperties;
+    SmallVector<Field, 8> AllStoredProperties;
     SmallVector<FieldAccess, 8> AllFieldAccesses;
 
     // If we're building a layout with tail-allocated elements, we do
@@ -277,14 +277,22 @@
     void addDirectFieldsFromClass(ClassDecl *rootClass, SILType rootClassType,
                                   ClassDecl *theClass, SILType classType,
                                   bool superclass) {
-      if (theClass->isRootDefaultActor())
-        addDefaultActorHeader();
+      bool collectStoredProperties =
+        !superclass ||
+        (rootClass->isGenericContext() && !rootClassType.getASTType()
+                                               ->getRecursiveProperties()
+                                               .hasUnboundGeneric());
 
-      for (VarDecl *var : theClass->getStoredProperties()) {
-        SILType type = classType.getFieldType(var, IGM.getSILModule(),
-                                              TypeExpansionContext::minimal());
+      forEachField(IGM, theClass, [&](Field field) {
+        // Ignore missing properties here; we should have flagged these
+        // with the classHasIncompleteLayout call above.
+        if (!field.isConcrete()) {
+          assert(Options & ClassMetadataFlags::ClassHasMissingMembers);
+          return;
+        }
 
         // Lower the field type.
+        SILType type = field.getType(IGM, classType);
         auto *eltType = &IGM.getTypeInfo(type);
         if (CompletelyFragileLayout && !eltType->isFixedSize()) {
           LoweringModeScope scope(IGM, TypeConverter::Mode::Legacy);
@@ -301,21 +309,16 @@
         auto element = ElementLayout::getIncomplete(*eltType);
         bool isKnownEmpty = !addField(element, LayoutStrategy::Universal);
 
-        bool isSpecializedGeneric =
-            (rootClass->isGenericContext() && !rootClassType.getASTType()
-                                                   ->getRecursiveProperties()
-                                                   .hasUnboundGeneric());
-
         // The 'Elements' list only contains superclass fields when we're
         // building a layout for tail allocation.
-        if (!superclass || TailTypes || isSpecializedGeneric)
+        if (collectStoredProperties || TailTypes)
           Elements.push_back(element);
 
-        if (!superclass || isSpecializedGeneric) {
-          AllStoredProperties.push_back(var);
+        if (collectStoredProperties) {
+          AllStoredProperties.push_back(field);
           AllFieldAccesses.push_back(getFieldAccess(isKnownEmpty));
         }
-      }
+      });
 
       if (!superclass) {
         // If we're calculating the layout of a specialized generic class type,
@@ -338,9 +341,9 @@
 
           for (unsigned index : indices(AllFieldAccesses)) {
             auto &access = AllFieldAccesses[index];
-            auto *var = AllStoredProperties[index];
+            auto field = AllStoredProperties[index];
             if (access == FieldAccess::NonConstantDirect)
-              access = abstractLayout->getFieldAccessAndElement(var).first;
+              access = abstractLayout->getFieldAccessAndElement(field).first;
           }
         }
 
@@ -1034,7 +1037,7 @@
     };
 
     llvm::SmallString<16> CategoryName;
-    SmallVector<VarDecl*, 8> Ivars;
+    SmallVector<Field, 8> Ivars;
     SmallVector<MethodDescriptor, 16> InstanceMethods;
     SmallVector<MethodDescriptor, 16> ClassMethods;
     SmallVector<MethodDescriptor, 16> OptInstanceMethods;
@@ -1073,6 +1076,9 @@
         : IGM(IGM), TheEntity(theUnion), TheExtension(nullptr),
           FieldLayout(&fieldLayout) {
       visitConformances(getClass());
+
+      if (getClass()->isRootDefaultActor())
+        Ivars.push_back(Field::DefaultActorStorage);
       visitMembers(getClass());
 
       if (Lowering::usesObjCAllocator(getClass())) {
@@ -1805,20 +1811,26 @@
     ///   uint32_t alignment;    // actually the log2 of the alignment
     ///   uint32_t size;
     /// };
-    void buildIvar(ConstantArrayBuilder &ivars, VarDecl *ivar) {
+    void buildIvar(ConstantArrayBuilder &ivars, Field field) {
       assert(FieldLayout && "can't build ivar for category");
 
-      auto fields = ivars.beginStruct();
-
       // For now, we never try to emit specialized versions of the
       // metadata statically, so compute the field layout using the
       // originally-declared type.
-      auto pair = FieldLayout->getFieldAccessAndElement(ivar);
+      auto pair = FieldLayout->getFieldAccessAndElement(field);
 
       llvm::Constant *offsetPtr;
       switch (pair.first) {
       case FieldAccess::ConstantDirect:
       case FieldAccess::NonConstantDirect: {
+        // Default actor storage doesn't get an ivar access variable.
+        if (field.getKind() == Field::DefaultActorStorage) {
+          offsetPtr = nullptr;
+          break;
+        }
+
+        // Otherwise, we should have a normal stored property.
+        auto ivar = field.getVarDecl();
         // If the field offset is fixed relative to the start of the superclass,
         // reference the global from the ivar metadata so that the Objective-C
         // runtime will slide it down.
@@ -1829,22 +1841,28 @@
       case FieldAccess::ConstantIndirect:
         // Otherwise, swift_initClassMetadata() will point the Objective-C
         // runtime into the field offset vector of the instantiated metadata.
-        offsetPtr
-          = llvm::ConstantPointerNull::get(IGM.IntPtrTy->getPointerTo());
+        offsetPtr = nullptr;
         break;
       }
 
-      fields.add(offsetPtr);
+      StringRef name = field.getName();
+      const TypeInfo &storageTI = pair.second.getType();
+      auto fields = ivars.beginStruct();
+
+      if (offsetPtr)
+        fields.add(offsetPtr);
+      else
+        fields.addNullPointer(IGM.IntPtrTy->getPointerTo());
 
       // TODO: clang puts this in __TEXT,__objc_methname,cstring_literals
-      fields.add(IGM.getAddrOfGlobalString(ivar->getName().str()));
+      fields.add(IGM.getAddrOfGlobalString(name));
 
       // TODO: clang puts this in __TEXT,__objc_methtype,cstring_literals
       fields.add(IGM.getAddrOfGlobalString(""));
 
       Size size;
       Alignment alignment;
-      if (auto fixedTI = dyn_cast<FixedTypeInfo>(&pair.second.getType())) {
+      if (auto fixedTI = dyn_cast<FixedTypeInfo>(&storageTI)) {
         size = fixedTI->getFixedSize();
         alignment = fixedTI->getFixedAlignment();
       } else {
@@ -1855,7 +1873,7 @@
       // If the size is larger than we can represent in 32-bits,
       // complain about the unimplementable ivar.
       if (uint32_t(size.getValue()) != size.getValue()) {
-        IGM.error(ivar->getLoc(),
+        IGM.error(field.getVarDecl()->getLoc(),
                   "ivar size (" + Twine(size.getValue()) +
                   " bytes) overflows Objective-C ivar layout");
         size = Size(0);
@@ -1878,8 +1896,8 @@
       return buildOptionalList(Ivars, eltSize, "_IVARS_",
                                /*constant*/ true,
                                [&](ConstantArrayBuilder &descriptors,
-                                   VarDecl *ivar) {
-        buildIvar(descriptors, ivar);
+                                   Field field) {
+        buildIvar(descriptors, field);
       });
     }
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 4fb879a..2fcdf3c 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -49,6 +49,7 @@
 #include "ClassTypeInfo.h"
 #include "ConstantBuilder.h"
 #include "EnumMetadataVisitor.h"
+#include "Field.h"
 #include "FixedTypeInfo.h"
 #include "ForeignClassMetadataVisitor.h"
 #include "GenArchetype.h"
@@ -1396,10 +1397,8 @@
     }
     
     void addLayoutInfo() {
-      auto properties = getType()->getStoredProperties();
-
       // uint32_t NumFields;
-      B.addInt32(properties.size());
+      B.addInt32(getNumFields(getType()));
 
       // uint32_t FieldOffsetVectorOffset;
       B.addInt32(FieldVectorOffset / IGM.getPointerSize());
@@ -1786,8 +1785,6 @@
         B.addInt32(0);
       }
 
-      auto properties = getType()->getStoredProperties();
-
       // union {
       //   uint32_t MetadataNegativeSizeInWords;
       //   RelativeDirectPointer<StoredClassMetadataBounds>
@@ -1827,7 +1824,7 @@
       B.addInt32(numImmediateMembers);
 
       // uint32_t NumFields;
-      B.addInt32(properties.size());
+      B.addInt32(getNumFields(getType()));
 
       // uint32_t FieldOffsetVectorOffset;
       B.addInt32(getFieldVectorOffset() / IGM.getPointerSize());
@@ -2196,33 +2193,30 @@
       .getAddress();
   
   // Collect the stored properties of the type.
-  llvm::SmallVector<VarDecl*, 4> storedProperties;
-  for (auto prop : target->getStoredProperties()) {
-    storedProperties.push_back(prop);
-  }
+  unsigned numFields = getNumFields(target);
 
   // Fill out an array with the field type metadata records.
   Address fields = IGF.createAlloca(
-                   llvm::ArrayType::get(IGM.Int8PtrPtrTy,
-                                        storedProperties.size()),
+                   llvm::ArrayType::get(IGM.Int8PtrPtrTy, numFields),
                    IGM.getPointerAlignment(), "classFields");
-  IGF.Builder.CreateLifetimeStart(fields,
-                  IGM.getPointerSize() * storedProperties.size());
+  IGF.Builder.CreateLifetimeStart(fields, IGM.getPointerSize() * numFields);
   fields = IGF.Builder.CreateStructGEP(fields, 0, Size(0));
 
   unsigned index = 0;
-  for (auto prop : storedProperties) {
-    auto propTy = T.getFieldType(prop, IGF.getSILModule(),
-                                 TypeExpansionContext::minimal());
-    llvm::Value *metadata = emitTypeLayoutRef(IGF, propTy, collector);
-    Address field = IGF.Builder.CreateConstArrayGEP(fields, index,
-                                                    IGM.getPointerSize());
-    IGF.Builder.CreateStore(metadata, field);
+  forEachField(IGM, target, [&](Field field) {
+    assert(field.isConcrete() &&
+           "initializing offset vector for type with missing member?");
+    SILType propTy = field.getType(IGM, T);
+    llvm::Value *fieldLayout = emitTypeLayoutRef(IGF, propTy, collector);
+    Address fieldLayoutAddr =
+      IGF.Builder.CreateConstArrayGEP(fields, index, IGM.getPointerSize());
+    IGF.Builder.CreateStore(fieldLayout, fieldLayoutAddr);
     ++index;
-  }
+  });
+  assert(index == numFields);
 
   // Ask the runtime to lay out the struct or class.
-  auto numFields = IGM.getSize(Size(storedProperties.size()));
+  auto numFieldsV = IGM.getSize(Size(numFields));
 
   if (auto *classDecl = dyn_cast<ClassDecl>(target)) {
     // Compute class layout flags.
@@ -2252,7 +2246,7 @@
         IGF.Builder.CreateCall(IGM.getInitClassMetadata2Fn(),
                                {metadata,
                                 IGM.getSize(Size(uintptr_t(flags))),
-                                numFields, fields.getAddress(), fieldVector});
+                                numFieldsV, fields.getAddress(), fieldVector});
       break;
 
     case ClassMetadataStrategy::Update:
@@ -2266,7 +2260,7 @@
         IGF.Builder.CreateCall(IGM.getUpdateClassMetadata2Fn(),
                                {metadata,
                                 IGM.getSize(Size(uintptr_t(flags))),
-                                numFields, fields.getAddress(), fieldVector});
+                                numFieldsV, fields.getAddress(), fieldVector});
       break;
 
     case ClassMetadataStrategy::Fixed:
@@ -2289,11 +2283,10 @@
     // Call swift_initStructMetadata().
     IGF.Builder.CreateCall(IGM.getInitStructMetadataFn(),
                            {metadata, IGM.getSize(Size(uintptr_t(flags))),
-                            numFields, fields.getAddress(), fieldVector});
+                            numFieldsV, fields.getAddress(), fieldVector});
   }
 
-  IGF.Builder.CreateLifetimeEnd(fields,
-                  IGM.getPointerSize() * storedProperties.size());
+  IGF.Builder.CreateLifetimeEnd(fields, IGM.getPointerSize() * numFields);
 }
 
 static void emitInitializeValueMetadata(IRGenFunction &IGF,
@@ -2341,8 +2334,13 @@
   // field offset globals for us; but if ObjC interop is disabled, we
   // have to do that ourselves, assuming we didn't just emit them all
   // correctly in the first place.
+  // FIXME: make the runtime do this in all cases, because there's no
+  // good reason it shouldn't
   if (!IGM.ObjCInterop) {
-    for (auto prop : classDecl->getStoredProperties()) {
+    forEachField(IGM, classDecl, [&](Field field) {
+      // FIXME: should we handle the other cases here?
+      if (field.getKind() != Field::Var) return;
+      auto prop = field.getVarDecl();
       auto fieldInfo = fieldLayout.getFieldAccessAndElement(prop);
       if (fieldInfo.first == FieldAccess::NonConstantDirect) {
         Address offsetA = IGM.getAddrOfFieldOffset(prop, ForDefinition);
@@ -2355,7 +2353,7 @@
         auto offsetVal = IGF.emitInvariantLoad(slot);
         IGF.Builder.CreateStore(offsetVal, offsetA);
       }
-    }
+    });
   }
 }
 
@@ -2753,7 +2751,23 @@
                                    ClassDecl *classDecl,
                                    const ClassLayout &fragileLayout,
                                    const ClassLayout &resilientLayout) {
-  for (auto prop : classDecl->getStoredProperties()) {
+  forEachField(IGM, classDecl, [&](Field field) {
+    switch (field.getKind()) {
+    // This is case we actually care about.
+    case Field::Var:
+      break;
+
+    // We should never be in this case when emitting a type.
+    case Field::MissingMember:
+      llvm_unreachable("unexpected missing member when emitting type");
+
+    // We don't need to emit an offset global for the default-actor
+    // storage, which is never accessed directly.
+    case Field::DefaultActorStorage:
+      return;
+    }
+
+    auto prop = field.getVarDecl();
     auto fieldInfo = fragileLayout.getFieldAccessAndElement(prop);
     auto access = fieldInfo.first;
     auto element = fieldInfo.second;
@@ -2813,7 +2827,7 @@
       // No global variable is needed.
       break;
     }
-  }
+  });
 }
 
 static ClassFlags getClassFlags(ClassDecl *classDecl) {
@@ -3124,6 +3138,10 @@
       B.add(data);
     }
 
+    void addDefaultActorStorageFieldOffset() {
+      B.addInt(IGM.SizeTy, getDefaultActorStorageFieldOffset(IGM).getValue());
+    }
+
     void addReifiedVTableEntry(SILDeclRef fn) {
       // Find the vtable entry.
       assert(VTable && "no vtable?!");
@@ -4236,7 +4254,7 @@
       if (!isa<FixedTypeInfo>(ti))
         return false;
 
-      if (Target->getStoredProperties().empty())
+      if (getNumFields(Target) == 0)
         return false;
 
       return true;
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index c6dd84d..34c2b22 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -28,10 +28,12 @@
 
 #include "ConstantBuilder.h"
 #include "Explosion.h"
+#include "Field.h"
 #include "GenClass.h"
 #include "GenDecl.h"
 #include "GenEnum.h"
 #include "GenHeap.h"
+#include "GenMeta.h"
 #include "GenProto.h"
 #include "GenType.h"
 #include "IRGenDebugInfo.h"
@@ -672,13 +674,8 @@
 private:
   const NominalTypeDecl *NTD;
 
-  void addFieldDecl(const ValueDecl *value, Type type,
-                    bool indirect=false) {
-    reflection::FieldRecordFlags flags;
-    flags.setIsIndirectCase(indirect);
-    if (auto var = dyn_cast<VarDecl>(value))
-      flags.setIsVar(!var->isLet());
-
+  void addField(reflection::FieldRecordFlags flags,
+                Type type, StringRef name) {
     B.addInt32(flags.getRawValue());
 
     if (!type) {
@@ -693,7 +690,6 @@
     }
 
     if (IGM.IRGen.Opts.EnableReflectionNames) {
-      auto name = value->getBaseIdentifier().str();
       auto fieldName = IGM.getAddrOfFieldName(name);
       B.addRelativeAddress(fieldName);
     } else {
@@ -701,6 +697,27 @@
     }
   }
 
+  void addField(Field field) {
+    reflection::FieldRecordFlags flags;
+    bool isLet = false;
+
+    switch (field.getKind()) {
+    case Field::Var: {
+      auto var = field.getVarDecl();
+      isLet = var->isLet();
+      break;
+    }
+    case Field::MissingMember:
+      llvm_unreachable("emitting reflection for type with missing member");
+    case Field::DefaultActorStorage:
+      flags.setIsArtificial();
+      break;
+    }
+    flags.setIsVar(!isLet);
+
+    addField(flags, field.getInterfaceType(IGM), field.getName());
+  }
+
   void layoutRecord() {
     auto kind = FieldDescriptorKind::Struct;
 
@@ -716,10 +733,20 @@
     B.addInt16(uint16_t(kind));
     B.addInt16(FieldRecordSize);
 
-    auto properties = NTD->getStoredProperties();
-    B.addInt32(properties.size());
-    for (auto property : properties)
-      addFieldDecl(property, property->getInterfaceType());
+    B.addInt32(getNumFields(NTD));
+    forEachField(IGM, NTD, [&](Field field) {
+      addField(field);
+    });
+  }
+
+  void addField(const EnumDecl *enumDecl, const EnumElementDecl *decl,
+                bool hasPayload) {
+    reflection::FieldRecordFlags flags;
+    if (hasPayload && (decl->isIndirect() || enumDecl->isIndirect()))
+      flags.setIsIndirectCase();
+
+    addField(flags, decl->getArgumentInterfaceType(),
+             decl->getBaseIdentifier().str());
   }
 
   void layoutEnum() {
@@ -741,14 +768,11 @@
                + strategy.getElementsWithNoPayload().size());
 
     for (auto enumCase : strategy.getElementsWithPayload()) {
-      bool indirect = (enumCase.decl->isIndirect() ||
-                       enumDecl->isIndirect());
-      addFieldDecl(enumCase.decl, enumCase.decl->getArgumentInterfaceType(),
-                   indirect);
+      addField(enumDecl, enumCase.decl, /*has payload*/ true);
     }
 
     for (auto enumCase : strategy.getElementsWithNoPayload()) {
-      addFieldDecl(enumCase.decl, enumCase.decl->getArgumentInterfaceType());
+      addField(enumDecl, enumCase.decl, /*has payload*/ false);
     }
   }
 
diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp
index 9177e36..3ad9e0d 100644
--- a/lib/IRGen/GenType.cpp
+++ b/lib/IRGen/GenType.cpp
@@ -2090,6 +2090,20 @@
     align = IGM.getCappedAlignment(align);
     return createPrimitive(llvmTy, size, align);
   }
+  case TypeKind::BuiltinDefaultActorStorage: {
+    // Builtin.DefaultActorStorage represents the extra storage
+    // (beyond the heap header) of a default actor class.  It is
+    // fixed-size and totally opaque.
+    auto numWords = NumWords_DefaultActor;
+
+    auto ty = llvm::StructType::create(IGM.getLLVMContext(),
+                                 llvm::ArrayType::get(IGM.Int8PtrTy, numWords),
+                                       "swift.defaultactor");
+    auto size = IGM.getPointerSize() * numWords;
+    auto align = Alignment(2 * IGM.getPointerAlignment().getValue());
+    auto spareBits = SpareBitVector::getConstant(size.getValueInBits(), false);
+    return new PrimitiveTypeInfo(ty, size, std::move(spareBits), align);
+  }
 
   case TypeKind::PrimaryArchetype:
   case TypeKind::OpenedArchetype:
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index d820482..1deabde 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -1633,6 +1633,7 @@
     case TypeKind::SILBox:
     case TypeKind::SILToken:
     case TypeKind::BuiltinUnsafeValueBuffer:
+    case TypeKind::BuiltinDefaultActorStorage:
 
       LLVM_DEBUG(llvm::dbgs() << "Unhandled type: ";
                  DbgTy.getType()->dump(llvm::dbgs()); llvm::dbgs() << "\n");
diff --git a/lib/IRGen/MetadataLayout.cpp b/lib/IRGen/MetadataLayout.cpp
index 5ea2eb6..d136f11 100644
--- a/lib/IRGen/MetadataLayout.cpp
+++ b/lib/IRGen/MetadataLayout.cpp
@@ -267,6 +267,8 @@
 
     ClassMetadataLayout &Layout;
 
+    bool IsInTargetFields = false;
+
     Scanner(IRGenModule &IGM, ClassDecl *decl, ClassMetadataLayout &layout)
       : super(IGM, decl), Layout(layout) {}
 
@@ -347,19 +349,37 @@
     }
 
     void noteStartOfFieldOffsets(ClassDecl *forClass) {
-      if (forClass == Target)
+      if (forClass == Target) {
+        assert(!IsInTargetFields);
+        IsInTargetFields = true;
         Layout.FieldOffsetVector = getNextOffset();
+      }
       super::noteStartOfFieldOffsets(forClass);
     }
 
+    void noteEndOfFieldOffsets(ClassDecl *forClass) {
+      assert(IsInTargetFields == (forClass == Target));
+      if (IsInTargetFields)
+        IsInTargetFields = false;
+      super::noteEndOfFieldOffsets(forClass);
+    }
+
     void addFieldOffset(VarDecl *field) {
-      if (field->getDeclContext() == Target) {
+      assert(IsInTargetFields == (field->getDeclContext() == Target));
+      if (IsInTargetFields) {
         ++Layout.NumImmediateMembers;
         Layout.FieldOffsets.try_emplace(field, getNextOffset());
       }
       super::addFieldOffset(field);
     }
 
+    void addDefaultActorStorageFieldOffset() {
+      if (IsInTargetFields) {
+        ++Layout.NumImmediateMembers;
+      }
+      super::addDefaultActorStorageFieldOffset();
+    }
+
     void addFieldOffsetPlaceholders(MissingMemberDecl *placeholder) {
       if (placeholder->getDeclContext() == Target) {
         Layout.NumImmediateMembers +=
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index 9620ea0..26f7311 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -1714,10 +1714,16 @@
       llvm_unreachable("error type should not appear in IRGen");
     }
 
-    MetadataResponse visitSILBlockStorageType(CanSILBlockStorageType type,
-                                              DynamicMetadataRequest request) {
-      llvm_unreachable("cannot ask for metadata of block storage");
+    // These types are artificial types used for for internal purposes and
+    // should never appear in a metadata request.
+#define INTERNAL_ONLY_TYPE(ID)                                               \
+    MetadataResponse visit##ID##Type(Can##ID##Type type,                     \
+                                     DynamicMetadataRequest request) {       \
+      llvm_unreachable("cannot ask for metadata of compiler-internal type"); \
     }
+    INTERNAL_ONLY_TYPE(SILBlockStorage)
+    INTERNAL_ONLY_TYPE(BuiltinDefaultActorStorage)
+#undef INTERNAL_ONLY_TYPE
 
     MetadataResponse visitSILBoxType(CanSILBoxType type,
                                      DynamicMetadataRequest request) {
diff --git a/lib/IRGen/StructLayout.cpp b/lib/IRGen/StructLayout.cpp
index 0e83305..2f6bc93 100644
--- a/lib/IRGen/StructLayout.cpp
+++ b/lib/IRGen/StructLayout.cpp
@@ -22,6 +22,7 @@
 #include "swift/ABI/MetadataValues.h"
 
 #include "BitPatternBuilder.h"
+#include "Field.h"
 #include "FixedTypeInfo.h"
 #include "IRGenFunction.h"
 #include "IRGenModule.h"
@@ -200,7 +201,7 @@
   headerSize = CurSize;
 }
 
-void StructLayoutBuilder::addDefaultActorHeader() {
+void StructLayoutBuilder::addDefaultActorHeader(ElementLayout &elt) {
   assert(StructFields.size() == 1 &&
          StructFields[0] == IGM.RefCountedStructTy &&
          "adding default actor header at wrong offset");
@@ -215,12 +216,18 @@
   // get internal padding.
   assert(CurSize.isMultipleOf(IGM.getPointerSize()));
   assert(align >= CurAlignment);
+  assert(CurSize == getDefaultActorStorageFieldOffset(IGM));
+  elt.completeFixed(IsNotPOD, CurSize, /*struct index*/ 1);
   CurSize += size;
   CurAlignment = align;
   StructFields.push_back(ty);
   headerSize = CurSize;
 }
 
+Size irgen::getDefaultActorStorageFieldOffset(IRGenModule &IGM) {
+  return IGM.RefCountedStructSize;
+}
+
 bool StructLayoutBuilder::addFields(llvm::MutableArrayRef<ElementLayout> elts,
                                     LayoutStrategy strategy) {
   // Track whether we've added any storage to our layout.
@@ -398,3 +405,68 @@
   }
   return spareBits.build();
 }
+
+unsigned irgen::getNumFields(const NominalTypeDecl *target) {
+  auto numFields =
+    target->getStoredPropertiesAndMissingMemberPlaceholders().size();
+  if (auto cls = dyn_cast<ClassDecl>(target)) {
+    if (cls->isRootDefaultActor())
+      numFields++;
+  }
+  return numFields;
+}
+
+void irgen::forEachField(IRGenModule &IGM, const NominalTypeDecl *typeDecl,
+                         llvm::function_ref<void(Field field)> fn) {
+  auto classDecl = dyn_cast<ClassDecl>(typeDecl);
+  if (classDecl && classDecl->isRootDefaultActor()) {
+    fn(Field::DefaultActorStorage);
+  }
+
+  for (auto decl :
+         typeDecl->getStoredPropertiesAndMissingMemberPlaceholders()) {
+    if (auto var = dyn_cast<VarDecl>(decl)) {
+      fn(var);
+    } else {
+      fn(cast<MissingMemberDecl>(decl));
+    }
+  }
+}
+
+SILType Field::getType(IRGenModule &IGM, SILType baseType) const {
+  switch (getKind()) {
+  case Field::Var:
+    return baseType.getFieldType(getVarDecl(), IGM.getSILModule(),
+                                 TypeExpansionContext::minimal());
+  case Field::MissingMember:
+    llvm_unreachable("cannot ask for type of missing member");
+  case Field::DefaultActorStorage:
+    return SILType::getPrimitiveObjectType(
+                             IGM.Context.TheDefaultActorStorageType);
+  }
+  llvm_unreachable("bad field kind");
+}
+
+Type Field::getInterfaceType(IRGenModule &IGM) const {
+  switch (getKind()) {
+  case Field::Var:
+    return getVarDecl()->getInterfaceType();
+  case Field::MissingMember:
+    llvm_unreachable("cannot ask for type of missing member");
+  case Field::DefaultActorStorage:
+    return IGM.Context.TheDefaultActorStorageType;
+  }
+  llvm_unreachable("bad field kind");
+}
+
+StringRef Field::getName() const {
+  switch (getKind()) {
+  case Field::Var:
+    return getVarDecl()->getName().str();
+  case Field::MissingMember:
+    llvm_unreachable("cannot ask for type of missing member");
+  case Field::DefaultActorStorage:
+    return DEFAULT_ACTOR_STORAGE_FIELD_NAME;
+  }
+  llvm_unreachable("bad field kind");
+}
diff --git a/lib/IRGen/StructLayout.h b/lib/IRGen/StructLayout.h
index 7d5ab54..d91d658 100644
--- a/lib/IRGen/StructLayout.h
+++ b/lib/IRGen/StructLayout.h
@@ -297,7 +297,7 @@
   void addNSObjectHeader();
   /// Add the default-actor header to the layout.  This must be the second
   /// thing added to the layout, following the Swift heap header.
-  void addDefaultActorHeader();
+  void addDefaultActorHeader(ElementLayout &elt);
   
   /// Add a number of fields to the layout.  The field layouts need
   /// only have the TypeInfo set; the rest will be filled out.
@@ -458,6 +458,8 @@
                      const llvm::Twine &name = "") const;
 };
 
+Size getDefaultActorStorageFieldOffset(IRGenModule &IGM);
+
 } // end namespace irgen
 } // end namespace swift
 
diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp
index ff6b658..58203c0 100644
--- a/lib/SIL/IR/TypeLowering.cpp
+++ b/lib/SIL/IR/TypeLowering.cpp
@@ -265,6 +265,15 @@
                                                isSensitive});
     }
 
+    RetTy visitBuiltinDefaultActorStorageType(
+                                         CanBuiltinDefaultActorStorageType type,
+                                         AbstractionPattern origType,
+                                         IsTypeExpansionSensitive_t isSensitive) {
+      return asImpl().handleAddressOnly(type, {IsNotTrivial, IsFixedABI,
+                                               IsAddressOnly, IsNotResilient,
+                                               isSensitive});
+    }
+
     RetTy visitAnyFunctionType(CanAnyFunctionType type,
                                AbstractionPattern origType,
                                IsTypeExpansionSensitive_t isSensitive) {
diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp
index 954ccad..3fbae1f 100644
--- a/lib/SILGen/SILGenPattern.cpp
+++ b/lib/SILGen/SILGenPattern.cpp
@@ -1398,6 +1398,25 @@
   llvm_unreachable("covered switch");
 }
 
+/// Given that we've broken down a source value into this subobject,
+/// and that we were supposed to use the given consumption rules on
+/// it, construct an appropriate managed value.
+static ConsumableManagedValue
+getManagedSubobject(SILGenFunction &SGF, ManagedValue value,
+                    CastConsumptionKind consumption) {
+  switch (consumption) {
+  case CastConsumptionKind::BorrowAlways:
+  case CastConsumptionKind::CopyOnSuccess:
+    return {value.unmanagedBorrow(), consumption};
+  case CastConsumptionKind::TakeAlways:
+  case CastConsumptionKind::TakeOnSuccess: {
+    auto loc = RegularLocation::getAutoGeneratedLocation();
+    return {value.ensurePlusOne(SGF, loc), consumption};
+  }
+  }
+  llvm_unreachable("covered switch");
+}
+
 static ConsumableManagedValue
 emitReabstractedSubobject(SILGenFunction &SGF, SILLocation loc,
                           ConsumableManagedValue value,
@@ -2064,29 +2083,34 @@
   }
 
   // Emit the switch_enum_addr instruction.
-  SILValue srcValue = src.getFinalManagedValue().forward(SGF);
-  SGF.B.createSwitchEnumAddr(loc, srcValue, blocks.getDefaultBlock(),
+  //
+  // NOTE: switch_enum_addr does not actually consume the underlying value.
+  SGF.B.createSwitchEnumAddr(loc, src.getValue(), blocks.getDefaultBlock(),
                              blocks.getCaseBlocks(), blocks.getCounts(),
                              defaultCaseCount);
 
   // Okay, now emit all the cases.
-  blocks.forEachCase([&](EnumElementDecl *elt, SILBasicBlock *caseBB,
+  blocks.forEachCase([&](EnumElementDecl *eltDecl, SILBasicBlock *caseBB,
                          const CaseInfo &caseInfo) {
     SILLocation loc = caseInfo.FirstMatcher;
     auto &specializedRows = caseInfo.SpecializedRows;
 
     SGF.B.setInsertionPoint(caseBB);
 
+    // We need to make sure our cleanup stays around long enough for us to emit
+    // our destroy, so setup a cleanup state restoration scope for each case.
+    CleanupStateRestorationScope srcScope(SGF.Cleanups);
+    forwardIntoIrrefutableSubtree(SGF, srcScope, src);
+
     // We're in conditionally-executed code; enter a scope.
     Scope scope(SGF.Cleanups, CleanupLocation::get(loc));
-      
+
     // Create a BB argument or 'unchecked_take_enum_data_addr'
     // instruction to receive the enum case data if it has any.
-
     SILType eltTy;
     bool hasElt = false;
-    if (elt->hasAssociatedValues()) {
-      eltTy = src.getType().getEnumElementType(elt, SGF.SGM.M,
+    if (eltDecl->hasAssociatedValues()) {
+      eltTy = src.getType().getEnumElementType(eltDecl, SGF.SGM.M,
                                                SGF.getTypeExpansionContext());
       hasElt = !eltTy.getASTType()->isVoid();
     }
@@ -2108,6 +2132,15 @@
         }
       }
 
+      // Forward src along this path so we don't emit a destroy_addr on our
+      // subject value for this case.
+      //
+      // FIXME: Do we actually want to do this? SILGen tests today assume this
+      // pattern. It might be worth leaving the destroy_addr there to create
+      // additional liveness information. For now though, we maintain the
+      // current behavior.
+      src.getFinalManagedValue().forward(SGF);
+
       SILValue result;
       if (hasNonAny) {
         result = SGF.emitEmptyTuple(loc);
@@ -2132,16 +2165,18 @@
         eltConsumption = CastConsumptionKind::TakeAlways;
       }
 
-      SILValue eltValue;
+      ManagedValue eltValue;
       // We can only project destructively from an address-only enum, so
       // copy the value if we can't consume it.
       // TODO: Should have a more efficient way to copy payload
       // nondestructively from an enum.
       switch (eltConsumption) {
-      case CastConsumptionKind::TakeAlways:
-        eltValue =
-            SGF.B.createUncheckedTakeEnumDataAddr(loc, srcValue, elt, eltTy);
+      case CastConsumptionKind::TakeAlways: {
+        auto finalValue = src.getFinalManagedValue();
+        eltValue = SGF.B.createUncheckedTakeEnumDataAddr(loc, finalValue,
+                                                         eltDecl, eltTy);
         break;
+      }
       case CastConsumptionKind::BorrowAlways:
         // If we reach this point, we know that we have a loadable
         // element type from an enum with mixed address
@@ -2150,11 +2185,15 @@
         // address only types do not support BorrowAlways.
         llvm_unreachable("not allowed");
       case CastConsumptionKind::CopyOnSuccess: {
-        auto copy = SGF.emitTemporaryAllocation(loc, srcValue->getType());
-        SGF.B.createCopyAddr(loc, srcValue, copy, IsNotTake, IsInitialization);
+        auto temp = SGF.emitTemporary(loc, SGF.getTypeLowering(src.getType()));
+        SGF.B.createCopyAddr(loc, src.getValue(), temp->getAddress(), IsNotTake,
+                             IsInitialization);
+        temp->finishInitialization(SGF);
+
         // We can always take from the copy.
         eltConsumption = CastConsumptionKind::TakeAlways;
-        eltValue = SGF.B.createUncheckedTakeEnumDataAddr(loc, copy, elt, eltTy);
+        eltValue = SGF.B.createUncheckedTakeEnumDataAddr(
+            loc, temp->getManagedAddress(), eltDecl, eltTy);
         break;
       }
 
@@ -2168,25 +2207,24 @@
       // the value. This invariant makes it easy to specialize code for
       // ownership.
       if (eltTL->isLoadable()) {
-        // If we do not have a loadable value, just use getManagedSubObject
+        // If we do not have a loadable value, just use getManagedSubobject
         // Load a loadable data value.
-        auto managedEltValue = ManagedValue::forUnmanaged(eltValue);
         if (eltConsumption == CastConsumptionKind::CopyOnSuccess) {
-          managedEltValue = SGF.B.createLoadBorrow(loc, managedEltValue);
+          eltValue = SGF.B.createLoadBorrow(loc, eltValue);
           eltConsumption = CastConsumptionKind::BorrowAlways;
         } else {
           assert(eltConsumption == CastConsumptionKind::TakeAlways);
-          managedEltValue = SGF.B.createLoadTake(loc, managedEltValue);
+          eltValue = SGF.B.createLoadTake(loc, eltValue);
         }
-        origCMV = {managedEltValue, eltConsumption};
+        origCMV = {eltValue, eltConsumption};
       } else {
-        origCMV = getManagedSubobject(SGF, eltValue, *eltTL, eltConsumption);
+        origCMV = getManagedSubobject(SGF, eltValue, eltConsumption);
       }
 
       eltCMV = origCMV;
 
       // If the payload is boxed, project it.
-      if (elt->isIndirect() || elt->getParentEnum()->isIndirect()) {
+      if (eltDecl->isIndirect() || eltDecl->getParentEnum()->isIndirect()) {
         ManagedValue boxedValue =
           SGF.B.createProjectBox(loc, origCMV.getFinalManagedValue(), 0);
         eltTL = &SGF.getTypeLowering(boxedValue.getType());
@@ -2202,14 +2240,14 @@
 
       // Reabstract to the substituted type, if needed.
       CanType substEltTy =
-        sourceType->getTypeOfMember(SGF.SGM.M.getSwiftModule(), elt,
-                                    elt->getArgumentInterfaceType())
+        sourceType->getTypeOfMember(SGF.SGM.M.getSwiftModule(), eltDecl,
+                                    eltDecl->getArgumentInterfaceType())
                   ->getCanonicalType();
 
       AbstractionPattern origEltTy =
-          (elt->getParentEnum()->isOptionalDecl()
+          (eltDecl->getParentEnum()->isOptionalDecl()
                ? AbstractionPattern(substEltTy)
-               : SGF.SGM.M.Types.getAbstractionPattern(elt));
+               : SGF.SGM.M.Types.getAbstractionPattern(eltDecl));
 
       eltCMV = emitReabstractedSubobject(SGF, loc, eltCMV, *eltTL,
                                          origEltTy, substEltTy);
diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp
index 37b8432..bdb83d5 100644
--- a/lib/Sema/TypeCheckEffects.cpp
+++ b/lib/Sema/TypeCheckEffects.cpp
@@ -1532,12 +1532,17 @@
       Self.Flags.set(ContextFlags::IsTryCovered);
       Self.Flags.clear(ContextFlags::HasTryThrowSite);
     }
-    
+
     void enterAwait() {
       Self.Flags.set(ContextFlags::IsAsyncCovered);
       Self.Flags.clear(ContextFlags::HasAnyAsyncSite);
     }
 
+    void enterAsyncLet() {
+      Self.Flags.set(ContextFlags::IsTryCovered);
+      Self.Flags.set(ContextFlags::IsAsyncCovered);
+    }
+
     void refineLocalContext(Context newContext) {
       Self.CurContext = newContext;
     }
@@ -1602,7 +1607,7 @@
       OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
       OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
     }
-    
+
     bool wasTopLevelDebuggerFunction() const {
       return OldFlags.has(ContextFlags::IsTopLevelDebuggerFunction);
     }
@@ -1678,6 +1683,7 @@
 
     case AutoClosureExpr::Kind::AsyncLet:
       scope.resetCoverage();
+      scope.enterAsyncLet();
       shouldPreserveCoverage = false;
       break;
     }
@@ -1817,10 +1823,11 @@
   }
 
   ShouldRecurse_t checkAsyncLet(PatternBindingDecl *patternBinding) {
-      // Diagnose async calls in a context that doesn't handle async.
-      if (!CurContext.handlesAsync()) {
-        CurContext.diagnoseUnhandledAsyncSite(Ctx.Diags, patternBinding);
-      }
+    // Diagnose async let in a context that doesn't handle async.
+    if (!CurContext.handlesAsync()) {
+      CurContext.diagnoseUnhandledAsyncSite(Ctx.Diags, patternBinding);
+    }
+
     return ShouldRecurse;
   }
 
diff --git a/lib/Serialization/ModuleFileCoreTableInfo.h b/lib/Serialization/ModuleFileCoreTableInfo.h
index a2cc855..0ecc463 100644
--- a/lib/Serialization/ModuleFileCoreTableInfo.h
+++ b/lib/Serialization/ModuleFileCoreTableInfo.h
@@ -600,9 +600,9 @@
   static data_type ReadData(internal_key_type key, const uint8_t *data,
                             unsigned length) {
     using namespace llvm::support;
-    auto str = std::string{reinterpret_cast<const char *>(data),
-                           Fingerprint::DIGEST_LENGTH};
-    return Fingerprint{str};
+    auto str = llvm::StringRef{reinterpret_cast<const char *>(data),
+                               Fingerprint::DIGEST_LENGTH};
+    return Fingerprint::fromString(str);
   }
 };
 
diff --git a/test/Concurrency/async_let_isolation.swift b/test/Concurrency/async_let_isolation.swift
index 006cff9..1028ec9 100644
--- a/test/Concurrency/async_let_isolation.swift
+++ b/test/Concurrency/async_let_isolation.swift
@@ -30,7 +30,7 @@
 
 func outside() async {
   let a = MyActor()
-  async let x = a.synchronous() // expected-error {{call is 'async' in an 'async let' initializer that is not marked with 'await'}}
+  async let x = a.synchronous() // okay, await is implicit
   async let y = await a.synchronous()
   _ = await x
   _ = await y
diff --git a/test/Driver/sanitize_recover.swift b/test/Driver/sanitize_recover.swift
index d35b209..ca7ca24 100644
--- a/test/Driver/sanitize_recover.swift
+++ b/test/Driver/sanitize_recover.swift
@@ -1,4 +1,3 @@
-// REQUIRES: 64784401
 // RUN: not %swiftc_driver -driver-print-jobs -sanitize=address -sanitize-recover=foo %s 2>&1 | %FileCheck -check-prefix=SAN_RECOVER_INVALID_ARG %s
 // RUN: not %swiftc_driver -driver-print-jobs -sanitize=address -sanitize-recover=thread %s 2>&1 | %FileCheck -check-prefix=SAN_RECOVER_UNSUPPORTED_ARG %s
 // RUN: %swiftc_driver -v -sanitize-recover=address %s -o %t 2>&1 | %FileCheck -check-prefix=SAN_RECOVER_MISSING_INSTRUMENTATION_OPTION %s
diff --git a/test/IRGen/actor_class.swift b/test/IRGen/actor_class.swift
index b72ab96..540d5b6 100644
--- a/test/IRGen/actor_class.swift
+++ b/test/IRGen/actor_class.swift
@@ -1,10 +1,11 @@
-// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -enable-experimental-concurrency | %target-FileCheck %s
+// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -enable-experimental-concurrency | %IRGenFileCheck %s
 // REQUIRES: concurrency
 
 // rdar_72047158
 // XFAIL: CPU=arm64e
 
-// CHECK: %T11actor_class7MyClassC = type <{ %swift.refcounted, [10 x i8*], %TSi }>
+// CHECK: %T11actor_class7MyClassC = type <{ %swift.refcounted, %swift.defaultactor, %TSi }>
+// CHECK: %swift.defaultactor = type { [10 x i8*] }
 
 // CHECK-objc-LABEL: @"$s11actor_class7MyClassCMm" = global
 // CHECK-objc-SAME: %objc_class* @"OBJC_METACLASS_$__TtCs12_SwiftObject"
@@ -19,10 +20,23 @@
 // CHECK-64-SAME: i32 104,
 // CHECK-32-SAME: i32 52,
 //   Alignment mask
-// CHECK-SAME: i16 15,
+// CHECK-64-SAME: i16 15,
+// CHECK-32-SAME: i16 7,
 //   Field offset for 'x'
 // CHECK-objc-SAME: [[INT]] {{48|96}},
 
+// Type descriptor.
+// CHECK-LABEL: @"$s11actor_class9ExchangerCMn" = {{.*}}constant
+//   superclass ref, negative bounds, positive bounds, num immediate members, num fields, field offset vector offset
+// CHECK-SAME: i32 0, i32 2, i32 [[#CLASS_METADATA_HEADER+9]], i32 9, i32 2, i32 [[#CLASS_METADATA_HEADER+1]],
+
+// Reflection field records.
+// CHECK-LABEL: @"$s11actor_class9ExchangerCMF" = internal constant
+//   Field descriptor kind, field size, num fields,
+//   (artificial var, "BD", ...)
+// CHECK-SAME: i16 1, i16 12, i32 2, i32 6,
+// CHECK-SAME: @"symbolic BD"
+
 public actor class MyClass {
   public var x: Int
   public init() { self.x = 0 }
@@ -36,7 +50,7 @@
 // CHECK-LABEL: define {{.*}}@"$s11actor_class7MyClassC1xSivg"
 // CHECK: [[T0:%.*]] = getelementptr inbounds %T11actor_class7MyClassC, %T11actor_class7MyClassC* %0, i32 0, i32 2
 // CHECK: [[T1:%.*]] = getelementptr inbounds %TSi, %TSi* [[T0]], i32 0, i32 0
-// CHECK: load [[INT]], [[INT]]* [[T1]], align 16
+// CHECK: load [[INT]], [[INT]]* [[T1]], align
 
 // CHECK-LABEL: define {{.*}}swiftcc %T11actor_class7MyClassC* @"$s11actor_class7MyClassCACycfc"
 // CHECK: swift_defaultActor_initialize
@@ -45,3 +59,21 @@
 // CHECK-LABEL: define {{.*}}swiftcc %swift.refcounted* @"$s11actor_class7MyClassCfd"
 // CHECK: swift_defaultActor_destroy
 // CHECK-LABEL: ret
+
+public actor class Exchanger<T> {
+  public var value: T
+
+  public init(value: T) { self.value = value }
+  public func exchange(newValue: T) -> T {
+    let oldValue = value
+    value = newValue
+    return oldValue
+  }
+}
+// CHECK-LABEL: define{{.*}} void @"$s11actor_class9ExchangerC5valuexvg"(
+//   Note that this is one more than the field offset vector offset from
+//   the class descriptor, since this is the second field.
+// CHECK:         [[T0:%.*]] = getelementptr inbounds [[INT]], [[INT]]* {{.*}}, [[INT]] [[#CLASS_METADATA_HEADER+2]]
+// CHECK-NEXT:    [[OFFSET:%.*]] = load [[INT]], [[INT]]* [[T0]], align
+// CHECK-NEXT:    [[T0:%.*]] = bitcast %T11actor_class9ExchangerC* %1 to i8*
+// CHECK-NEXT:    getelementptr inbounds i8, i8* [[T0]], [[INT]] [[OFFSET]]
diff --git a/test/IRGen/actor_class_objc.swift b/test/IRGen/actor_class_objc.swift
index 5e5af0a..ed9a91e 100644
--- a/test/IRGen/actor_class_objc.swift
+++ b/test/IRGen/actor_class_objc.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -enable-experimental-concurrency | %target-FileCheck %s
+// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -enable-experimental-concurrency | %IRGenFileCheck %s
 // REQUIRES: concurrency
 // REQUIRES: objc_interop
 
@@ -7,7 +7,8 @@
 
 import Foundation
 
-// CHECK: %T16actor_class_objc7MyClassC = type <{ %swift.refcounted, [10 x i8*], %TSi }>
+// CHECK: %T16actor_class_objc7MyClassC = type <{ %swift.refcounted, %swift.defaultactor, %TSi }>
+// CHECK: %swift.defaultactor = type { [10 x i8*] }
 
 // CHECK-LABEL: @"OBJC_METACLASS_$__TtC16actor_class_objc7MyClass" = global
 //   Metaclass is an instance of the root class.
@@ -25,7 +26,8 @@
 // CHECK-64-SAME: i32 104,
 // CHECK-32-SAME: i32 52,
 //   Alignment mask
-// CHECK-SAME: i16 15,
+// CHECK-64-SAME: i16 15,
+// CHECK-32-SAME: i16 7,
 //   Field offset for 'x'
 // CHECK-64-SAME: i64 96,
 // CHECK-32-SAME: i32 48,
@@ -42,7 +44,7 @@
 // CHECK-LABEL: define {{.*}} @"$s16actor_class_objc7MyClassC1xSivg"
 // CHECK: [[T0:%.*]] = getelementptr inbounds %T16actor_class_objc7MyClassC, %T16actor_class_objc7MyClassC* %0, i32 0, i32 2
 // CHECK: [[T1:%.*]] = getelementptr inbounds %TSi, %TSi* [[T0]], i32 0, i32 0
-// CHECK: load [[INT]], [[INT]]* [[T1]], align 16
+// CHECK: load [[INT]], [[INT]]* [[T1]], align
 
 // CHECK-LABEL: define {{.*}}swiftcc %T16actor_class_objc7MyClassC* @"$s16actor_class_objc7MyClassCACycfc"
 // CHECK: swift_defaultActor_initialize
diff --git a/test/Interpreter/switch_default.swift b/test/Interpreter/switch_default.swift
new file mode 100644
index 0000000..5880578
--- /dev/null
+++ b/test/Interpreter/switch_default.swift
@@ -0,0 +1,28 @@
+// RUN: %target-run-simple-swift
+
+// REQUIRES: executable_test
+
+import StdlibUnittest
+
+var SwitchDefaultTestSuite = TestSuite("Switch.Default")
+defer { runAllTests() }
+
+class Klass {}
+protocol Protocol {}
+
+enum Enum {
+  case value1(LifetimeTracked)
+  case value2(Protocol)
+}
+
+SwitchDefaultTestSuite.test("do not leak default case payload") {
+  // We are passing in Enum.value1 so we go down the default and leak our
+  // lifetime tracked.
+  func f(_ e: Enum?) {
+    switch (e) {
+    case .value2: return
+    default: return
+    }
+  }
+  f(.value1(LifetimeTracked(0)))
+}
diff --git a/test/SILGen/switch_default.swift b/test/SILGen/switch_default.swift
new file mode 100644
index 0000000..ace48b6
--- /dev/null
+++ b/test/SILGen/switch_default.swift
@@ -0,0 +1,54 @@
+// RUN: %target-swift-emit-silgen -module-name switch_default %s | %FileCheck %s
+
+class Klass {}
+protocol Protocol {}
+
+enum Enum {
+  case value1(Klass)
+  case value2(Protocol)
+}
+
+// CHECK-LABEL: sil hidden [ossa] @$s14switch_default33testAddressOnlySubjectDefaultCaseyyAA4EnumOSgF : $@convention(thin) (@in_guaranteed Optional<Enum>) -> () {
+// CHECK: bb0([[ARG:%.*]] :
+// CHECK:   [[STACK:%.*]] = alloc_stack $Optional<Enum>
+// CHECK:   copy_addr [[ARG]] to [initialization] [[STACK]]
+// CHECK:   switch_enum_addr [[STACK]] : $*Optional<Enum>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]*]], default [[DEFAULT_BB:bb[0-9]*]]
+//
+// CHECK: [[SOME_BB]]:
+// CHECK:    [[STACK_1:%.*]] = alloc_stack $Optional<Enum>
+// CHECK:    copy_addr [[STACK]] to [initialization] [[STACK_1]]
+// CHECK:    [[TAKEN_ADDR:%.*]] = unchecked_take_enum_data_addr [[STACK_1]]
+// CHECK:    switch_enum_addr [[TAKEN_ADDR]] : $*Enum, case #Enum.value2!enumelt: [[VALUE2_BB:bb[0-9]*]], default [[DEFAULT_BB_2:bb[0-9]*]]
+//
+// CHECK: [[VALUE2_BB]]:
+// CHECK:    [[TAKEN_TAKEN_ADDR:%.*]] = unchecked_take_enum_data_addr [[TAKEN_ADDR]]
+// CHECK:    destroy_addr [[TAKEN_TAKEN_ADDR]]
+// CHECK:    dealloc_stack [[STACK_1]]
+// CHECK:    destroy_addr [[STACK]]
+// CHECK:    dealloc_stack [[STACK]]
+// CHECK:    br [[EXIT_BB:bb[0-9]+]]
+//
+// We used to leak here!
+// CHECK: [[DEFAULT_BB_2]]:
+// CHECK:    destroy_addr [[TAKEN_ADDR]]
+// CHECK:    dealloc_stack [[STACK_1]]
+// CHECK:    br [[CONT_BB:bb[0-9]*]]
+//
+// CHECK: [[DEFAULT_BB]]:
+// CHECK:    br [[CONT_BB]]
+//
+// CHECK: [[CONT_BB]]:
+// CHECK:    destroy_addr [[STACK]]
+// CHECK:    dealloc_stack [[STACK]]
+// CHECK:    br [[EXIT_BB]]
+//
+// CHECK: [[EXIT_BB]]:
+// CHECK-NEXT: tuple
+// CHECK-NEXT: return
+// } // end sil function '$s14switch_default33testAddressOnlySubjectDefaultCaseyyAA4EnumOSgF'
+func testAddressOnlySubjectDefaultCase(_ e: Enum?) {
+  switch (e) {
+  case .value2: return
+  default: return
+  }
+}
diff --git a/test/expr/unary/async_await.swift b/test/expr/unary/async_await.swift
index 812e3df..b2fa40d 100644
--- a/test/expr/unary/async_await.swift
+++ b/test/expr/unary/async_await.swift
@@ -165,12 +165,9 @@
   } catch {
   }
 
-  async let x1 = getIntUnsafely() // expected-error{{call can throw but is not marked with 'try'}}
-  // expected-note@-1{{did you mean to use 'try'}}
-  // expected-note@-2{{did you mean to handle error as optional value?}}
-  // expected-note@-3{{did you mean to disable error propagation?}}
+  async let x1 = getIntUnsafely() // okay, try is implicit here
 
-  async let x2 = getInt() // expected-error{{call is 'async' in an 'async let' initializer that is not marked with 'await'}}
+  async let x2 = getInt() // okay, await is implicit here
 
   async let x3 = try getIntUnsafely()
   async let x4 = try! getIntUnsafely()
diff --git a/test/lit.cfg b/test/lit.cfg
index 49fdf74..7c7951a 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -2146,9 +2146,18 @@
   config.substitutions.append( ('%diff', 'diff') )
   config.substitutions.append( ('%long-tmp', '%t') )
 
+# Compute the size of the Swift class metadata header in words.
+run_class_metadata_header_size = 2
+if run_objc_interop == 'objc':
+  run_class_metadata_header_size = 5
+if run_ptrsize == '64':
+  run_class_metadata_header_size = run_class_metadata_header_size + 5
+else:
+  run_class_metadata_header_size = run_class_metadata_header_size + 8
+
 # A FileCheck that automatically supports a large variety of target
-# conditionalization.
-run_target_filecheck = '%s --check-prefix=CHECK --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s -DINT=i%s' % (
+# conditionalization that's useful in IRGen.
+IRGenFileCheck = '%s --check-prefix=CHECK --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s --check-prefix=CHECK-%s -DINT=i%s -D#CLASS_METADATA_HEADER=%s' % (
         run_filecheck,
         run_os,
         run_cpu,
@@ -2156,8 +2165,9 @@
         run_ptrsize,
         run_ptrauth,
         run_objc_interop,
-        run_ptrsize)
-config.substitutions.append( ('%target-FileCheck', run_target_filecheck) )
+        run_ptrsize,
+        run_class_metadata_header_size)
+config.substitutions.append( ('%IRGenFileCheck', IRGenFileCheck) )
 
 visual_studio_version = os.environ.get('VisualStudioVersion')
 if kIsWindows and visual_studio_version:
diff --git a/tools/swift-dependency-tool/swift-dependency-tool.cpp b/tools/swift-dependency-tool/swift-dependency-tool.cpp
index 625ac60..d773eb2 100644
--- a/tools/swift-dependency-tool/swift-dependency-tool.cpp
+++ b/tools/swift-dependency-tool/swift-dependency-tool.cpp
@@ -69,7 +69,7 @@
     os << fp.getRawValue();
   }
   static StringRef input(StringRef s, void *, swift::Fingerprint &fp) {
-    fp = swift::Fingerprint{s.str()};
+    fp = swift::Fingerprint::fromString(s);
     return StringRef();
   }
   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
diff --git a/unittests/Driver/MockingFineGrainedDependencyGraphs.cpp b/unittests/Driver/MockingFineGrainedDependencyGraphs.cpp
index b979db3..502e194 100644
--- a/unittests/Driver/MockingFineGrainedDependencyGraphs.cpp
+++ b/unittests/Driver/MockingFineGrainedDependencyGraphs.cpp
@@ -45,7 +45,7 @@
   assert(!swiftDeps.empty());
   swiftDeps.resize(Fingerprint::DIGEST_LENGTH, 'X');
   auto interfaceHash =
-    interfaceHashIfNonEmpty.getValueOr(Fingerprint{swiftDeps});
+    interfaceHashIfNonEmpty.getValueOr(Fingerprint::fromString(swiftDeps));
 
   SourceManager sm;
   DiagnosticEngine diags(sm);
diff --git a/unittests/Driver/UnitTestSourceFileDepGraphFactory.cpp b/unittests/Driver/UnitTestSourceFileDepGraphFactory.cpp
index 27adf39..6352f7d 100644
--- a/unittests/Driver/UnitTestSourceFileDepGraphFactory.cpp
+++ b/unittests/Driver/UnitTestSourceFileDepGraphFactory.cpp
@@ -57,7 +57,7 @@
   fingerprintString.resize(Fingerprint::DIGEST_LENGTH, 'X');
   const Optional<Fingerprint> fingerprint = fingerprintString.empty()
                                               ? Optional<Fingerprint>()
-                                              : Fingerprint{fingerprintString};
+                                              : Fingerprint::fromString(fingerprintString);
 
   AbstractSourceFileDepGraphFactory::addADefinedDecl(key.getValue(),
                                                      fingerprint);