Merge pull request #17729 from DougGregor/minimize-override-checking

[Type checker] Minimize checking needed to compute the set of overridden declarations
diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h
index 0b918ff..95d842a 100644
--- a/include/swift/AST/ASTScope.h
+++ b/include/swift/AST/ASTScope.h
@@ -489,11 +489,14 @@
   /// introduced by this statement.
   static ASTScope *createIfNeeded(const ASTScope *parent, Stmt *stmt);
 
-  /// Create a new AST scope if one is needed for the given expression.
+  /// Create a new AST scope if one is needed for the given child expression(s).
+  /// In the first variant, the expression can be \c null.
   ///
   /// \returns the newly-created AST scope, or \c null if there is no scope
   /// introduced by this expression.
-  static ASTScope *createIfNeeded(const ASTScope *parent, Expr *Expr);
+  static ASTScope *createIfNeeded(const ASTScope *parent, Expr *expr);
+  static ASTScope *createIfNeeded(const ASTScope *parent,
+                                  ArrayRef<Expr *> exprs);
 
   /// Create a new AST scope if one is needed for the given AST node.
   ///
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 2edbebf..e33843d 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -4134,6 +4134,9 @@
   /// is a member.  Currently only variables can be static.
   inline bool isStatic() const; // defined in this header
 
+  /// \brief Return the interface type of the stored value.
+  Type getValueInterfaceType() const;
+
   /// \brief Determine how this storage is implemented.
   StorageImplInfo getImplInfo() const {
     if (auto ptr = Accessors.getPointer())
diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def
index ddaaa02..37cc113 100644
--- a/include/swift/AST/DiagnosticsDriver.def
+++ b/include/swift/AST/DiagnosticsDriver.def
@@ -155,10 +155,6 @@
         "the option '-driver-use-filelists' is deprecated; use "
         "'-driver-filelist-threshold=0' instead", ())
 
-WARNING(warn_emit_public_type_metadata_accessors_deprecated, none,
-        "the option '-emit-public-type-metadata-accessors' is no longer "
-        "needed and is deprecated; consider removing it", ())
-
 ERROR(cannot_find_migration_script, none,
       "missing migration script from path '%0'", (StringRef))
 
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 8e2a5b9..1f76292 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -686,8 +686,8 @@
 ERROR(use_unresolved_identifier,none,
       "use of unresolved %select{identifier|operator}1 %0", (DeclName, bool))
 ERROR(use_unresolved_identifier_corrected,none,
-      "use of unresolved %select{identifier|operator}1 %0; did you mean %2?",
-      (DeclName, bool, DeclName))
+      "use of unresolved %select{identifier|operator}1 %0; did you mean '%2'?",
+      (DeclName, bool, StringRef))
 NOTE(confusable_character,none,
       "%select{identifier|operator}0 '%1' contains possibly confused characters; "
       "did you mean to use '%2'?",
diff --git a/include/swift/AST/ExistentialLayout.h b/include/swift/AST/ExistentialLayout.h
index 7610fcc..3126fd4 100644
--- a/include/swift/AST/ExistentialLayout.h
+++ b/include/swift/AST/ExistentialLayout.h
@@ -37,8 +37,8 @@
   ExistentialLayout(ProtocolType *type);
   ExistentialLayout(ProtocolCompositionType *type);
 
-  /// The superclass constraint, if any.
-  Type superclass;
+  /// The explicit superclass constraint, if any.
+  Type explicitSuperclass;
 
   /// Whether the existential contains an explicit '& AnyObject' constraint.
   bool hasExplicitAnyObject : 1;
@@ -50,7 +50,9 @@
 
   bool isObjC() const {
     // FIXME: Does the superclass have to be @objc?
-    return ((superclass || hasExplicitAnyObject || !getProtocols().empty()) &&
+    return ((explicitSuperclass ||
+             hasExplicitAnyObject ||
+             !getProtocols().empty()) &&
             !containsNonObjCProtocol);
   }
 
@@ -58,11 +60,16 @@
   /// '& AnyObject' member or because of a superclass or protocol constraint.
   bool requiresClass() const;
 
-  // Does this existential contain the Error protocol?
+  /// Returns the existential's superclass, if any; this is either an explicit
+  /// superclass term in a composition type, or the superclass of one of the
+  /// protocols.
+  Type getSuperclass() const;
+
+  /// Does this existential contain the Error protocol?
   bool isExistentialWithError(ASTContext &ctx) const;
 
-  // Does this existential consist of an Error protocol only with no other
-  // constraints?
+  /// Does this existential consist of an Error protocol only with no other
+  /// constraints?
   bool isErrorExistential() const;
 
   static inline ProtocolType *getProtocolType(const Type &Ty) {
diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h
index 1ae9020..0f665db 100644
--- a/include/swift/AST/Module.h
+++ b/include/swift/AST/Module.h
@@ -151,7 +151,7 @@
   };
 
 private:
-  /// If non-NULL, an plug-in that should be used when performing external
+  /// If non-NULL, a plug-in that should be used when performing external
   /// lookups.
   // FIXME: Do we really need to bloat all modules with this?
   DebuggerClient *DebugClient = nullptr;
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 7bb1322..2238b0a 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -358,11 +358,6 @@
   Alias<warn_swift3_objc_inference_complete>,
   Flags<[FrontendOption, DoesNotAffectIncrementalBuild, HelpHidden]>;
 
-def emit_public_type_metadata_accessors :
-  Flag<["-"], "emit-public-type-metadata-accessors">,
-  Flags<[FrontendOption]>,
-  HelpText<"Emit all type metadata accessors as public (deprecated: now does nothing)">;
-
 def Rpass_EQ : Joined<["-"], "Rpass=">,
   Flags<[FrontendOption]>,
   HelpText<"Report performed transformations by optimization passes whose "
diff --git a/include/swift/Runtime/Config.h b/include/swift/Runtime/Config.h
index 2113157..dd83b7c 100644
--- a/include/swift/Runtime/Config.h
+++ b/include/swift/Runtime/Config.h
@@ -17,8 +17,79 @@
 #ifndef SWIFT_RUNTIME_CONFIG_H
 #define SWIFT_RUNTIME_CONFIG_H
 
-// Bring in visibility attribute macros for library visibility.
-#include "llvm/Support/Compiler.h"
+/// \macro SWIFT_RUNTIME_GNUC_PREREQ
+/// Extend the default __GNUC_PREREQ even if glibc's features.h isn't
+/// available.
+#ifndef SWIFT_RUNTIME_GNUC_PREREQ
+# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+#  define SWIFT_RUNTIME_GNUC_PREREQ(maj, min, patch) \
+    ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
+     ((maj) << 20) + ((min) << 10) + (patch))
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__)
+#  define SWIFT_RUNTIME_GNUC_PREREQ(maj, min, patch) \
+    ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
+# else
+#  define SWIFT_RUNTIME_GNUC_PREREQ(maj, min, patch) 0
+# endif
+#endif
+
+/// SWIFT_RUNTIME_LIBRARY_VISIBILITY - If a class marked with this attribute is
+/// linked into a shared library, then the class should be private to the
+/// library and not accessible from outside it.  Can also be used to mark
+/// variables and functions, making them private to any shared library they are
+/// linked into.
+/// On PE/COFF targets, library visibility is the default, so this isn't needed.
+#if (__has_attribute(visibility) || SWIFT_RUNTIME_GNUC_PREREQ(4, 0, 0)) &&    \
+    !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_WIN32)
+#define SWIFT_RUNTIME_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
+#else
+#define SWIFT_RUNTIME_LIBRARY_VISIBILITY
+#endif
+
+/// Attributes.
+/// SWIFT_RUNTIME_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
+/// mark a method "not for inlining".
+#if __has_attribute(noinline) || SWIFT_RUNTIME_GNUC_PREREQ(3, 4, 0)
+#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER)
+#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE __declspec(noinline)
+#else
+#define SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
+#endif
+
+/// SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
+/// so, mark a method "always inline" because it is performance sensitive. GCC
+/// 3.4 supported this but is buggy in various cases and produces unimplemented
+/// errors, just use it in GCC 4.0 and later.
+#if __has_attribute(always_inline) || SWIFT_RUNTIME_GNUC_PREREQ(4, 0, 0)
+#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
+#elif defined(_MSC_VER)
+#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE __forceinline
+#else
+#define SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+#ifdef __GNUC__
+#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN __declspec(noreturn)
+#else
+#define SWIFT_RUNTIME_ATTRIBUTE_NORETURN
+#endif
+
+/// SWIFT_RUNTIME_BUILTIN_TRAP - On compilers which support it, expands to an expression
+/// which causes the program to exit abnormally.
+#if __has_builtin(__builtin_trap) || SWIFT_RUNTIME_GNUC_PREREQ(4, 3, 0)
+# define SWIFT_RUNTIME_BUILTIN_TRAP __builtin_trap()
+#elif defined(_MSC_VER)
+// The __debugbreak intrinsic is supported by MSVC, does not require forward
+// declarations involving platform-specific typedefs (unlike RaiseException),
+// results in a call to vectored exception handlers, and encodes to a short
+// instruction that still causes the trapping behavior we want.
+# define SWIFT_RUNTIME_BUILTIN_TRAP __debugbreak()
+#else
+# define SWIFT_RUNTIME_BUILTIN_TRAP *(volatile int*)0x11 = 0
+#endif
 
 /// Does the current Swift platform support "unbridged" interoperation
 /// with Objective-C?  If so, the implementations of various types must
diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h
index 0ecc8f8..9c5de7b 100644
--- a/include/swift/Runtime/Debug.h
+++ b/include/swift/Runtime/Debug.h
@@ -17,7 +17,6 @@
 #ifndef _SWIFT_RUNTIME_DEBUG_HELPERS_
 #define _SWIFT_RUNTIME_DEBUG_HELPERS_
 
-#include <llvm/Support/Compiler.h>
 #include <cstdarg>
 #include <cstdio>
 #include <stdint.h>
@@ -41,23 +40,23 @@
 };
 
 extern "C" {
-LLVM_LIBRARY_VISIBILITY
+SWIFT_RUNTIME_LIBRARY_VISIBILITY
 extern struct crashreporter_annotations_t gCRAnnotations;
 }
 
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
 static inline void CRSetCrashLogMessage(const char *message) {
   gCRAnnotations.message = reinterpret_cast<uint64_t>(message);
 }
 
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
 static inline const char *CRGetCrashLogMessage() {
   return reinterpret_cast<const char *>(gCRAnnotations.message);
 }
 
 #else
 
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
 static inline void CRSetCrashLogMessage(const char *) {}
 
 #endif
@@ -73,18 +72,18 @@
 // swift::crash() halts with a crash log message, 
 // but otherwise tries not to disturb register state.
 
-LLVM_ATTRIBUTE_NORETURN
-LLVM_ATTRIBUTE_ALWAYS_INLINE // Minimize trashed registers
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE // Minimize trashed registers
 static inline void crash(const char *message) {
   CRSetCrashLogMessage(message);
 
-  LLVM_BUILTIN_TRAP;
+  SWIFT_RUNTIME_BUILTIN_TRAP;
   swift_runtime_unreachable("Expected compiler to crash.");
 }
 
 // swift::fatalError() halts with a crash log message, 
 // but makes no attempt to preserve register state.
-LLVM_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
 extern void
 fatalError(uint32_t flags, const char *format, ...);
 
@@ -94,7 +93,7 @@
 
 // swift_dynamicCastFailure halts using fatalError()
 // with a description of a failed cast's types.
-LLVM_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
 void
 swift_dynamicCastFailure(const Metadata *sourceType,
                          const Metadata *targetType,
@@ -102,7 +101,7 @@
 
 // swift_dynamicCastFailure halts using fatalError()
 // with a description of a failed cast's types.
-LLVM_ATTRIBUTE_NORETURN
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
 void
 swift_dynamicCastFailure(const void *sourceType, const char *sourceName, 
                          const void *targetType, const char *targetName, 
@@ -112,19 +111,19 @@
 void swift_reportError(uint32_t flags, const char *message);
 
 // Halt due to an overflow in swift_retain().
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
 void swift_abortRetainOverflow();
 
 // Halt due to reading an unowned reference to a dead object.
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
 void swift_abortRetainUnowned(const void *object);
 
 // Halt due to an overflow in swift_unownedRetain().
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
 void swift_abortUnownedRetainOverflow();
 
 // Halt due to an overflow in incrementWeak().
-LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
 void swift_abortWeakRetainOverflow();
 
 /// This function dumps one line of a stack trace. It is assumed that \p framePC
@@ -134,7 +133,7 @@
 void dumpStackTraceEntry(unsigned index, void *framePC,
                          bool shortOutput = false);
 
-LLVM_ATTRIBUTE_NOINLINE
+SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
 void printCurrentBacktrace(unsigned framesToSkip = 1);
 
 /// Debugger breakpoint ABI. This structure is passed to the debugger (and needs
@@ -221,7 +220,7 @@
 bool _swift_shouldReportFatalErrorsToDebugger();
 
 
-LLVM_ATTRIBUTE_ALWAYS_INLINE
+SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
 inline static int swift_asprintf(char **strp, const char *fmt, ...) {
   va_list args;
   va_start(args, fmt);
diff --git a/include/swift/Runtime/Heap.h b/include/swift/Runtime/Heap.h
index 6ff7558..4f9e3c8 100644
--- a/include/swift/Runtime/Heap.h
+++ b/include/swift/Runtime/Heap.h
@@ -17,6 +17,4 @@
 #ifndef SWIFT_RUNTIME_HEAP_H
 #define SWIFT_RUNTIME_HEAP_H
 
-#include <llvm/Support/Compiler.h>
-
 #endif /* SWIFT_RUNTIME_HEAP_H */
diff --git a/include/swift/Runtime/Unreachable.h b/include/swift/Runtime/Unreachable.h
index 671e261..4147d4c 100644
--- a/include/swift/Runtime/Unreachable.h
+++ b/include/swift/Runtime/Unreachable.h
@@ -18,11 +18,12 @@
 #ifndef SWIFT_RUNTIME_UNREACHABLE_H
 #define SWIFT_RUNTIME_UNREACHABLE_H
 
-#include "llvm/Support/Compiler.h"
 #include <assert.h>
 #include <stdlib.h>
 
-LLVM_ATTRIBUTE_NORETURN
+#include "swift/Runtime/Config.h"
+
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN
 inline static void swift_runtime_unreachable(const char *msg) {
   assert(false && msg);
   (void)msg;
diff --git a/include/swift/SIL/Projection.h b/include/swift/SIL/Projection.h
index 8566f70..eace9a2 100644
--- a/include/swift/SIL/Projection.h
+++ b/include/swift/SIL/Projection.h
@@ -78,7 +78,7 @@
 /// TypeAlignments.h.
 ///
 /// Projection Kinds which can be represented via indices can use as many bits
-/// as they want to represent the kind. When the index value is uses at most 11
+/// as they want to represent the kind. When the index value uses at most 11
 /// bits, we represent it inline in the data structure. This is taking advantage
 /// of the fact that on most modern OSes (including Darwin), the zero page is
 /// not allocated. In the case where we have more than 11 bits of value
diff --git a/include/swift/SILOptimizer/Analysis/CallerAnalysis.h b/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
index e1eb98c..375c06e 100644
--- a/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
@@ -40,49 +40,9 @@
 /// In addition of caller information this analysis also provides information
 /// about partial applies of a function.
 class CallerAnalysis : public SILAnalysis {
-
 public:
+  class FunctionInfo;
 
-  /// NOTE: this can be extended to contain the callsites of the function.
-  class FunctionInfo {
-    friend class CallerAnalysis;
-
-    /// A list of all the functions this function calls or partially applies.
-    llvm::SetVector<SILFunction *> Callees;
-    /// A list of all the callers this function has.
-    llvm::SmallSet<SILFunction *, 4> Callers;
-
-    /// The number of partial applied arguments of this function.
-    ///
-    /// Specifically, it stores the minimum number of partial applied arguments
-    /// of each function which contain one or multiple partial_applys of this
-    /// function.
-    /// This is a little bit off-topic because a partial_apply is not really
-    /// a "call" of this function.
-    llvm::DenseMap<SILFunction *, int> PartialAppliers;
-
-  public:
-    /// Returns true if this function has at least one caller.
-    bool hasCaller() const {
-      return !Callers.empty();
-    }
-
-    /// Returns non zero if this function is partially applied anywhere.
-    ///
-    /// The return value is the minimum number of partially applied arguments.
-    /// Usually all partial applies of a function partially apply the same
-    /// number of arguments anyway.
-    int getMinPartialAppliedArgs() const {
-      int minArgs = 0;
-      for (auto Iter : PartialAppliers) {
-        int numArgs = Iter.second;
-        if (minArgs == 0 || numArgs < minArgs)
-          minArgs = numArgs;
-      }
-      return minArgs;
-    }
-  };
-  
 private:
   /// Current module we are analyzing.
   SILModule &Mod;
@@ -167,6 +127,44 @@
   }
 };
 
+/// NOTE: this can be extended to contain the callsites of the function.
+class CallerAnalysis::FunctionInfo {
+  friend class CallerAnalysis;
+
+  /// A list of all the functions this function calls or partially applies.
+  llvm::SetVector<SILFunction *> Callees;
+  /// A list of all the callers this function has.
+  llvm::SmallSet<SILFunction *, 4> Callers;
+
+  /// The number of partial applied arguments of this function.
+  ///
+  /// Specifically, it stores the minimum number of partial applied arguments
+  /// of each function which contain one or multiple partial_applys of this
+  /// function.
+  /// This is a little bit off-topic because a partial_apply is not really
+  /// a "call" of this function.
+  llvm::DenseMap<SILFunction *, int> PartialAppliers;
+
+public:
+  /// Returns true if this function has at least one caller.
+  bool hasCaller() const { return !Callers.empty(); }
+
+  /// Returns non zero if this function is partially applied anywhere.
+  ///
+  /// The return value is the minimum number of partially applied arguments.
+  /// Usually all partial applies of a function partially apply the same
+  /// number of arguments anyway.
+  int getMinPartialAppliedArgs() const {
+    int minArgs = 0;
+    for (auto Iter : PartialAppliers) {
+      int numArgs = Iter.second;
+      if (minArgs == 0 || numArgs < minArgs)
+        minArgs = numArgs;
+    }
+    return minArgs;
+  }
+};
+
 } // end namespace swift
 
 #endif
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 9f3a625..7cf2c52 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4148,19 +4148,20 @@
     protos.push_back(proto->getDecl());
 
   auto layoutConstraint = layout.getLayoutConstraint();
+  auto layoutSuperclass = layout.getSuperclass();
 
   auto arena = AllocationArena::Permanent;
   void *mem = ctx.Allocate(
       totalSizeToAlloc<ProtocolDecl *, Type, LayoutConstraint, UUID>(
       protos.size(),
-      layout.superclass ? 1 : 0,
+      layoutSuperclass ? 1 : 0,
       layoutConstraint ? 1 : 0, 1),
       alignof(ArchetypeType), arena);
 
   // FIXME: Pass in class layout constraint
   auto result =
       ::new (mem) ArchetypeType(ctx, existential,
-                                protos, layout.superclass,
+                                protos, layoutSuperclass,
                                 layoutConstraint, *knownID);
   openedExistentialArchetypes[*knownID] = result;
 
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 08ae82e..654992e 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -654,7 +654,7 @@
     assert(((relatedEntityKind[0] >= 'a' && relatedEntityKind[0] <= 'j') ||
             (relatedEntityKind[0] >= 'A' && relatedEntityKind[0] <= 'J')) &&
            "Only [a-jA-J] are reserved for related entity kinds");
-    return appendOperatorParam("L", synthesizedTypeAttr->getManglingName());
+    return appendOperatorParam("L", relatedEntityKind);
   }
 
   StringRef privateDiscriminator = getPrivateDiscriminatorIfNecessary(decl);
@@ -838,8 +838,8 @@
       if (First)
         appendOperator("y");
 
-      if (layout.superclass) {
-        appendType(layout.superclass);
+      if (auto superclass = layout.explicitSuperclass) {
+        appendType(superclass);
         return appendOperator("Xc");
       } else if (layout.hasExplicitAnyObject) {
         return appendOperator("Xl");
diff --git a/lib/AST/ASTScope.cpp b/lib/AST/ASTScope.cpp
index b13f137..41d83f8 100644
--- a/lib/AST/ASTScope.cpp
+++ b/lib/AST/ASTScope.cpp
@@ -1070,9 +1070,8 @@
 }
 
 /// Find all of the (non-nested) closures referenced within this expression.
-static SmallVector<ClosureExpr *, 4> findClosures(Expr *expr) {
-  SmallVector<ClosureExpr *, 4> closures;
-  if (!expr) return closures;
+static void findClosures(Expr *expr, SmallVectorImpl<ClosureExpr *> &closures) {
+  if (!expr) return;
 
   /// AST walker that finds top-level closures in an expression.
   class ClosureFinder : public ASTWalker {
@@ -1110,14 +1109,20 @@
   };
 
   expr->walk(ClosureFinder(closures));
-  return closures;
 }
 
 ASTScope *ASTScope::createIfNeeded(const ASTScope *parent, Expr *expr) {
   if (!expr) return nullptr;
+  return createIfNeeded(parent, llvm::makeArrayRef(expr));
+}
 
-  // Dig out closure expressions within the given expression.
-  auto closures = findClosures(expr);
+ASTScope *ASTScope::createIfNeeded(const ASTScope *parent,
+                                   ArrayRef<Expr *> exprs) {
+  SmallVector<ClosureExpr*, 4> closures;
+
+  // Dig out closure expressions within the given expressions.
+  for (auto expr: exprs)
+    findClosures(expr, closures);
   if (closures.empty())
     return nullptr;
 
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 4b70ec6..0d95ad2 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -934,6 +934,7 @@
     void verifyChecked(DeferStmt *S) {
       auto FT = S->getTempDecl()->getInterfaceType()->castTo<AnyFunctionType>();
       assert(FT->isNoEscape() && "Defer statements must not escape");
+      (void)FT;
       verifyCheckedBase(S);
     }
 
@@ -1251,7 +1252,7 @@
       }
 
       auto layout = srcTy->getExistentialLayout();
-      if (layout.superclass ||
+      if (layout.explicitSuperclass ||
           !layout.isObjC() ||
           layout.getProtocols().size() != 1) {
         Out << "ProtocolMetatypeToObject with non-ObjC-protocol metatype:\n";
diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp
index 26a286c..50209f9 100644
--- a/lib/AST/ConformanceLookupTable.cpp
+++ b/lib/AST/ConformanceLookupTable.cpp
@@ -246,7 +246,7 @@
         }
         if (inheritedType->isExistentialType()) {
           auto layout = inheritedType->getExistentialLayout();
-          if (layout.superclass) {
+          if (layout.explicitSuperclass) {
             superclassLoc = inherited.getSourceRange().Start;
             return superclassLoc;
           }
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 7b47141..6824d87 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3394,6 +3394,10 @@
         return true;
       }
     }
+    if (type->getClassOrBoundGenericClass()) {
+      Bits.ProtocolDecl.RequiresClass = true;
+      return true;
+    }
   }
 
   return Bits.ProtocolDecl.RequiresClass;
@@ -4067,6 +4071,12 @@
   return SourceLoc();
 }
 
+Type AbstractStorageDecl::getValueInterfaceType() const {
+  if (auto var = dyn_cast<VarDecl>(this))
+    return var->getInterfaceType();
+  return cast<SubscriptDecl>(this)->getElementInterfaceType();
+}
+
 Type VarDecl::getType() const {
   if (!typeInContext) {
     const_cast<VarDecl *>(this)->typeInContext =
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 683bcd6..c117271 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1544,6 +1544,7 @@
   assert((Implicit || ElementNames.size() == ElementNameLocs.size() ||
           (!hasNonEmptyIdentifier(ElementNames) && ElementNameLocs.empty())) &&
          "trying to create non-implicit tuple-expr without name locations");
+  (void)hasNonEmptyIdentifier;
 
   size_t size =
       totalSizeToAlloc<Expr *, Identifier, SourceLoc>(SubExprs.size(),
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 3941a3f..2b4b83c 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -4788,9 +4788,9 @@
         anyErrors = true;
     }
 
-    if (layout.superclass) {
+    if (auto superclass = layout.explicitSuperclass) {
       if (isErrorResult(addSuperclassRequirementDirect(resolvedSubject,
-                                                       layout.superclass,
+                                                       superclass,
                                                        source)))
         anyErrors = true;
     }
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 0f40db1..4ddf34d 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -611,15 +611,29 @@
 
     // If the existential is class-constrained, the class might conform
     // concretely.
-    if (layout.superclass) {
-      if (auto result = lookupConformance(layout.superclass, protocol))
+    if (auto superclass = layout.explicitSuperclass) {
+      if (auto result = lookupConformance(superclass, protocol))
         return result;
     }
 
     // Otherwise, the existential might conform abstractly.
     for (auto proto : layout.getProtocols()) {
       auto *protoDecl = proto->getDecl();
-      if (protoDecl == protocol || protoDecl->inheritsFrom(protocol))
+
+      // If we found the protocol we're looking for, return an abstract
+      // conformance to it.
+      if (protoDecl == protocol)
+        return ProtocolConformanceRef(protocol);
+
+      // If the protocol has a superclass constraint, we might conform
+      // concretely.
+      if (auto superclass = protoDecl->getSuperclass()) {
+        if (auto result = lookupConformance(superclass, protocol))
+          return result;
+      }
+
+      // Now check refined protocols.
+      if (protoDecl->inheritsFrom(protocol))
         return ProtocolConformanceRef(protocol);
     }
 
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 888fb6a..291acc9 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -1728,8 +1728,8 @@
         stack.push_back(proto);
 
     // Look into the superclasses of this archetype.
-    if (auto superclassTy = archetypeTy->getSuperclass())
-      if (auto superclassDecl = superclassTy->getAnyNominal())
+    if (auto superclass = archetypeTy->getSuperclass())
+      if (auto superclassDecl = superclass->getClassOrBoundGenericClass())
         if (visited.insert(superclassDecl).second)
           stack.push_back(superclassDecl);
   }
@@ -1747,8 +1747,8 @@
         stack.push_back(protoDecl);
     }
 
-    if (layout.superclass) {
-      auto *nominalDecl = layout.superclass->getAnyNominal();
+    if (auto superclass = layout.explicitSuperclass) {
+      auto *nominalDecl = superclass->getClassOrBoundGenericClass();
       if (visited.insert(nominalDecl).second)
         stack.push_back(nominalDecl);
     }
@@ -1843,13 +1843,18 @@
       }
 
       if (visitSuperclass) {
-        if (auto superclassType = classDecl->getSuperclass())
-          if (auto superclassDecl = superclassType->getClassOrBoundGenericClass())
-            if (visited.insert(superclassDecl).second)
-              stack.push_back(superclassDecl);
+        if (auto superclassDecl = classDecl->getSuperclassDecl())
+          if (visited.insert(superclassDecl).second)
+            stack.push_back(superclassDecl);
       }
     }
 
+    if (auto protocolDecl = dyn_cast<ProtocolDecl>(current)) {
+      if (auto superclassDecl = protocolDecl->getSuperclassDecl())
+        if (visited.insert(superclassDecl).second)
+          stack.push_back(superclassDecl);
+    }
+
     // If we're not looking at a protocol and we're not supposed to
     // visit the protocols that this type conforms to, skip the next
     // step.
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 01db66d..056ffa9 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -257,7 +257,7 @@
   auto members = type->getMembers();
   if (!members.empty() &&
       isa<ClassDecl>(members[0]->getAnyNominal())) {
-    superclass = members[0];
+    explicitSuperclass = members[0];
     members = members.slice(1);
   }
 
@@ -284,7 +284,7 @@
 }
 
 bool ExistentialLayout::requiresClass() const {
-  if (hasExplicitAnyObject || superclass)
+  if (hasExplicitAnyObject || explicitSuperclass)
     return true;
 
   for (auto proto : getProtocols()) {
@@ -295,8 +295,20 @@
   return false;
 }
 
+Type ExistentialLayout::getSuperclass() const {
+  if (explicitSuperclass)
+    return explicitSuperclass;
+
+  for (auto proto : getProtocols()) {
+    if (auto superclass = proto->getSuperclass())
+      return superclass;
+  }
+
+  return Type();
+}
+
 bool ExistentialLayout::isAnyObject() const {
-  return (hasExplicitAnyObject && !superclass && getProtocols().empty());
+  return (hasExplicitAnyObject && !explicitSuperclass && getProtocols().empty());
 }
 
 bool TypeBase::isObjCExistentialType() {
@@ -624,7 +636,7 @@
 bool ExistentialLayout::isErrorExistential() const {
   auto protocols = getProtocols();
   return (!hasExplicitAnyObject &&
-          !superclass &&
+          !explicitSuperclass &&
           protocols.size() == 1 &&
           protocols[0]->getDecl()->isSpecificProtocol(KnownProtocolKind::Error));
 }
@@ -785,7 +797,17 @@
                                             parenTy->getParameterFlags()));
     return result;
   }
-    
+
+  // If `Void` has been explicitly specified, resulting decomposition
+  // should be empty, just like empty tuple would be.
+  case TypeKind::NameAlias: {
+    auto &ctx = type->getASTContext();
+    auto *typealias = cast<NameAliasType>(type.getPointer());
+    if (typealias->getDecl() == ctx.getVoidDecl())
+      return result;
+    break;
+  }
+
   default:
     // Default behavior below; inject the argument as the sole parameter.
     break;
@@ -1443,8 +1465,11 @@
     if (auto dynamicSelfTy = getAs<DynamicSelfType>())
       return dynamicSelfTy->getSelfType();
 
+    if (auto protocolTy = getAs<ProtocolType>())
+      return protocolTy->getDecl()->getSuperclass();
+
     if (auto compositionTy = getAs<ProtocolCompositionType>())
-      return compositionTy->getExistentialLayout().superclass;
+      return compositionTy->getExistentialLayout().getSuperclass();
 
     // No other types have superclasses.
     return Type();
@@ -1848,8 +1873,8 @@
   if (type->isExistentialType()) {
     auto layout = type->getExistentialLayout();
     if (layout.isObjC() &&
-        (!layout.superclass ||
-         getObjCObjectRepresentable(layout.superclass, dc) ==
+        (!layout.explicitSuperclass ||
+         getObjCObjectRepresentable(layout.explicitSuperclass, dc) ==
            ForeignRepresentableKind::Object))
       return ForeignRepresentableKind::Object;
   }
@@ -3186,7 +3211,7 @@
     } else if (auto dynamicSelfTy = t->getAs<DynamicSelfType>()) {
       return dynamicSelfTy->getSelfType();
     } else if (auto compositionTy = t->getAs<ProtocolCompositionType>()) {
-      return compositionTy->getExistentialLayout().superclass;
+      return compositionTy->getExistentialLayout().explicitSuperclass;
     }
   }
   return t;
@@ -4086,8 +4111,8 @@
   case TypeKind::ProtocolComposition: {
     auto layout = getExistentialLayout();
     assert(layout.requiresClass() && "Opaque existentials don't use refcounting");
-    if (layout.superclass)
-      return layout.superclass->usesNativeReferenceCounting(resilience);
+    if (auto superclass = layout.getSuperclass())
+      return superclass->usesNativeReferenceCounting(resilience);
     return ::doesOpaqueClassUseNativeReferenceCounting(type->getASTContext());
   }
 
diff --git a/lib/Basic/Unix/TaskQueue.inc b/lib/Basic/Unix/TaskQueue.inc
index ecdd37f..07410f9 100644
--- a/lib/Basic/Unix/TaskQueue.inc
+++ b/lib/Basic/Unix/TaskQueue.inc
@@ -556,6 +556,7 @@
   assert((events & POLLNVAL) == 0 && "Asked poll() to watch a closed fd");
   const short expectedEvents = POLLIN | POLLPRI | POLLHUP | POLLERR;
   assert((events & ~expectedEvents) == 0 && "Received unexpected event");
+  (void)expectedEvents;
 }
 
 void TaskMonitor::readDataIfAvailable(const short events, const int fd,
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 981d2d3..dcf69ff 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -6399,11 +6399,10 @@
   if (!decl->getDeclContext()->isTypeContext())
     return;
 
-  auto classTy = decl->getDeclContext()->getDeclaredInterfaceType()
-      ->getAs<ClassType>();
-  if (!classTy)
+  auto classDecl = decl->getDeclContext()->getAsClassOrClassExtensionContext();
+  if (!classDecl)
     return;
-  auto superTy = classTy->getSuperclass();
+  auto superTy = classDecl->getSuperclass();
   if (!superTy)
     return;
   // Dig out the Objective-C superclass.
@@ -7909,6 +7908,7 @@
 
   const ProtocolDecl *proto = conformance->getProtocol();
   assert(origBase->isEqual(proto->getSelfInterfaceType()));
+  (void)proto;
   return conformance->getTypeWitness(depMemTy->getAssocType(),
                                      /*resolver=*/nullptr);
 }
diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h
index 324fb81..2286d35 100644
--- a/lib/ClangImporter/ImporterImpl.h
+++ b/lib/ClangImporter/ImporterImpl.h
@@ -625,11 +625,9 @@
     } else if (auto *CD = dyn_cast<ConstructorDecl>(decl)) {
       assert(CD->getInterfaceType());
       ty = CD->getResultInterfaceType();
-    } else if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
-      ty = SD->getElementInterfaceType();
     } else {
-      auto *VD = cast<VarDecl>(decl);
-      ty = VD->getInterfaceType()->getReferenceStorageReferent();
+      ty = cast<AbstractStorageDecl>(decl)->getValueInterfaceType()
+                                          ->getReferenceStorageReferent();
     }
 #endif
 
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index abd382a..7872bd4 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -244,10 +244,6 @@
   validateDebugInfoArgs(diags, args);
   validateCompilationConditionArgs(diags, args);
   validateAutolinkingArgs(diags, args);
-
-  if (args.hasArg(options::OPT_emit_public_type_metadata_accessors))
-    diags.diagnose(SourceLoc(),
-                   diag::warn_emit_public_type_metadata_accessors_deprecated);
 }
 
 std::unique_ptr<ToolChain>
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 7e13d1c..dbf283b 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -297,6 +297,7 @@
     auto R =
         jobsByInput.insert(std::make_pair(IA->getInputArg().getValue(), J));
     assert(R.second);
+    (void)R;
   }
   for (const InputPair &P : C.getInputFiles()) {
     auto I = jobsByInput.find(P.second->getValue());
diff --git a/lib/Frontend/FrontendInputsAndOutputs.cpp b/lib/Frontend/FrontendInputsAndOutputs.cpp
index fad6b90..4b11e1c 100644
--- a/lib/Frontend/FrontendInputsAndOutputs.cpp
+++ b/lib/Frontend/FrontendInputsAndOutputs.cpp
@@ -293,6 +293,7 @@
     assert(outputFiles.size() == N && "Must have one main output per primary");
     assert(supplementaryOutputs.size() == N &&
            "Must have one set of supplementary outputs per primary");
+    (void)N;
 
     unsigned i = 0;
     for (auto &input : AllInputs) {
diff --git a/lib/FrontendTool/ReferenceDependencies.cpp b/lib/FrontendTool/ReferenceDependencies.cpp
index 0c62eb2..87c947e 100644
--- a/lib/FrontendTool/ReferenceDependencies.cpp
+++ b/lib/FrontendTool/ReferenceDependencies.cpp
@@ -490,8 +490,8 @@
   }
 
   auto layout = type->getExistentialLayout();
-  assert(!layout.superclass && "Should not have a subclass existential "
-                               "in the inheritance clause of an extension");
+  assert(!layout.explicitSuperclass && "Should not have a subclass existential "
+                                       "in the inheritance clause of an extension");
   for (auto protoTy : layout.getProtocols()) {
     if (!declIsPrivate(protoTy->getDecl()))
       return false;
diff --git a/lib/IRGen/GenCast.cpp b/lib/IRGen/GenCast.cpp
index 42489c4..0796a15 100644
--- a/lib/IRGen/GenCast.cpp
+++ b/lib/IRGen/GenCast.cpp
@@ -522,7 +522,7 @@
   bool hasClassConstraint = layout.requiresClass();
   bool hasClassConstraintByProtocol = false;
 
-  bool hasSuperclassConstraint = bool(layout.superclass);
+  bool hasSuperclassConstraint = bool(layout.getSuperclass());
 
   for (auto protoTy : layout.getProtocols()) {
     auto *protoDecl = protoTy->getDecl();
@@ -563,7 +563,7 @@
   // The source of a scalar cast is statically known to be a class or a
   // metatype, so we only have to check the class constraint in two cases:
   //
-  // 1) The destination type has an explicit superclass constraint that is
+  // 1) The destination type has a superclass constraint that is
   //    more derived than what the source type is known to be.
   //
   // 2) We are casting between metatypes, in which case the source might
@@ -739,7 +739,7 @@
   args.push_back(metadataValue);
 
   if (checkSuperclassConstraint)
-    args.push_back(IGF.emitTypeMetadataRef(CanType(layout.superclass)));
+    args.push_back(IGF.emitTypeMetadataRef(CanType(layout.getSuperclass())));
 
   for (auto proto : witnessTableProtos)
     args.push_back(proto);
diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp
index c70b3ac..d36aad4 100644
--- a/lib/IRGen/GenClangType.cpp
+++ b/lib/IRGen/GenClangType.cpp
@@ -623,10 +623,10 @@
     return getClangIdType(getClangASTContext());
 
   auto superclassTy = clangCtx.ObjCBuiltinIdTy;
-  if (layout.superclass) {
+  if (auto layoutSuperclassTy = layout.getSuperclass()) {
     superclassTy = clangCtx.getCanonicalType(
       cast<clang::ObjCObjectPointerType>(
-        Converter.convert(IGM, CanType(layout.superclass)))
+        Converter.convert(IGM, CanType(layoutSuperclassTy)))
         ->getPointeeType());
   }
 
diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp
index e7e5fb5..4fc638d 100644
--- a/lib/IRGen/GenExistential.cpp
+++ b/lib/IRGen/GenExistential.cpp
@@ -1431,8 +1431,8 @@
     ReferenceCounting refcounting = getReferenceCountingForType(IGM, T);
 
     llvm::PointerType *reprTy = nullptr;
-    if (layout.superclass) {
-      auto &superTI = IGM.getTypeInfoForUnlowered(layout.superclass);
+    if (auto superclass = layout.getSuperclass()) {
+      auto &superTI = IGM.getTypeInfoForUnlowered(superclass);
       reprTy = cast<llvm::PointerType>(superTI.getStorageType());
     } else if (refcounting == ReferenceCounting::Native) {
       reprTy = IGM.RefCountedPtrTy;
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 6ec7f07..20182e8 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -700,7 +700,10 @@
     uint16_t getKindSpecificFlags() {
       TypeContextDescriptorFlags flags;
 
-      flags.setIsReflectable(true); // struct always reflectable
+      // Structs are reflectable unless we emit them with opaque reflection
+      // metadata.
+      flags.setIsReflectable(
+                            !IGM.shouldEmitOpaqueTypeMetadataRecord(getType()));
 
       getClangImportedFlags(flags);
       return flags.getOpaqueValue();
@@ -875,7 +878,7 @@
       auto *dc = fn.getDecl()->getDeclContext();
       assert(!isa<ExtensionDecl>(dc));
 
-      if (fn.getDecl()->getDeclContext() == getType()) {
+      if (dc == getType()) {
         if (auto entry = VTable->getEntry(IGM.getSILModule(), fn)) {
           assert(entry->TheKind == SILVTable::Entry::Kind::Normal);
           auto *implFn = IGM.getAddrOfSILFunction(entry->Implementation,
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 7879df4..ea36378 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -2614,6 +2614,7 @@
           return /*finished?*/ false;
         });
     assert(found && "too many conditional conformances");
+    (void)found;
 
     sourceKey.Kind =
         LocalTypeDataKind::forAbstractProtocolWitnessTable(conformingProto);
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index 16c8fd8..379bbe6 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -1400,4 +1400,5 @@
                                            SILType T) const {
   auto canType = T.getASTType();
   assert(!canType->is<ArchetypeType>() && "Did not expect an ArchetypeType");
+  (void)canType;
 }
diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp
index 003e72e..9f4aa69 100644
--- a/lib/IRGen/IRGenMangler.cpp
+++ b/lib/IRGen/IRGenMangler.cpp
@@ -141,19 +141,17 @@
       if (i == 0)
         appendOperator("_");
     }
-    if (layout.superclass) {
-      auto superclassTy = layout.superclass;
-
+    if (auto superclass = layout.explicitSuperclass) {
       // We share type infos for different instantiations of a generic type
       // when the archetypes have the same exemplars.  We cannot mangle
       // archetypes, and the mangling does not have to be unique, so we just
       // mangle the unbound generic form of the type.
-      if (superclassTy->hasArchetype()) {
-        superclassTy = superclassTy->getClassOrBoundGenericClass()
+      if (superclass->hasArchetype()) {
+        superclass = superclass->getClassOrBoundGenericClass()
           ->getDeclaredType();
       }
 
-      appendType(CanType(superclassTy));
+      appendType(CanType(superclass));
       appendOperator("Xc");
     } else if (layout.getLayoutConstraint()) {
       appendOperator("Xl");
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 4553214..75df440 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -3956,6 +3956,7 @@
 
   auto fnType = operandType.getAs<SILFunctionType>();
   assert(fnType->getExtInfo().hasContext() && "Must have a closure operand");
+  (void)fnType;
 
   // This code relies on that an optional<()->()>'s tag fits in the function
   // pointer.
@@ -3963,6 +3964,7 @@
   assert(TI.mayHaveExtraInhabitants(IGM) &&
          "Must have extra inhabitants to be able to handle the optional "
          "closure case");
+  (void)TI;
 
   Explosion closure = getLoweredExplosion(i->getOperand());
   auto func = closure.claimNext();
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 31b0700..9bca707 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -949,6 +949,7 @@
     assert(pass.allocToApplyRetMap.find(opAsInstr) !=
                pass.allocToApplyRetMap.end() &&
            "Unexpected dealloc instr!");
+    (void)opAsInstr;
   }
 }
 
@@ -1377,6 +1378,7 @@
                  "Expected SILFunctionType or Optional for the result type");
           assert(optionalType.is<SILFunctionType>() &&
                  "Expected a SILFunctionType inside the optional Type");
+          (void)optionalType;
         }
         continue;
       }
@@ -2018,6 +2020,8 @@
     assert(srcType && "Expected an address-type source");
     assert(tgtType.isAddress() && "Expected an address-type target");
     assert(srcType == tgtType && "Source and target type do not match");
+    (void)srcType;
+    (void)tgtType;
 
     SILBuilderWithScope copyBuilder(instr);
     createOutlinedCopyCall(copyBuilder, src, tgt, pass);
@@ -2406,6 +2410,7 @@
     assert(oldYields.size() == newYields.size() &&
            oldYields.size() == oldYieldedValues.size() &&
            newYields.size() == newYieldedValues.size());
+    (void)newYields;
     for (auto i : indices(oldYields)) {
       SILValue oldValue = oldYieldedValues[i];
       SILValue newValue = newYieldedValues[i];
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index 4769372..6fd74ea 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -561,8 +561,28 @@
     if (nominalDecl->isGenericContext())
       return false;
 
+    auto expansion = ResilienceExpansion::Maximal;
+
+    // Normally, if a value type is known to have a fixed layout to us, we will
+    // have emitted fully initialized metadata for it, including a payload size
+    // field for enum metadata for example, allowing the type metadata to be
+    // used in other resilience domains without initialization.
+    //
+    // However, when -enable-resilience-bypass is on, we might be using a value
+    // type from another module built with resilience enabled. In that case, the
+    // type looks like it has fixed size to us, since we're bypassing resilience,
+    // but the metadata still requires runtime initialization, so its incorrect
+    // to reference it directly.
+    //
+    // While unconditionally using minimal expansion is correct, it is not as
+    // efficient as it should be, so only do so if -enable-resilience-bypass is on.
+    //
+    // FIXME: All of this goes away once lldb supports resilience.
+    if (IGM.IRGen.Opts.EnableResilienceBypass)
+      expansion = ResilienceExpansion::Minimal;
+
     // Resiliently-sized metadata access always requires an accessor.
-    return (IGM.getTypeInfoForUnlowered(type).isFixedSize());
+    return (IGM.getTypeInfoForUnlowered(type).isFixedSize(expansion));
   }
 
   // The empty tuple type has a singleton metadata.
@@ -1155,9 +1175,9 @@
                                !layout.requiresClass());
       llvm::Value *superclassConstraint =
         llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy);
-      if (layout.superclass) {
+      if (auto superclass = layout.explicitSuperclass) {
         superclassConstraint = IGF.emitAbstractTypeMetadataRef(
-          CanType(layout.superclass));
+          CanType(superclass));
       }
 
       auto call = IGF.Builder.CreateCall(IGF.IGM.getGetExistentialMetadataFn(),
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index 825fe29..b9c230a 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -1028,6 +1028,7 @@
     }
 
     // Change attribute(rawValue: "value") to "value"
+    // Change attribute("value") to "value"
     if (auto *CE = dyn_cast<CallExpr>(E)) {
       auto Found = false;
       if (auto *CRC = dyn_cast<ConstructorRefCallExpr>(CE->getFn())) {
@@ -1040,10 +1041,14 @@
         return false;
       std::vector<CallArgInfo> AllArgs =
         getCallArgInfo(SM, CE->getArg(), LabelRangeEndAt::LabelNameOnly);
-      if (AllArgs.size() == 1 && AllArgs.front().LabelRange.str() == "rawValue") {
-        Editor.replace(CE->getSourceRange(), Lexer::getCharSourceRangeFromSourceRange(SM,
-          AllArgs.front().ArgExp->getSourceRange()).str());
-        return true;
+      if (AllArgs.size() == 1) {
+        auto Label = AllArgs.front().LabelRange.str();
+        if (Label == "rawValue" || Label.empty()) {
+          Editor.replace(CE->getSourceRange(),
+                         Lexer::getCharSourceRangeFromSourceRange(SM,
+                           AllArgs.front().ArgExp->getSourceRange()).str());
+          return true;
+        }
       }
     }
     return false;
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 605bc13..fb535ab 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -463,6 +463,17 @@
   return sub;
 }
 
+static Expr *formUnaryArgument(ASTContext &context, Expr *argument) {
+  if (isa<ParenExpr>(argument))
+    return argument;
+
+  auto *arg = new (context)
+      ParenExpr(argument->getStartLoc(), argument, argument->getEndLoc(),
+                /*hasTrailingClosure*/ false);
+  arg->setImplicit();
+  return arg;
+}
+
 /// parseExprUnary
 ///
 ///   expr-unary(Mode):
@@ -538,8 +549,8 @@
     }
   }
 
-  return makeParserResult(
-      new (Context) PrefixUnaryExpr(Operator, SubExpr.get()));
+  return makeParserResult(new (Context) PrefixUnaryExpr(
+      Operator, formUnaryArgument(Context, SubExpr.get())));
 }
 
 /// expr-keypath-swift:
@@ -1330,8 +1341,9 @@
         break;
 
       Expr *oper = parseExprOperator();
-      Result =
-          makeParserResult(new (Context) PostfixUnaryExpr(oper, Result.get()));
+
+      Result = makeParserResult(new (Context) PostfixUnaryExpr(
+          oper, formUnaryArgument(Context, Result.get())));
       SyntaxContext->createNodeInPlace(SyntaxKind::PostfixUnaryExpr);
       continue;
     }
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 2522604..624caeb 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -847,6 +847,7 @@
 
   auto *GenericEnv = F->getGenericEnvironment();
   assert(GenericEnv);
+  (void)GenericEnv;
 
   IdentTypeReprLookup PerformLookup(P);
   // Use parser lexical scopes to resolve references
diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp
index 7871a87..c7dd8aa 100644
--- a/lib/PrintAsObjC/PrintAsObjC.cpp
+++ b/lib/PrintAsObjC/PrintAsObjC.cpp
@@ -1733,14 +1733,14 @@
       return;
     }
 
-    if (layout.superclass) {
-      auto *CD = layout.superclass->getClassOrBoundGenericClass();
+    if (auto superclass = layout.explicitSuperclass) {
+      auto *CD = superclass->getClassOrBoundGenericClass();
       assert(CD->isObjC());
       if (isMetatype) {
         os << "SWIFT_METATYPE(" << getNameForObjC(CD) << ")";
       } else {
         os << getNameForObjC(CD);
-        if (auto *BGT = layout.superclass->getAs<BoundGenericClassType>())
+        if (auto *BGT = superclass->getAs<BoundGenericClassType>())
           printGenericArgs(BGT);
       }
     } else {
@@ -1752,7 +1752,7 @@
       protos.push_back(proto->getDecl());
     printProtocols(protos);
 
-    if (layout.superclass && !isMetatype)
+    if (layout.explicitSuperclass && !isMetatype)
       os << " *";
 
     printNullability(optionalKind);
@@ -2007,8 +2007,8 @@
 
   void visitProtocolCompositionType(ProtocolCompositionType *composition) {
     auto layout = composition->getExistentialLayout();
-    if (layout.superclass)
-      visit(layout.superclass);
+    if (auto superclass = layout.explicitSuperclass)
+      visit(superclass);
     for (auto proto : layout.getProtocols())
       visit(proto);
   }
diff --git a/lib/SIL/InstructionUtils.cpp b/lib/SIL/InstructionUtils.cpp
index dacb37b..dfc6c32 100644
--- a/lib/SIL/InstructionUtils.cpp
+++ b/lib/SIL/InstructionUtils.cpp
@@ -355,6 +355,7 @@
 static SILValue findClosureStoredIntoBlock(SILValue V) {
   auto FnType = V->getType().castTo<SILFunctionType>();
   assert(FnType->getRepresentation() == SILFunctionTypeRepresentation::Block);
+  (void)FnType;
 
   // Given a no escape block argument to a function,
   // pattern match to find the noescape closure that invoking the block
diff --git a/lib/SIL/SILCoverageMap.cpp b/lib/SIL/SILCoverageMap.cpp
index a215a6b..f2f0c94 100644
--- a/lib/SIL/SILCoverageMap.cpp
+++ b/lib/SIL/SILCoverageMap.cpp
@@ -45,6 +45,7 @@
 
   // Assert that this coverage map is unique.
   assert(result.second && "Duplicate coverage mapping for function");
+  (void)result;
 
   return CM;
 }
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index ff6681e..f82a76a 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -2122,6 +2122,7 @@
 
   auto inserted = ConstantTypes.insert({constant, result});
   assert(inserted.second);
+  (void)inserted;
   return *result;
 }
 
@@ -2289,6 +2290,7 @@
   
   auto inserted = ConstantOverrideTypes.insert({{derived, base}, result});
   assert(inserted.second);
+  (void)inserted;
   return *result;
 }
 
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index 259e7d7..ebabf1c 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -129,6 +129,7 @@
   return isGuaranteedForwardingValueKind(SILNodeKind(I->getKind()));
 }
 
+LLVM_ATTRIBUTE_UNUSED
 static bool isOwnershipForwardingInst(SILInstruction *I) {
   return isOwnershipForwardingValueKind(SILNodeKind(I->getKind()));
 }
@@ -154,7 +155,9 @@
                                    OwnershipUseCheckerResult> {
 public:
 private:
+  LLVM_ATTRIBUTE_UNUSED
   SILModule &Mod;
+
   const Operand &Op;
   SILValue BaseValue;
   ErrorBehaviorKind ErrorBehavior;
diff --git a/lib/SIL/SILProfiler.cpp b/lib/SIL/SILProfiler.cpp
index f32b86f..312320d 100644
--- a/lib/SIL/SILProfiler.cpp
+++ b/lib/SIL/SILProfiler.cpp
@@ -86,6 +86,7 @@
 } // namespace swift
 
 /// Check that the input AST has at least been type-checked.
+LLVM_ATTRIBUTE_UNUSED
 static bool hasASTBeenTypeChecked(ASTNode N) {
   DeclContext *DC = N.getAsDeclContext();
   assert(DC && "Invalid AST node for profiling");
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index df4a5a7..b5fb13b 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -3151,8 +3151,8 @@
               "init_existential of class existential with non-class type");
     }
 
-    if (layout.superclass) {
-      require(layout.superclass->isExactSuperclassOf(concreteType),
+    if (auto superclass = layout.getSuperclass()) {
+      require(superclass->isExactSuperclassOf(concreteType),
               "init_existential of subclass existential with wrong type");
     }
 
@@ -4984,6 +4984,8 @@
                "Witnesses must either have a concrete Self, or an "
                "an abstract Self that is constrained to their "
                "protocol.");
+        (void)protocol;
+        (void)witnessSelfProtocol;
       }
     }
 }
diff --git a/lib/SILGen/Cleanup.cpp b/lib/SILGen/Cleanup.cpp
index bdaf095..0cd9596 100644
--- a/lib/SILGen/Cleanup.cpp
+++ b/lib/SILGen/Cleanup.cpp
@@ -56,7 +56,7 @@
 }
 
 void CleanupManager::emitCleanups(CleanupsDepth depth, CleanupLocation loc,
-                                  bool popCleanups) {
+                                  ForUnwind_t forUnwind, bool popCleanups) {
   auto begin = stack.stable_begin();
   while (begin != depth) {
     auto iter = stack.find(begin);
@@ -76,7 +76,7 @@
       stack.pop();
 
     if (cleanup.isActive() && SGF.B.hasValidInsertionPoint())
-      cleanup.emit(SGF, loc);
+      cleanup.emit(SGF, loc, forUnwind);
 
     stack.checkIterator(begin);
   }
@@ -95,7 +95,7 @@
   
   // Iteratively mark cleanups dead and pop them.
   // Maybe we'd get better results if we marked them all dead in one shot?
-  emitCleanups(depth, loc);
+  emitCleanups(depth, loc, NotForUnwind);
 }
 
 bool CleanupManager::hasAnyActiveCleanups(CleanupsDepth from,
@@ -111,11 +111,12 @@
 /// threading out through any cleanups we might need to run.  This does not
 /// pop the cleanup stack.
 void CleanupManager::emitBranchAndCleanups(JumpDest dest, SILLocation branchLoc,
-                                           ArrayRef<SILValue> args) {
+                                           ArrayRef<SILValue> args,
+                                           ForUnwind_t forUnwind) {
   SILGenBuilder &builder = SGF.getBuilder();
   assert(builder.hasValidInsertionPoint() && "Emitting branch in invalid spot");
   emitCleanups(dest.getDepth(), dest.getCleanupLocation(),
-               /*popCleanups=*/false);
+               forUnwind, /*popCleanups=*/false);
   builder.createBranch(branchLoc, dest.getBlock(), args);
 }
 
@@ -123,7 +124,7 @@
   SILGenBuilder &builder = SGF.getBuilder();
   assert(builder.hasValidInsertionPoint() && "Emitting return in invalid spot");
   (void)builder;
-  emitCleanups(stack.stable_end(), loc, /*popCleanups=*/false);
+  emitCleanups(stack.stable_end(), loc, NotForUnwind, /*popCleanups=*/false);
 }
 
 /// Emit a new block that jumps to the specified location and runs necessary
@@ -131,7 +132,8 @@
 /// returns the dest block.
 SILBasicBlock *CleanupManager::emitBlockForCleanups(JumpDest dest,
                                                     SILLocation branchLoc,
-                                                    ArrayRef<SILValue> args) {
+                                                    ArrayRef<SILValue> args,
+                                                    ForUnwind_t forUnwind) {
   // If there are no cleanups to run, just return the Dest block directly.
   if (!hasAnyActiveCleanups(dest.getDepth()))
     return dest.getBlock();
@@ -139,7 +141,7 @@
   // Otherwise, create and emit a new block.
   auto *newBlock = SGF.createBasicBlock();
   SILGenSavedInsertionPoint IPRAII(SGF, newBlock);
-  emitBranchAndCleanups(dest, branchLoc, args);
+  emitBranchAndCleanups(dest, branchLoc, args, forUnwind);
   return newBlock;
 }
 
diff --git a/lib/SILGen/Cleanup.h b/lib/SILGen/Cleanup.h
index 28dc213..4213811 100644
--- a/lib/SILGen/Cleanup.h
+++ b/lib/SILGen/Cleanup.h
@@ -37,6 +37,21 @@
 class SharedBorrowFormalAccess;
 class FormalEvaluationScope;
 
+/// Is a cleanup being executed as a result of some sort of forced
+/// unwinding, such as an error being thrown, or are we just cleaning up
+/// after some operation?
+///
+/// Most cleanups don't care, but the cleanups tied to l-value accesses do:
+/// the access will be aborted rather than ended normally, which may cause
+/// e.g. writebacks to be skipped.  It is also important that no actions
+/// be undertaken by an unwind cleanup that might change control flow,
+/// such as throwing an error.  In contrast, non-unwinding cleanups are
+/// permitted to change control flow.
+enum ForUnwind_t : bool {
+  NotForUnwind,
+  IsForUnwind
+};
+
 /// The valid states that a cleanup can be in.
 enum class CleanupState {
   /// The cleanup is inactive but may be activated later.
@@ -80,7 +95,8 @@
   bool isActive() const { return state >= CleanupState::Active; }
   bool isDead() const { return state == CleanupState::Dead; }
 
-  virtual void emit(SILGenFunction &SGF, CleanupLocation loc) = 0;
+  virtual void emit(SILGenFunction &SGF, CleanupLocation loc,
+                    ForUnwind_t forUnwind) = 0;
   virtual void dump(SILGenFunction &SGF) const = 0;
 };
 
@@ -120,6 +136,7 @@
 
   void popTopDeadCleanups(CleanupsDepth end);
   void emitCleanups(CleanupsDepth depth, CleanupLocation l,
+                    ForUnwind_t forUnwind,
                     bool popCleanups=true);
   void endScope(CleanupsDepth depth, CleanupLocation l);
 
@@ -151,7 +168,8 @@
   /// \param branchLoc  The location of the branch instruction.
   /// \param args       Arguments to pass to the destination block.
   void emitBranchAndCleanups(JumpDest dest, SILLocation branchLoc,
-                             ArrayRef<SILValue> args = {});
+                             ArrayRef<SILValue> args = {},
+                             ForUnwind_t forUnwind = NotForUnwind);
 
   /// emitCleanupsForReturn - Emit the top-level cleanups needed prior to a
   /// return from the function.
@@ -161,7 +179,8 @@
   /// cleanups based on its level.  If there are no cleanups to run, this just
   /// returns the dest block.
   SILBasicBlock *emitBlockForCleanups(JumpDest dest, SILLocation branchLoc,
-                                      ArrayRef<SILValue> args = {});
+                                      ArrayRef<SILValue> args = {},
+                                      ForUnwind_t forUnwind = NotForUnwind);
 
   /// pushCleanup - Push a new cleanup.
   template<class T, class... A>
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index db9437f..8787f42 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -3338,7 +3338,7 @@
 public:
   DeallocateUninitializedBox(SILValue box) : box(box) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
     SGF.B.createDeallocBox(l, box);
   }
 
@@ -3857,6 +3857,7 @@
   }
 
   assert(substFnType->getNumResults() == 1);
+  (void)substFnType;
   ManagedValue resultMV = SGF.emitInjectEnum(
       uncurriedLoc, std::move(payload), SGF.getLoweredType(formalResultType),
       element, uncurriedContext);
@@ -4829,7 +4830,7 @@
     DeallocateUninitializedArray(SILValue array)
       : Array(array) {}
 
-    void emit(SILGenFunction &SGF, CleanupLocation l) override {
+    void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
       SGF.emitUninitializedArrayDeallocation(l, Array);
     }
 
@@ -5198,6 +5199,7 @@
       auto subscriptsTupleType = cast<TupleType>(subscripts.getType());
       assert(accessType.getParams().size()
               == 1 + subscriptsTupleType->getNumElements());
+      (void)subscriptsTupleType;
       SmallVector<RValue, 8> eltRVs;
       std::move(subscripts).extractElements(eltRVs);
       for (auto &elt : eltRVs)
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 68bbb0e..9f1c46a 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -67,8 +67,8 @@
 
     // They're also convertible to Error if they have a class bound that
     // conforms to Error.
-    if (auto cls = layout.superclass) {
-      type = cls->getCanonicalType();
+    if (auto superclass = layout.getSuperclass()) {
+      type = superclass->getCanonicalType();
 
     // Otherwise, they are not convertible to Error.
     } else {
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index eb6b25e..879640c 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -219,6 +219,8 @@
              SILFunctionTypeRepresentation::Thick &&
          !fnType->isNoEscape() && resultFnType->isNoEscape() &&
          "Expect a escaping to noescape conversion");
+  (void)fnType;
+  (void)resultFnType;
   SILValue fnValue = fn.getValue();
   SILValue result = createConvertEscapeToNoEscape(
       loc, fnValue, resultTy, isEscapedByUser, false);
diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp
index 4a7d52a..007a74a 100644
--- a/lib/SILGen/SILGenBuiltin.cpp
+++ b/lib/SILGen/SILGenBuiltin.cpp
@@ -901,6 +901,7 @@
          "ValueToBridgeObject should have one sub");
   auto &fromTL = SGF.getTypeLowering(subs.getReplacementTypes()[0]);
   assert(fromTL.isTrivial() && "Expected a trivial type");
+  (void)fromTL;
 
   SILValue result = SGF.B.createValueToBridgeObject(loc, args[0].getValue());
   return SGF.emitManagedRetain(loc, result);
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index e1358da..f7ae959 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -784,15 +784,13 @@
                                           VarDecl *selfDecl) {
   CanType selfFormalType = selfDecl->getType()->getCanonicalType();
   if (selfFormalType->hasReferenceSemantics())
-    return SGF.emitRValueForDecl(loc, selfDecl, selfDecl->getType(),
+    return SGF.emitRValueForDecl(loc, selfDecl, selfFormalType,
                                  AccessSemantics::DirectToStorage,
                                  SGFContext::AllowImmediatePlusZero)
       .getAsSingleValue(SGF, loc);
   else
-    return SGF.emitLValueForDecl(loc, selfDecl,
-                                 selfDecl->getType()->getCanonicalType(),
-                                 AccessKind::Write,
-                                 AccessSemantics::DirectToStorage);
+    return SGF.emitAddressOfLocalVarDecl(loc, selfDecl, selfFormalType,
+                                         AccessKind::Write);
 }
 
 static LValue emitLValueForMemberInit(SILGenFunction &SGF, SILLocation loc,
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index e816a99..6331c4c 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -131,7 +131,8 @@
     SILValue closure;
   public:
     CleanupClosureConstant(SILValue closure) : closure(closure) {}
-    void emit(SILGenFunction &SGF, CleanupLocation l) override {
+    void emit(SILGenFunction &SGF, CleanupLocation l,
+              ForUnwind_t forUnwind) override {
       SGF.B.emitDestroyValueOperation(l, closure);
     }
     void dump(SILGenFunction &) const override {
@@ -250,7 +251,8 @@
   EndBorrowCleanup(SILValue original, SILValue borrowed)
       : original(original), borrowed(borrowed) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.B.createEndBorrow(l, borrowed, original);
   }
 
@@ -271,7 +273,8 @@
 public:
   ReleaseValueCleanup(SILValue v) : v(v) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     if (v->getType().isAddress())
       SGF.B.createDestroyAddr(l, v);
     else
@@ -295,7 +298,8 @@
 public:
   DeallocStackCleanup(SILValue addr) : Addr(addr) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.B.createDeallocStack(l, Addr);
   }
 
@@ -316,7 +320,8 @@
 public:
   DestroyLocalVariable(VarDecl *var) : Var(var) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.destroyLocalVariable(l, Var);
   }
 
@@ -349,7 +354,8 @@
 public:
   DeallocateUninitializedLocalVariable(VarDecl *var) : Var(var) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.deallocateUninitializedLocalVariable(l, Var);
   }
 
@@ -1304,7 +1310,8 @@
         concreteFormalType(concreteFormalType),
         repr(repr) {}
     
-    void emit(SILGenFunction &SGF, CleanupLocation l) override {
+    void emit(SILGenFunction &SGF, CleanupLocation l,
+              ForUnwind_t forUnwind) override {
       switch (repr) {
       case ExistentialRepresentation::None:
       case ExistentialRepresentation::Class:
@@ -1481,7 +1488,8 @@
     state = newState;
   }
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     getEvaluation(SGF).finish(SGF);
   }
 
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 14dc138..03453e1 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -168,7 +168,8 @@
   EndBorrowCleanup(SILValue originalValue, SILValue borrowedValue)
       : originalValue(originalValue), borrowedValue(borrowedValue) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.B.createEndBorrow(l, borrowedValue, originalValue);
   }
 
@@ -187,7 +188,7 @@
 
   FormalEvaluationEndBorrowCleanup() : Depth() {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
     getEvaluation(SGF).finish(SGF);
   }
 
@@ -276,7 +277,8 @@
 
   EndBorrowArgumentCleanup(SILPHIArgument *arg) : arg(arg) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.B.createEndBorrowArgument(l, arg);
   }
 
@@ -690,56 +692,6 @@
       ArrayRef<SILValue>());
 }
 
-/// Emit the specified declaration as an address if possible,
-/// otherwise return null.
-ManagedValue SILGenFunction::emitLValueForDecl(SILLocation loc, VarDecl *var,
-                                               CanType formalRValueType,
-                                               AccessKind accessKind,
-                                               AccessSemantics semantics) {
-  // For local decls, use the address we allocated or the value if we have it.
-  auto It = VarLocs.find(var);
-  if (It != VarLocs.end()) {
-    // If this has an address, return it.  By-value let's have no address.
-    SILValue ptr = It->second.value;
-    if (ptr->getType().isAddress())
-      return ManagedValue::forLValue(ptr);
-    
-    // Otherwise, it is an RValue let.
-    return ManagedValue();
-  }
-
-  auto strategy = var->getAccessStrategy(semantics, accessKind, FunctionDC);
-
-  switch (strategy.getKind()) {
-  case AccessStrategy::Storage:
-    // The only kind of stored variable that should make it to here is
-    // a global variable.  Just invoke its accessor function to get its
-    // address.
-    return emitGlobalVariableRef(loc, var);
-
-  case AccessStrategy::DirectToAccessor:
-  case AccessStrategy::DispatchToAccessor: {
-    auto accessor = strategy.getAccessor();
-    if (accessor != AccessorKind::Address &&
-        accessor != AccessorKind::MutableAddress)
-      return ManagedValue();
-
-    LValue lvalue =
-      emitLValueForAddressedNonMemberVarDecl(loc, var, formalRValueType,
-                                             accessKind, semantics);
-    return emitAddressOfLValue(loc, std::move(lvalue), accessKind);
-  }
-
-  case AccessStrategy::MaterializeToTemporary:
-    return ManagedValue();
-    
-  case AccessStrategy::BehaviorStorage:
-    // TODO: Behaviors aren't supported on non-instance properties yet.
-    llvm_unreachable("not implemented");
-  }
-  llvm_unreachable("bad access strategy");
-}
-
 namespace {
 
 /// This is a simple cleanup class that is only meant to help with delegating
@@ -758,7 +710,7 @@
                                    SILValue value)
       : loc(loc), lvalueAddress(lvalueAddress), value(value) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
     SILValue valueToStore = value;
     SILType lvalueObjTy = lvalueAddress->getType().getObjectType();
 
@@ -924,9 +876,6 @@
   assert(!ncRefType->is<LValueType>() &&
          "RValueEmitter shouldn't be called on lvalues");
 
-  // Any writebacks for this access are tightly scoped.
-  FormalEvaluationScope scope(*this);
-
   // If this is a decl that we have an lvalue for, produce and return it.
   ValueDecl *decl = declRef.getDecl();
   
@@ -954,140 +903,12 @@
     return getUnmanagedRValue(B.createMetatype(loc, getLoweredType(refType)));
   }
   
-  // If this is a reference to a var, produce an address or value.
+  // If this is a reference to a var, emit it as an l-value and then load.
   if (auto *var = dyn_cast<VarDecl>(decl)) {
     assert(!declRef.isSpecialized() &&
            "Cannot handle specialized variable references");
 
-    // If this VarDecl is represented as an address, emit it as an lvalue, then
-    // perform a load to get the rvalue.
-    if (ManagedValue result =
-            emitLValueForDecl(loc, var, refType, AccessKind::Read, semantics)) {
-      bool guaranteedValid = false;
-      IsTake_t shouldTake = IsNotTake;
-
-      // We should only end up in this path for local and global variables,
-      // i.e. ones whose lifetime is assured for the duration of the evaluation.
-      // Therefore, if the variable is a constant, the value is guaranteed
-      // valid as well.
-      if (var->isLet())
-        guaranteedValid = true;
-
-      // Protect the lvalue read with access markers. The !is<LValueType> assert
-      // above ensures that the "LValue" is actually immutable, so we use an
-      // unenforced access marker.
-      SILValue destAddr = result.getLValueAddress();
-      SILValue accessAddr = UnenforcedFormalAccess::enter(*this, loc, destAddr,
-                                                          SILAccessKind::Read);
-      auto propagateRValuePastAccess = [&](RValue &&rvalue) {
-        // Check if a new begin_access was emitted and returned as the
-        // RValue. This means that the load did not actually load. If so, then
-        // fix the rvalue to begin_access operand. The end_access cleanup
-        // doesn't change. FIXME: this can't happen with sil-opaque-values.
-        if (accessAddr != destAddr && rvalue.isComplete()
-            && rvalue.isPlusZero(*this) && !isa<TupleType>(rvalue.getType())) {
-          auto mv = std::move(rvalue).getScalarValue();
-          if (mv.getValue() == accessAddr)
-            mv = std::move(mv).transform(
-                cast<BeginAccessInst>(accessAddr)->getOperand());
-          return RValue(*this, loc, refType, mv);
-        }
-        return std::move(rvalue);
-      };
-      // If we have self, see if we are in an 'init' delegation sequence. If so,
-      // call out to the special delegation init routine. Otherwise, use the
-      // normal RValue emission logic.
-      if (var->getName() == getASTContext().Id_self &&
-          SelfInitDelegationState != NormalSelf) {
-        auto rvalue =
-            emitRValueForSelfInDelegationInit(loc, refType, accessAddr, C);
-        return propagateRValuePastAccess(std::move(rvalue));
-      }
-
-      // Avoid computing an abstraction pattern for local variables.
-      // This is a slight compile-time optimization, but more importantly
-      // it avoids problems where locals don't always have interface types.
-      if (var->getDeclContext()->isLocalContext()) {
-        auto rvalue = RValue(*this, loc, refType,
-                             emitLoad(loc, accessAddr, getTypeLowering(refType),
-                                      C, shouldTake, guaranteedValid));
-
-        return propagateRValuePastAccess(std::move(rvalue));
-      }
-
-      // Otherwise, do the full thing where we potentially bridge and
-      // reabstract the declaration.
-      auto origFormalType = SGM.Types.getAbstractionPattern(var);
-      auto rvalue = RValue(*this, loc, refType,
-                           emitLoad(loc, accessAddr, origFormalType, refType,
-                                    getTypeLowering(refType), C, shouldTake,
-                                    guaranteedValid));
-      return propagateRValuePastAccess(std::move(rvalue));
-    }
-
-    // For local decls, use the address we allocated or the value if we have it.
-    auto It = VarLocs.find(decl);
-    if (It != VarLocs.end()) {
-      // Mutable lvalue and address-only 'let's are LValues.
-      assert(!It->second.value->getType().isAddress() &&
-             "LValue cases should be handled above");
-
-      SILValue Scalar = It->second.value;
-
-      // For weak and unowned types, convert the reference to the right
-      // pointer.
-      if (Scalar->getType().is<ReferenceStorageType>()) {
-        Scalar = emitConversionToSemanticRValue(loc, Scalar,
-                                                getTypeLowering(refType));
-        // emitConversionToSemanticRValue always produces a +1 strong result.
-        return RValue(*this, loc,
-                      refType, emitManagedRValueWithCleanup(Scalar));
-      }
-
-      // This is a let, so we can make guarantees, so begin the borrow scope.
-      ManagedValue Result = emitManagedBeginBorrow(loc, Scalar);
-
-      // If the client can't handle a +0 result, retain it to get a +1.
-      // This is a 'let', so we can make guarantees.
-      return RValue(*this, loc, refType,
-                    C.isGuaranteedPlusZeroOk()
-                      ? Result : Result.copyUnmanaged(*this, loc));
-    }
-
-    assert(var->getGetter() && "Unknown rvalue case");
-
-    SILDeclRef getter = SGM.getGetterDeclRef(var);
-
-    ArgumentSource selfSource;
-    
-    // Global properties have no base or subscript. Static properties
-    // use the metatype as their base.
-    // FIXME: This has to be dynamically looked up for classes, and
-    // dynamically instantiated for generics.
-    if (var->isStatic()) {
-      auto baseTy = cast<NominalTypeDecl>(var->getDeclContext())
-        ->getDeclaredInterfaceType();
-      assert(!baseTy->is<BoundGenericType>() &&
-             "generic static stored properties not implemented");
-      assert((baseTy->getStructOrBoundGenericStruct() ||
-              baseTy->getEnumOrBoundGenericEnum()) &&
-             "static stored properties for classes/protocols not implemented");
-      auto baseMeta = MetatypeType::get(baseTy)->getCanonicalType();
-
-      auto metatype = B.createMetatype(loc,
-                                       getLoweredLoadableType(baseMeta));
-      auto metatypeMV = ManagedValue::forUnmanaged(metatype);
-      auto metatypeRV = RValue(*this, loc, baseMeta, metatypeMV);
-      selfSource = ArgumentSource(loc, std::move(metatypeRV));
-    }
-
-    bool isDirectAccessorUse =
-      (semantics == AccessSemantics::DirectToImplementation);
-    return emitGetAccessor(loc, getter,
-                           SGM.getNonMemberVarDeclSubstitutions(var),
-                           std::move(selfSource),
-                           /*isSuper=*/false, isDirectAccessorUse,
-                           RValue(), C);
+    return emitRValueForNonMemberVarDecl(loc, var, refType, semantics, C);
   }
   
   // If the referenced decl isn't a VarDecl, it should be a constant of some
@@ -1638,8 +1459,8 @@
     // in emitRValueForDecl that causing any borrow for this LValue to be
     // popped too soon.
     selfValue =
-        SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
-                              AccessKind::Read, dre->getAccessSemantics());
+      SGF.emitAddressOfLocalVarDecl(dre, vd, dre->getType()->getCanonicalType(),
+                                    AccessKind::Read);
     selfValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
                        E, dre->getType()->getCanonicalType(),
                        selfValue.getLValueAddress(), ctx)
@@ -2856,11 +2677,11 @@
     // in emitRValueForDecl that causing any borrow for this LValue to be
     // popped too soon.
     FES.emplace(SGF);
-    selfValue =
-        SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
-                              AccessKind::Read, dre->getAccessSemantics());
+    CanType formalRValueType = dre->getType()->getCanonicalType();
+    selfValue = SGF.emitAddressOfLocalVarDecl(dre, vd, formalRValueType,
+                                              AccessKind::Read);
     selfValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
-                       loc, dre->getType()->getCanonicalType(),
+                       loc, formalRValueType,
                        selfValue.getLValueAddress(), ctx)
                     .getAsSingleValue(SGF, loc);
   }
@@ -4364,8 +4185,8 @@
 
   // We know that self is a box, so get its address.
   SILValue selfAddr =
-    SGF.emitLValueForDecl(E, selfDecl, selfTy->getCanonicalType(),
-                          AccessKind::Write).getLValueAddress();
+    SGF.emitAddressOfLocalVarDecl(E, selfDecl, selfTy->getCanonicalType(),
+                                  AccessKind::Write).getLValueAddress();
 
   // Handle a nested optional case (see above).
   if (innerIsOptional)
@@ -4765,6 +4586,7 @@
     void visitTupleExpr(TupleExpr *E) {
       auto *TTy = E->getType()->castTo<TupleType>();
       assert(TTy->hasLValueType() || TTy->isVoid());
+      (void)TTy;
       for (auto &elt : E->getElements()) {
         visit(elt);
       }
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index d0d5b89..183e34d 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -498,6 +498,7 @@
     // Fix up the string parameters to have the right type.
     SILType nameArgTy = fnConv.getSILArgumentType(3);
     assert(nameArgTy == fnConv.getSILArgumentType(2));
+    (void)nameArgTy;
     auto managedName = ManagedValue::forUnmanaged(optName);
     SILValue nilValue;
     assert(optName->getType() == nameArgTy);
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index d7c69d8..6b49cc2 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -1059,14 +1059,18 @@
                               SILDeclRef constant,
                               CanSILFunctionType constantTy);
 
-  /// Emit the specified VarDecl as an LValue if possible, otherwise return
-  /// null.
-  ManagedValue emitLValueForDecl(SILLocation loc, VarDecl *var,
-                                 CanType formalRValueType,
-                                 AccessKind accessKind,
-                                 AccessSemantics semantics
-                                   = AccessSemantics::Ordinary);
-  
+  /// Given that a variable is a local stored variable, return its address.
+  ManagedValue emitAddressOfLocalVarDecl(SILLocation loc, VarDecl *var,
+                                         CanType formalRValueType,
+                                         AccessKind accessKind);
+
+  // FIXME: demote this to private state.
+  ManagedValue maybeEmitAddressOfNonMemberVarDecl(SILLocation loc,
+                                                  VarDecl *var,
+                                                  CanType formalRValueType,
+                                                  AccessKind accessKind,
+                                                  AccessSemantics semantics);
+
   /// Produce an RValue for a reference to the specified declaration,
   /// with the given type and in response to the specified expression.  Try to
   /// emit into the specified SGFContext to avoid copies (when provided).
@@ -1758,11 +1762,10 @@
   LValue emitLValue(Expr *E, AccessKind accessKind,
                     LValueOptions options = LValueOptions());
 
-  /// Emit a reference to a variable as an lvalue.
-  LValue emitLValueForAddressedNonMemberVarDecl(SILLocation loc, VarDecl *var,
-                                                CanType formalRValueType,
-                                                AccessKind accessKind,
-                                                AccessSemantics semantics);
+  RValue emitRValueForNonMemberVarDecl(SILLocation loc, VarDecl *var,
+                                       CanType formalRValueType,
+                                       AccessSemantics semantics,
+                                       SGFContext C);
 
   /// Emit an lvalue that directly refers to the given instance variable
   /// (without going through getters or setters).
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index f85301f..970b326 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -44,7 +44,9 @@
 
   LValueWritebackCleanup() : Depth() {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation loc) override {
+  void emit(SILGenFunction &SGF, CleanupLocation loc,
+            ForUnwind_t forUnwind) override {
+    // TODO: honor forUnwind!
     auto &evaluation = *SGF.FormalEvalContext.find(Depth);
     assert(evaluation.getKind() == FormalAccess::Exclusive);
     auto &lvalue = static_cast<ExclusiveBorrowFormalAccess &>(evaluation);
@@ -554,7 +556,8 @@
 
   UnenforcedAccessCleanup() : Depth() {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation loc) override {
+  void emit(SILGenFunction &SGF, CleanupLocation loc,
+            ForUnwind_t forUnwind) override {
     auto &evaluation = *SGF.FormalEvalContext.find(Depth);
     assert(evaluation.getKind() == FormalAccess::Unenforced);
     auto &formalAccess = static_cast<UnenforcedFormalAccess &>(evaluation);
@@ -2185,11 +2188,12 @@
         // in emitRValueForDecl that causing any borrow for this LValue to be
         // popped too soon.
         auto *vd = cast<ParamDecl>(dre->getDecl());
+        CanType formalRValueType = dre->getType()->getCanonicalType();
         ManagedValue selfLValue =
-            SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
-                                  AccessKind::Read, dre->getAccessSemantics());
+          SGF.emitAddressOfLocalVarDecl(dre, vd, formalRValueType,
+                                        AccessKind::Read);
         selfLValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
-                            e, dre->getType()->getCanonicalType(),
+                            e, formalRValueType,
                             selfLValue.getLValueAddress(), ctx)
                          .getAsSingleValue(SGF, e);
 
@@ -2276,17 +2280,6 @@
                                  CanType(), typeData, storageType);
 }
 
-LValue
-SILGenFunction::emitLValueForAddressedNonMemberVarDecl(SILLocation loc,
-                                                       VarDecl *var,
-                                                       CanType formalRValueType,
-                                                       AccessKind accessKind,
-                                                       AccessSemantics semantics) {
-  LValue lv;
-  addNonMemberVarDeclAddressorComponent(SGM, var, formalRValueType, lv);
-  return lv;
-}
-
 static LValue emitLValueForNonMemberVarDecl(SILGenFunction &SGF,
                                             SILLocation loc, VarDecl *var,
                                             CanType formalRValueType,
@@ -2321,8 +2314,9 @@
   case AccessStrategy::Storage: {
     // If it's a physical value (e.g. a local variable in memory), push its
     // address.
-    auto address = SGF.emitLValueForDecl(loc, var, formalRValueType,
-                                         accessKind, semantics);
+    auto address =
+      SGF.maybeEmitAddressOfNonMemberVarDecl(loc, var, formalRValueType,
+                                             accessKind, semantics);
     assert(address.isLValue() &&
            "physical lvalue decl ref must evaluate to an address");
     auto typeData = getPhysicalStorageTypeData(SGF.SGM, var, formalRValueType);
@@ -2357,6 +2351,212 @@
   return lv;
 }
 
+/// Emit the specified declaration as an address if possible,
+/// otherwise return null.
+ManagedValue
+SILGenFunction::maybeEmitAddressOfNonMemberVarDecl(SILLocation loc,
+                                                   VarDecl *var,
+                                                   CanType formalRValueType,
+                                                   AccessKind accessKind,
+                                                   AccessSemantics semantics) {
+  // For local decls, use the address we allocated or the value if we have it.
+  auto It = VarLocs.find(var);
+  if (It != VarLocs.end()) {
+    // If this has an address, return it.  By-value let's have no address.
+    SILValue ptr = It->second.value;
+    if (ptr->getType().isAddress())
+      return ManagedValue::forLValue(ptr);
+
+    // Otherwise, it is an RValue let.
+    return ManagedValue();
+  }
+
+  auto strategy = var->getAccessStrategy(semantics, accessKind, FunctionDC);
+
+  switch (strategy.getKind()) {
+  case AccessStrategy::Storage:
+    // The only kind of stored variable that should make it to here is
+    // a global variable.  Just invoke its accessor function to get its
+    // address.
+    return emitGlobalVariableRef(loc, var);
+
+  case AccessStrategy::DirectToAccessor:
+  case AccessStrategy::DispatchToAccessor: {
+    auto accessor = strategy.getAccessor();
+    if (accessor != AccessorKind::Address &&
+        accessor != AccessorKind::MutableAddress)
+      return ManagedValue();
+
+    LValue lv;
+    addNonMemberVarDeclAddressorComponent(SGM, var, formalRValueType, lv);
+    return emitAddressOfLValue(loc, std::move(lv), accessKind);
+  }
+
+  case AccessStrategy::MaterializeToTemporary:
+    return ManagedValue();
+
+  case AccessStrategy::BehaviorStorage:
+    // TODO: Behaviors aren't supported on non-instance properties yet.
+    llvm_unreachable("not implemented");
+  }
+  llvm_unreachable("bad access strategy");
+}
+
+ManagedValue
+SILGenFunction::emitAddressOfLocalVarDecl(SILLocation loc, VarDecl *var,
+                                          CanType formalRValueType,
+                                          AccessKind accessKind) {
+  assert(var->getDeclContext()->isLocalContext());
+  assert(var->getImplInfo().isSimpleStored());
+  auto address =
+    maybeEmitAddressOfNonMemberVarDecl(loc, var, formalRValueType, accessKind,
+                                       AccessSemantics::Ordinary);
+  assert(address);
+  assert(address.isLValue());
+  return address;
+}
+
+RValue SILGenFunction::emitRValueForNonMemberVarDecl(SILLocation loc,
+                                                     VarDecl *var,
+                                                     CanType formalRValueType,
+                                                     AccessSemantics semantics,
+                                                     SGFContext C) {
+  // Any writebacks for this access are tightly scoped.
+  FormalEvaluationScope scope(*this);
+
+  // If this VarDecl is represented as an address, emit it as an lvalue, then
+  // perform a load to get the rvalue.
+  if (ManagedValue result =
+        maybeEmitAddressOfNonMemberVarDecl(loc, var, formalRValueType,
+                                           AccessKind::Read, semantics)) {
+    bool guaranteedValid = false;
+    IsTake_t shouldTake = IsNotTake;
+
+    // We should only end up in this path for local and global variables,
+    // i.e. ones whose lifetime is assured for the duration of the evaluation.
+    // Therefore, if the variable is a constant, the value is guaranteed
+    // valid as well.
+    if (var->isLet())
+      guaranteedValid = true;
+
+    // Protect the lvalue read with access markers. The !is<LValueType> assert
+    // above ensures that the "LValue" is actually immutable, so we use an
+    // unenforced access marker.
+    SILValue destAddr = result.getLValueAddress();
+    SILValue accessAddr = UnenforcedFormalAccess::enter(*this, loc, destAddr,
+                                                        SILAccessKind::Read);
+    auto propagateRValuePastAccess = [&](RValue &&rvalue) {
+      // Check if a new begin_access was emitted and returned as the
+      // RValue. This means that the load did not actually load. If so, then
+      // fix the rvalue to begin_access operand. The end_access cleanup
+      // doesn't change. FIXME: this can't happen with sil-opaque-values.
+      if (accessAddr != destAddr && rvalue.isComplete()
+          && rvalue.isPlusZero(*this) && !isa<TupleType>(rvalue.getType())) {
+        auto mv = std::move(rvalue).getScalarValue();
+        if (mv.getValue() == accessAddr)
+          mv = std::move(mv).transform(
+              cast<BeginAccessInst>(accessAddr)->getOperand());
+        return RValue(*this, loc, formalRValueType, mv);
+      }
+      return std::move(rvalue);
+    };
+    // If we have self, see if we are in an 'init' delegation sequence. If so,
+    // call out to the special delegation init routine. Otherwise, use the
+    // normal RValue emission logic.
+    if (var->getName() == getASTContext().Id_self &&
+        SelfInitDelegationState != NormalSelf) {
+      auto rvalue =
+        emitRValueForSelfInDelegationInit(loc, formalRValueType, accessAddr, C);
+      return propagateRValuePastAccess(std::move(rvalue));
+    }
+
+    // Avoid computing an abstraction pattern for local variables.
+    // This is a slight compile-time optimization, but more importantly
+    // it avoids problems where locals don't always have interface types.
+    if (var->getDeclContext()->isLocalContext()) {
+      auto &rvalueTL = getTypeLowering(formalRValueType);
+      auto rvalue = RValue(*this, loc, formalRValueType,
+                           emitLoad(loc, accessAddr, rvalueTL,
+                                    C, shouldTake, guaranteedValid));
+
+      return propagateRValuePastAccess(std::move(rvalue));
+    }
+
+    // Otherwise, do the full thing where we potentially bridge and
+    // reabstract the declaration.
+    auto origFormalType = SGM.Types.getAbstractionPattern(var);
+    auto rvalue = RValue(*this, loc, formalRValueType,
+                         emitLoad(loc, accessAddr, origFormalType,
+                                  formalRValueType,
+                                  getTypeLowering(formalRValueType),
+                                  C, shouldTake, guaranteedValid));
+    return propagateRValuePastAccess(std::move(rvalue));
+  }
+
+  // For local decls, use the address we allocated or the value if we have it.
+  auto It = VarLocs.find(var);
+  if (It != VarLocs.end()) {
+    // Mutable lvalue and address-only 'let's are LValues.
+    assert(!It->second.value->getType().isAddress() &&
+           "LValue cases should be handled above");
+
+    SILValue Scalar = It->second.value;
+
+    // For weak and unowned types, convert the reference to the right
+    // pointer.
+    if (Scalar->getType().is<ReferenceStorageType>()) {
+      Scalar = emitConversionToSemanticRValue(loc, Scalar,
+                                             getTypeLowering(formalRValueType));
+      // emitConversionToSemanticRValue always produces a +1 strong result.
+      return RValue(*this, loc, formalRValueType,
+                    emitManagedRValueWithCleanup(Scalar));
+    }
+
+    // This is a let, so we can make guarantees, so begin the borrow scope.
+    ManagedValue Result = emitManagedBeginBorrow(loc, Scalar);
+
+    // If the client can't handle a +0 result, retain it to get a +1.
+    // This is a 'let', so we can make guarantees.
+    return RValue(*this, loc, formalRValueType,
+                  C.isGuaranteedPlusZeroOk()
+                    ? Result : Result.copyUnmanaged(*this, loc));
+  }
+
+  assert(var->getGetter() && "Unknown rvalue case");
+
+  SILDeclRef getter = SGM.getGetterDeclRef(var);
+
+  ArgumentSource selfSource;
+
+  // Global properties have no base or subscript. Static properties
+  // use the metatype as their base.
+  // FIXME: This has to be dynamically looked up for classes, and
+  // dynamically instantiated for generics.
+  if (var->isStatic()) {
+    auto baseTy = cast<NominalTypeDecl>(var->getDeclContext())
+      ->getDeclaredInterfaceType();
+    assert(!baseTy->is<BoundGenericType>() &&
+           "generic static stored properties not implemented");
+    assert((baseTy->getStructOrBoundGenericStruct() ||
+            baseTy->getEnumOrBoundGenericEnum()) &&
+           "static stored properties for classes/protocols not implemented");
+    auto baseMeta = MetatypeType::get(baseTy)->getCanonicalType();
+
+    auto metatype = B.createMetatype(loc,
+                                     getLoweredLoadableType(baseMeta));
+    auto metatypeMV = ManagedValue::forUnmanaged(metatype);
+    auto metatypeRV = RValue(*this, loc, baseMeta, metatypeMV);
+    selfSource = ArgumentSource(loc, std::move(metatypeRV));
+  }
+
+  bool isDirectAccessorUse =
+    (semantics == AccessSemantics::DirectToImplementation);
+  return emitGetAccessor(loc, getter,
+                         SGM.getNonMemberVarDeclSubstitutions(var),
+                         std::move(selfSource),
+                         /*isSuper=*/false, isDirectAccessorUse,
+                         RValue(), C);
+}
 
 LValue SILGenLValue::visitDiscardAssignmentExpr(DiscardAssignmentExpr *e,
                                                 AccessKind accessKind,
diff --git a/lib/SILGen/SILGenMaterializeForSet.cpp b/lib/SILGen/SILGenMaterializeForSet.cpp
index 2d4b300..2948e1f 100644
--- a/lib/SILGen/SILGenMaterializeForSet.cpp
+++ b/lib/SILGen/SILGenMaterializeForSet.cpp
@@ -952,7 +952,8 @@
   public:
     DeallocateValueBuffer(SILType valueType, SILValue buffer)
       : Buffer(buffer), ValueType(valueType) {}
-    void emit(SILGenFunction &SGF, CleanupLocation loc) override {
+    void emit(SILGenFunction &SGF, CleanupLocation loc,
+              ForUnwind_t forUnwind) override {
       SGF.B.createDeallocValueBuffer(loc, ValueType, Buffer);
     }
     void dump(SILGenFunction &) const override {
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 3d884bb..ca398e1 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -570,7 +570,7 @@
       instanceType = metatypeType.getInstanceType();
 
     auto layout = instanceType.getExistentialLayout();
-    if (layout.superclass) {
+    if (layout.explicitSuperclass) {
       CanType openedType = ArchetypeType::getAnyOpened(inputSubstType);
       SILType loweredOpenedType = SGF.getLoweredType(openedType);
 
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index 5c358fb..ad65c96 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -45,7 +45,8 @@
   CleanupWriteBackToInOut(VarDecl *var, SILValue inoutAddr)
     : var(var), inoutAddr(inoutAddr) {}
 
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     // Assign from the local variable to the inout address with an
     // 'autogenerated' copyaddr.
     l.markAutoGenerated();
@@ -61,7 +62,8 @@
   SILValue box;
 public:
   StrongReleaseCleanup(SILValue box) : box(box) {}
-  void emit(SILGenFunction &SGF, CleanupLocation l) override {
+  void emit(SILGenFunction &SGF, CleanupLocation l,
+            ForUnwind_t forUnwind) override {
     SGF.B.emitDestroyValueOperation(l, box);
   }
 
@@ -105,6 +107,7 @@
             == parent->getParent()->mapTypeIntoContext(
                    SGF.getSILType(parameterInfo))
         && "argument does not have same type as specified by parameter info");
+    (void)parameterInfo;
 
     ManagedValue mv = SGF.B.createInputFunctionArgument(
         argType, loc.getAsASTNode<ValueDecl>());
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index dce2e32..54069ba 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -426,7 +426,7 @@
     SourceLoc deferLoc;
   public:
     DeferEscapeCheckerCleanup(SourceLoc deferLoc) : deferLoc(deferLoc) {}
-    void emit(SILGenFunction &SGF, CleanupLocation l) override {
+    void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
       assert(false && "Sema didn't catch exit out of a defer?");
     }
     void dump(SILGenFunction &) const override {
@@ -446,7 +446,7 @@
   public:
     DeferCleanup(SourceLoc deferLoc, Expr *call)
       : deferLoc(deferLoc), call(call) {}
-    void emit(SILGenFunction &SGF, CleanupLocation l) override {
+    void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
       SGF.Cleanups.pushCleanup<DeferEscapeCheckerCleanup>(deferLoc);
       auto TheCleanup = SGF.Cleanups.getTopCleanup();
 
@@ -1010,5 +1010,5 @@
   }
 
   // Branch to the cleanup destination.
-  Cleanups.emitBranchAndCleanups(ThrowDest, loc, exn);
+  Cleanups.emitBranchAndCleanups(ThrowDest, loc, exn, IsForUnwind);
 }
diff --git a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
index 7264c14..da5c56d 100644
--- a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
@@ -81,6 +81,7 @@
   bool isValid() const { return bool(site); }
 };
 
+LLVM_ATTRIBUTE_UNUSED
 raw_ostream &operator<<(raw_ostream &os, const AddressCapture &capture) {
   os << *capture.site.getInstruction() << " captures Arg #"
      << capture.calleeArgIdx;
diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp
index 40688d1..a765859 100644
--- a/lib/SILOptimizer/PassManager/PassManager.cpp
+++ b/lib/SILOptimizer/PassManager/PassManager.cpp
@@ -516,6 +516,7 @@
     SILTransform *Tr = Transformations[Idx];
     assert((isa<SILFunctionTransform>(Tr) || isa<SILModuleTransform>(Tr)) &&
            "Unexpected pass kind!");
+    (void)Tr;
 
     unsigned FirstFuncTrans = Idx;
     while (Idx < NumTransforms && isa<SILFunctionTransform>(Transformations[Idx]))
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 2ac6fc2..abc8a5e 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -393,6 +393,7 @@
             ConvertCalleeTy->getExtInfo().withNoEscape(false));
       assert(Use->get()->getType().castTo<SILFunctionType>() ==
              EscapingCalleeTy);
+      (void)EscapingCalleeTy;
       Uses.append(CFI->getUses().begin(), CFI->getUses().end());
       continue;
     }
diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp
index ba043ed..457adc6 100644
--- a/lib/SILOptimizer/Transforms/Outliner.cpp
+++ b/lib/SILOptimizer/Transforms/Outliner.cpp
@@ -1141,7 +1141,7 @@
   llvm::DenseMap<CanType, SILDeclRef> BridgeFromObjectiveCache;
 
 public:
-  /// Try matching an outlineable pattern from the current current instruction.
+  /// Try matching an outlineable pattern from the current instruction.
   OutlinePattern *tryToMatch(SILBasicBlock::iterator CurInst) {
     if (BridgedPropertyPattern.matchInstSequence(CurInst))
       return &BridgedPropertyPattern;
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 4349af2..d1fa971 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -4501,27 +4501,42 @@
       .diagnose();
 }
 
-static bool isRawRepresentableMismatch(Type fromType, Type toType,
-                                       KnownProtocolKind kind,
-                                       const ConstraintSystem &CS) {
+namespace {
+enum class RawRepresentableMismatch {
+  NotApplicable,
+  Convertible,
+  ExactMatch
+};
+}
+
+static RawRepresentableMismatch
+checkRawRepresentableMismatch(Type fromType, Type toType,
+                              KnownProtocolKind kind,
+                              const ConstraintSystem &CS) {
   toType = toType->lookThroughAllOptionalTypes();
   fromType = fromType->lookThroughAllOptionalTypes();
 
   // First check if this is an attempt to convert from something to
   // raw representable.
   if (conformsToKnownProtocol(fromType, kind, CS)) {
-    if (isRawRepresentable(toType, kind, CS))
-      return true;
+    if (auto rawType = isRawRepresentable(toType, kind, CS)) {
+      if (rawType->isEqual(fromType))
+        return RawRepresentableMismatch::ExactMatch;
+      return RawRepresentableMismatch::Convertible;
+    }
   }
 
   // Otherwise, it might be an attempt to convert from raw representable
   // to its raw value.
-  if (isRawRepresentable(fromType, kind, CS)) {
-    if (conformsToKnownProtocol(toType, kind, CS))
-      return true;
+  if (auto rawType = isRawRepresentable(fromType, kind, CS)) {
+    if (conformsToKnownProtocol(toType, kind, CS)) {
+      if (rawType->isEqual(toType))
+        return RawRepresentableMismatch::ExactMatch;
+      return RawRepresentableMismatch::Convertible;
+    }
   }
 
-  return false;
+  return RawRepresentableMismatch::NotApplicable;
 }
 
 static bool diagnoseRawRepresentableMismatch(CalleeCandidateInfo &CCI,
@@ -4546,13 +4561,17 @@
   if (!argType || argType->hasTypeVariable() || argType->hasUnresolvedType())
     return false;
 
-  ArrayRef<KnownProtocolKind> rawRepresentableProtocols = {
+  KnownProtocolKind rawRepresentableProtocols[] = {
       KnownProtocolKind::ExpressibleByStringLiteral,
       KnownProtocolKind::ExpressibleByIntegerLiteral};
 
   const auto &CS = CCI.CS;
   auto arguments = decomposeArgType(argType, argLabels);
-  auto *tupleArgs = dyn_cast<TupleExpr>(argExpr);
+
+  auto bestMatchKind = RawRepresentableMismatch::NotApplicable;
+  const UncurriedCandidate *bestMatchCandidate = nullptr;
+  KnownProtocolKind bestMatchProtocol;
+  size_t bestMatchIndex;
 
   for (auto &candidate : CCI.candidates) {
     auto *decl = candidate.getDecl();
@@ -4563,6 +4582,7 @@
       continue;
 
     auto parameters = candidate.getParameters();
+    // FIXME: Default arguments?
     if (parameters.size() != arguments.size())
       continue;
 
@@ -4573,24 +4593,38 @@
       for (auto kind : rawRepresentableProtocols) {
         // If trying to convert from raw type to raw representable,
         // or vice versa from raw representable (e.g. enum) to raw type.
-        if (!isRawRepresentableMismatch(argType, paramType, kind, CS))
-          continue;
-
-        auto *expr = argExpr;
-        if (tupleArgs)
-          expr = tupleArgs->getElement(i);
-
-        auto diag =
-            CS.TC.diagnose(expr->getLoc(), diag::cannot_convert_argument_value,
-                           argType, paramType);
-
-        tryRawRepresentableFixIts(diag, CS, argType, paramType, kind, expr);
-        return true;
+        auto matchKind = checkRawRepresentableMismatch(argType, paramType, kind,
+                                                       CS);
+        if (matchKind > bestMatchKind) {
+          bestMatchKind = matchKind;
+          bestMatchProtocol = kind;
+          bestMatchCandidate = &candidate;
+          bestMatchIndex = i;
+        }
       }
     }
   }
 
-  return false;
+  if (bestMatchKind == RawRepresentableMismatch::NotApplicable)
+    return false;
+
+  const Expr *expr = argExpr;
+  if (auto *tupleArgs = dyn_cast<TupleExpr>(argExpr))
+    expr = tupleArgs->getElement(bestMatchIndex);
+  expr = expr->getValueProvidingExpr();
+
+  auto parameters = bestMatchCandidate->getParameters();
+  auto paramType = parameters[bestMatchIndex].getType();
+  auto singleArgType = arguments[bestMatchIndex].getType();
+
+  auto diag = CS.TC.diagnose(expr->getLoc(),
+                             diag::cannot_convert_argument_value,
+                             singleArgType, paramType);
+
+  tryRawRepresentableFixIts(diag, CS, singleArgType, paramType,
+                            bestMatchProtocol, expr);
+  return true;
+
 }
 
 // Extract expression for failed argument number
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 66d97d4..b74d292 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1387,10 +1387,10 @@
     }
   }
 
-  if (layout.superclass) {
+  if (layout.explicitSuperclass) {
     auto subKind = std::min(ConstraintKind::Subtype, kind);
-    auto result = matchTypes(type1, layout.superclass, subKind, subflags,
-                             locator);
+    auto result = matchTypes(type1, layout.explicitSuperclass, subKind,
+                             subflags, locator);
     if (result.isFailure())
       return result;
   }
@@ -1398,6 +1398,14 @@
   for (auto *proto : layout.getProtocols()) {
     auto *protoDecl = proto->getDecl();
 
+    if (auto superclass = protoDecl->getSuperclass()) {
+      auto subKind = std::min(ConstraintKind::Subtype, kind);
+      auto result = matchTypes(type1, superclass, subKind,
+                               subflags, locator);
+      if (result.isFailure())
+        return result;
+    }
+
     switch (simplifyConformsToConstraint(type1, protoDecl, kind, locator,
                                          subflags)) {
       case SolutionKind::Solved:
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index e3367ae..58b2af2 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -808,6 +808,7 @@
                                              IsImplicit));
 }
 
+LLVM_ATTRIBUTE_UNUSED
 static bool isSynthesizedComputedProperty(AbstractStorageDecl *storage) {
   return (storage->getAttrs().hasAttribute<LazyAttr>() ||
           storage->getAttrs().hasAttribute<NSManagedAttr>());
diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp
index 5ad9840..3397329 100644
--- a/lib/Sema/TypeCheckAccess.cpp
+++ b/lib/Sema/TypeCheckAccess.cpp
@@ -956,7 +956,7 @@
           return false;
         Type ty = inherited.getType();
         if (ty->is<ProtocolCompositionType>())
-          if (auto superclass = ty->getExistentialLayout().superclass)
+          if (auto superclass = ty->getExistentialLayout().explicitSuperclass)
             ty = superclass;
         return ty->getAnyNominal() == superclassDecl;
       });
@@ -1476,7 +1476,7 @@
           return false;
         Type ty = inherited.getType();
         if (ty->is<ProtocolCompositionType>())
-          if (auto superclass = ty->getExistentialLayout().superclass)
+          if (auto superclass = ty->getExistentialLayout().explicitSuperclass)
             ty = superclass;
         return ty->getAnyNominal() == superclassDecl;
       });
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index ef7a897..da318aa 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -304,8 +304,8 @@
 /// needs whitespace.  If so, emit specific diagnostics for it and return true,
 /// otherwise return false.
 static bool diagnoseOperatorJuxtaposition(UnresolvedDeclRefExpr *UDRE,
-                                    DeclContext *DC,
-                                    TypeChecker &TC) {
+                                          DeclContext *DC,
+                                          TypeChecker &TC) {
   Identifier name = UDRE->getName().getBaseIdentifier();
   StringRef nameStr = name.str();
   if (!name.isOperator() || nameStr.size() < 2)
@@ -403,6 +403,32 @@
   }
 }
 
+
+static bool diagnoseRangeOperatorMisspell(UnresolvedDeclRefExpr *UDRE,
+                                          TypeChecker &TC) {
+  auto name = UDRE->getName().getBaseIdentifier();
+  if (!name.isOperator())
+    return false;
+
+  auto corrected = StringRef();
+  if (name.str() == ".." || name.str() == "...." ||
+      name.str() == ".…" || name.str() == "…" || name.str() == "….")
+    corrected = "...";
+  else if (name.str() == "...<" || name.str() == "....<" ||
+           name.str() == "…<")
+    corrected = "..<";
+
+  if (!corrected.empty()) {
+    TC.diagnose(UDRE->getLoc(), diag::use_unresolved_identifier_corrected,
+                name, true, corrected)
+      .highlight(UDRE->getSourceRange())
+      .fixItReplace(UDRE->getSourceRange(), corrected);
+
+    return true;
+  }
+  return false;
+}
+
 static bool findNonMembers(TypeChecker &TC,
                            ArrayRef<LookupResultEntry> lookupResults,
                            DeclRefKind refKind, bool breakOnMember,
@@ -455,7 +481,7 @@
 }
 
 /// Bind an UnresolvedDeclRefExpr by performing name lookup and
-/// returning the resultant expression.  Context is the DeclContext used
+/// returning the resultant expression. Context is the DeclContext used
 /// for the lookup.
 Expr *TypeChecker::
 resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC) {
@@ -473,10 +499,11 @@
   auto Lookup = lookupUnqualified(DC, Name, Loc, lookupOptions);
 
   if (!Lookup) {
-    // If we failed lookup of an operator, check to see it to see if it is
-    // because two operators are juxtaposed e.g. (x*-4) that needs whitespace.
-    // If so, emit specific diagnostics for it.
-    if (diagnoseOperatorJuxtaposition(UDRE, DC, *this)) {
+    // If we failed lookup of an operator, check to see if this is a range
+    // operator misspelling. Otherwise try to diagnose a juxtaposition
+    // e.g. (x*-4) that needs whitespace.
+    if (diagnoseRangeOperatorMisspell(UDRE, *this) ||
+        diagnoseOperatorJuxtaposition(UDRE, DC, *this)) {
       return new (Context) ErrorExpr(UDRE->getSourceRange());
     }
 
@@ -520,9 +547,8 @@
                                                         strlen(buffer)))
            != ~0U) {
       int length = (buffer - simpleName.get()) - offset;
-      char expectedCodepoint;
-      if ((expectedCodepoint =
-           confusable::tryConvertConfusableCharacterToASCII(codepoint))) {
+      if (auto expectedCodepoint =
+          confusable::tryConvertConfusableCharacterToASCII(codepoint)) {
         isConfused = true;
         expectedIdentifier += expectedCodepoint;
       } else {
@@ -544,7 +570,8 @@
 
       if (auto typo = corrections.claimUniqueCorrection()) {
         auto diag = diagnose(Loc, diag::use_unresolved_identifier_corrected,
-                             Name, Name.isOperator(), typo->CorrectedName);
+                             Name, Name.isOperator(),
+                             typo->CorrectedName.getBaseIdentifier().str());
         diag.highlight(UDRE->getSourceRange());
         typo->addFixits(diag);
       } else {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index b80ff7d..df67867 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -202,34 +202,6 @@
   
 } // namespace llvm
 
-/// Determine whether the given declaration can inherit a class.
-static bool canInheritClass(Decl *decl) {
-  // Classes can inherit from a class.
-  if (isa<ClassDecl>(decl))
-    return true;
-
-  // Generic type parameters can inherit a class.
-  if (isa<GenericTypeParamDecl>(decl))
-    return true;
-
-  // Associated types can inherit a class.
-  if (isa<AssociatedTypeDecl>(decl))
-    return true;
-
-  return false;
-}
-
-// Add implicit conformances to the given declaration.
-static void addImplicitConformances(
-              TypeChecker &tc, Decl *decl,
-              llvm::SmallSetVector<ProtocolDecl *, 4> &allProtocols) {
-  if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
-    SmallVector<ProtocolDecl *, 2> protocols;
-    nominal->getImplicitProtocols(protocols);
-    allProtocols.insert(protocols.begin(), protocols.end());
-  }
-}
-
 /// Check that the declaration attributes are ok.
 static void validateAttributes(TypeChecker &TC, Decl *D);
 
@@ -388,9 +360,7 @@
   // Check all of the types listed in the inheritance clause.
   Type superclassTy;
   SourceRange superclassRange;
-  llvm::SmallSetVector<ProtocolDecl *, 4> allProtocols;
   llvm::SmallDenseMap<CanType, std::pair<unsigned, SourceRange>> inheritedTypes;
-  addImplicitConformances(*this, decl, allProtocols);
   for (unsigned i = 0, n = inheritedClause.size(); i != n; ++i) {
     auto &inherited = inheritedClause[i];
 
@@ -406,20 +376,6 @@
     if (inheritedTy->hasError())
       continue;
 
-    // Retrieve the interface type for this inherited type.
-    //
-    // If we have a generic parameter, mapTypeOutOfContext() might not
-    // work yet, if we're calling this while building the generic
-    // signature. However, we're also not storing inheritedTy back
-    // anywhere, so it's OK to leave it as an archetype.
-    //
-    // FIXME: Ideally, we wouldn't have code paths that take a mix
-    // of archetypes and interface types. Other than generic parameters,
-    // the only time we get an interface type here is with invalid
-    // circular cases. That should be diagnosed elsewhere.
-    if (inheritedTy->hasArchetype() && !isa<GenericTypeParamDecl>(decl))
-      inheritedTy = inheritedTy->mapTypeOutOfContext();
-
     // Check whether we inherited from the same type twice.
     CanType inheritedCanTy = inheritedTy->getCanonicalType();
     auto knownType = inheritedTypes.find(inheritedCanTy);
@@ -460,14 +416,13 @@
       // Protocols, generic parameters and associated types can inherit
       // from subclass existentials, which are "exploded" into their
       // corresponding requirements.
+      //
+      // Classes can only inherit from subclass existentials that do not
+      // have a superclass term.
       if (isa<ProtocolDecl>(decl) ||
           isa<AbstractTypeParamDecl>(decl) ||
           (!layout.hasExplicitAnyObject &&
-           !layout.superclass)) {
-        for (auto proto : layout.getProtocols()) {
-          auto *protoDecl = proto->getDecl();
-          allProtocols.insert(protoDecl);
-        }
+           !layout.explicitSuperclass)) {
         continue;
       }
 
@@ -475,13 +430,8 @@
       // do not contain an explicit AnyObject member.
       if (isa<ClassDecl>(decl) &&
           !layout.hasExplicitAnyObject) {
-        for (auto proto : layout.getProtocols()) {
-          auto *protoDecl = proto->getDecl();
-          allProtocols.insert(protoDecl);
-        }
-
         // Superclass inheritance is handled below.
-        inheritedTy = layout.superclass;
+        inheritedTy = layout.explicitSuperclass;
         if (!inheritedTy)
           continue;
       }
@@ -526,10 +476,6 @@
       // Record the raw type.
       superclassTy = inheritedTy;
       superclassRange = inherited.getSourceRange();
-      
-      // Add the RawRepresentable conformance implied by the raw type.
-      allProtocols.insert(getProtocol(decl->getLoc(),
-                                      KnownProtocolKind::RawRepresentable));
       continue;
     }
 
@@ -550,7 +496,7 @@
 
       // If the declaration we're looking at doesn't allow a superclass,
       // complain.
-      if (!canInheritClass(decl)) {
+      if (isa<StructDecl>(decl) || isa<ExtensionDecl>(decl)) {
         diagnose(decl->getLoc(),
                  isa<ExtensionDecl>(decl)
                    ? diag::extension_class_inheritance
@@ -565,7 +511,7 @@
       }
 
       // If this is not the first entry in the inheritance clause, complain.
-      if (i > 0) {
+      if (isa<ClassDecl>(decl) && i > 0) {
         auto removeRange = getRemovalRange(i);
         diagnose(inherited.getSourceRange().Start,
                  diag::superclass_not_first, inheritedTy)
@@ -584,33 +530,13 @@
 
     // We can't inherit from a non-class, non-protocol type.
     diagnose(decl->getLoc(),
-             canInheritClass(decl)
-               ? diag::inheritance_from_non_protocol_or_class
-               : diag::inheritance_from_non_protocol,
+             (isa<StructDecl>(decl) || isa<ExtensionDecl>(decl))
+               ? diag::inheritance_from_non_protocol
+               : diag::inheritance_from_non_protocol_or_class,
              inheritedTy);
     // FIXME: Note pointing to the declaration 'inheritedTy' references?
     inherited.setInvalidType(Context);
   }
-
-  if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
-    // Check for circular inheritance.
-    // FIXME: The diagnostics here should be improved.
-    bool diagnosedCircularity = false;
-    for (unsigned i = 0, n = allProtocols.size(); i != n; /*in loop*/) {
-      if (allProtocols[i] == proto || allProtocols[i]->inheritsFrom(proto)) {
-        if (!diagnosedCircularity) {
-          diagnose(proto, diag::circular_protocol_def, proto->getName());
-          diagnosedCircularity = true;
-        }
-
-        allProtocols.remove(allProtocols[i]);
-        --n;
-        continue;
-      }
-
-      ++i;
-    }
-  }
 }
 
 /// Retrieve the set of protocols the given protocol inherits.
@@ -618,8 +544,21 @@
 getInheritedForCycleCheck(TypeChecker &tc,
                           ProtocolDecl *proto,
                           ProtocolDecl **scratch) {
-  tc.resolveInheritedProtocols(proto);
-  return proto->getInheritedProtocols();
+  TinyPtrVector<ProtocolDecl *> result;
+
+  for (unsigned index : indices(proto->getInherited())) {
+    if (auto type = proto->getInheritedType(index)) {
+      if (type->isExistentialType()) {
+        auto layout = type->getExistentialLayout();
+        for (auto protoTy : layout.getProtocols()) {
+          auto *protoDecl = protoTy->getDecl();
+          result.push_back(protoDecl);
+        }
+      }
+    }
+  }
+
+  return result;
 }
 
 /// Retrieve the superclass of the given class.
@@ -3532,14 +3471,6 @@
       checkCircularity(TC, PD, diag::circular_protocol_def,
                        DescriptiveDeclKind::Protocol, path);
 
-      // Make sure the parent protocols have been fully validated.
-      for (auto inherited : PD->getLocalProtocols()) {
-        TC.validateDecl(inherited);
-        for (auto *member : inherited->getMembers())
-          if (auto *requirement = dyn_cast<ValueDecl>(member))
-            TC.validateDecl(requirement);
-      }
-
       if (auto *SF = PD->getParentSourceFile()) {
         if (auto *tracker = SF->getReferencedNameTracker()) {
           bool isNonPrivate =
@@ -3590,6 +3521,9 @@
       canRequirementSig->print(llvm::errs());
       llvm::errs() << "\n";
     }
+
+    // Explicitly calculate this bit.
+    (void) PD->existentialTypeSupported(&TC);
   }
 
   void visitVarDecl(VarDecl *VD) {
@@ -6456,6 +6390,9 @@
   //
   // Returns whether the target conforms to the protocol.
   auto evaluateTargetConformanceTo = [&](ProtocolDecl *protocol) {
+    if (!protocol)
+      return false;
+
     auto targetType = target->getDeclaredInterfaceType();
     if (auto ref = conformsToProtocol(
                         targetType, protocol, target,
@@ -6493,12 +6430,11 @@
     }
   } else {
     auto argumentNames = member.getArgumentNames();
-    if (argumentNames.size() != 1)
+    if (member.isCompoundName() && argumentNames.size() != 1)
       return;
 
-    auto argumentName = argumentNames.front();
     if (baseName == DeclBaseName::createConstructor() &&
-        argumentName == Context.Id_from) {
+        (member.isSimpleName() || argumentNames.front() == Context.Id_from)) {
       // init(from:) may be synthesized as part of derived conformance to the
       // Decodable protocol.
       // If the target should conform to the Decodable protocol, check the
@@ -6507,7 +6443,8 @@
       (void)evaluateTargetConformanceTo(decodableProto);
     } else if (!baseName.isSpecial() &&
                baseName.getIdentifier() == Context.Id_encode &&
-               argumentName == Context.Id_to) {
+               (member.isSimpleName() ||
+                argumentNames.front() == Context.Id_to)) {
       // encode(to:) may be synthesized as part of derived conformance to the
       // Encodable protocol.
       // If the target should conform to the Encodable protocol, check the
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index 177533a..7cf2352 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -70,9 +70,7 @@
 
   auto abstractStorage = dyn_cast<AbstractStorageDecl>(member);
   assert((method || abstractStorage) && "Not a method or abstractStorage?");
-  SubscriptDecl *subscript = nullptr;
-  if (abstractStorage)
-    subscript = dyn_cast<SubscriptDecl>(abstractStorage);
+  SubscriptDecl *subscript = dyn_cast_or_null<SubscriptDecl>(abstractStorage);
 
   if (!member->hasInterfaceType()) {
     auto lazyResolver = ctx.getLazyResolver();
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index ad1d913..0e65a4a 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -220,8 +220,8 @@
       // pull out the superclass instead, and use that below.
       if (foundInType->isExistentialType()) {
         auto layout = foundInType->getExistentialLayout();
-        if (layout.superclass) {
-          conformingType = layout.superclass;
+        if (auto superclass = layout.getSuperclass()) {
+          conformingType = superclass;
         } else {
           // Non-subclass existential: don't need to look for further
           // conformance or witness.
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 22015c1..4dad072 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -1497,6 +1497,7 @@
       } else {
         auto parenTy = dyn_cast<ParenType>(elementType.getPointer());
         assert(parenTy && "Associated value type is neither paren nor tuple?");
+        (void)parenTy;
         
         auto *subPattern = new (Context) AnyPattern(SourceLoc());
         elements.push_back(TuplePatternElt(Identifier(), SourceLoc(),
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 367d8e7..056bf7e 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2783,6 +2783,21 @@
 
     case CheckKind::Access:
     case CheckKind::AccessOfSetter: {
+      // Swift 4.2 relaxed some rules for protocol witness matching.
+      //
+      // This meant that it was possible for an optional protocol requirement
+      // to have a witness where previously in Swift 4.1 it did not.
+      //
+      // Since witnesses must be as visible as the protocol, this caused a
+      // source compatibility break if the witness was not sufficiently
+      // visible.
+      //
+      // Work around this by discarding the witness if its not sufficiently
+      // visible.
+      if (!TC.Context.isSwiftVersionAtLeast(5))
+        if (requirement->getAttrs().hasAttribute<OptionalAttr>())
+          return ResolveWitnessResult::Missing;
+
       // Avoid relying on the lifetime of 'this'.
       const DeclContext *DC = this->DC;
       diagnoseOrDefer(requirement, false,
@@ -3796,8 +3811,8 @@
 
     // First, if we have a superclass constraint, the class may conform
     // concretely.
-    if (layout.superclass) {
-      if (auto result = conformsToProtocol(layout.superclass, Proto,
+    if (layout.explicitSuperclass) {
+      if (auto result = conformsToProtocol(layout.explicitSuperclass, Proto,
                                            DC, options)) {
         return result;
       }
@@ -3806,11 +3821,24 @@
     // Next, check if the existential contains the protocol in question.
     for (auto P : layout.getProtocols()) {
       auto *PD = P->getDecl();
+
       // If we found the protocol we're looking for, return an abstract
       // conformance to it.
-      if (PD == Proto || PD->inheritsFrom(Proto)) {
+      if (PD == Proto)
         return ProtocolConformanceRef(Proto);
+
+      // If the protocol has a superclass constraint, we might conform
+      // concretely.
+      if (auto superclass = PD->getSuperclass()) {
+        if (auto result = conformsToProtocol(superclass, Proto,
+                                             DC, options)) {
+          return result;
+        }
       }
+
+      // Now check refined protocols.
+      if (PD->inheritsFrom(Proto))
+        return ProtocolConformanceRef(Proto);
     }
 
     return None;
diff --git a/lib/Sema/TypeCheckRequestFunctions.cpp b/lib/Sema/TypeCheckRequestFunctions.cpp
index f973d65..7584fc9 100644
--- a/lib/Sema/TypeCheckRequestFunctions.cpp
+++ b/lib/Sema/TypeCheckRequestFunctions.cpp
@@ -103,7 +103,7 @@
     // If we found an existential with a superclass bound, return it.
     if (inheritedType->isExistentialType()) {
       if (auto superclassType =
-            inheritedType->getExistentialLayout().superclass) {
+            inheritedType->getExistentialLayout().explicitSuperclass) {
         if (superclassType->getClassOrBoundGenericClass()) {
           if (superclassType->hasArchetype())
             return superclassType->mapTypeOutOfContext();
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index a9f49a4..2e3ffd6 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -502,13 +502,6 @@
         }
       }
 
-      /// Convenience declaration to make the intersection operation look more
-      /// symmetric.
-      static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
-                             const DeclContext *DC) {
-        return a.intersect(b, TC, DC);
-      }
-
       // Returns the intersection of this space with another.  The intersection
       // is the largest shared subspace occupied by both arguments.
       Space intersect(const Space &other, TypeChecker &TC,
@@ -530,7 +523,7 @@
           std::transform(
               other.getSpaces().begin(), other.getSpaces().end(),
               std::back_inserter(intersectedCases),
-              [&](const Space &s) { return intersect(*this, s, TC, DC); });
+              [&](const Space &s) { return this->intersect(s, TC, DC); });
           return Space::forDisjunct(intersectedCases);
         }
 
@@ -540,7 +533,7 @@
         PAIRCASE (SpaceKind::Disjunct, SpaceKind::BooleanConstant):
         PAIRCASE (SpaceKind::Disjunct, SpaceKind::UnknownCase): {
           // (S1 || ... || Sn) & S iff (S & S1) && ... && (S & Sn)
-          return intersect(other, *this, TC, DC);
+          return other.intersect(*this, TC, DC);
         }
         PAIRCASE (SpaceKind::Type, SpaceKind::Type): {
           // Optimization: The intersection of equal types is that type.
@@ -548,10 +541,10 @@
             return other;
           } else if (canDecompose(this->getType(), DC)) {
             auto decomposition = decompose(TC, DC, this->getType());
-            return intersect(decomposition, other, TC, DC);
+            return decomposition.intersect(other, TC, DC);
           } else if (canDecompose(other.getType(), DC)) {
             auto decomposition = decompose(TC, DC, other.getType());
-            return intersect(*this, decomposition, TC, DC);
+            return this->intersect(decomposition, TC, DC);
           } else {
             return other;
           }
@@ -559,7 +552,7 @@
         PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
           if (canDecompose(this->getType(), DC)) {
             auto decomposition = decompose(TC, DC, this->getType());
-            return intersect(decomposition, other, TC, DC);
+            return decomposition.intersect(other, TC, DC);
           } else {
             return other;
           }
@@ -580,7 +573,7 @@
           std::transform(this->getSpaces().begin(), this->getSpaces().end(),
                          std::back_inserter(newSubSpaces),
                          [&](const Space &subSpace) {
-                           return intersect(subSpace, other, TC, DC);
+                           return subSpace.intersect(other, TC, DC);
                          });
           return Space::forConstructor(this->getType(), this->getHead(),
                                        this->canDowngradeToWarning(),
@@ -605,7 +598,7 @@
           auto j = other.getSpaces().begin();
           for (; i != this->getSpaces().end() && j != other.getSpaces().end();
                ++i, ++j) {
-            auto result = intersect(*i, *j, TC, DC);
+            auto result = i->intersect(*j, TC, DC);
             // If at least one of the constructor sub-spaces is empty,
             // it makes the whole space empty as well.
             if (result.isEmpty()) {
@@ -619,7 +612,7 @@
 
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Type):
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Constructor):
-          return intersect(other, *this, TC, DC);
+          return other.intersect(*this, TC, DC);
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::UnknownCase):
           if (other.isAllowedButNotRequired())
             return other;
@@ -635,7 +628,7 @@
 
           if (canDecompose(other.getType(), DC)) {
             auto decomposition = decompose(TC, DC, other.getType());
-            return intersect(*this, decomposition, TC, DC);
+            return this->intersect(decomposition, TC, DC);
           }
           return Space();
         }
@@ -645,7 +638,7 @@
           return Space();
 
         PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
-          return intersect(other, *this, TC, DC);
+          return other.intersect(*this, TC, DC);
         }
 
         PAIRCASE (SpaceKind::Empty, SpaceKind::BooleanConstant):
@@ -689,10 +682,10 @@
             return Space();
           } else if (canDecompose(this->getType(), DC)) {
             auto decomposition = decompose(TC, DC, this->getType());
-            return intersect(decomposition, other, TC, DC);
+            return decomposition.intersect(other, TC, DC);
           } else if (canDecompose(other.getType(), DC)) {
             auto decomposition = decompose(TC, DC, other.getType());
-            return intersect(*this, decomposition, TC, DC);
+            return this->intersect(decomposition, TC, DC);
           }
           return Space();
         }
@@ -783,7 +776,7 @@
             auto &s2 = *j;
             // If the intersection of each subspace is ever empty then the
             // two spaces are disjoint and their difference is the first space.
-            if (intersect(s1, s2, TC, DC).isEmpty()) {
+            if (s1.intersect(s2, TC, DC).isEmpty()) {
               return *this;
             }
 
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index cbfa4eb..9415621 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -944,22 +944,6 @@
     tc.diagnose(comp->getIdLoc(), diag::no_module_type,
                 comp->getIdentifier(), moduleType->getModule()->getName());
   } else {
-    // Situation where class tries to inherit from itself, such
-    // would produce an assertion when trying to lookup members of the class.
-    //
-    // FIXME: Handle this in a more principled way, since there are many
-    // similar checks.
-    if (auto superClass = parentType->getSuperclass()) {
-      if (superClass->isEqual(parentType)) {
-        auto decl = parentType->getAnyNominal();
-        if (decl) {
-          tc.diagnose(decl->getLoc(), diag::circular_class_inheritance,
-                      decl->getName());
-          return ErrorType::get(tc.Context);
-        }
-      }
-    }
-
     LookupResult memberLookup;
     // Let's try to lookup given identifier as a member of the parent type,
     // this allows for more precise diagnostic, which distinguishes between
@@ -2993,8 +2977,8 @@
 
     if (ty->isExistentialType()) {
       auto layout = ty->getExistentialLayout();
-      if (layout.superclass)
-        if (checkSuperclass(tyR->getStartLoc(), layout.superclass))
+      if (auto superclass = layout.explicitSuperclass)
+        if (checkSuperclass(tyR->getStartLoc(), superclass))
           continue;
       if (!layout.getProtocols().empty())
         HasProtocol = true;
@@ -3919,11 +3903,12 @@
     auto layout = T->getExistentialLayout();
 
     // See if the superclass is not @objc.
-    if (layout.superclass &&
-        !layout.superclass->getClassOrBoundGenericClass()->isObjC()) {
-      diagnose(TypeRange.Start, diag::not_objc_class_constraint,
-               layout.superclass);
-      return;
+    if (auto superclass = layout.explicitSuperclass) {
+      if (!superclass->getClassOrBoundGenericClass()->isObjC()) {
+        diagnose(TypeRange.Start, diag::not_objc_class_constraint,
+                 superclass);
+        return;
+      }
     }
 
     // Find a protocol that is not @objc.
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index bd6b9af..df0f7a4 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1428,6 +1428,7 @@
     assert(expectedType == getSILType(Ty, (SILValueCategory)TyCategory) &&
            "Type of a global variable does not match GlobalAddr.");
     (void)Ty;
+    (void)expectedType;
     if (OpCode == SILInstructionKind::GlobalAddrInst) {
       ResultVal = Builder.createGlobalAddr(Loc, g);
     } else {
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index e6f1e7c..50264ba 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -2433,6 +2433,7 @@
   // FIXME: Resilience: could write out vtable for fragile classes.
   const DeclContext *assocDC = SILMod->getAssociatedContext();
   assert(assocDC && "cannot serialize SIL without an associated DeclContext");
+  (void)assocDC;
   for (const SILVTable &vt : SILMod->getVTables()) {
     if ((ShouldSerializeAll || vt.isSerialized()) &&
         SILMod->shouldSerializeEntitiesAssociatedWithDeclContext(vt.getClass()))
diff --git a/stdlib/private/StdlibUnittest/GetOSVersion.mm b/stdlib/private/StdlibUnittest/GetOSVersion.mm
index 085ed92..e487546 100644
--- a/stdlib/private/StdlibUnittest/GetOSVersion.mm
+++ b/stdlib/private/StdlibUnittest/GetOSVersion.mm
@@ -15,7 +15,7 @@
 
 #include "swift/Runtime/Config.h"
 
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY extern "C"
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
 const char *
 getSystemVersionPlistProperty(const char *PropertyName) {
   // This function is implemented in Objective-C because Swift does not support
diff --git a/stdlib/private/StdlibUnittest/InterceptTraps.cpp b/stdlib/private/StdlibUnittest/InterceptTraps.cpp
index b1fdd08..e8f7987 100644
--- a/stdlib/private/StdlibUnittest/InterceptTraps.cpp
+++ b/stdlib/private/StdlibUnittest/InterceptTraps.cpp
@@ -33,7 +33,7 @@
   _exit(0);
 }
 
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY extern "C"
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
 void installTrapInterceptor() {
   // Disable buffering on stdout so that everything is printed before crashing.
   setbuf(stdout, 0);
diff --git a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp
index 1373304..ce47606 100644
--- a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp
+++ b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp
@@ -12,6 +12,6 @@
 
 #include "swift/Runtime/Config.h"
 
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY extern "C"
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
 void *getPointer(void *x) { return x; }
 
diff --git a/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm b/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm
index 3426c62..c2d9bf0 100644
--- a/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm
+++ b/stdlib/private/StdlibUnittestFoundationExtras/UnavailableFoundationMethodThunks.mm
@@ -13,7 +13,7 @@
 #include <Foundation/Foundation.h>
 #include "swift/Runtime/Config.h"
 
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY
 extern "C" void
 NSArray_getObjects(NSArray SWIFT_NS_RELEASES_ARGUMENT *_Nonnull nsArray,
                    id *objects, NSUInteger rangeLocation,
@@ -22,7 +22,7 @@
   SWIFT_CC_PLUSONE_GUARD([nsArray release]);
 }
 
-SWIFT_CC(swift) LLVM_LIBRARY_VISIBILITY
+SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY
 extern "C" void
 NSDictionary_getObjects(NSDictionary *_Nonnull nsDictionary,
                         id *objects, id *keys) {
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index 85fd10f..8bd108b 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -198,7 +198,6 @@
                 var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: range.count, alignment: MemoryLayout<UInt>.alignment)
                 defer { buffer.deallocate() }
 
-                let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
                 var enumerated = 0
                 d.enumerateBytes { (ptr, byteRange, stop) in
                     if byteRange.upperBound - _offset < range.lowerBound {
diff --git a/stdlib/public/core/FloatingPoint.swift.gyb b/stdlib/public/core/FloatingPoint.swift.gyb
index 2fb08da..60be846 100644
--- a/stdlib/public/core/FloatingPoint.swift.gyb
+++ b/stdlib/public/core/FloatingPoint.swift.gyb
@@ -2185,7 +2185,9 @@
           sign: source.sign,
           exponentBitPattern: Self.nan.exponentBitPattern,
           significandBitPattern: payload | Self.nan.significandBitPattern)
-      return payload_ == payload ? (value, true) : (value, false)
+      // We define exactness by equality after roundtripping; since NaN is never
+      // equal to itself, it can never be converted exactly.
+      return (value, false)
     }
 
     let exponent = source.exponent
@@ -2299,8 +2301,7 @@
   /// exactly.
   ///
   /// If the given floating-point value cannot be represented exactly, the
-  /// result is `nil`. A value that is NaN ("not a number") cannot be
-  /// represented exactly if its payload cannot be encoded exactly.
+  /// result is `nil`.
   ///
   /// - Parameter value: A floating-point value to be converted.
   @inlinable // FIXME(sil-serialize-all)
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 70b3580..8c4b7ba 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -3390,6 +3390,7 @@
   size_t numRequirements =
     protocol->NumRequirements + WitnessTableFirstRequirementOffset;
   assert(numPatternWitnesses <= numRequirements);
+  (void)numRequirements;
 
   // Number of bytes for any private storage used by the conformance itself.
   size_t privateSizeInWords = genericTable->WitnessTablePrivateSizeInWords;
diff --git a/stdlib/public/runtime/ReflectionMirror.mm b/stdlib/public/runtime/ReflectionMirror.mm
index b562138..9b8e190 100644
--- a/stdlib/public/runtime/ReflectionMirror.mm
+++ b/stdlib/public/runtime/ReflectionMirror.mm
@@ -257,11 +257,21 @@
 
 // Implementation for structs.
 struct StructImpl : ReflectionMirrorImpl {
+  bool isReflectable() {
+    const auto *Struct = static_cast<const StructMetadata *>(type);
+    const auto &Description = Struct->getDescription();
+    return Description->getTypeContextDescriptorFlags().isReflectable();
+  }
+
   char displayStyle() {
     return 's';
   }
   
   intptr_t count() {
+    if (!isReflectable()) {
+      return 0;
+    }
+
     auto *Struct = static_cast<const StructMetadata *>(type);
     return Struct->getDescription()->NumFields;
   }
@@ -399,11 +409,20 @@
 
 // Implementation for classes.
 struct ClassImpl : ReflectionMirrorImpl {
+  bool isReflectable() {
+    const auto *Class = static_cast<const ClassMetadata *>(type);
+    const auto &Description = Class->getDescription();
+    return Description->getTypeContextDescriptorFlags().isReflectable();
+  }
+
   char displayStyle() {
     return 'c';
   }
   
   intptr_t count() {
+    if (!isReflectable())
+      return 0;
+
     auto *Clas = static_cast<const ClassMetadata*>(type);
     auto count = Clas->getDescription()->NumFields;
 
diff --git a/stdlib/public/stubs/UnicodeNormalization.cpp b/stdlib/public/stubs/UnicodeNormalization.cpp
index 99d2c21..abc4638 100644
--- a/stdlib/public/stubs/UnicodeNormalization.cpp
+++ b/stdlib/public/stubs/UnicodeNormalization.cpp
@@ -78,31 +78,6 @@
 #include <mutex>
 #include <assert.h>
 
-static const UCollator *MakeRootCollator() {
-  UErrorCode ErrorCode = U_ZERO_ERROR;
-  UCollator *root = ucol_open("", &ErrorCode);
-  if (U_FAILURE(ErrorCode)) {
-    swift::crash("ucol_open: Failure setting up default collation.");
-  }
-  ucol_setAttribute(root, UCOL_NORMALIZATION_MODE, UCOL_ON, &ErrorCode);
-  ucol_setAttribute(root, UCOL_STRENGTH, UCOL_TERTIARY, &ErrorCode);
-  ucol_setAttribute(root, UCOL_NUMERIC_COLLATION, UCOL_OFF, &ErrorCode);
-  ucol_setAttribute(root, UCOL_CASE_LEVEL, UCOL_OFF, &ErrorCode);
-  if (U_FAILURE(ErrorCode)) {
-    swift::crash("ucol_setAttribute: Failure setting up default collation.");
-  }
-  return root;
-}
-
-// According to this thread in the ICU mailing list, it should be safe
-// to assume the UCollator object is thread safe so long as you're only
-// passing it to functions that take a const pointer to it. So, we make it
-// const here to make sure we don't misuse it.
-// http://sourceforge.net/p/icu/mailman/message/27427062/
-static const UCollator *GetRootCollator() {
-  return SWIFT_LAZY_CONSTANT(MakeRootCollator());
-}
-
 /// Convert the unicode string to uppercase. This function will return the
 /// required buffer length as a result. If this length does not match the
 /// 'DestinationCapacity' this function must be called again with a buffer of
diff --git a/test/ClangImporter/Inputs/objc_init_generics.h b/test/ClangImporter/Inputs/objc_init_generics.h
new file mode 100644
index 0000000..624c79e
--- /dev/null
+++ b/test/ClangImporter/Inputs/objc_init_generics.h
@@ -0,0 +1,10 @@
+@import Foundation;
+
+@interface MyIntermediateClass : NSObject
+- (nonnull instancetype)initWithDouble:(double)value NS_DESIGNATED_INITIALIZER;
+@end
+
+@interface MyGenericClass<__covariant T> : MyIntermediateClass
+- (nonnull instancetype)initWithValue:(nonnull T)value;
+@end
+
diff --git a/test/ClangImporter/objc_init_generics.swift b/test/ClangImporter/objc_init_generics.swift
new file mode 100644
index 0000000..349eed1
--- /dev/null
+++ b/test/ClangImporter/objc_init_generics.swift
@@ -0,0 +1,17 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules -import-objc-header %S/Inputs/objc_init_generics.h %s -verify
+
+// REQUIRES: objc_interop
+
+// expected-no-diagnostics
+
+import Foundation
+
+class MyConcreteClass: MyGenericClass<NSObject> {
+  // Make sure we don't complain about this "override", because MyGenericClass
+  // was getting an init() that was distinct from its superclass's init() due
+  // to a bug in the Clang importer.
+	init() {
+    super.init(value: NSObject())
+	}
+}
+
diff --git a/test/Compatibility/anyobject_class.swift b/test/Compatibility/anyobject_class.swift
index 1d26d16..8c89eac 100644
--- a/test/Compatibility/anyobject_class.swift
+++ b/test/Compatibility/anyobject_class.swift
@@ -1,5 +1,5 @@
 // RUN: %target-typecheck-verify-swift -swift-version 4
-// RUN: not %target-swift-frontend -tyepcheck -swift-version 5
+// RUN: not %target-swift-frontend -typecheck -swift-version 5
 
 protocol P : class, AnyObject { } // expected-warning{{redundant inheritance from 'AnyObject' and Swift 3 'class' keyword}}{{14-21=}}
 // expected-warning@-1{{redundant constraint 'Self' : 'AnyObject'}}
diff --git a/test/Compatibility/optional_visibility.swift b/test/Compatibility/optional_visibility.swift
new file mode 100644
index 0000000..f2fa30c
--- /dev/null
+++ b/test/Compatibility/optional_visibility.swift
@@ -0,0 +1,13 @@
+// RUN: %target-typecheck-verify-swift -enable-objc-interop -swift-version 4
+
+@objc protocol Opt {
+  @objc optional func f(callback: @escaping () -> ())
+}
+
+class Conforms : Opt {
+  private func f(callback: () -> ()) {} // expected-note {{'f' declared here}}
+}
+
+func g(x: Conforms) {
+  _ = x.f(callback: {}) // expected-error {{'f' is inaccessible due to 'private' protection level}}
+}
diff --git a/test/Driver/emit_public_type_metadata_accessors.swift b/test/Driver/emit_public_type_metadata_accessors.swift
deleted file mode 100644
index 123c136..0000000
--- a/test/Driver/emit_public_type_metadata_accessors.swift
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: %target-build-swift %s -emit-public-type-metadata-accessors 2>&1 | %FileCheck %s
-
-// CHECK: the option '-emit-public-type-metadata-accessors' is no longer needed and is deprecated; consider removing it
diff --git a/test/Generics/superclass_constraint.swift b/test/Generics/superclass_constraint.swift
index ecbea04..33c373a 100644
--- a/test/Generics/superclass_constraint.swift
+++ b/test/Generics/superclass_constraint.swift
@@ -92,12 +92,11 @@
 // expected-warning@-3{{redundant conformance constraint 'T': 'P4'}}
 // expected-note@-4{{conformance constraint 'T': 'P4' implied here}}
 
-protocol P5: A { } // expected-error{{non-class type 'P5' cannot inherit from class 'A'}}
+protocol P5: A { }
 
 protocol P6: A, Other { } // expected-error {{protocol 'P6' cannot be a subclass of both 'Other' and 'A'}}
-// expected-error@-1{{non-class type 'P6' cannot inherit from class 'A'}}
-// expected-error@-2{{non-class type 'P6' cannot inherit from class 'Other'}}
-// expected-note@-3{{superclass constraint 'Self' : 'A' written here}}
+// expected-error@-1{{multiple inheritance from classes 'A' and 'Other'}}
+// expected-note@-2 {{superclass constraint 'Self' : 'A' written here}}
 
 func takeA(_: A) { }
 func takeP5<T: P5>(_ t: T) {
diff --git a/test/IDE/print_ast_tc_decls_errors.swift b/test/IDE/print_ast_tc_decls_errors.swift
index 2affaa9..d2b85f5 100644
--- a/test/IDE/print_ast_tc_decls_errors.swift
+++ b/test/IDE/print_ast_tc_decls_errors.swift
@@ -149,15 +149,15 @@
 // NO-TYREPR: {{^}}protocol ProtocolWithInheritance2 : <<error type>>, <<error type>> {{{$}}
 // TYREPR: {{^}}protocol ProtocolWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {{{$}}
 
-protocol ProtocolWithInheritance3 : FooClass {} // expected-error {{non-class type 'ProtocolWithInheritance3' cannot inherit from class 'FooClass'}}
-// NO-TYREPR: {{^}}protocol ProtocolWithInheritance3 : <<error type>> {{{$}}
+protocol ProtocolWithInheritance3 : FooClass {}
+// NO-TYREPR: {{^}}protocol ProtocolWithInheritance3 : FooClass {{{$}}
 // TYREPR: {{^}}protocol ProtocolWithInheritance3 : FooClass {{{$}}
 
-protocol ProtocolWithInheritance4 : FooClass, FooProtocol {} // expected-error {{non-class type 'ProtocolWithInheritance4' cannot inherit from class 'FooClass'}}
-// NO-TYREPR: {{^}}protocol ProtocolWithInheritance4 : <<error type>>, FooProtocol {{{$}}
+protocol ProtocolWithInheritance4 : FooClass, FooProtocol {}
+// NO-TYREPR: {{^}}protocol ProtocolWithInheritance4 : FooClass, FooProtocol {{{$}}
 // TYREPR: {{^}}protocol ProtocolWithInheritance4 : FooClass, FooProtocol {{{$}}
 
-protocol ProtocolWithInheritance5 : FooClass, BarClass {} // expected-error {{non-class type 'ProtocolWithInheritance5' cannot inherit from class 'FooClass'}} expected-error {{non-class type 'ProtocolWithInheritance5' cannot inherit from class 'BarClass'}} expected-error{{protocol 'ProtocolWithInheritance5' cannot be a subclass of both 'BarClass' and 'FooClass'}} // expected-note{{superclass constraint 'Self' : 'FooClass' written here}}
+protocol ProtocolWithInheritance5 : FooClass, BarClass {} // expected-error{{multiple inheritance from classes 'FooClass' and 'BarClass'}} expected-error{{protocol 'ProtocolWithInheritance5' cannot be a subclass of both 'BarClass' and 'FooClass'}} // expected-note{{superclass constraint 'Self' : 'FooClass' written here}}
 // NO-TYREPR: {{^}}protocol ProtocolWithInheritance5 : <<error type>>, <<error type>> {{{$}}
 // TYREPR: {{^}}protocol ProtocolWithInheritance5 : FooClass, BarClass {{{$}}
 
diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift
index b68eca2..06b1e88 100644
--- a/test/IRGen/abitypes.swift
+++ b/test/IRGen/abitypes.swift
@@ -89,6 +89,7 @@
   // armv7-ios: [[RESULT:%.*]] = call float bitcast (void ()* @objc_msgSend to float (i8*, i8*, [4 x i32])*)(i8* [[SELFCAST]], i8* [[SEL]], [4 x i32] [[LOADED]])
 
   // armv7s-ios: define hidden swiftcc float @"$S8abitypes3FooC17getXFromRectSwift{{[_0-9a-zA-Z]*}}F"(float, float, float, float, [[SELF:%.*]]* swiftself) {{.*}} {
+  // armv7s-ios: [[DEBUGVAR:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4
   // armv7s-ios: [[COERCED:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4
   // armv7s-ios: [[SEL:%.*]] = load i8*, i8** @"\01L_selector(getXFromRect:)", align 4
   // armv7s-ios: [[CAST:%.*]] = bitcast [[MYRECT]]* [[COERCED]] to [4 x i32]*
diff --git a/test/IRGen/resilience_bypass.swift b/test/IRGen/resilience_bypass.swift
index e8492e7..4a17e95 100644
--- a/test/IRGen/resilience_bypass.swift
+++ b/test/IRGen/resilience_bypass.swift
@@ -4,13 +4,37 @@
 // RUN: %target-swift-frontend -emit-module -emit-module-path=%t/second.swiftmodule -module-name=second %S/Inputs/resilience_bypass/second.swift -I %t
 // RUN: %target-swift-frontend -emit-ir -enable-resilience-bypass %s -I %t | %FileCheck %s -DINT=i%target-ptrsize
 
+import first
 import second
 
 // CHECK:       define{{( dllexport| protected)?}} swiftcc [[INT]] @"$S17resilience_bypass7getSizeSiyF"() {{.*}} {
 // CHECK-NEXT:  entry:
+
+// FIXME: The metadata accessor call is not necessary
+// CHECK-NEXT:    [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$S6second1EOMa"
+// CHECK-NEXT:    [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0
+
 // CHECK-NEXT:    ret [[INT]] {{5|9}}
 // CHECK-NEXT:  }
 
 public func getSize() -> Int {
   return MemoryLayout<E>.size
 }
+
+public func makeE(_ s: S) -> E {
+  return .b(s)
+}
+
+// CHECK:       define{{( dllexport| protected)?}} swiftcc void @"$S17resilience_bypass7makeAnyyyp5first1SVF"(
+// CHECK-NEXT:  entry:
+
+// Make sure we form the existential using the result of the metadata accessor, instead of
+// directly using the address of the metadata global.
+//
+// FIXME: The metadata global should have hidden linkage to rule out this kind of bug.
+
+// CHECK-NEXT:    [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$S6second1EOMa"
+
+public func makeAny(_ s: S) -> Any {
+  return makeE(s)
+}
diff --git a/test/Interpreter/enforce_exclusive_access.swift b/test/Interpreter/enforce_exclusive_access.swift
index 3ddcb2c..7453be5 100644
--- a/test/Interpreter/enforce_exclusive_access.swift
+++ b/test/Interpreter/enforce_exclusive_access.swift
@@ -3,6 +3,7 @@
 //
 // RUN: %target-run %t/a.out
 // REQUIRES: executable_test
+// REQUIRES: rdar41660554
 
 // Tests for traps at run time when enforcing exclusive access.
 
diff --git a/test/Migrator/Inputs/Cities.swift b/test/Migrator/Inputs/Cities.swift
index edc531a..652cab9 100644
--- a/test/Migrator/Inputs/Cities.swift
+++ b/test/Migrator/Inputs/Cities.swift
@@ -77,7 +77,8 @@
 }
 
 public struct AwesomeCityAttribute: RawRepresentable {
-  public init?(rawValue: String) { self.rawValue = rawValue }
+  public init(rawValue: String) { self.rawValue = rawValue }
+  public init(_ rawValue: String) { self.rawValue = rawValue }
   public var rawValue: String
   public typealias RawValue = String
 }
@@ -86,6 +87,7 @@
   public struct Attribute: RawRepresentable {
     public static let KnownAttr = Wrapper.Attribute(rawValue: "")
     public init(rawValue: String) { self.rawValue = rawValue }
+    public init(_ rawValue: String) { self.rawValue = rawValue }
     public var rawValue: String
     public typealias RawValue = String
   }
diff --git a/test/Migrator/string-representable.swift b/test/Migrator/string-representable.swift
index 2178340..e9d31b2 100644
--- a/test/Migrator/string-representable.swift
+++ b/test/Migrator/string-representable.swift
@@ -49,11 +49,15 @@
 func revert(_ a: AwesomeCityAttribute, b: Wrapper.Attribute) {
   _ = AwesomeCityAttribute(rawValue: "somevalue")
   _ = AwesomeCityAttribute.init(rawValue: "somevalue")
+  _ = AwesomeCityAttribute("somevalue")
+  _ = AwesomeCityAttribute.init("somevalue")
   _ = a.rawValue
   _ = Wrapper.Attribute(rawValue: "somevalue")
   _ = Wrapper.Attribute.init(rawValue: "somevalue")
   _ = b.rawValue
   _ = Wrapper.Attribute.KnownAttr.rawValue
+  _ = Wrapper.Attribute("somevalue")
+  _ = Wrapper.Attribute.init("somevalue")
 }
 
 
diff --git a/test/Migrator/string-representable.swift.expected b/test/Migrator/string-representable.swift.expected
index 9108b47..318e369 100644
--- a/test/Migrator/string-representable.swift.expected
+++ b/test/Migrator/string-representable.swift.expected
@@ -49,11 +49,15 @@
 func revert(_ a: AwesomeCityAttribute, b: Wrapper.Attribute) {
   _ = "somevalue"
   _ = "somevalue"
+  _ = "somevalue"
+  _ = "somevalue"
   _ = a
   _ = "somevalue"
   _ = "somevalue"
   _ = b
   _ = NewAttributeWrapper.NewKnownAttr
+  _ = "somevalue"
+  _ = "somevalue"
 }
 
 
diff --git a/test/Parse/invalid.swift b/test/Parse/invalid.swift
index d76269b..428a5be 100644
--- a/test/Parse/invalid.swift
+++ b/test/Parse/invalid.swift
@@ -140,7 +140,7 @@
 }
 
 let x: () = ()
-!() // expected-error {{missing argument for parameter #1 in call}}
+!() // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
 !(()) // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
 !(x) // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
 !x // expected-error {{cannot convert value of type '()' to expected argument type 'Bool'}}
diff --git a/test/Sema/enum_raw_representable.swift b/test/Sema/enum_raw_representable.swift
index a92d185..27820c8 100644
--- a/test/Sema/enum_raw_representable.swift
+++ b/test/Sema/enum_raw_representable.swift
@@ -120,7 +120,7 @@
 // expected-error@-1 {{reference to member 'baz' cannot be resolved without a contextual type}}
 
 rdar32431165_1("")
-// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{15-15=E_32431165(rawValue: }} {{19-19=)}}
+// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{16-16=E_32431165(rawValue: }} {{18-18=)}}
 rdar32431165_1(42, "")
 // expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{20-20=E_32431165(rawValue: }} {{22-22=)}}
 
@@ -129,7 +129,7 @@
 func rdar32431165_2(_: Int, _: String) {}
 
 rdar32431165_2(E_32431165.bar)
-// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{15-15=}} {{31-31=.rawValue}}
+// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{16-16=}} {{30-30=.rawValue}}
 rdar32431165_2(42, E_32431165.bar)
 // expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{20-20=}} {{34-34=.rawValue}}
 
@@ -145,6 +145,29 @@
   // expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{11-11=}} {{17-17=.rawValue}}
 }
 
+func sr8150_helper1(_: Int) {}
+func sr8150_helper1(_: Double) {}
+
+func sr8150_helper2(_: Double) {}
+func sr8150_helper2(_: Int) {}
+
+func sr8150_helper3(_: Foo) {}
+func sr8150_helper3(_: Bar) {}
+
+func sr8150_helper4(_: Bar) {}
+func sr8150_helper4(_: Foo) {}
+
+func sr8150(bar: Bar) {
+  sr8150_helper1(bar)
+  // expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{18-18=}} {{21-21=.rawValue}}
+  sr8150_helper2(bar)
+  // expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{18-18=}} {{21-21=.rawValue}}
+  sr8150_helper3(0.0)
+  // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Bar'}} {{18-18=Bar(rawValue: }} {{21-21=)}}
+  sr8150_helper4(0.0)
+  // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Bar'}} {{18-18=Bar(rawValue: }} {{21-21=)}}
+}
+
 
 struct NotEquatable { }
 
diff --git a/test/attr/attr_dynamic_infer.swift b/test/attr/attr_dynamic_infer.swift
index cd0c9c3..3264184 100644
--- a/test/attr/attr_dynamic_infer.swift
+++ b/test/attr/attr_dynamic_infer.swift
@@ -1,16 +1,16 @@
-// RUN: %target-swift-ide-test -print-ast-typechecked -source-filename=%s -print-implicit-attrs -disable-objc-attr-requires-foundation-module -swift-version 3 | %FileCheck %s
+// RUN: %target-swift-ide-test -print-ast-typechecked -source-filename=%s -print-implicit-attrs -disable-objc-attr-requires-foundation-module | %FileCheck %s
 
 @objc class Super {
-  func baseFoo() {}
+  @objc dynamic func baseFoo() {}
 }
 
 // CHECK: extension Super {
 extension Super {
   // CHECK:  @objc dynamic func foo
-  func foo() { }
+  @objc func foo() { }
 
   // CHECK: @objc dynamic var prop: Super
-  var prop: Super {
+  @objc var prop: Super {
     // CHECK: @objc dynamic get
     get { return Super() }
     // CHECK: @objc dynamic set
@@ -18,7 +18,7 @@
   }
 
   // CHECK: @objc dynamic subscript(sup: Super) -> Super
-  subscript(sup: Super) -> Super {
+  @objc subscript(sup: Super) -> Super {
     // CHECK: @objc dynamic get
     get { return sup }
     // CHECK: @objc dynamic set
@@ -60,10 +60,10 @@
 
 extension FinalTests {
   // CHECK: @objc final func foo
-  final func foo() { }
+  @objc final func foo() { }
 
   // CHECK: @objc final var prop: Super
-  final var prop: Super {
+  @objc final var prop: Super {
     // CHECK: @objc final get
     get { return Super() }
     // CHECK: @objc final set
@@ -71,7 +71,7 @@
   }
 
   // CHECK: @objc final subscript(sup: Super) -> Super
-  final subscript(sup: Super) -> Super {
+  @objc final subscript(sup: Super) -> Super {
     // CHECK: @objc final get
     get { return sup }
     // CHECK: @objc final set
@@ -79,9 +79,9 @@
   }
 
   // CHECK: @objc static var x
-  static var x: Int = 0
+  @objc static var x: Int = 0
 
   // CHECK: @objc static func bar
-  static func bar() { }
+  @objc static func bar() { }
 }
 
diff --git a/test/decl/class/override.swift b/test/decl/class/override.swift
index 1fa1df1..b5b1962 100644
--- a/test/decl/class/override.swift
+++ b/test/decl/class/override.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -parse-as-library -enable-objc-interop -swift-version 3
+// RUN: %target-typecheck-verify-swift -parse-as-library -enable-objc-interop
 
 class A {
   func ret_sametype() -> Int { return 0 }
@@ -161,23 +161,23 @@
 }
 
 @objc class IUOTestBaseClass {
-  func none() {}
+  @objc func none() {}
 
-  func oneA(_: AnyObject) {}
-  func oneB(x: AnyObject) {}
-  func oneC(_ x: AnyObject) {}
+  @objc func oneA(_: AnyObject) {}
+  @objc func oneB(x: AnyObject) {}
+  @objc func oneC(_ x: AnyObject) {}
 
-  func manyA(_: AnyObject, _: AnyObject) {}
-  func manyB(_ a: AnyObject, b: AnyObject) {}
-  func manyC(var a: AnyObject,  // expected-error {{'var' as a parameter attribute is not allowed}}
-             var b: AnyObject) {} // expected-error {{'var' as a parameter attribute is not allowed}}
+  @objc func manyA(_: AnyObject, _: AnyObject) {}
+  @objc func manyB(_ a: AnyObject, b: AnyObject) {}
+  @objc func manyC(var a: AnyObject,  // expected-error {{'var' as a parameter attribute is not allowed}}
+                   var b: AnyObject) {} // expected-error {{'var' as a parameter attribute is not allowed}}
 
-  func result() -> AnyObject? { return nil }
-  func both(_ x: AnyObject) -> AnyObject? { return x }
+  @objc func result() -> AnyObject? { return nil }
+  @objc func both(_ x: AnyObject) -> AnyObject? { return x }
 
-  init(_: AnyObject) {}
-  init(one: AnyObject) {}
-  init(a: AnyObject, b: AnyObject) {}
+  @objc init(_: AnyObject) {}
+  @objc init(one: AnyObject) {}
+  @objc init(a: AnyObject, b: AnyObject) {}
 }
 
 class IUOTestSubclass : IUOTestBaseClass {
diff --git a/test/decl/func/operator.swift b/test/decl/func/operator.swift
index 9d87916..3c7bc1b 100644
--- a/test/decl/func/operator.swift
+++ b/test/decl/func/operator.swift
@@ -355,3 +355,13 @@
     if x == x && x = x { } // expected-error{{expression is not assignable: '&&' returns immutable value}}
   }
 }
+
+_ = 1..<1 // OK
+_ = 1…1 // expected-error {{use of unresolved operator '…'; did you mean '...'?}} {{6-9=...}}
+_ = 1….1 // expected-error {{use of unresolved operator '…'; did you mean '...'?}} {{6-9=...}}
+_ = 1.…1 // expected-error {{use of unresolved operator '.…'; did you mean '...'?}} {{6-10=...}}
+_ = 1…<1 // expected-error {{use of unresolved operator '…<'; did you mean '..<'?}} {{6-10=..<}}
+_ = 1..1 // expected-error {{use of unresolved operator '..'; did you mean '...'?}} {{6-8=...}}
+_ = 1....1 // expected-error {{use of unresolved operator '....'; did you mean '...'?}} {{6-10=...}}
+_ = 1...<1 // expected-error {{use of unresolved operator '...<'; did you mean '..<'?}} {{6-10=..<}}
+_ = 1....<1 // expected-error {{use of unresolved operator '....<'; did you mean '..<'?}} {{6-11=..<}}
diff --git a/test/decl/inherit/inherit.swift b/test/decl/inherit/inherit.swift
index a675255..10e193e 100644
--- a/test/decl/inherit/inherit.swift
+++ b/test/decl/inherit/inherit.swift
@@ -34,7 +34,7 @@
 struct S : A { } // expected-error{{non-class type 'S' cannot inherit from class 'A'}}
 
 // Protocol inheriting a class
-protocol Q : A { } // expected-error{{non-class type 'Q' cannot inherit from class 'A'}}
+protocol Q : A { }
 
 // Extension inheriting a class
 extension C : A { } // expected-error{{extension of type 'C' cannot inherit from class 'A'}}
@@ -44,14 +44,12 @@
 
 // Protocol composition in inheritance clauses
 struct S3 : P, P & Q { } // expected-error {{redundant conformance of 'S3' to protocol 'P'}}
-                         // expected-error @-1 {{'Q' requires that 'S3' inherit from 'A'}}
-                         // expected-note @-2 {{requirement specified as 'Self' : 'A' [with Self = S3]}}
-                         // expected-note @-3 {{'S3' declares conformance to protocol 'P' here}}
+                         // expected-error @-1 {{non-class type 'S3' cannot conform to class protocol 'Q'}}
+                         // expected-note @-2 {{'S3' declares conformance to protocol 'P' here}}
 struct S4 : P, P { }     // expected-error {{duplicate inheritance from 'P'}}
 struct S6 : P & { }      // expected-error {{expected identifier for type name}}
 struct S7 : protocol<P, Q> { }  // expected-error {{'protocol<...>' composition syntax has been removed; join the protocols using '&'}}
-                                // expected-error @-1 {{'Q' requires that 'S7' inherit from 'A'}}
-                                // expected-note @-2 {{requirement specified as 'Self' : 'A' [with Self = S7]}}
+                                // expected-error @-1 {{non-class type 'S7' cannot conform to class protocol 'Q'}}
 
 class GenericBase<T> {}
 
diff --git a/test/decl/nested/protocol.swift b/test/decl/nested/protocol.swift
index d886754..4bb32f0 100644
--- a/test/decl/nested/protocol.swift
+++ b/test/decl/nested/protocol.swift
@@ -66,12 +66,10 @@
 
 class OuterClass {
   protocol InnerProtocol : OuterClass { }
-  // expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OuterClass'}}
-  // expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
+  // expected-error@-1{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
 }
 
 class OtherGenericClass<T> {
   protocol InnerProtocol : OtherGenericClass { }
-  // expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OtherGenericClass<T>'}}
-  // expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
+  // expected-error@-1{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
 }
diff --git a/test/decl/nested/type_in_function.swift b/test/decl/nested/type_in_function.swift
index 509dcf8..97adaef 100644
--- a/test/decl/nested/type_in_function.swift
+++ b/test/decl/nested/type_in_function.swift
@@ -128,9 +128,10 @@
 func genericFunction<T>(t: T) {
   class First : Second<T>.UnknownType { }
   // expected-error@-1 {{type 'First' cannot be nested in generic function 'genericFunction(t:)'}}
+  // expected-error@-2 {{'UnknownType' is not a member type of 'Second<T>'}}
   class Second<T> : Second { }
   // expected-error@-1 {{type 'Second' cannot be nested in generic function 'genericFunction(t:)'}}
-  // expected-error@-2 2 {{'Second' inherits from itself}}
+  // expected-error@-2 {{'Second' inherits from itself}}
 }
 
 // Spurious "Self or associated type requirements" diagnostic.
diff --git a/test/decl/protocol/protocols.swift b/test/decl/protocol/protocols.swift
index 2e7dc74..a785ae5 100644
--- a/test/decl/protocol/protocols.swift
+++ b/test/decl/protocol/protocols.swift
@@ -39,7 +39,7 @@
 }
 
 protocol Bogus : Int {}
-// expected-error@-1{{inheritance from non-protocol type 'Int'}}
+// expected-error@-1{{inheritance from non-protocol, non-class type 'Int'}}
 // expected-error@-2{{type 'Self' constrained to non-protocol, non-class type 'Int'}}
 
 // Explicit conformance checks (successful).
@@ -98,15 +98,13 @@
 
 // Circular protocols
 
-protocol CircleMiddle : CircleStart { func circle_middle() } // expected-error 2 {{protocol 'CircleMiddle' refines itself}}
+protocol CircleMiddle : CircleStart { func circle_middle() } // expected-error {{protocol 'CircleMiddle' refines itself}}
 protocol CircleStart : CircleEnd { func circle_start() }
 // expected-note@-1{{protocol 'CircleStart' declared here}}
-// expected-error@-2{{protocol 'CircleStart' refines itself}}
 protocol CircleEnd : CircleMiddle { func circle_end()} // expected-note{{protocol 'CircleEnd' declared here}}
-// expected-error@-1{{protocol 'CircleEnd' refines itself}}
 
 protocol CircleEntry : CircleTrivial { }
-protocol CircleTrivial : CircleTrivial { } // expected-error 2{{protocol 'CircleTrivial' refines itself}}
+protocol CircleTrivial : CircleTrivial { } // expected-error {{protocol 'CircleTrivial' refines itself}}
 
 struct Circle {
   func circle_start() {}
diff --git a/test/decl/protocol/req/optional_visibility.swift b/test/decl/protocol/req/optional_visibility.swift
new file mode 100644
index 0000000..13c5dca
--- /dev/null
+++ b/test/decl/protocol/req/optional_visibility.swift
@@ -0,0 +1,15 @@
+// RUN: %target-typecheck-verify-swift -enable-objc-interop -swift-version 5
+
+@objc protocol Opt {
+  @objc optional func f(callback: @escaping () -> ())
+}
+
+class Conforms : Opt {
+  private func f(callback: () -> ()) {}
+  // expected-error@-1 {{method 'f(callback:)' must be declared internal because it matches a requirement in internal protocol 'Opt'}}
+  // expected-note@-2 {{mark the instance method as 'internal' to satisfy the requirement}}
+}
+
+func g(x: Conforms) {
+  _ = x.f(callback: {})
+}
diff --git a/test/decl/protocol/special/coding/class_codable_inherited.swift b/test/decl/protocol/special/coding/class_codable_inherited.swift
new file mode 100644
index 0000000..c19d32c
--- /dev/null
+++ b/test/decl/protocol/special/coding/class_codable_inherited.swift
@@ -0,0 +1,25 @@
+// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+
+class SR8083_Base: Codable {
+  var thing: String { return "Abstract" }
+}
+
+class SR8083_Sub: SR8083_Base {
+  override var thing: String { return "Yo" }
+}
+
+func sr8083(decoder: Decoder) throws {
+  _ = try SR8083_Sub(from: decoder)
+}
+
+// CHECK-LABEL: sil_vtable SR8083_Base {
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfc	// SR8083_Base.init()
+// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfC
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfc	// SR8083_Base.init(from:)
+// CHECK: {{^}$}}
+
+// CHECK-LABEL: sil_vtable SR8083_Sub {
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfc [override]	// SR8083_Sub.init()
+// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfC [override]	// SR8083_Sub.__allocating_init(from:)
+// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfc [override]	// SR8083_Sub.init(from:)
+// CHECK: {{^}$}}
diff --git a/test/lit.cfg b/test/lit.cfg
index 21d6cb0..10a0f0d 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -120,7 +120,7 @@
     elif run_os == 'tvos':
         return "simctl spawn 'Apple TV 4K'"
     elif run_os == 'watchos':
-        return "simctl spawn 'Apple Watch - 42mm'"
+        return "simctl spawn 'Apple Watch Series 3 - 38mm'"
     else:
         lit_config.fatal("Unknown simulator OS %r" % run_os)
 
diff --git a/test/stdlib/Reflection_objc.swift b/test/stdlib/Reflection_objc.swift
index 414221c..3ce8008 100644
--- a/test/stdlib/Reflection_objc.swift
+++ b/test/stdlib/Reflection_objc.swift
@@ -14,6 +14,7 @@
 
 import Swift
 import Foundation
+import simd
 
 #if os(macOS)
 import AppKit
@@ -284,6 +285,11 @@
 // CHECK-NEXT: HasStringQLO overboard
 // CHECK-NEXT: CanaryBase overboard
 
+// simd types get no reflection info, so should have no mirror children
+let x = float4(0)
+print("float4 has \(Mirror(reflecting: x).children.count) children")
+// CHECK-NEXT: float4 has 0 children
+
 // CHECK-LABEL: and now our song is done
 print("and now our song is done")
 
diff --git a/test/type/subclass_composition.swift b/test/type/subclass_composition.swift
index c1beafc..9fa66df 100644
--- a/test/type/subclass_composition.swift
+++ b/test/type/subclass_composition.swift
@@ -449,10 +449,10 @@
 
 protocol ProtoConstraintsSelfToClass where Self : Base<Int> {}
 
-protocol ProtoRefinesClass : Base<Int> {} // FIXME expected-error {{}}
+protocol ProtoRefinesClass : Base<Int> {}
 protocol ProtoRefinesClassAndProtocolAlias : BaseIntAndP2 {}
 protocol ProtoRefinesClassAndProtocolDirect : Base<Int> & P2 {}
-protocol ProtoRefinesClassAndProtocolExpanded : Base<Int>, P2 {} // FIXME expected-error {{}}
+protocol ProtoRefinesClassAndProtocolExpanded : Base<Int>, P2 {}
 
 class ClassConformsToClassProtocolBad1 : ProtoConstraintsSelfToClass {}
 // expected-error@-1 {{'ProtoConstraintsSelfToClass' requires that 'ClassConformsToClassProtocolBad1' inherit from 'Base<Int>'}}
diff --git a/utils/bug_reducer/README.md b/utils/bug_reducer/README.md
index 23b8615..4ca63cc 100644
--- a/utils/bug_reducer/README.md
+++ b/utils/bug_reducer/README.md
@@ -62,7 +62,7 @@
 
 Then the bug_reducer will first attempt to reduce the passes. Then, it will
 attempt to reduce the test case by splitting the module and only optimizing part
-of it. The output will be look something like:
+of it. The output will look something like:
 
     *** Successfully Reduced file!
     *** Final File: ${FINAL_SIB_FILE}
diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
index 1da8583..9b30b77 100644
--- a/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
+++ b/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
@@ -1,4 +1,9 @@
-// RUN: %target-swift-frontend %s -typecheck -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify
+
+// Note: this used to type check successfully in Swift 3. In Swift 4, it produces
+// an error, so probably this test isn't testing anything useful anymore, since
+// we already exercise many such cases in test/Constraints/tuple_arguments.swift.
+// However, there's no harm in keeping it around in case it exposes other bugs later.
 
 public enum R<V> {
   case value(V)
@@ -14,7 +19,7 @@
   public func test() -> P<I, [O]> {
     return P<I, [O]> { input in
       var output: [O] = []
-      _ = R<([O], I)>.value(output, input)
+      _ = R<([O], I)>.value(output, input) // expected-error {{enum element 'value' expects a single parameter of type '([O], I)'}}
       return R<([O], I)>.value((output, input))
     }
   }
diff --git a/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift b/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift
index 3a86462..7bb9057 100644
--- a/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift
+++ b/validation-test/compiler_crashers_2_fixed/0001-rdar19792730.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
 
 // rdar://problem/19792730
 
@@ -6,17 +6,17 @@
   Expected : Sequence,
   Actual : Sequence,
   T : Comparable
+>(expected: Expected, actual: Actual)
   where
   Expected.Iterator.Element == Actual.Iterator.Element,
-  Expected.Iterator.Element == T
->(expected: Expected, actual: Actual) {}
+  Expected.Iterator.Element == T {}
 
 public func foo<
   Expected : Sequence,
   Actual : Sequence,
   T : Comparable
+>(expected: Expected, actual: Actual)
   where
   Expected.Iterator.Element == Actual.Iterator.Element,
-  Expected.Iterator.Element == (T, T)
->(expected: Expected, actual: Actual) {}
+  Expected.Iterator.Element == (T, T) {}
 
diff --git a/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift b/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift
index 019c7aa..e71078e 100644
--- a/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift
+++ b/validation-test/compiler_crashers_2_fixed/0002-rdar19792768.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
 
 // rdar://problem/19792768
 
@@ -6,10 +6,10 @@
   Expected : Sequence,
   Actual : Sequence,
   T : Comparable
+>(_ expected: Expected, _ actual: Actual)
   where
   Expected.Iterator.Element == Actual.Iterator.Element,
-  Expected.Iterator.Element == (T, T)
->(_ expected: Expected, _ actual: Actual) {}
+  Expected.Iterator.Element == (T, T) {}
 
 func f() {
   foo(
diff --git a/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift b/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift
index 397b483..5496017 100644
--- a/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift
+++ b/validation-test/compiler_crashers_2_fixed/0012-rdar20270240.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
 
 protocol FooProtocol {
   associatedtype Element
@@ -10,9 +10,9 @@
 
   mutating func extend<
     C : FooProtocol
+  >(elements: C)
     where
     C.Element == Element
-  >(elements: C)
 }
 
 struct FooImpl<T> : FooProtocol {
@@ -27,8 +27,8 @@
 
   mutating func extend<
     C : FooProtocol
+  >(elements: C)
     where
-    C.Element == T
-  >(elements: C) {}
+    C.Element == T {}
 }
 
diff --git a/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift b/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift
index df46428..dddc8ff 100644
--- a/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift
+++ b/validation-test/compiler_crashers_2_fixed/0013-rdar19519590.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
 
 protocol SourceTargetTransformable {
     associatedtype Source
@@ -15,13 +15,13 @@
                                         SourceIterator: IteratorProtocol,
                                         TransformerIterator: IteratorProtocol,
                                         Transformable: SourceTargetTransformable
-                                      where
-                                        Transformable.Source == Source,
-                                        Transformable.Target == Target,
-                                        SourceIterator.Element == Source,
-                                        TransformerIterator.Element == Transformable.Transformer
                                       >
-       : IteratorProtocol {
+       : IteratorProtocol
+      where
+	Transformable.Source == Source,
+	Transformable.Target == Target,
+	SourceIterator.Element == Source,
+	TransformerIterator.Element == Transformable.Transformer {
     typealias Element = Target
     
     var sourceIterator: SourceIterator
@@ -46,10 +46,10 @@
         SourceSequence: Sequence,
         TransformerSequence: Sequence,
         Transformable: SourceTargetTransformable
+        >: Sequence
     where
         SourceSequence.Iterator.Element == Transformable.Source,
-        TransformerSequence.Iterator.Element == Transformable.Transformer
-        >: Sequence {
+        TransformerSequence.Iterator.Element == Transformable.Transformer {
     
     typealias Source = SourceSequence.Iterator.Element
     typealias Target = Transformable.Target
diff --git a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
index 8d2f13c..10346cf 100644
--- a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
+++ b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3
+// RUN: %target-swift-frontend %s -emit-silgen
 
 import StdlibUnittest
 
@@ -389,15 +389,16 @@
 }
 
 public func expectCustomizable<
-  T : Wrapper where
-  T : LoggingType,
-  T.Base : Wrapper, T.Base : LoggingType,
-  T.Log == T.Base.Log
+  T : Wrapper
 >(_: T, _ counters: TypeIndexed<Int>,
   stackTrace: SourceLocStack? = nil,
   file: String = #file, line: UInt = #line,
   collectMoreInfo: (()->String)? = nil
-) {
+)
+  where
+    T : LoggingType,
+    T.Base : Wrapper, T.Base : LoggingType,
+    T.Log == T.Base.Log {
   expectNotEqual(
     0, counters[T.self], collectMoreInfo?() ?? "",
     stackTrace: stackTrace ?? SourceLocStack(), file: file, line: line)
@@ -408,15 +409,16 @@
 }
 
 public func expectNotCustomizable<
-  T : Wrapper where
-  T : LoggingType,
-  T.Base : Wrapper, T.Base : LoggingType,
-  T.Log == T.Base.Log
+  T : Wrapper
 >(_: T, _ counters: TypeIndexed<Int>,
   stackTrace: SourceLocStack? = nil,
   file: String = #file, line: UInt = #line,
   collectMoreInfo: (()->String)? = nil
-) {
+)
+  where
+    T : LoggingType,
+    T.Base : Wrapper, T.Base : LoggingType,
+    T.Log == T.Base.Log {
   expectNotEqual(
     0, counters[T.self], collectMoreInfo?() ?? "",
     stackTrace: stackTrace ?? SourceLocStack(), file: file, line: line)
diff --git a/validation-test/compiler_crashers_2_fixed/0053-sr490.swift b/validation-test/compiler_crashers_2_fixed/0053-sr490.swift
index 0c0c6bc..e861bea 100644
--- a/validation-test/compiler_crashers_2_fixed/0053-sr490.swift
+++ b/validation-test/compiler_crashers_2_fixed/0053-sr490.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
 
 enum Value {
     case IntValue(Int)
@@ -13,7 +13,7 @@
 
 protocol RawProducable {
     var rawValueForType : Int16 { get }
-    init<T: Storable where T.Representation == Self>(value: T)
+    init<T: Storable>(value: T) where T.Representation == Self
 }
 
 extension Int : Storable {
diff --git a/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift b/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift
index 311a456..f222e36 100644
--- a/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift
+++ b/validation-test/compiler_crashers_2_fixed/0060-sr2702.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
-// RUN: %target-swift-frontend %s -emit-ir -O -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
+// RUN: %target-swift-frontend %s -emit-ir -O
 
 // REQUIRES: objc_interop
 
@@ -47,16 +47,14 @@
 		}
 		
 		let classesPtr = memory.assumingMemoryBound(to: Optional<AnyClass>.self)
-		let classes = AutoreleasingUnsafeMutablePointer<AnyClass?>(classesPtr)
+		let classes = AutoreleasingUnsafeMutablePointer<AnyClass>(classesPtr)
 		numClasses = objc_getClassList(classes, numClasses)
 
 		for i in 0 ..< Int(numClasses) {
 			// Go through the classes, find out if the class is kind of aClass
 			// and then add it to the list
 
-			guard let cl = classes[i] else {
-				continue
-			}
+			let cl = classes[i]
 
 			if XUClassKindOfClass(cl, wantedSuperclass: aClass) && cl != aClass {
 				result.append(cl as! T.Type)
diff --git a/validation-test/compiler_crashers_2_fixed/0165-rdar40722855.swift b/validation-test/compiler_crashers_2_fixed/0165-rdar40722855.swift
new file mode 100644
index 0000000..30e1905
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0165-rdar40722855.swift
@@ -0,0 +1,24 @@
+// RUN: %target-typecheck-verify-swift
+
+postfix operator %
+postfix func % (_: Any) {}
+
+prefix operator ~
+prefix func ~ (_: Any) {}
+
+func foo(_: String) -> Void {}
+func foo(_: Int) -> Void {}
+
+_ = foo("answer")% // Ok
+_ = ~foo(42)       // Ok
+
+class A {
+  func bar(_: Int) {}
+}
+
+extension A {
+  func bar(_ qux: String) {
+    bar(qux)% // Ok
+    ~bar(qux) // Ok
+  }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0166-rdar30168645.swift b/validation-test/compiler_crashers_2_fixed/0166-rdar30168645.swift
new file mode 100644
index 0000000..201d19a
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0166-rdar30168645.swift
@@ -0,0 +1,7 @@
+// RUN: %target-swift-frontend %s -emit-ir
+
+protocol P {}
+
+class Base<T: P> {}
+
+class Derived: Base<Derived>, P {}
diff --git a/validation-test/compiler_crashers_2_fixed/0167-rdar39059582.swift b/validation-test/compiler_crashers_2_fixed/0167-rdar39059582.swift
new file mode 100644
index 0000000..74acc48
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0167-rdar39059582.swift
@@ -0,0 +1,17 @@
+// RUN: %target-swift-frontend %s -emit-ir
+
+protocol X {
+  associatedtype R : Y
+}
+
+protocol Y {
+  associatedtype Q : X where Q.R == Self
+}
+
+struct B : Y {
+  typealias Q = L<B> 
+}
+
+struct L<V : Y> : X {
+  typealias R = V
+}
diff --git a/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift b/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift
index 9c9c20f..dd456bf 100644
--- a/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift
+++ b/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift
@@ -5,14 +5,14 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
 
 // Test case submitted to project by https://github.com/tmu (Teemu Kurppa)
 // rdar://18118173
 
 class a<T : Hashable> {
   var b = [T : Bool]()
-  init<S : Sequence where S.Iterator.Element == T>(_ c: S) {
+  init<S : Sequence>(_ c: S) where S.Iterator.Element == T {
     c.map { self.b[$0] = true }
   }
 }
diff --git a/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift b/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift
index 7eec361..50f1480 100644
--- a/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift
+++ b/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift
@@ -6,9 +6,9 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
 
 // Issue found by https://github.com/jansabbe (Jan Sabbe)
 
-class A<B : Collection where B : AnyObject> {
+class A<B : Collection> where B : AnyObject {
 }
diff --git a/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift
index 4059c59..057b5c5 100644
--- a/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift
+++ b/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift
@@ -5,13 +5,12 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -typecheck -verify -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify
 
 // Test case submitted to project by https://github.com/tmu (Teemu Kurppa)
 // rdar://18175202
 
-func d<b: Sequence, e where Optional<e> == b.Iterator.Element>(c : b) -> e? {
-  // expected-warning@-1 {{'where' clause next to generic parameters}}
+func d<b: Sequence, e>(c : b) -> e? where Optional<e> == b.Iterator.Element {
   for mx : e? in c { // expected-warning {{immutable value 'mx' was never used}}
   }
 }
diff --git a/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift
index e3410fa..6e6fffb 100644
--- a/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift
+++ b/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift
@@ -6,10 +6,9 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -typecheck -verify -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify
 
 // Issue found by https://github.com/julasamer (julasamer)
 
-struct c<d, e: b where d.c == e> { // expected-error {{use of undeclared type 'b'}} expected-error {{'c' is not a member type of 'd'}}
-  // expected-warning@-1 {{'where' clause next to generic parameters is deprecated}}
+struct c<d, e: b> where d.c == e { // expected-error {{use of undeclared type 'b'}} expected-error {{'c' is not a member type of 'd'}}
 }
diff --git a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
index dd315c5..64c07ba 100644
--- a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
+++ b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
@@ -6,7 +6,7 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -typecheck -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck
 
 // Issue found by https://github.com/austinzheng (Austin Zheng)
 
@@ -16,7 +16,7 @@
 }
 
 func foo() -> A<(String, String?)> {
-    _ = A<(String, String?)>.Just("abc", "def")
-    _ = A.Just("abc", "def")
-    return A.Just("abc", "def")
+    _ = A<(String, String?)>.Just(("abc", "def"))
+    _ = A.Just(("abc", "def"))
+    return A.Just(("abc", "def"))
 }
diff --git a/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift b/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift
index 336c601..6f76a91 100644
--- a/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift
+++ b/validation-test/compiler_crashers_fixed/28342-getpointerelementtype-is-not-storagetype.swift
@@ -5,7 +5,7 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
 protocol A {
     associatedtype B
 }
@@ -14,9 +14,9 @@
 }
 protocol E {
     associatedtype F
-    func g<T where F == T.B>(_: C<T>)
+    func g<T>(_: C<T>) where F == T.B
 }
 struct H: E {
     typealias F = Void
-    func g<T where F == T.B>(_: C<T>) {}
+    func g<T>(_: C<T>) where F == T.B {}
 }
diff --git a/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift b/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift
index 15f1ff5..d5b8f5e 100644
--- a/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift
+++ b/validation-test/compiler_crashers_fixed/28369-swift-decl-walk.swift
@@ -7,11 +7,11 @@
 
 // Credits: https://twitter.com/kiliankoe/status/752090953977036800
 
-// RUN: %target-swift-frontend %s -typecheck -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck
 protocol P {
 }
 struct A<T> {
-    func a<B where T: P>(b: B) -> B {
+    func a<B>(b: B) -> B where T: P {
       return b
     }
 }
diff --git a/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift b/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift
index d7b668a..7b961c3 100644
--- a/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift
+++ b/validation-test/compiler_crashers_fixed/28399-getpointerelementtype-is-not-storagetype.swift
@@ -5,15 +5,15 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: %target-swift-frontend %s -emit-ir -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir
 protocol A{associatedtype B
 }
 struct C<T:A>{
 }
 protocol E{associatedtype F
-func g<T where F==T.B>(_:C<T>)
+func g<T>(_:C<T>) where F==T.B
 }
 struct H:E{
 typealias F = Void
-func g<T where F==T.B>(_:C<T>){}
+func g<T>(_:C<T>) where F==T.B{}
 }
diff --git a/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift b/validation-test/compiler_crashers_fixed/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
similarity index 81%
rename from validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
rename to validation-test/compiler_crashers_fixed/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
index fdd416e..c0504d8 100644
--- a/validation-test/compiler_crashers/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
+++ b/validation-test/compiler_crashers_fixed/28869-swift-diagnosticengine-formatdiagnostictext-llvm-raw-ostream-llvm-stringref-llvm.swift
@@ -5,6 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-// REQUIRES: rdar38932729
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol A:A&CLong