Merge pull request #17515 from mikeash/nested-nserror-to-error-bridging

[Runtime] Extend ObjC bridging casts to convert NSError to Error when nested in a container type.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1e1d804..6cdc36f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -225,11 +225,10 @@
 * [SE-0143][]
 
   The standard library types `Optional`, `Array`, `ArraySlice`,
-  `ContiguousArray`, `Dictionary`, `DictionaryLiteral`, `Range`, and
-  `ClosedRange` now conform to the `Hashable` protocol when their element or
-  bound types (as the case may be) conform to `Hashable`.  This makes
-  synthesized `Hashable` implementations available for types that include stored
-  properties of these types.
+  `ContiguousArray`, `Dictionary`, `Range`, and `ClosedRange` now conform to the
+  `Hashable` protocol when their element or bound types (as the case may be)
+  conform to `Hashable`.  This makes synthesized `Hashable` implementations
+  available for types that include stored properties of these types.
 
 * [SE-0196][]
   
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 80fc41b..10fbf98 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -1870,6 +1870,13 @@
               FILES "${UNIVERSAL_LIBRARY_NAME}"
               DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${resource_dir}/${resource_dir_sdk_subdir}"
               PERMISSIONS ${file_permissions})
+          swift_is_installing_component("${SWIFTLIB_INSTALL_IN_COMPONENT}" is_installing)
+
+          if(NOT is_installing)
+            set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${VARIANT_NAME})
+          else()
+            set_property(GLOBAL APPEND PROPERTY SWIFT_EXPORTS ${VARIANT_NAME})
+          endif()
         endif()
 
         # If we built static variants of the library, create a lipo target for
diff --git a/cmake/modules/SwiftSource.cmake b/cmake/modules/SwiftSource.cmake
index 6be8b08..04e9b27 100644
--- a/cmake/modules/SwiftSource.cmake
+++ b/cmake/modules/SwiftSource.cmake
@@ -257,9 +257,9 @@
                             "-Xfrontend" "${GROUP_INFO_JSON_FILE}")
   endif()
 
-  # Force swift 3 compatibility mode for Standard Library.
+  # Force swift 4 compatibility mode for Standard Library.
   if (SWIFTFILE_IS_STDLIB)
-    list(APPEND swift_flags "-swift-version" "3")
+    list(APPEND swift_flags "-swift-version" "4")
   endif()
   
   # Force swift 4 compatibility mode for overlays.
diff --git a/docs/Android.md b/docs/Android.md
index 8b97f16..112603c 100644
--- a/docs/Android.md
+++ b/docs/Android.md
@@ -82,7 +82,7 @@
     --android-api-level 21 \                   # The Android API level to target. Swift only supports 21 or greater.
     --android-icu-uc ${ARM_DIR}/libicuucswift.so \
     --android-icu-uc-include ${ARM_DIR}/icu/source/common \
-    --android-icu-i18 ${ARM_DIR}/libicui18nswift.so \
+    --android-icu-i18n ${ARM_DIR}/libicui18nswift.so \
     --android-icu-i18n-include ${ARM_DIR}/icu/source/i18n
 ```
 
diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md
index 52f850e..0c3b000 100644
--- a/docs/ContinuousIntegration.md
+++ b/docs/ContinuousIntegration.md
@@ -11,6 +11,7 @@
     - [Linting](#linting)
     - [Source Compatibility Testing](#source-compatibility-testing)
     - [Specific Preset Testing](#specific-preset-testing)
+    - [Build Swift Toolchain](#build-swift-toolchain)
     - [Testing Compiler Performance](#testing-compiler-performance)
 - [Cross Repository Testing](#cross-repository-testing)
 - [ci.swift.org bots](#ciswiftorg-bots)
@@ -150,6 +151,12 @@
 @swift-ci Please test macOS with preset
 
 ```
+### Build Swift Toolchain
+
+Platform       | Comment | Check Status
+------------   | ------- | ------------
+macOS platform | @swift-ci Please Build Toolchain macOS Platform| Swift Build Toolchain macOS Platform
+Linux platform | @swift-ci Please Build Toolchain Linux Platform| Swift Build Toolchain Linux Platform
 
 ### Testing Compiler Performance
 
diff --git a/docs/DebuggingTheCompiler.rst b/docs/DebuggingTheCompiler.rst
index 9c72f49..bbed049 100644
--- a/docs/DebuggingTheCompiler.rst
+++ b/docs/DebuggingTheCompiler.rst
@@ -437,6 +437,25 @@
 For more information and a high level example, see:
 ./swift/utils/bug_reducer/README.md.
 
+Using ``clang-tidy`` to run the Static Analyzer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Recent versions of LLVM package the tool ``clang-tidy``. This can be used in
+combination with a json compilation database to run static analyzer checks as
+well as cleanups/modernizations on a code-base. Swift's cmake invocation by
+default creates one of these json databases at the root path of the swift host
+build, for example on macOS::
+
+    $PATH_TO_BUILD/swift-macosx-x86_64/compile_commands.json
+
+Using this file, one invokes ``clang-tidy`` on a specific file in the codebase
+as follows::
+
+    clang-tidy -p=$PATH_TO_BUILD/swift-macosx-x86_64/compile_commands.json $FULL_PATH_TO_FILE
+
+One can also use shell regex to visit multiple files in the same directory. Example::
+
+    clang-tidy -p=$PATH_TO_BUILD/swift-macosx-x86_64/compile_commands.json $FULL_PATH_TO_DIR/*.cpp
 
 Debugging Swift Executables
 ===========================
@@ -460,6 +479,13 @@
     Module: file = "/Volumes/Files/work/solon/build/build-swift/validation-test-macosx-x86_64/stdlib/Output/CollectionType.swift.gyb.tmp/CollectionType3", arch = "x86_64"
     Symbol: id = {0x0000008c}, range = [0x0000000100004db0-0x00000001000056f0), name="ext.CollectionType3.CollectionType3.MutableCollectionType2<A where A: CollectionType3.MutableCollectionType2>.(subscript.materializeForSet : (Swift.Range<A.Index>) -> Swift.MutableSlice<A>).(closure #1)", mangled="_TFFeRq_15CollectionType322MutableCollectionType2_S_S0_m9subscriptFGVs5Rangeqq_s16MutableIndexable5Index_GVs12MutableSliceq__U_FTBpRBBRQPS0_MS4__T_"
 
+Manually symbolication using LLDB
+---------------------------------
+
+One can perform manual symbolication of a crash log or an executable using LLDB
+without running the actual executable. For a detailed guide on how to do this,
+see: https://lldb.llvm.org/symbolication.html.
+
 Debugging LLDB failures
 =======================
 
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 082d901..5f3fa60 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -25,6 +25,8 @@
 - Using the latest Visual Studio version is recommended (tested with Visual
   Studio 2017 - Version 15.5.5). Swift may fail to build with older C++ 
   compilers.
+- Note that the release version of Swift on Windows may crash when you try to compile a 
+  Swift program. See bug report [SR-7867](https://bugs.swift.org/browse/SR-7867).
 
 ### 1. Install dependencies
 1. Latest version (2.7.12 tested) of [Python
@@ -44,6 +46,7 @@
 1. Clone `apple/swift-cmark` into a folder named `cmark`
 1. Clone `apple/swift-clang` into a folder named `clang`
 1. Clone `apple/swift-llvm` into a folder named `llvm`
+1. Clone `apple/swift-compiler-rt` into a folder named `compiler-rt`
 1. Clone `apple/swift` into a folder named `swift`
 - Currently, other repositories in the Swift project have not been tested and
   may not be supported.
@@ -51,7 +54,7 @@
 ### 3. Build ICU
 1. Download and extract the [ICU source
 code](http://site.icu-project.org/download) to a folder named `icu` in the same
-directory as the other Swift project repositories.
+directory as the other Swift project repositories (tested with ICU versions 55.1 and 59.1).
 1. Open `src/win32/allinone.sln` in Visual Studio.
 1. Make sure to select the correct architecture from the drop-down in Visual
 Studio.
@@ -81,32 +84,37 @@
 set swift_source_dir=path-to-directory-containing-all-cloned-repositories
 ```
 
+- Decide whether you want to build a release or debug version of Swift on Windows and 
+  replace the `CMAKE_BUILD_TYPE` parameter in the build steps below with the correct value 
+  (`Debug`, `RelWithDebInfoAssert` or `Release`) to avoid conflicts between the debug and 
+  non-debug version of the MSCRT library.
+
 ### 5. Build CMark
 - This must be done from within a developer command prompt. CMark is a fairly
   small project and should only take a few minutes to build.
 ```cmd
-mkdir "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/cmark-windows-amd64"
-pushd "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/cmark-windows-amd64"
-cmake -G "Ninja" "%swift_source_dir%/cmark"
+mkdir "%swift_source_dir%/build/Ninja-DebugAssert/cmark-windows-amd64"
+pushd "%swift_source_dir%/build/Ninja-DebugAssert/cmark-windows-amd64"
+cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug "%swift_source_dir%/cmark"
 popd
-cmake --build "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/cmark-windows-amd64/"
+cmake --build "%swift_source_dir%/build/Ninja-DebugAssert/cmark-windows-amd64/"
 ```
 
 ### 6. Build LLVM/Clang/Compiler-RT
 - This must be done from within a developer command prompt. LLVM and Clang are
   large projects, so building might take a few hours. Make sure that the build
-  type (e.g. Debug, Release, RelWithDebInfoAssert) for LLVM/Clang matches the
+  type (e.g. `Debug`, `Release`, `RelWithDebInfoAssert`) for LLVM/Clang matches the
   build type for Swift.
 - Optionally, you can omit building compiler-rt by removing all lines referring
   to `compiler-rt` below, which should give faster build times.
 ```cmd
 mklink /J "%swift_source_dir%/llvm/tools/clang" "%swift_source_dir%/clang"
 mklink /J "%swift_source_dir%/llvm/tools/compiler-rt" "%swift_source_dir%/compiler-rt"
-mkdir "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"
-pushd "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"
+mkdir "%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"
+pushd "%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"
 cmake -G "Ninja"^
  -DLLVM_ENABLE_ASSERTIONS=TRUE^
- -DCMAKE_BUILD_TYPE=RelWithDebInfo^
+ -DCMAKE_BUILD_TYPE=Debug^
  -DLLVM_TOOL_SWIFT_BUILD=NO^
  -DLLVM_INCLUDE_DOCS=TRUE^
  -DLLVM_TOOL_COMPILER_RT_BUILD=TRUE^
@@ -115,14 +123,14 @@
  -DLLVM_TARGETS_TO_BUILD=X86^
  "%swift_source_dir%/llvm"
 popd
-cmake --build "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"
+cmake --build "%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"
 ```
 - Store the LLVM `bin` directory in an environment variable so it can be used
   to build Swift. Assuming you followed the instructions exactly, the path
   below is correct, but it may be different based on your build variant and
   platform, so double check.
 ```cmd
-set llvm_bin_dir="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64/bin"
+set llvm_bin_dir="%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64/bin"
 ```
 
 ### 7. Build Swift
@@ -136,12 +144,12 @@
 cmake -G "Ninja" "%swift_source_dir%/swift"^
  -DCMAKE_BUILD_TYPE=Debug^
  -DSWIFT_PATH_TO_CMARK_SOURCE="%swift_source_dir%/cmark"^
- -DSWIFT_PATH_TO_CMARK_BUILD="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/cmark-windows-amd64"^
- -DSWIFT_CMARK_LIBRARY_DIR="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/cmark-windows-amd64/src"^
+ -DSWIFT_PATH_TO_CMARK_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/cmark-windows-amd64"^
+ -DSWIFT_CMARK_LIBRARY_DIR="%swift_source_dir%/build/Ninja-DebugAssert/cmark-windows-amd64/src"^
  -DSWIFT_PATH_TO_LLVM_SOURCE="%swift_source_dir%/llvm"^
- -DSWIFT_PATH_TO_LLVM_BUILD="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"^
+ -DSWIFT_PATH_TO_LLVM_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"^
  -DSWIFT_PATH_TO_CLANG_SOURCE="%swift_source_dir%/llvm/tools/clang"^
- -DSWIFT_PATH_TO_CLANG_BUILD="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"^
+ -DSWIFT_PATH_TO_CLANG_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"^
  -DICU_UC_INCLUDE_DIR="%swift_source_dir%/icu/include"^
  -DICU_UC_LIBRARY_DIRS="%swift_source_dir%/icu/lib64"^
  -DICU_I18N_INCLUDE_DIR="%swift_source_dir%/icu/include"^
@@ -153,7 +161,12 @@
  -DCMAKE_C_COMPILER="%llvm_bin_dir%/clang-cl.exe"^
  -DCMAKE_CXX_COMPILER="%llvm_bin_dir%/clang-cl.exe"^
  -DCMAKE_C_FLAGS="-fms-compatibility-version=19.00 /Z7"^
- -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 -Z7" ^
+ -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 -Z7"^
+ -DCMAKE_EXE_LINKER_FLAGS:STRING="/INCREMENTAL:NO"^
+ -DCMAKE_MODULE_LINKER_FLAGS="/INCREMENTAL:NO"^
+ -DCMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO"^
+ -DCMAKE_STATIC_LINKER_FLAGS="/INCREMENTAL:NO"^
+ -DCMAKE_INSTALL_PREFIX="C:/Program Files (x86)/Swift"^
  -DSWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER=FALSE
 popd
 cmake --build "%swift_source_dir%/build/Ninja-DebugAssert/swift-windows-amd64"
@@ -176,21 +189,40 @@
 - This must be done from within a developer command prompt and could take hours
   depending on your system.
 ```cmd
-mkdir "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/lldb-windows-amd64"
-pushd "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/lldb-windows-amd64"
+mkdir "%swift_source_dir%/build/Ninja-DebugAssert/lldb-windows-amd64"
+pushd "%swift_source_dir%/build/Ninja-DebugAssert/lldb-windows-amd64"
 cmake -G "Ninja" "%swift_source_dir%/lldb"^
-  -DCMAKE_BUILD_TYPE=RelWithDebInfo^
+  -DCMAKE_BUILD_TYPE=Debug^
   -DLLDB_PATH_TO_CMARK_SOURCE="%swift_source_dir%/cmark"^
-  -DLLDB_PATH_TO_CMARK_BUILD="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/cmark-windows-amd64"^
+  -DLLDB_PATH_TO_CMARK_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/cmark-windows-amd64"^
   -DLLDB_PATH_TO_LLVM_SOURCE="%swift_source_dir%/llvm"^
-  -DLLDB_PATH_TO_LLVM_BUILD="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"^
+  -DLLDB_PATH_TO_LLVM_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"^
   -DLLDB_PATH_TO_CLANG_SOURCE="%swift_source_dir%/clang"^
-  -DLLDB_PATH_TO_CLANG_BUILD="%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/llvm-windows-amd64"^
+  -DLLDB_PATH_TO_CLANG_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"^
+  -DLLDB_PATH_TO_SWIFT_SOURCE="%swift_source_dir%/swift"^
+  -DLLDB_PATH_TO_SWIFT_BUILD="%swift_source_dir%/build/Ninja-DebugAssert/swift-windows-amd64"^
+  -DCMAKE_C_COMPILER="%llvm_bin_dir%/clang-cl.exe"^
+  -DCMAKE_CXX_COMPILER="%llvm_bin_dir%/clang-cl.exe"^
+  -DCMAKE_C_FLAGS="-fms-compatibility-version=19.00 /Z7"^
+  -DCMAKE_CXX_FLAGS="-fms-compatibility-version=19.00 -Z7 -Wno-c++98-compat"^
   -DLLVM_ENABLE_ASSERTIONS=YES
 popd
 cmake --build "%swift_source_dir%/build/Ninja-RelWithDebInfoAssert/lldb-windows-amd64"
 ```
 
+### 9. Install Swift on Windows
+
+- Run ninja install:
+```cmd 
+pushd "%swift_source_dir%/build/Ninja-DebugAssert/swift-windows-amd64"
+ninja install
+popd
+```
+- Add the Swift on Windows binaries path (`C:\Program Files (x86)\Swift\bin`)  to the 
+  `Path` environment variable.
+- Add the Swift on Windows library path (`C:\Program Files (x86)\Swift\lib\swift\windows`) 
+  to the `Path` environment variable.
+
 ## MSVC
 
 Follow instructions 1-6 for `clang-cl`, but run the following instead to build Swift
diff --git a/docs/WindowsCrossCompile.md b/docs/WindowsCrossCompile.md
index 9e73691..30a0e60 100644
--- a/docs/WindowsCrossCompile.md
+++ b/docs/WindowsCrossCompile.md
@@ -1,6 +1,6 @@
 # Cross-compiling Swift for Windows with `clang`
 
-This document describes how to cross compile Swift on Windows on a non-Windows
+This document describes how to cross compile Swift for Windows on a non-Windows
 host. For more context on the status of Swift on Windows in general, see
 [Getting Started with Swift on Windows](./Windows.md)
 
diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h
index bb8d6bd..ab3cb49 100644
--- a/include/swift/ABI/Metadata.h
+++ b/include/swift/ABI/Metadata.h
@@ -3168,6 +3168,21 @@
 
   llvm::ArrayRef<GenericParamDescriptor> getGenericParams() const;
 
+  bool isSynthesizedRelatedEntity() const {
+    return getTypeContextDescriptorFlags().isSynthesizedRelatedEntity();
+  }
+
+  /// Return the tag used to discriminate declarations synthesized by the
+  /// Clang importer and give them stable identities.
+  StringRef getSynthesizedDeclRelatedEntityTag() const {
+    if (!isSynthesizedRelatedEntity())
+      return {};
+    // The tag name comes after the null terminator for the name.
+    const char *nameBegin = Name.get();
+    auto *nameEnd = nameBegin + strlen(nameBegin) + 1;
+    return nameEnd;
+  }
+
   /// Return the offset of the start of generic arguments in the nominal
   /// type's metadata. The returned value is measured in sizeof(void*).
   int32_t getGenericArgumentOffset() const;
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index 0a82e16..e59acda 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -1189,6 +1189,12 @@
     ///
     /// Meaningful for all type-descriptor kinds.
     IsReflectable = 2,
+    
+    /// Set if the type is a Clang-importer-synthesized related entity. After
+    /// the null terminator for the type name is another null-terminated string
+    /// containing the tag that discriminates the entity from other synthesized
+    /// declarations associated with the same declaration.
+    IsSynthesizedRelatedEntity = 3,
 
     /// Set if the context descriptor is includes metadata for dynamically
     /// constructing a class's vtables at metadata instantiation time.
@@ -1221,6 +1227,10 @@
   FLAGSET_DEFINE_FLAG_ACCESSORS(IsCTypedef, isCTypedef, setIsCTypedef)
   FLAGSET_DEFINE_FLAG_ACCESSORS(IsReflectable, isReflectable, setIsReflectable)
 
+  FLAGSET_DEFINE_FLAG_ACCESSORS(IsSynthesizedRelatedEntity,
+                                isSynthesizedRelatedEntity,
+                                setIsSynthesizedRelatedEntity)
+
   FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasVTable,
                                 class_hasVTable,
                                 class_setHasVTable)
diff --git a/include/swift/AST/ASTMangler.h b/include/swift/AST/ASTMangler.h
index 09d4898..9dd0e3c 100644
--- a/include/swift/AST/ASTMangler.h
+++ b/include/swift/AST/ASTMangler.h
@@ -197,6 +197,15 @@
 
   void appendBoundGenericArgs(Type type, bool &isFirstArgList);
 
+  /// Append the bound generics arguments for the given declaration context
+  /// based on a complete substitution map.
+  ///
+  /// \returns the number of generic parameters that were emitted
+  /// thus far.
+  unsigned appendBoundGenericArgs(DeclContext *dc,
+                                  SubstitutionMap subs,
+                                  bool &isFirstArgList);
+
   /// Append any retroactive conformances.
   void appendRetroactiveConformances(Type type);
 
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 553f334..23306bc 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -306,7 +306,7 @@
     NumElements : 32
   );
 
-  SWIFT_INLINE_BITFIELD(ValueDecl, Decl, 1+1+1,
+  SWIFT_INLINE_BITFIELD(ValueDecl, Decl, 1+1+1+1+1,
     AlreadyInLookupTable : 1,
 
     /// Whether we have already checked whether this declaration is a 
@@ -315,7 +315,13 @@
 
     /// Whether the decl can be accessed by swift users; for instance,
     /// a.storage for lazy var a is a decl that cannot be accessed.
-    IsUserAccessible : 1
+    IsUserAccessible : 1,
+
+    /// Whether the "IsObjC" bit has been computed yet.
+    IsObjCComputed : 1,
+
+    /// Whether this declaration is exposed to Objective-C.
+    IsObjC : 1
   );
 
   SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+4,
@@ -332,7 +338,7 @@
     StorageKind : 4
   );
 
-  SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+4+1+1+1,
+  SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+4+1+1+1+1,
     /// \brief Whether this property is a type property (currently unfortunately
     /// called 'static').
     IsStatic : 1,
@@ -351,7 +357,11 @@
 
     /// \brief Whether this is a property used in expressions in the debugger.
     /// It is up to the debugger to instruct SIL how to access this variable.
-    IsDebuggerVar : 1
+    IsDebuggerVar : 1,
+
+    /// \brief Whether this is a property defined in the debugger's REPL.
+    /// FIXME: Remove this once LLDB has proper support for resilience.
+    IsREPLVar : 1
   );
 
   SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 1 + NumDefaultArgumentKindBits,
@@ -2170,6 +2180,8 @@
     Bits.ValueDecl.AlreadyInLookupTable = false;
     Bits.ValueDecl.CheckedRedeclaration = false;
     Bits.ValueDecl.IsUserAccessible = true;
+    Bits.ValueDecl.IsObjCComputed = false;
+    Bits.ValueDecl.IsObjC = false;
   }
 
   // MemberLookupTable borrows a bit from this type
@@ -2190,7 +2202,7 @@
   /// Determine whether we have already checked whether this
   /// declaration is a redeclaration.
   bool alreadyCheckedRedeclaration() const { 
-    return Bits.ValueDecl.CheckedRedeclaration; 
+    return Bits.ValueDecl.CheckedRedeclaration;
   }
 
   /// Set whether we have already checked this declaration as a
@@ -2405,10 +2417,9 @@
   /// This can be true even if there is no 'objc' attribute on the declaration.
   /// In that case it was inferred by the type checker and set with a call to
   /// markAsObjC().
-  bool isObjC() const {
-    return getAttrs().hasAttribute<ObjCAttr>();
-  }
-  
+  bool isObjC() const;
+
+  /// Note whether this declaration is known to be exposed to Objective-C.
   void setIsObjC(bool Value);
 
   /// Is this declaration marked with 'final'?
@@ -3726,6 +3737,15 @@
 
   bool existentialTypeSupportedSlow(LazyResolver *resolver);
 
+  struct {
+    /// The superclass type and a bit to indicate whether the
+    /// superclass was computed yet or not.
+    llvm::PointerIntPair<Type, 1, bool> Superclass;
+  } LazySemanticInfo;
+
+  friend class SuperclassTypeRequest;
+  friend class TypeChecker;
+
 public:
   ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc, SourceLoc NameLoc,
                Identifier Name, MutableArrayRef<TypeLoc> Inherited,
@@ -3736,6 +3756,19 @@
   /// Retrieve the set of protocols inherited from this protocol.
   llvm::TinyPtrVector<ProtocolDecl *> getInheritedProtocols() const;
 
+  /// Determine whether this protocol has a superclass.
+  bool hasSuperclass() const { return (bool)getSuperclass(); }
+
+  /// Retrieve the superclass of this protocol, or null if there is no superclass.
+  Type getSuperclass() const;
+
+  /// Retrieve the ClassDecl for the superclass of this protocol, or null if there
+  /// is no superclass.
+  ClassDecl *getSuperclassDecl() const;
+
+  /// Set the superclass of this protocol.
+  void setSuperclass(Type superclass);
+
   /// Retrieve the set of AssociatedTypeDecl members of this protocol; this
   /// saves loading the set of members in cases where there's no possibility of
   /// a protocol having nested types (ObjC protocols).
@@ -4556,6 +4589,7 @@
     Bits.VarDecl.Specifier = static_cast<unsigned>(Sp);
     Bits.VarDecl.IsCaptureList = IsCaptureList;
     Bits.VarDecl.IsDebuggerVar = false;
+    Bits.VarDecl.IsREPLVar = false;
     Bits.VarDecl.HasNonPatternBindingInit = false;
     setType(Ty);
   }
@@ -4742,6 +4776,13 @@
   void setDebuggerVar(bool IsDebuggerVar) {
     Bits.VarDecl.IsDebuggerVar = IsDebuggerVar;
   }
+  
+  /// Is this a special debugger REPL variable?
+  /// FIXME: Remove this once LLDB has proper support for resilience.
+  bool isREPLVar() const { return Bits.VarDecl.IsREPLVar; }
+  void setREPLVar(bool IsREPLVar) {
+    Bits.VarDecl.IsREPLVar = IsREPLVar;
+  }
 
   /// Return the Objective-C runtime name for this property.
   Identifier getObjCPropertyName() const;
diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def
index 873f081..c388f9c 100644
--- a/include/swift/AST/DiagnosticsFrontend.def
+++ b/include/swift/AST/DiagnosticsFrontend.def
@@ -220,6 +220,10 @@
       "symbol '%0' (%1) is in generated IR file, but not in TBD file",
       (StringRef, StringRef))
 
+ERROR(tbd_validation_failure,none,
+      "please file a radar or open a bug on bugs.swift.org with this code, and "
+      "add -Xfrontend -validate-tbd-against-ir=none to squash the errors", ())
+
 ERROR(redundant_prefix_compilation_flag,none,
       "invalid argument '-D%0'; did you provide a redundant '-D' in your build settings?", 
       (StringRef))    
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 7331fda..c6d2e96 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
@@ -495,6 +495,9 @@
 ERROR(expr_smart_keypath_application_type_mismatch,none,
       "key path of type %0 cannot be applied to a base of type %1",
       (Type, Type))
+WARNING(expr_deprecated_writable_keypath,none,
+        "forming a writable keypath to property %0 that is read-only in this context "
+        "is deprecated and will be removed in a future release",(DeclName))
 
 // Selector expressions.
 ERROR(expr_selector_no_objc_runtime,none,
@@ -1823,7 +1826,7 @@
       "generic parameter base", (Identifier))
 
 ERROR(circular_protocol_def,none,
-      "circular protocol inheritance %0", (StringRef))
+      "protocol %0 refines itself", (Identifier))
 ERROR(objc_protocol_inherits_non_objc_protocol,none,
       "@objc protocol %0 cannot refine non-@objc protocol %1", (Type, Type))
 WARNING(protocol_composition_with_postfix,none,
@@ -2153,7 +2156,7 @@
 ERROR(superclass_of_open_not_open,none,
   "superclass %0 of open class must be open", (Type))
 ERROR(circular_class_inheritance,none,
-      "circular class inheritance %0", (StringRef))
+      "%0 inherits from itself", (Identifier))
 ERROR(inheritance_from_final_class,none,
       "inheritance from a final class %0", (Identifier))
 ERROR(inheritance_from_unspecialized_objc_generic_class,none,
@@ -2197,7 +2200,7 @@
 ERROR(multiple_enum_raw_types,none,
   "multiple enum raw types %0 and %1", (Type, Type))
 ERROR(circular_enum_inheritance,none,
-      "circular enum raw types %0", (StringRef))
+      "%0 has a raw type that depends on itself", (Identifier))
 ERROR(raw_type_not_first,none,
   "raw type %0 must appear first in the enum inheritance clause", (Type))
 ERROR(raw_type_not_literal_convertible,none,
diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h
index a630968..45a041d 100644
--- a/include/swift/AST/LazyResolver.h
+++ b/include/swift/AST/LazyResolver.h
@@ -74,6 +74,9 @@
   /// Retrieve the superclass of the given class.
   virtual Type getSuperclass(const ClassDecl *classDecl) = 0;
 
+  /// Retrieve the superclass of the given protocol.
+  virtual Type getSuperclass(const ProtocolDecl *protocolDecl) = 0;
+
   /// Resolve the raw type of the given enum.
   virtual Type getRawType(EnumDecl *enumDecl) = 0;
 
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index 5cfff48..3b1e4d9 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -35,6 +35,7 @@
 NODE(BoundGenericClass)
 NODE(BoundGenericEnum)
 NODE(BoundGenericStructure)
+NODE(BoundGenericProtocol)
 NODE(BoundGenericOtherNominalType)
 NODE(BoundGenericTypeAlias)
 NODE(BuiltinTypeName)
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index 18529be..835b4e7 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -244,13 +244,14 @@
 
   /// The different modes for validating TBD against the LLVM IR.
   enum class TBDValidationMode {
+    Default,        ///< Do the default validation for the current platform.
     None,           ///< Do no validation.
     MissingFromTBD, ///< Only check for symbols that are in IR but not TBD.
     All, ///< Check for symbols that are in IR but not TBD and TBD but not IR.
   };
 
   /// Compare the symbols in the IR against the TBD file we would generate.
-  TBDValidationMode ValidateTBDAgainstIR = TBDValidationMode::None;
+  TBDValidationMode ValidateTBDAgainstIR = TBDValidationMode::Default;
 
   /// The install_name to use in the TBD file.
   std::string TBDInstallName;
diff --git a/include/swift/Parse/ParseSILSupport.h b/include/swift/Parse/ParseSILSupport.h
index 8a335f8..00eaba3 100644
--- a/include/swift/Parse/ParseSILSupport.h
+++ b/include/swift/Parse/ParseSILSupport.h
@@ -43,11 +43,7 @@
     Parser &P;
   public:
     explicit PrettyStackTraceParser(Parser &P) : P(P) {}
-    void print(llvm::raw_ostream &out) const override {
-      out << "With parser at source location: ";
-      P.Tok.getLoc().print(out, P.Context.SourceMgr);
-      out << '\n';
-    }
+    void print(llvm::raw_ostream &out) const override;
   };
 } // end namespace swift
 
diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h
index 2173e25..a87f538 100644
--- a/include/swift/Remote/MetadataReader.h
+++ b/include/swift/Remote/MetadataReader.h
@@ -1138,12 +1138,13 @@
   Demangle::NodePointer
   buildNominalTypeMangling(ContextDescriptorRef descriptor,
                            Demangle::NodeFactory &nodeFactory) {
-    std::vector<std::pair<Demangle::Node::Kind, std::string>>
+    std::vector<std::pair<Demangle::Node::Kind, Demangle::NodePointer>>
       nameComponents;
     ContextDescriptorRef parent = descriptor;
     
     while (parent) {
       std::string nodeName;
+      std::string relatedTag;
       Demangle::Node::Kind nodeKind;
       
       auto getTypeName = [&]() -> bool {
@@ -1151,7 +1152,16 @@
           reinterpret_cast<const TargetTypeContextDescriptor<Runtime> *>
             (parent.getLocalBuffer());
         auto nameAddress = resolveRelativeField(parent, typeBuffer->Name);
-        return Reader->readString(RemoteAddress(nameAddress), nodeName);
+        if (!Reader->readString(RemoteAddress(nameAddress), nodeName))
+          return false;
+        
+        if (typeBuffer->isSynthesizedRelatedEntity()) {
+          nameAddress += nodeName.size() + 1;
+          if (!Reader->readString(RemoteAddress(nameAddress), relatedTag))
+            return false;
+        }
+        
+        return true;
       };
       
       bool isTypeContext = false;
@@ -1210,8 +1220,17 @@
         else if (typeFlags.isCTypedef())
           nodeKind = Demangle::Node::Kind::TypeAlias;
       }
+      
+      auto nameNode = nodeFactory.createNode(Node::Kind::Identifier,
+                                             nodeName);
+      if (!relatedTag.empty()) {
+        auto relatedNode =
+          nodeFactory.createNode(Node::Kind::RelatedEntityDeclName, relatedTag);
+        relatedNode->addChild(nameNode, nodeFactory);
+        nameNode = relatedNode;
+      }
 
-      nameComponents.emplace_back(nodeKind, nodeName);
+      nameComponents.emplace_back(nodeKind, nameNode);
       
       parent = readParentContextDescriptor(parent);
     }
@@ -1224,13 +1243,11 @@
     auto moduleInfo = std::move(nameComponents.back());
     nameComponents.pop_back();
     auto demangling =
-      nodeFactory.createNode(Node::Kind::Module, moduleInfo.second);
+      nodeFactory.createNode(Node::Kind::Module, moduleInfo.second->getText());
     for (auto &component : reversed(nameComponents)) {
-      auto name = nodeFactory.createNode(Node::Kind::Identifier,
-                                         component.second);
       auto parent = nodeFactory.createNode(component.first);
       parent->addChild(demangling, nodeFactory);
-      parent->addChild(name, nodeFactory);
+      parent->addChild(component.second, nodeFactory);
       demangling = parent;
     }
     
diff --git a/include/swift/SIL/MemAccessUtils.h b/include/swift/SIL/MemAccessUtils.h
index 562f5d8..3cc5dca 100644
--- a/include/swift/SIL/MemAccessUtils.h
+++ b/include/swift/SIL/MemAccessUtils.h
@@ -221,6 +221,7 @@
     }
   }
 
+  /// Return true if the storage is guaranteed local.
   bool isLocal() const {
     switch (getKind()) {
     case Box:
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index b5182bc..58be1f1 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -92,6 +92,15 @@
     this->silConv = silConv;
   }
 
+  void setOpenedArchetypesTracker(SILOpenedArchetypesTracker *Tracker) {
+    OpenedArchetypesTracker = Tracker;
+    OpenedArchetypes.setOpenedArchetypesTracker(OpenedArchetypesTracker);
+  }
+
+  SILOpenedArchetypesTracker *getOpenedArchetypesTracker() const {
+    return OpenedArchetypesTracker;
+  }
+
 protected:
   /// Notify the context of each new instruction after it is inserted in the
   /// instruction stream.
@@ -186,12 +195,11 @@
   }
 
   void setOpenedArchetypesTracker(SILOpenedArchetypesTracker *Tracker) {
-    C.OpenedArchetypesTracker = Tracker;
-    C.OpenedArchetypes.setOpenedArchetypesTracker(C.OpenedArchetypesTracker);
+    C.setOpenedArchetypesTracker(Tracker);
   }
 
   SILOpenedArchetypesTracker *getOpenedArchetypesTracker() const {
-    return C.OpenedArchetypesTracker;
+    return C.getOpenedArchetypesTracker();
   }
 
   SILOpenedArchetypesState &getOpenedArchetypes() { return C.OpenedArchetypes; }
diff --git a/include/swift/SIL/SILGlobalVariable.h b/include/swift/SIL/SILGlobalVariable.h
index a1d07bb..8203327 100644
--- a/include/swift/SIL/SILGlobalVariable.h
+++ b/include/swift/SIL/SILGlobalVariable.h
@@ -68,7 +68,8 @@
   /// once (either in its declaration, or once later), making it immutable.
   unsigned IsLet : 1;
 
-  /// The VarDecl associated with this SILGlobalVariable. For debugger purpose.
+  /// The VarDecl associated with this SILGlobalVariable. Must by nonnull for
+  /// language-level global variables.
   VarDecl *VDecl;
 
   /// Whether or not this is a declaration.
@@ -225,4 +226,38 @@
 
 } // end llvm namespace
 
+//===----------------------------------------------------------------------===//
+// Utilities for verification and optimization.
+//===----------------------------------------------------------------------===//
+
+namespace swift {
+
+/// Given an addressor, AddrF, return the global variable being addressed, or
+/// return nullptr if the addressor isn't a recognized pattern.
+SILGlobalVariable *getVariableOfGlobalInit(SILFunction *AddrF);
+
+/// Return the callee of a once call.
+SILFunction *getCalleeOfOnceCall(BuiltinInst *BI);
+
+/// Helper for getVariableOfGlobalInit(), so GlobalOpts can deeply inspect and
+/// rewrite the initialization pattern.
+///
+/// Given an addressor, AddrF, find the call to the global initializer if
+/// present, otherwise return null. If an initializer is returned, then
+/// `CallToOnce` is initialized to the corresponding builtin "once" call.
+SILFunction *findInitializer(SILModule *Module, SILFunction *AddrF,
+                             BuiltinInst *&CallToOnce);
+
+/// Helper for getVariableOfGlobalInit(), so GlobalOpts can deeply inspect and
+/// rewrite the initialization pattern.
+///
+/// Given a global initializer, InitFunc, return the GlobalVariable that it
+/// statically initializes or return nullptr if it isn't an obvious static
+/// initializer. If a global variable is returned, InitVal is initialized to the
+/// the instruction producing the global's initial value.
+SILGlobalVariable *getVariableOfStaticInitializer(
+  SILFunction *InitFunc, SingleValueInstruction *&InitVal);
+
+} // namespace swift
+
 #endif
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 78ae6d7..9b91efe 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -1930,8 +1930,6 @@
     assert(hasSelfArgument() && "Must have a self argument");
     assert(getNumArguments() && "Should only be called when Callee has "
            "at least a self parameter.");
-    assert(hasSubstitutions() && "Should only be called when Callee has "
-           "substitutions.");
     ArrayRef<Operand> ops = this->getArgumentOperands();
     ArrayRef<Operand> opsWithoutSelf = ArrayRef<Operand>(&ops[0],
                                                          ops.size()-1);
diff --git a/include/swift/SIL/SILLinkage.h b/include/swift/SIL/SILLinkage.h
index 6559bb7..e2b97af 100644
--- a/include/swift/SIL/SILLinkage.h
+++ b/include/swift/SIL/SILLinkage.h
@@ -17,6 +17,8 @@
 
 namespace swift {
 
+class ValueDecl;
+
 /// Linkage for a SIL object.  This concept combines the notions
 /// of symbol linkage and visibility.
 ///
@@ -176,6 +178,8 @@
   return linkage <= SILLinkage::Hidden;
 }
 
+SILLinkage getDeclSILLinkage(const ValueDecl *decl);
+
 inline bool hasPublicVisibility(SILLinkage linkage) {
   switch (linkage) {
   case SILLinkage::Public:
diff --git a/include/swift/SIL/SILLocation.h b/include/swift/SIL/SILLocation.h
index 988e1cf..75061c2 100644
--- a/include/swift/SIL/SILLocation.h
+++ b/include/swift/SIL/SILLocation.h
@@ -406,6 +406,13 @@
   /// Return the location as a DeclContext or null.
   DeclContext *getAsDeclContext() const;
 
+  /// Convert a specialized location kind into a regular location.
+  SILLocation getAsRegularLocation() {
+    SILLocation RegularLoc = *this;
+    RegularLoc.setLocationKind(RegularKind);
+    return RegularLoc;
+  }
+
   SourceLoc getDebugSourceLoc() const;
   SourceLoc getSourceLoc() const;
   SourceLoc getStartSourceLoc() const;
diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h
index 07451cf..e76688b 100644
--- a/include/swift/SIL/SILModule.h
+++ b/include/swift/SIL/SILModule.h
@@ -474,6 +474,14 @@
   void setOptRecordStream(std::unique_ptr<llvm::yaml::Output> &&Stream,
                           std::unique_ptr<llvm::raw_ostream> &&RawStream);
 
+  // This is currently limited to VarDecl because the visibility of global
+  // variables and class properties is straightforward, while the visibility of
+  // class methods (ValueDecls) depends on the subclass scope. "Visiblity" has
+  // a different meaning when vtable layout is at stake.
+  bool isVisibleExternally(const VarDecl *decl) {
+    return isPossiblyUsedExternally(getDeclSILLinkage(decl), isWholeModule());
+  }
+
   PropertyListType &getPropertyList() { return properties; }
   const PropertyListType &getPropertyList() const { return properties; }
   
diff --git a/include/swift/SILOptimizer/Utils/Existential.h b/include/swift/SILOptimizer/Utils/Existential.h
index 51d5842..c84e85f 100644
--- a/include/swift/SILOptimizer/Utils/Existential.h
+++ b/include/swift/SILOptimizer/Utils/Existential.h
@@ -31,13 +31,76 @@
                                bool &isCopied);
 
 /// Find the init_existential, which could be used to determine a concrete
-/// type of the \p Self.
+/// type of the value used by \p openedUse.
 /// If the value is copied from another stack location, \p isCopied is set to
 /// true.
-SILInstruction *findInitExistential(FullApplySite AI, SILValue Self,
+///
+/// FIXME: replace all uses of this with ConcreteExistentialInfo.
+SILInstruction *findInitExistential(Operand &openedUse,
                                     ArchetypeType *&OpenedArchetype,
                                     SILValue &OpenedArchetypeDef,
                                     bool &isCopied);
+
+/// Record conformance and concrete type info derived from an init_existential
+/// value that is reopened before it's use. This is useful for finding the
+/// concrete type of an apply's self argument. For example, an important pattern
+/// for a class existential is:
+///
+/// %e = init_existential_ref %c : $C : $C, $P & Q
+/// %o = open_existential_ref %e : $P & Q to $@opened("PQ") P & Q
+/// %r = apply %f<@opened("PQ") P & Q>(%o)
+///   : $@convention(method) <τ_0_0 where τ_0_0 : P, τ_0_0 : Q>
+///     (@guaranteed τ_0_0) -> @owned τ_0_0
+struct ConcreteExistentialInfo {
+  // The opened type passed as self. `$@opened("PQ")` above.
+  // This is also the replacement type of the method's Self type.
+  ArchetypeType *OpenedArchetype = nullptr;
+  // The definition of the OpenedArchetype.
+  SILValue OpenedArchetypeDef;
+  // True if the openedValue is copied from another stack location
+  bool isCopied;
+  // The init_existential instruction that produces the opened existential.
+  SILInstruction *InitExistential = nullptr;
+  // The existential type of the self argument before it is opened,
+  // produced by an init_existential.
+  CanType ExistentialType;
+  // The conformances required by the init_existential. `$C : $P & $Q` above.
+  ArrayRef<ProtocolConformanceRef> ExistentialConformances;
+  // The concrete type of self from the init_existential. `$C` above.
+  CanType ConcreteType;
+  // When ConcreteType is itself an opened existential, record the type
+  // definition. May be nullptr for a valid AppliedConcreteType.
+  SingleValueInstruction *ConcreteTypeDef = nullptr;
+  // The Substitution map derived from the init_existential.
+  // This maps a single generic parameter to the replacement ConcreteType
+  // and includes the full list of existential conformances.
+  // signature: <P & Q>, replacement: $C : conformances: [$P, $Q]
+  SubstitutionMap ExistentialSubs;
+  // The value of concrete type used to initialize the existential. `%c` above.
+  SILValue ConcreteValue;
+
+  // Search for a recognized pattern in which the given value is an opened
+  // existential that was previously initialized to a concrete type.
+  // Constructs a valid ConcreteExistentialInfo object if successfull.
+  ConcreteExistentialInfo(Operand &openedUse);
+
+  ConcreteExistentialInfo(ConcreteExistentialInfo &) = delete;
+
+  bool isValid() const {
+    return OpenedArchetype && OpenedArchetypeDef && InitExistential
+           && ConcreteType && !ExistentialSubs.empty() && ConcreteValue;
+  }
+
+  // Do a conformance lookup on ConcreteType with the given requirement, P. If P
+  // is satisfiable based on the existential's conformance, return the new
+  // conformance on P. Otherwise return None.
+  Optional<ProtocolConformanceRef>
+  lookupExistentialConformance(ProtocolDecl *P) const {
+    CanType selfTy = P->getSelfInterfaceType()->getCanonicalType();
+    return ExistentialSubs.lookupConformance(selfTy, P);
+  }
+};
+
 } // end namespace swift
 
 #endif
diff --git a/include/swift/Sema/TypeCheckRequests.h b/include/swift/Sema/TypeCheckRequests.h
index 2da1459..3d5142e 100644
--- a/include/swift/Sema/TypeCheckRequests.h
+++ b/include/swift/Sema/TypeCheckRequests.h
@@ -73,7 +73,7 @@
     public SimpleRequest<SuperclassTypeRequest,
                          CacheKind::SeparatelyCached,
                          Type,
-                         ClassDecl *> {
+                         NominalTypeDecl *> {
 public:
   using SimpleRequest::SimpleRequest;
   using SimpleRequest::operator();
@@ -82,7 +82,7 @@
   friend class SimpleRequest;
 
   // Evaluation.
-  Type operator()(Evaluator &evaluator, ClassDecl *classDecl) const;
+  Type operator()(Evaluator &evaluator, NominalTypeDecl *classDecl) const;
 
 public:
   // Cycle handling
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 278fb55..432b45d 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -55,7 +55,7 @@
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
 /// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t VERSION_MINOR = 421; // Last change: track whether xrefs come from Clang
+const uint16_t VERSION_MINOR = 424; // Last change: isObjC bits
 
 using DeclIDField = BCFixed<31>;
 
@@ -861,8 +861,9 @@
     IdentifierIDField,      // name
     DeclContextIDField,     // context decl
     BCFixed<1>,             // implicit flag
+    BCFixed<1>,             // isObjC
     GenericEnvironmentIDField, // generic environment
-    AccessLevelField, // access level
+    AccessLevelField,       // access level
     BCVBR<4>,               // number of conformances
     BCArray<TypeIDField>    // inherited types
     // Trailed by the generic parameters (if any), the members record, and
@@ -874,9 +875,10 @@
     IdentifierIDField,      // name
     DeclContextIDField,     // context decl
     BCFixed<1>,             // implicit flag
+    BCFixed<1>,             // isObjC
     GenericEnvironmentIDField, // generic environment
     TypeIDField,            // raw type
-    AccessLevelField, // access level
+    AccessLevelField,       // access level
     BCVBR<4>,               // number of conformances
     BCVBR<4>,               // number of inherited types
     BCArray<TypeIDField>    // inherited types, followed by dependency types
@@ -886,15 +888,15 @@
 
   using ClassLayout = BCRecordLayout<
     CLASS_DECL,
-    IdentifierIDField, // name
-    DeclContextIDField,// context decl
-    BCFixed<1>,        // implicit?
-    BCFixed<1>,        // explicitly objc?
-    BCFixed<1>,        // requires stored property initial values?
-    BCFixed<1>,        // inherits convenience initializers from its superclass?
+    IdentifierIDField,      // name
+    DeclContextIDField,     // context decl
+    BCFixed<1>,             // implicit?
+    BCFixed<1>,             // explicitly objc?
+    BCFixed<1>,             // requires stored property initial values?
+    BCFixed<1>,             // inherits convenience initializers from its superclass?
     GenericEnvironmentIDField, // generic environment
-    TypeIDField,       // superclass
-    AccessLevelField, // access level
+    TypeIDField,            // superclass
+    AccessLevelField,       // access level
     BCVBR<4>,               // number of conformances
     BCArray<TypeIDField>    // inherited types
     // Trailed by the generic parameters (if any), the members record, and
@@ -910,7 +912,8 @@
     BCFixed<1>,             // objc?
     BCFixed<1>,             // existential-type-supported?
     GenericEnvironmentIDField, // generic environment
-    AccessLevelField, // access level
+    TypeIDField,            // superclass
+    AccessLevelField,       // access level
     BCArray<DeclIDField>    // inherited types
     // Trailed by the generic parameters (if any), the members record, and
     // the default witness table record
@@ -981,7 +984,7 @@
     BCFixed<1>,   // implicit?
     BCFixed<1>,   // is 'static' or 'class'?
     StaticSpellingKindField, // spelling of 'static' or 'class'
-    BCFixed<1>,   // explicitly objc?
+    BCFixed<1>,   // isObjC?
     SelfAccessKindField,   // self access kind
     BCFixed<1>,   // has dynamic self?
     BCFixed<1>,   // has forced static dispatch?
@@ -1010,7 +1013,7 @@
     BCFixed<1>,   // implicit?
     BCFixed<1>,   // is 'static' or 'class'?
     StaticSpellingKindField, // spelling of 'static' or 'class'
-    BCFixed<1>,   // explicitly objc?
+    BCFixed<1>,   // isObjC?
     SelfAccessKindField,   // self access kind
     BCFixed<1>,   // has dynamic self?
     BCFixed<1>,   // has forced static dispatch?
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index b3e52dd..08ae82e 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -22,6 +22,7 @@
 #include "swift/AST/Initializer.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/ParameterList.h"
+#include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/ProtocolConformanceRef.h"
 #include "swift/Basic/Defer.h"
@@ -380,6 +381,9 @@
 
 std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC,
                                               GenericEnvironment *GE) {
+  PrettyStackTraceType prettyStackTrace(Ty->getASTContext(),
+                                        "mangling type for debugger", Ty);
+
   GenericEnv = GE;
   DWARFMangling = true;
   beginMangling();
@@ -746,17 +750,13 @@
         return appendType(aliasTy->getSinglyDesugaredType());
       }
 
-      if (type->isSpecialized()) {
+      if (aliasTy->getSubstitutionMap().hasAnySubstitutableParams()) {
         // Try to mangle the entire name as a substitution.
         if (tryMangleSubstitution(tybase))
           return;
 
         appendAnyGenericType(decl);
         bool isFirstArgList = true;
-        if (auto *nominalType = type->getAs<NominalType>()) {
-          if (nominalType->getParent())
-            type = nominalType->getParent();
-        }
         appendBoundGenericArgs(type, isFirstArgList);
         appendRetroactiveConformances(type);
         appendOperator("G");
@@ -1039,16 +1039,74 @@
     bindGenericParameters(sig->getCanonicalSignature());
 }
 
+unsigned ASTMangler::appendBoundGenericArgs(DeclContext *dc,
+                                            SubstitutionMap subs,
+                                            bool &isFirstArgList) {
+  auto decl = dc->getInnermostDeclarationDeclContext();
+  if (!decl) return 0;
+
+  // For an extension declaration, use the nominal type declaration instead.
+  // This is important when extending a nested type, because the generic
+  // parameters will line up with the (semantic) nesting of the nominal type.
+  if (auto ext = dyn_cast<ExtensionDecl>(decl))
+    decl = ext->getAsNominalTypeOrNominalTypeExtensionContext();
+
+  // Handle the generic arguments of the parent.
+  unsigned currentGenericParamIdx =
+    appendBoundGenericArgs(decl->getDeclContext(), subs, isFirstArgList);
+
+  // If this is potentially a generic context, emit a generic argument list.
+  if (auto genericContext = decl->getAsGenericContext()) {
+    if (isFirstArgList) {
+      appendOperator("y");
+      isFirstArgList = false;
+    } else {
+      appendOperator("_");
+    }
+
+    // If we are generic at this level, emit all of the replacements at
+    // this level.
+    if (genericContext->isGeneric()) {
+      auto genericParams = subs.getGenericSignature()->getGenericParams();
+      unsigned depth = genericParams[currentGenericParamIdx]->getDepth();
+      assert(genericContext->getGenericParams()->getDepth() == depth &&
+             "Depth mismatch mangling substitution map");
+      auto replacements = subs.getReplacementTypes();
+      for (unsigned lastGenericParamIdx = genericParams.size();
+           (currentGenericParamIdx != lastGenericParamIdx &&
+            genericParams[currentGenericParamIdx]->getDepth() == depth);
+           ++currentGenericParamIdx) {
+        Type replacementType = replacements[currentGenericParamIdx];
+        if (replacementType->hasArchetype())
+          replacementType = replacementType->mapTypeOutOfContext();
+
+        appendType(replacementType);
+      }
+    }
+  }
+
+  return currentGenericParamIdx;
+}
+
 void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) {
-  BoundGenericType *boundType = nullptr;
-  if (auto *unboundType = type->getAs<UnboundGenericType>()) {
+  TypeBase *typePtr = type.getPointer();
+  ArrayRef<Type> genericArgs;
+  if (auto *typeAlias = dyn_cast<NameAliasType>(typePtr)) {
+    appendBoundGenericArgs(typeAlias->getDecl(),
+                           typeAlias->getSubstitutionMap(),
+                           isFirstArgList);
+    return;
+  }
+
+  if (auto *unboundType = dyn_cast<UnboundGenericType>(typePtr)) {
     if (Type parent = unboundType->getParent())
       appendBoundGenericArgs(parent, isFirstArgList);
-  } else if (auto *nominalType = type->getAs<NominalType>()) {
+  } else if (auto *nominalType = dyn_cast<NominalType>(typePtr)) {
     if (Type parent = nominalType->getParent())
       appendBoundGenericArgs(parent, isFirstArgList);
   } else {
-    boundType = type->castTo<BoundGenericType>();
+    auto boundType = cast<BoundGenericType>(typePtr);
+    genericArgs = boundType->getGenericArgs();
     if (Type parent = boundType->getParent())
       appendBoundGenericArgs(parent, isFirstArgList);
   }
@@ -1058,10 +1116,8 @@
   } else {
     appendOperator("_");
   }
-  if (boundType) {
-    for (Type arg : boundType->getGenericArgs()) {
-      appendType(arg);
-    }
+  for (Type arg : genericArgs) {
+    appendType(arg);
   }
 }
 
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 749a60f..e4d1d58 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -740,6 +740,16 @@
     Options.ExcludeAttrList.push_back(DAK_Final);
   }
 
+  // If the declaration is implicitly @objc, print the attribute now.
+  if (Options.PrintImplicitAttrs) {
+    if (auto VD = dyn_cast<ValueDecl>(D)) {
+      if (VD->isObjC() && !VD->getAttrs().hasAttribute<ObjCAttr>()) {
+        Printer.printAttrName("@objc");
+        Printer << " ";
+      }
+    }
+  }
+
   D->getAttrs().print(Printer, Options, D);
 
   Options.ExcludeAttrList.resize(originalExcludeAttrCount);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index fb393e3..589376a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1946,19 +1946,25 @@
   return CanType();
 }
 
-void ValueDecl::setIsObjC(bool Value) {
-  bool CurrentValue = isObjC();
-  if (CurrentValue == Value)
-    return;
+bool ValueDecl::isObjC() const {
+  if (Bits.ValueDecl.IsObjCComputed)
+    return Bits.ValueDecl.IsObjC;
 
-  if (!Value) {
-    for (auto *Attr : getAttrs()) {
-      if (auto *OA = dyn_cast<ObjCAttr>(Attr))
-        OA->setInvalid();
-    }
-  } else {
-    getAttrs().add(ObjCAttr::createUnnamedImplicit(getASTContext()));
+  // Fallback: look for an @objc attribute.
+  // FIXME: This should become an error, eventually.
+  return getAttrs().hasAttribute<ObjCAttr>();
+}
+
+void ValueDecl::setIsObjC(bool value) {
+  assert(!Bits.ValueDecl.IsObjCComputed || Bits.ValueDecl.IsObjC == value);
+
+  if (Bits.ValueDecl.IsObjCComputed) {
+    assert(Bits.ValueDecl.IsObjC == value);
+    return;
   }
+
+  Bits.ValueDecl.IsObjCComputed = true;
+  Bits.ValueDecl.IsObjC = value;
 }
 
 bool ValueDecl::canBeAccessedByDynamicLookup() const {
@@ -2888,8 +2894,9 @@
   DD->setGenericEnvironment(getGenericEnvironmentOfContext());
 
   // Mark DD as ObjC, as all dtors are.
-  DD->setIsObjC(true);
-  recordObjCMethod(DD);
+  DD->setIsObjC(getASTContext().LangOpts.EnableObjCInterop);
+  if (getASTContext().LangOpts.EnableObjCInterop)
+    recordObjCMethod(DD);
 
   // Assign DD the interface type (Self) -> () -> ()
   ArrayRef<AnyFunctionType::Param> noParams;
@@ -3277,6 +3284,27 @@
   return result;
 }
 
+Type ProtocolDecl::getSuperclass() const {
+  ASTContext &ctx = getASTContext();
+  if (auto lazyResolver = ctx.getLazyResolver()) {
+    return lazyResolver->getSuperclass(this);
+  }
+
+  return LazySemanticInfo.Superclass.getPointer();
+}
+
+ClassDecl *ProtocolDecl::getSuperclassDecl() const {
+  if (auto superclass = getSuperclass())
+    return superclass->getClassOrBoundGenericClass();
+  return nullptr;
+}
+
+void ProtocolDecl::setSuperclass(Type superclass) {
+  assert((!superclass || !superclass->hasArchetype())
+         && "superclass must be interface type");
+  LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
+}
+
 bool ProtocolDecl::walkInheritedProtocols(
               llvm::function_ref<TypeWalker::Action(ProtocolDecl *)> fn) const {
   auto self = const_cast<ProtocolDecl *>(this);
diff --git a/lib/AST/LookupVisibleDecls.cpp b/lib/AST/LookupVisibleDecls.cpp
index 80a8bf1..e0262fd 100644
--- a/lib/AST/LookupVisibleDecls.cpp
+++ b/lib/AST/LookupVisibleDecls.cpp
@@ -441,9 +441,13 @@
         continue;
       }
       if (auto *VD = dyn_cast<ValueDecl>(Member)) {
-        if (TypeResolver)
+        if (TypeResolver) {
           TypeResolver->resolveDeclSignature(VD);
-
+          if (!NormalConformance->hasWitness(VD) &&
+              (Conformance->getDeclContext()->getParentSourceFile() !=
+              FromContext->getParentSourceFile()))
+            TypeResolver->resolveWitness(NormalConformance, VD);
+        }
         // Skip value requirements that have corresponding witnesses. This cuts
         // down on duplicates.
         if (!NormalConformance->hasWitness(VD) ||
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index 9c4511c..7e5d364 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -130,12 +130,6 @@
                                              ProtocolConformanceRef conformance,
                                              Identifier name,
                                              LazyResolver *resolver) {
-  // For an archetype, retrieve the nested type with the appropriate
-  // name. There are no conformance tables.
-  if (auto archetype = type->getAs<ArchetypeType>()) {
-    return archetype->getNestedType(name);
-  }
-
   // Find the named requirement.
   AssociatedTypeDecl *assocType = nullptr;
   auto members = conformance.getRequirement()->lookupDirect(name);
@@ -149,8 +143,15 @@
   if (!assocType)
     return nullptr;
 
-  if (conformance.isAbstract())
+  if (conformance.isAbstract()) {
+    // For an archetype, retrieve the nested type with the appropriate
+    // name. There are no conformance tables.
+    if (auto archetype = type->getAs<ArchetypeType>()) {
+      return archetype->getNestedType(name);
+    }
+
     return DependentMemberType::get(type, assocType);
+  }
 
   auto concrete = conformance.getConcrete();
   if (!concrete->hasTypeWitness(assocType, resolver)) {
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index a221ab8..3c38887 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -1198,6 +1198,7 @@
 
   auto call = CallExpr::createImplicit(context, zeroInitializerRef, {}, {});
   call->setType(selfType);
+  call->setThrows(false);
 
   auto assign = new (context) AssignExpr(lhs, SourceLoc(), call,
                                          /*implicit*/ true);
@@ -1641,9 +1642,9 @@
 
   thunk->setAccess(getOverridableAccessLevel(dc));
 
-  auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>();
-  assert(objcAttr);
-  thunk->getAttrs().add(objcAttr->clone(C));
+  if (auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>())
+    thunk->getAttrs().add(objcAttr->clone(C));
+  thunk->setIsObjC(getter->isObjC());
   // FIXME: Should we record thunks?
 
   return thunk;
@@ -1711,9 +1712,9 @@
 
   thunk->setAccess(getOverridableAccessLevel(dc));
 
-  auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>();
-  assert(objcAttr);
-  thunk->getAttrs().add(objcAttr->clone(C));
+  if (auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>())
+    thunk->getAttrs().add(objcAttr->clone(C));
+  thunk->setIsObjC(setter->isObjC());
 
   return thunk;
 }
@@ -3811,7 +3812,11 @@
     /// The importer should use this rather than adding the attribute directly.
     void addObjCAttribute(ValueDecl *decl, Optional<ObjCSelector> name) {
       auto &ctx = Impl.SwiftContext;
-      decl->getAttrs().add(ObjCAttr::create(ctx, name, /*implicitName=*/true));
+      if (name) {
+        decl->getAttrs().add(ObjCAttr::create(ctx, name,
+                                              /*implicitName=*/true));
+      }
+      decl->setIsObjC(true);
 
       // If the declaration we attached the 'objc' attribute to is within a
       // class, record it in the class.
@@ -6515,7 +6520,8 @@
       auto swiftSel = Impl.importSelector(sel);
       for (auto found : classDecl->lookupDirect(swiftSel, true)) {
         if (auto foundFunc = dyn_cast<FuncDecl>(found))
-          return foundFunc;
+          if (foundFunc->hasClangNode())
+            return foundFunc;
       }
     }
 
@@ -6530,18 +6536,24 @@
 
   // Determine the selector of the counterpart.
   FuncDecl *getter = nullptr, *setter = nullptr;
+  const clang::ObjCMethodDecl *getterObjCMethod = nullptr,
+                              *setterObjCMethod = nullptr;
   clang::Selector counterpartSelector;
   if (objcMethod->getSelector() == Impl.objectAtIndexedSubscript) {
     getter = cast<FuncDecl>(decl);
+    getterObjCMethod = objcMethod;
     counterpartSelector = Impl.setObjectAtIndexedSubscript;
   } else if (objcMethod->getSelector() == Impl.setObjectAtIndexedSubscript) {
     setter = cast<FuncDecl>(decl);
+    setterObjCMethod = objcMethod;
     counterpartSelector = Impl.objectAtIndexedSubscript;
   } else if (objcMethod->getSelector() == Impl.objectForKeyedSubscript) {
     getter = cast<FuncDecl>(decl);
+    getterObjCMethod = objcMethod;
     counterpartSelector = Impl.setObjectForKeyedSubscript;
   } else if (objcMethod->getSelector() == Impl.setObjectForKeyedSubscript) {
     setter = cast<FuncDecl>(decl);
+    setterObjCMethod = objcMethod;
     counterpartSelector = Impl.objectForKeyedSubscript;
   } else {
     llvm_unreachable("Unknown getter/setter selector");
@@ -6552,13 +6564,15 @@
                           clang::ObjCMethodDecl::Optional);
 
   if (auto *counterpart = findCounterpart(counterpartSelector)) {
+    const clang::ObjCMethodDecl *counterpartMethod = nullptr;
+
     // If the counterpart to the method we're attempting to import has the
     // swift_private attribute, don't import as a subscript.
     if (auto importedFrom = counterpart->getClangDecl()) {
       if (importedFrom->hasAttr<clang::SwiftPrivateAttr>())
         return nullptr;
 
-      auto counterpartMethod = dyn_cast<clang::ObjCMethodDecl>(importedFrom);
+      counterpartMethod = cast<clang::ObjCMethodDecl>(importedFrom);
       if (optionalMethods)
         optionalMethods = (counterpartMethod->getImplementationControl() ==
                            clang::ObjCMethodDecl::Optional);
@@ -6566,10 +6580,13 @@
 
     assert(!counterpart || !counterpart->isStatic());
 
-    if (getter)
+    if (getter) {
       setter = counterpart;
-    else
+      setterObjCMethod = counterpartMethod;
+    } else {
       getter = counterpart;
+      getterObjCMethod = counterpartMethod;
+    }
   }
 
   // Swift doesn't have write-only subscripting.
@@ -6657,6 +6674,7 @@
       // Otherwise, just forget we had a setter.
       // FIXME: This feels very, very wrong.
       setter = nullptr;
+      setterObjCMethod = nullptr;
       setterIndex = nullptr;
     }
 
@@ -6717,9 +6735,14 @@
         buildSubscriptSetterDecl(Impl, subscript, setter, elementTy,
                                  dc, setterIndex);
 
-  /// Record the subscript as an alternative declaration.
+  // Record the subscript as an alternative declaration.
   Impl.addAlternateDecl(associateWithSetter ? setter : getter, subscript);
 
+  // Import attributes for the accessors if there is a pair.
+  Impl.importAttributes(getterObjCMethod, getterThunk);
+  if (setterObjCMethod)
+    Impl.importAttributes(setterObjCMethod, setterThunk);
+
   subscript->setGenericEnvironment(dc->getGenericEnvironmentOfContext());
 
   subscript->setIsSetterMutating(false);
@@ -7374,6 +7397,11 @@
     Decl *MappedDecl,
     const clang::ObjCContainerDecl *NewContext)
 {
+  // Subscripts are special-cased since there isn't a 1:1 mapping
+  // from its accessor(s) to the subscript declaration.
+  if (isa<SubscriptDecl>(MappedDecl))
+    return;
+
   ASTContext &C = SwiftContext;
 
   if (auto maybeDefinition = getDefinitionForClangTypeDecl(ClangDecl))
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index f8ee116..77463eb 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -1332,6 +1332,9 @@
     case Node::Kind::Enum:
       kind = Node::Kind::BoundGenericEnum;
       break;
+    case Node::Kind::Protocol:
+      kind = Node::Kind::BoundGenericProtocol;
+      break;
     case Node::Kind::OtherNominalType:
       kind = Node::Kind::BoundGenericOtherNominalType;
       break;
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index 6953889..3cd7257 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -266,6 +266,7 @@
     case Node::Kind::BoundGenericClass:
     case Node::Kind::BoundGenericEnum:
     case Node::Kind::BoundGenericStructure:
+    case Node::Kind::BoundGenericProtocol:
     case Node::Kind::BoundGenericOtherNominalType:
     case Node::Kind::BoundGenericTypeAlias:
     case Node::Kind::BuiltinTypeName:
@@ -540,6 +541,15 @@
       return;
     }
 
+    // Print the conforming type for a "bound" protocol node "as" the protocol
+    // type.
+    if (Node->getKind() == Node::Kind::BoundGenericProtocol) {
+      printChildren(Node->getChild(1));
+      Printer << " as ";
+      print(Node->getChild(0));
+      return;
+    }
+
     SugarType sugarType = findSugar(Node);
     
     switch (sugarType) {
@@ -1558,6 +1568,7 @@
   case Node::Kind::BoundGenericClass:
   case Node::Kind::BoundGenericStructure:
   case Node::Kind::BoundGenericEnum:
+  case Node::Kind::BoundGenericProtocol:
   case Node::Kind::BoundGenericOtherNominalType:
   case Node::Kind::BoundGenericTypeAlias:
     printBoundGeneric(Node);
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index 60e1f19..d68fa3b 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -1243,11 +1243,7 @@
 }
 
 void Remangler::mangleTypeAlias(Node *node, EntityContext &ctx) {
-  SubstitutionEntry entry;
-  if (trySubstitution(node, entry)) return;
-  Out << 'a';
-  mangleChildNodes(node); // context, identifier
-  addSubstitution(entry);
+  mangleAnyNominalType(node, ctx);
 }
 
 void Remangler::mangleFunctionType(Node *node) {
@@ -1824,6 +1820,9 @@
   case Node::Kind::Class:
     mangleNominalType(node, 'C', ctx);
     break;
+  case Node::Kind::TypeAlias:
+    mangleNominalType(node, 'a', ctx);
+    break;
   default:
     unreachable("bad nominal type kind");
   }
@@ -1873,6 +1872,11 @@
   mangleAnyNominalType(node, ctx);
 }
 
+void Remangler::mangleBoundGenericProtocol(Node *node) {
+  EntityContext ctx;
+  mangleAnyNominalType(node, ctx);
+}
+
 void Remangler::mangleBoundGenericTypeAlias(Node *node) {
   EntityContext ctx;
   mangleAnyNominalType(node, ctx);
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index c63aa5f..a876ab8 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -248,10 +248,10 @@
   }
 
   void manglePureProtocol(Node *Proto) {
+    Proto = skipType(Proto);
     if (mangleStandardSubstitution(Proto))
       return;
     
-    Proto = skipType(Proto);
     mangleChildNodes(Proto);
   }
 
@@ -474,6 +474,7 @@
     case Node::Kind::Structure:
     case Node::Kind::Enum:
     case Node::Kind::Class:
+    case Node::Kind::TypeAlias:
       mangleGenericArgs(node->getChild(0), Separator);
       Buffer << Separator;
       Separator = '_';
@@ -483,6 +484,7 @@
     case Node::Kind::BoundGenericStructure:
     case Node::Kind::BoundGenericEnum:
     case Node::Kind::BoundGenericClass:
+    case Node::Kind::BoundGenericProtocol:
     case Node::Kind::BoundGenericTypeAlias: {
       NodePointer unboundType = node->getChild(0);
       assert(unboundType->getKind() == Node::Kind::Type);
@@ -595,6 +597,10 @@
   mangleAnyNominalType(node);
 }
 
+void Remangler::mangleBoundGenericProtocol(Node *node) {
+  mangleAnyNominalType(node);
+}
+
 void Remangler::mangleBoundGenericTypeAlias(Node *node) {
   mangleAnyNominalType(node);
 }
@@ -1712,7 +1718,7 @@
 }
 
 void Remangler::mangleTypeAlias(Node *node) {
-  mangleAnyGenericType(node, "a");
+  mangleAnyNominalType(node);
 }
 
 void Remangler::mangleTypeList(Node *node) {
@@ -2052,12 +2058,15 @@
     case Node::Kind::BoundGenericClass:
     case Node::Kind::BoundGenericOtherNominalType:
     case Node::Kind::BoundGenericTypeAlias:
+    case Node::Kind::BoundGenericProtocol:
       return true;
 
     case Node::Kind::Structure:
     case Node::Kind::Enum:
     case Node::Kind::Class:
+    case Node::Kind::TypeAlias:
     case Node::Kind::OtherNominalType:
+    case Node::Kind::Protocol:
       return isSpecialized(node->getChild(0));
 
     case Node::Kind::Extension:
@@ -2073,6 +2082,7 @@
     case Node::Kind::Structure:
     case Node::Kind::Enum:
     case Node::Kind::Class:
+    case Node::Kind::TypeAlias:
     case Node::Kind::OtherNominalType: {
       NodePointer result = Factory.createNode(node->getKind());
       NodePointer parentOrModule = node->getChild(0);
@@ -2087,8 +2097,10 @@
     case Node::Kind::BoundGenericStructure:
     case Node::Kind::BoundGenericEnum:
     case Node::Kind::BoundGenericClass:
+    case Node::Kind::BoundGenericProtocol:
     case Node::Kind::BoundGenericOtherNominalType:
-    case Node::Kind::BoundGenericTypeAlias: {
+    case Node::Kind::BoundGenericTypeAlias:
+    {
       NodePointer unboundType = node->getChild(0);
       assert(unboundType->getKind() == Node::Kind::Type);
       NodePointer nominalType = unboundType->getChild(0);
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 319f196..abd382a 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -672,6 +672,86 @@
   return None;
 }
 
+static bool computeIncremental(const llvm::opt::InputArgList *ArgList,
+                               const bool ShowIncrementalBuildDecisions) {
+  if (!ArgList->hasArg(options::OPT_incremental))
+    return false;
+
+  const char *ReasonToDisable =
+      ArgList->hasArg(options::OPT_whole_module_optimization)
+          ? "is not compatible with whole module optimization."
+          : ArgList->hasArg(options::OPT_embed_bitcode)
+                ? "is not currently compatible with embedding LLVM IR bitcode."
+                : nullptr;
+
+  if (!ReasonToDisable)
+    return true;
+
+  if (ShowIncrementalBuildDecisions) {
+    llvm::outs() << "Incremental compilation has been disabled, because it "
+                 << ReasonToDisable;
+  }
+  return false;
+}
+
+static std::string
+computeWorkingDirectory(const llvm::opt::InputArgList *ArgList) {
+  if (auto *A = ArgList->getLastArg(options::OPT_working_directory)) {
+    SmallString<128> workingDirectory;
+    workingDirectory = A->getValue();
+    llvm::sys::fs::make_absolute(workingDirectory);
+    std::string result = workingDirectory.str().str();
+    return result;
+  }
+  return std::string();
+}
+
+static std::unique_ptr<UnifiedStatsReporter>
+createStatsReporter(const llvm::opt::InputArgList *ArgList,
+                    const InputFileList &Inputs, const OutputInfo OI,
+                    StringRef DefaultTargetTriple) {
+  const Arg *A = ArgList->getLastArgNoClaim(options::OPT_stats_output_dir);
+  if (!A)
+    return nullptr;
+
+  StringRef OptType;
+  if (const Arg *OptA = ArgList->getLastArgNoClaim(options::OPT_O_Group)) {
+    OptType = OptA->getSpelling();
+  }
+  StringRef InputName;
+  if (Inputs.size() == 1) {
+    InputName = Inputs[0].second->getSpelling();
+  }
+  StringRef OutputType = file_types::getTypeTempSuffix(OI.CompilerOutputType);
+  return llvm::make_unique<UnifiedStatsReporter>("swift-driver",
+                                                 OI.ModuleName,
+                                                 InputName,
+                                                 DefaultTargetTriple,
+                                                 OutputType,
+                                                 OptType,
+                                                 A->getValue());
+}
+
+static bool
+computeContinueBuildingAfterErrors(const bool BatchMode,
+                                   const llvm::opt::InputArgList *ArgList) {
+  // Note: Batch mode handling of serialized diagnostics requires that all
+  // batches get to run, in order to make sure that all diagnostics emitted
+  // during the compilation end up in at least one serialized diagnostic file.
+  // Therefore, treat batch mode as implying -continue-building-after-errors.
+  // (This behavior could be limited to only when serialized diagnostics are
+  // being emitted, but this seems more consistent and less surprising for
+  // users.)
+  // FIXME: We don't really need (or want) a full ContinueBuildingAfterErrors.
+  // If we fail to precompile a bridging header, for example, there's no need
+  // to go on to compilation of source files, and if compilation of source files
+  // fails, we shouldn't try to link. Instead, we'd want to let all jobs finish
+  // but not schedule any new ones.
+  return BatchMode ||
+         ArgList->hasArg(options::OPT_continue_building_after_errors);
+
+}
+
 std::unique_ptr<Compilation>
 Driver::buildCompilation(const ToolChain &TC,
                          std::unique_ptr<llvm::opt::InputArgList> ArgList) {
@@ -682,47 +762,9 @@
   // Claim --driver-mode here, since it's already been handled.
   (void) ArgList->hasArg(options::OPT_driver_mode);
 
-  bool DriverPrintActions = ArgList->hasArg(options::OPT_driver_print_actions);
-  bool DriverPrintOutputFileMap =
-    ArgList->hasArg(options::OPT_driver_print_output_file_map);
-  bool DriverPrintDerivedOutputFileMap =
-    ArgList->hasArg(options::OPT_driver_print_derived_output_file_map);
   DriverPrintBindings = ArgList->hasArg(options::OPT_driver_print_bindings);
-  bool ShowIncrementalBuildDecisions =
-    ArgList->hasArg(options::OPT_driver_show_incremental);
-  bool ShowJobLifecycle =
-    ArgList->hasArg(options::OPT_driver_show_job_lifecycle);
-  unsigned DriverBatchSeed = getDriverBatchSeed(*ArgList, Diags);
-  Optional<unsigned> DriverBatchCount = getDriverBatchCount(*ArgList, Diags);
-  bool DriverForceOneBatchRepartition =
-      ArgList->hasArg(options::OPT_driver_force_one_batch_repartition);
 
-  bool Incremental = ArgList->hasArg(options::OPT_incremental);
-  if (ArgList->hasArg(options::OPT_whole_module_optimization)) {
-    if (Incremental && ShowIncrementalBuildDecisions) {
-      llvm::outs() << "Incremental compilation has been disabled, because it "
-                   << "is not compatible with whole module optimization.";
-    }
-    Incremental = false;
-  }
-  if (ArgList->hasArg(options::OPT_embed_bitcode)) {
-    if (Incremental && ShowIncrementalBuildDecisions) {
-      llvm::outs() << "Incremental compilation has been disabled, because it "
-                   << "is not currently compatible with embedding LLVM IR "
-                   << "bitcode.";
-    }
-    Incremental = false;
-  }
-
-  bool SaveTemps = ArgList->hasArg(options::OPT_save_temps);
-  bool ShowDriverTimeCompilation =
-    ArgList->hasArg(options::OPT_driver_time_compilation);
-
-  SmallString<128> workingDirectory;
-  if (auto *A = ArgList->getLastArg(options::OPT_working_directory)) {
-    workingDirectory = A->getValue();
-    llvm::sys::fs::make_absolute(workingDirectory);
-  }
+  const std::string workingDirectory = computeWorkingDirectory(ArgList.get());
 
   std::unique_ptr<DerivedArgList> TranslatedArgList(
       translateInputAndPathArgs(*ArgList, workingDirectory));
@@ -749,45 +791,9 @@
   OI.CompilerMode = computeCompilerMode(*TranslatedArgList, Inputs, BatchMode);
   buildOutputInfo(TC, *TranslatedArgList, BatchMode, Inputs, OI);
 
-  // Note: Batch mode handling of serialized diagnostics requires that all
-  // batches get to run, in order to make sure that all diagnostics emitted
-  // during the compilation end up in at least one serialized diagnostic file.
-  // Therefore, treat batch mode as implying -continue-building-after-errors.
-  // (This behavior could be limited to only when serialized diagnostics are
-  // being emitted, but this seems more consistent and less surprising for
-  // users.)
-  // FIXME: We don't really need (or want) a full ContinueBuildingAfterErrors.
-  // If we fail to precompile a bridging header, for example, there's no need
-  // to go on to compilation of source files, and if compilation of source files
-  // fails, we shouldn't try to link. Instead, we'd want to let all jobs finish
-  // but not schedule any new ones.
-  const bool ContinueBuildingAfterErrors =
-      BatchMode || ArgList->hasArg(options::OPT_continue_building_after_errors);
-
   if (Diags.hadAnyError())
     return nullptr;
 
-  std::unique_ptr<UnifiedStatsReporter> StatsReporter;
-  if (const Arg *A =
-      ArgList->getLastArgNoClaim(options::OPT_stats_output_dir)) {
-    StringRef OptType;
-    if (const Arg *OptA = ArgList->getLastArgNoClaim(options::OPT_O_Group)) {
-      OptType = OptA->getSpelling();
-    }
-    StringRef InputName;
-    if (Inputs.size() == 1) {
-      InputName = Inputs[0].second->getSpelling();
-    }
-    StringRef OutputType = file_types::getTypeTempSuffix(OI.CompilerOutputType);
-    StatsReporter = llvm::make_unique<UnifiedStatsReporter>("swift-driver",
-                                                            OI.ModuleName,
-                                                            InputName,
-                                                            DefaultTargetTriple,
-                                                            OutputType,
-                                                            OptType,
-                                                            A->getValue());
-  }
-
   assert(OI.CompilerOutputType != file_types::ID::TY_INVALID &&
          "buildOutputInfo() must set a valid output type!");
 
@@ -803,7 +809,7 @@
   if (Diags.hadAnyError())
     return nullptr;
 
-  if (DriverPrintOutputFileMap) {
+  if (ArgList->hasArg(options::OPT_driver_print_output_file_map)) {
     if (OFM)
       OFM->dump(llvm::errs(), true);
     else
@@ -811,6 +817,11 @@
     return nullptr;
   }
 
+  const bool ShowIncrementalBuildDecisions =
+      ArgList->hasArg(options::OPT_driver_show_incremental);
+  const bool Incremental =
+      computeIncremental(ArgList.get(), ShowIncrementalBuildDecisions);
+
   std::string buildRecordPath;
   bool outputBuildRecordForModuleOnlyBuild = false;
   getCompilationRecordPath(buildRecordPath, outputBuildRecordForModuleOnlyBuild,
@@ -848,25 +859,53 @@
       llvm_unreachable("Unknown OutputLevel argument!");
   }
 
-  std::unique_ptr<Compilation> C(
-      new Compilation(Diags, TC, OI, Level,
-                      std::move(ArgList),
-                      std::move(TranslatedArgList),
-                      std::move(Inputs),
-                      buildRecordPath,
-                      outputBuildRecordForModuleOnlyBuild,
-                      ArgsHash,
-                      StartTime,
-                      LastBuildTime,
-                      DriverFilelistThreshold,
-                      Incremental,
-                      BatchMode,
-                      DriverBatchSeed,
-                      DriverBatchCount,
-                      DriverForceOneBatchRepartition,
-                      SaveTemps,
-                      ShowDriverTimeCompilation,
-                      std::move(StatsReporter)));
+  
+  // About to move argument list, so capture some flags that will be needed
+  // later.
+  const bool DriverPrintActions =
+      ArgList->hasArg(options::OPT_driver_print_actions);
+  const bool DriverPrintDerivedOutputFileMap =
+      ArgList->hasArg(options::OPT_driver_print_derived_output_file_map);
+  const bool ContinueBuildingAfterErrors =
+      computeContinueBuildingAfterErrors(BatchMode, ArgList.get());
+  const bool ShowJobLifecycle =
+      ArgList->hasArg(options::OPT_driver_show_job_lifecycle);
+
+  // In order to confine the values below, while still moving the argument
+  // list, and preserving the interface to Compilation, enclose the call to the
+  // constructor in a block:
+  std::unique_ptr<Compilation> C;
+  {
+    const unsigned DriverBatchSeed = getDriverBatchSeed(*ArgList, Diags);
+    const Optional<unsigned> DriverBatchCount = getDriverBatchCount(*ArgList, Diags);
+    const bool DriverForceOneBatchRepartition =
+    ArgList->hasArg(options::OPT_driver_force_one_batch_repartition);
+    const bool SaveTemps = ArgList->hasArg(options::OPT_save_temps);
+    const bool ShowDriverTimeCompilation =
+        ArgList->hasArg(options::OPT_driver_time_compilation);
+    std::unique_ptr<UnifiedStatsReporter> StatsReporter =
+        createStatsReporter(ArgList.get(), Inputs, OI, DefaultTargetTriple);
+    
+    C = llvm::make_unique<Compilation>(
+        Diags, TC, OI, Level,
+        std::move(ArgList),
+        std::move(TranslatedArgList),
+        std::move(Inputs),
+        buildRecordPath,
+        outputBuildRecordForModuleOnlyBuild,
+        ArgsHash,
+        StartTime,
+        LastBuildTime,
+        DriverFilelistThreshold,
+        Incremental,
+        BatchMode,
+        DriverBatchSeed,
+        DriverBatchCount,
+        DriverForceOneBatchRepartition,
+        SaveTemps,
+        ShowDriverTimeCompilation,
+        std::move(StatsReporter));
+  }
 
   // Construct the graph of Actions.
   SmallVector<const Action *, 8> TopLevelActions;
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index 71d53fd..1182804 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -1166,9 +1166,20 @@
     return false;
 
   const auto &frontendOpts = Invocation.getFrontendOptions();
-  const auto mode = frontendOpts.ValidateTBDAgainstIR;
+  auto mode = frontendOpts.ValidateTBDAgainstIR;
   // Ensure all cases are covered by using a switch here.
   switch (mode) {
+  case FrontendOptions::TBDValidationMode::Default:
+#ifndef NDEBUG
+    // When a debug compiler is targeting an apple platform, we do some
+    // validation by default.
+    if (Invocation.getLangOptions().Target.getVendor() == llvm::Triple::Apple) {
+      mode = FrontendOptions::TBDValidationMode::MissingFromTBD;
+      break;
+    }
+#endif
+    // Otherwise, the default is to do nothing.
+    LLVM_FALLTHROUGH;
   case FrontendOptions::TBDValidationMode::None:
     return false;
   case FrontendOptions::TBDValidationMode::All:
diff --git a/lib/FrontendTool/TBD.cpp b/lib/FrontendTool/TBD.cpp
index 0a634be..fb6d6d0 100644
--- a/lib/FrontendTool/TBD.cpp
+++ b/lib/FrontendTool/TBD.cpp
@@ -113,6 +113,10 @@
     }
   }
 
+  if (error) {
+    diags.diagnose(SourceLoc(), diag::tbd_validation_failure);
+  }
+
   return error;
 }
 
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 9f44000..89ff552 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -1371,8 +1371,7 @@
       llvm_unreachable("module scope context handled above");
 
     case DeclContextKind::SubscriptDecl:
-      // FIXME: what do we need to check here?
-      return true;
+      return typeCheckCompletionDecl(cast<SubscriptDecl>(DC));
 
     case DeclContextKind::TopLevelCodeDecl:
       return typeCheckTopLevelCodeDecl(cast<TopLevelCodeDecl>(DC));
@@ -3268,8 +3267,17 @@
   }
 
   void tryPostfixOperator(Expr *expr, PostfixOperatorDecl *op) {
-    if (!expr->getType())
+    auto Ty = expr->getType();
+    if (!Ty)
       return;
+
+    SWIFT_DEFER {
+      // Restore type.
+      // FIXME: This is workaround for getTypeOfExpressionWithoutApplying()
+      // modifies type of 'expr'.
+      expr->setType(Ty);
+    };
+
     // We allocate these expressions on the stack because we know they can't
     // escape and there isn't a better way to allocate scratch Expr nodes.
     UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::PostfixOperator,
@@ -3344,6 +3352,9 @@
                            LHS->getType()->is<AnyFunctionType>()))
       return;
 
+    // Preserve LHS type for restoring it.
+    Type LHSTy = LHS->getType();
+
     // We allocate these expressions on the stack because we know they can't
     // escape and there isn't a better way to allocate scratch Expr nodes.
     UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::BinaryOperator,
@@ -3356,13 +3367,20 @@
       // Reset sequence.
       SE->setElement(SE->getNumElements() - 1, nullptr);
       SE->setElement(SE->getNumElements() - 2, nullptr);
+      LHS->setType(LHSTy);
       prepareForRetypechecking(SE);
 
-      // Reset any references to operators in types, so they are properly
-      // handled as operators by sequence folding.
-      //
-      // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
       for (auto &element : sequence.drop_back(2)) {
+        // Unfold AssignExpr for re-typechecking sequence.
+        if (auto *AE = dyn_cast_or_null<AssignExpr>(element)) {
+          AE->setSrc(nullptr);
+          AE->setDest(nullptr);
+        }
+
+        // Reset any references to operators in types, so they are properly
+        // handled as operators by sequence folding.
+        //
+        // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
         if (auto operatorRef = element->getMemberOperatorRef()) {
           operatorRef->setType(nullptr);
           element = operatorRef;
@@ -3396,20 +3414,20 @@
     }
   }
 
-  void flattenBinaryExpr(BinaryExpr *expr, SmallVectorImpl<Expr *> &sequence) {
-    auto LHS = expr->getArg()->getElement(0);
-    if (auto binexpr = dyn_cast<BinaryExpr>(LHS))
-      flattenBinaryExpr(binexpr, sequence);
-    else
-      sequence.push_back(LHS);
-
-    sequence.push_back(expr->getFn());
-
-    auto RHS = expr->getArg()->getElement(1);
-    if (auto binexpr = dyn_cast<BinaryExpr>(RHS))
-      flattenBinaryExpr(binexpr, sequence);
-    else
-      sequence.push_back(RHS);
+  void flattenBinaryExpr(Expr *expr, SmallVectorImpl<Expr *> &sequence) {
+    if (auto binExpr = dyn_cast<BinaryExpr>(expr)) {
+      flattenBinaryExpr(binExpr->getArg()->getElement(0), sequence);
+      sequence.push_back(binExpr->getFn());
+      flattenBinaryExpr(binExpr->getArg()->getElement(1), sequence);
+    } else if (auto assignExpr = dyn_cast<AssignExpr>(expr)) {
+      flattenBinaryExpr(assignExpr->getDest(), sequence);
+      sequence.push_back(assignExpr);
+      flattenBinaryExpr(assignExpr->getSrc(), sequence);
+      assignExpr->setDest(nullptr);
+      assignExpr->setSrc(nullptr);
+    } else {
+      sequence.push_back(expr);
+    }
   }
 
   void typeCheckLeadingSequence(SmallVectorImpl<Expr *> &sequence) {
@@ -3419,10 +3437,10 @@
     // Take advantage of the fact the type-checker leaves the types on the AST.
     if (!typeCheckExpression(const_cast<DeclContext *>(CurrDeclContext),
                              expr)) {
-      if (auto binexpr = dyn_cast<BinaryExpr>(expr)) {
+      if (isa<BinaryExpr>(expr) || isa<AssignExpr>(expr)) {
         // Rebuild the sequence from the type-checked version.
         sequence.clear();
-        flattenBinaryExpr(binexpr, sequence);
+        flattenBinaryExpr(expr, sequence);
         return;
       }
     }
@@ -3448,6 +3466,9 @@
     if (sequence.size() > 1)
       typeCheckLeadingSequence(sequence);
 
+    // Retrieve typechecked LHS.
+    LHS = sequence.back();
+
     // Create a single sequence expression, which we will modify for each
     // operator, filling in the operator and dummy right-hand side.
     sequence.push_back(nullptr); // operator
diff --git a/lib/IDE/TypeReconstruction.cpp b/lib/IDE/TypeReconstruction.cpp
index 155c535..bcb2c3e 100644
--- a/lib/IDE/TypeReconstruction.cpp
+++ b/lib/IDE/TypeReconstruction.cpp
@@ -772,13 +772,31 @@
   }
 
   if (generic_type_result._decls.size() != 1 ||
-      generic_type_result._types.size() != 1 ||
-      template_types_result._types.empty())
+      generic_type_result._types.size() != 1)
     return;
 
   auto *genericTypeAlias =
       cast<TypeAliasDecl>(generic_type_result._decls.front());
   GenericSignature *signature = genericTypeAlias->getGenericSignature();
+  if (signature &&
+      template_types_result._types.size() !=
+        signature->getGenericParams().size()) {
+    result._error = stringWithFormat(
+        "wrong number of generic arguments (%d) for generic typealias %s; "
+        "expected %d",
+        template_types_result._types.size(),
+        genericTypeAlias->getBaseName().userFacingName(),
+        signature->getGenericParams().size());
+
+    return;
+  }
+
+  if (signature && signature->getNumConformanceRequirements() != 0) {
+    result._error =
+      "cannot handle generic typealias with conformance requirements";
+    return;
+  }
+
   // FIXME: handle conformances.
   SubstitutionMap subMap;
   if (signature)
@@ -2250,6 +2268,14 @@
     VisitNodeBoundGeneric(ast, node, result);
     break;
 
+  case Demangle::Node::Kind::BoundGenericProtocol:
+    if (node->getNumChildren() < 2)
+      return;
+
+    // Only visit the conforming type.
+    VisitNode(ast, node->getChild(1), result);
+    break;
+
   case Demangle::Node::Kind::BoundGenericTypeAlias:
     VisitNodeGenericTypealias(ast, node, result);
     break;
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 257c601..1b900bd 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -2250,7 +2250,7 @@
                                            /*generics*/ nullptr,
                                            Context.TheBuiltinModule);
   SwiftRootClass->computeType();
-  SwiftRootClass->setIsObjC(true);
+  SwiftRootClass->setIsObjC(Context.LangOpts.EnableObjCInterop);
   SwiftRootClass->getAttrs().add(ObjCAttr::createNullary(Context, objcName,
     /*isNameImplicit=*/true));
   SwiftRootClass->setImplicit();
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index bc0c4a7..0fce67f 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2136,6 +2136,12 @@
   bool inFixedBuffer = false;
   bool indirectForDebugInfo = false;
 
+  // FIXME: Remove this once LLDB has proper support for resilience.
+  bool isREPLVar = false;
+  if (auto *decl = var->getDecl())
+    if (decl->isREPLVar())
+      isREPLVar = true;
+
   if (var->isInitializedObject()) {
     assert(ti.isFixedSize(expansion));
     StructLayout *Layout = StaticObjectLayouts[var].get();
@@ -2155,7 +2161,7 @@
     fixedSize = Layout->getSize();
     fixedAlignment = Layout->getAlignment();
     assert(fixedAlignment >= TargetInfo.HeapObjectAlignment);
-  } else if (ti.isFixedSize(expansion)) {
+  } else if (isREPLVar || ti.isFixedSize(expansion)) {
     // Allocate static storage.
     auto &fixedTI = cast<FixedTypeInfo>(ti);
     storageType = fixedTI.getStorageType();
@@ -4137,6 +4143,9 @@
 // layout. Calling isResilient() with this scope will always return false.
 ResilienceExpansion
 IRGenModule::getResilienceExpansionForLayout(NominalTypeDecl *decl) {
+  if (Types.isCompletelyFragile())
+    return ResilienceExpansion::Minimal;
+
   if (isResilient(decl, ResilienceExpansion::Minimal))
     return ResilienceExpansion::Maximal;
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 3f9cdda..6ec7f07 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -481,11 +481,21 @@
     }
     
     void addName() {
+      SmallString<32> nameBuf;
       StringRef name;
-      
+
+      // Use the original name with tag for synthesized decls. The tag comes
+      // after the null terminator for the name.
+      if (auto *synthesizedTypeAttr =
+            Type->getAttrs().getAttribute<ClangImporterSynthesizedTypeAttr>()) {
+        nameBuf.append(synthesizedTypeAttr->originalTypeName);
+        nameBuf.push_back('\0');
+        nameBuf.append(synthesizedTypeAttr->getManglingName());
+        
+        name = nameBuf;
       // Try to use the Clang name if there is one.
-      if (auto namedClangDecl =
-                             Mangle::ASTMangler::getClangDeclForMangling(Type)) {
+      } else if (auto namedClangDecl =
+                            Mangle::ASTMangler::getClangDeclForMangling(Type)) {
         name = namedClangDecl->getName();
       } else {
         name = Type->getName().str();
@@ -565,22 +575,18 @@
     /// Flags to indicate Clang-imported declarations so we mangle them
     /// consistently at runtime.
     void getClangImportedFlags(TypeContextDescriptorFlags &flags) const {
-      auto clangDecl = Mangle::ASTMangler::getClangDeclForMangling(Type);
-      if (!clangDecl)
-        return;
-      
-      if (isa<clang::TagDecl>(clangDecl)) {
-        flags.setIsCTag(true);
-        return;
+      if (Type->getAttrs().getAttribute<ClangImporterSynthesizedTypeAttr>()) {
+        flags.setIsSynthesizedRelatedEntity(true);
       }
       
-      if (isa<clang::TypedefNameDecl>(clangDecl)
-          || isa<clang::ObjCCompatibleAliasDecl>(clangDecl)) {
-        flags.setIsCTypedef(true);
-        return;
+      if (auto clangDecl = Mangle::ASTMangler::getClangDeclForMangling(Type)) {
+        if (isa<clang::TagDecl>(clangDecl)) {
+          flags.setIsCTag(true);
+        } else if (isa<clang::TypedefNameDecl>(clangDecl)
+                   || isa<clang::ObjCCompatibleAliasDecl>(clangDecl)) {
+          flags.setIsCTypedef(true);
+        }
       }
-      
-      return;
     }
 
     // Subclasses should provide:
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index d5c0dee..4553214 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -965,9 +965,7 @@
   void visitRetainValueInst(RetainValueInst *i);
   void visitRetainValueAddrInst(RetainValueAddrInst *i);
   void visitCopyValueInst(CopyValueInst *i);
-  void visitCopyUnownedValueInst(CopyUnownedValueInst *i) {
-    llvm_unreachable("unimplemented");
-  }
+  void visitCopyUnownedValueInst(CopyUnownedValueInst *i);
   void visitReleaseValueInst(ReleaseValueInst *i);
   void visitReleaseValueAddrInst(ReleaseValueAddrInst *i);
   void visitDestroyValueInst(DestroyValueInst *i);
@@ -1861,9 +1859,15 @@
 
   auto expansion = IGM.getResilienceExpansionForLayout(var);
 
+  // FIXME: Remove this once LLDB has proper support for resilience.
+  bool isREPLVar = false;
+  if (auto *decl = var->getDecl())
+    if (decl->isREPLVar())
+      isREPLVar = true;
+
   // If the global is fixed-size in all resilience domains that can see it,
   // we allocated storage for it statically, and there's nothing to do.
-  if (ti.isFixedSize(expansion))
+  if (isREPLVar || ti.isFixedSize(expansion))
     return;
 
   // Otherwise, the static storage for the global consists of a fixed-size
@@ -1891,9 +1895,15 @@
   Address addr = IGM.getAddrOfSILGlobalVariable(var, ti,
                                                 NotForDefinition);
 
+  // FIXME: Remove this once LLDB has proper support for resilience.
+  bool isREPLVar = false;
+  if (auto *decl = var->getDecl())
+    if (decl->isREPLVar())
+      isREPLVar = true;
+
   // If the global is fixed-size in all resilience domains that can see it,
   // we allocated storage for it statically, and there's nothing to do.
-  if (ti.isFixedSize(expansion)) {
+  if (isREPLVar || ti.isFixedSize(expansion)) {
     setLoweredAddress(i, addr);
     return;
   }
@@ -3841,6 +3851,18 @@
                                                        : irgen::Atomicity::NonAtomic);
 }
 
+void IRGenSILFunction::visitCopyUnownedValueInst(
+    swift::CopyUnownedValueInst *i) {
+  Explosion in = getLoweredExplosion(i->getOperand());
+  auto &ti = getReferentTypeInfo(*this, i->getOperand()->getType());
+  ti.strongRetainUnowned(*this, in, irgen::Atomicity::Atomic);
+  // Semantically we are just passing through the input parameter but as a
+  // strong reference... at LLVM IR level these type differences don't
+  // matter. So just set the lowered explosion appropriately.
+  Explosion output = getLoweredExplosion(i->getOperand());
+  setLoweredExplosion(i, output);
+}
+
 void IRGenSILFunction::visitUnownedRetainInst(swift::UnownedRetainInst *i) {
   Explosion lowered = getLoweredExplosion(i->getOperand());
   auto &ti = getReferentTypeInfo(*this, i->getOperand()->getType());
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 6af4794..acf9390 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3285,7 +3285,7 @@
     // Catch #warning(oops, forgot the quotes)
     SourceLoc wordsStartLoc = Tok.getLoc();
 
-    while (!Tok.isAtStartOfLine() && Tok.isNot(tok::r_paren)) {
+    while (!Tok.isAtStartOfLine() && !Tok.isAny(tok::r_paren, tok::eof)) {
       skipSingle();
     }
 
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 1c6dcc9..d3f0714 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -17,9 +17,10 @@
 #include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/Timer.h"
+#include "swift/Demangling/Demangle.h"
 #include "swift/Parse/Lexer.h"
-#include "swift/Parse/Parser.h"
 #include "swift/Parse/ParseSILSupport.h"
+#include "swift/Parse/Parser.h"
 #include "swift/SIL/AbstractionPattern.h"
 #include "swift/SIL/InstructionUtils.h"
 #include "swift/SIL/SILArgument.h"
@@ -28,8 +29,8 @@
 #include "swift/SIL/SILModule.h"
 #include "swift/SIL/SILUndef.h"
 #include "swift/SIL/TypeLowering.h"
-#include "swift/Syntax/SyntaxKind.h"
 #include "swift/Subsystems.h"
+#include "swift/Syntax/SyntaxKind.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/SaveAndRestore.h"
 
@@ -99,6 +100,12 @@
 
 SILParserState::~SILParserState() = default;
 
+void PrettyStackTraceParser::print(llvm::raw_ostream &out) const {
+  out << "With parser at source location: ";
+  P.Tok.getLoc().print(out, P.Context.SourceMgr);
+  out << '\n';
+}
+
 bool swift::parseIntoSourceFile(SourceFile &SF,
                                 unsigned BufferID,
                                 bool *Done,
@@ -5374,6 +5381,53 @@
   return false;
 }
 
+/// Lookup a global variable declaration from its demangled name.
+///
+/// A variable declaration exists for all sil_global variables defined in
+/// Swift. A Swift global defined outside this module will be exposed
+/// via an addressor rather than as a sil_global. Globals imported
+/// from clang will produce a sil_global but will not have any corresponding
+/// VarDecl.
+///
+/// FIXME: lookupGlobalDecl() can handle collisions between private or
+/// fileprivate global variables in the same SIL Module, but the typechecker
+/// will still incorrectly diagnose this as an "invalid redeclaration" and give
+/// all but the first declaration an error type.
+static Optional<VarDecl *> lookupGlobalDecl(Identifier GlobalName,
+                                            SILLinkage GlobalLinkage,
+                                            SILType GlobalType, Parser &P) {
+  // Create a set of DemangleOptions to produce the global variable's
+  // identifier, which is used as a search key in the declaration context.
+  Demangle::DemangleOptions demangleOpts;
+  demangleOpts.QualifyEntities = false;
+  demangleOpts.ShowPrivateDiscriminators = false;
+  demangleOpts.DisplayEntityTypes = false;
+  std::string GlobalDeclName = Demangle::demangleSymbolAsString(
+    GlobalName.str(), demangleOpts);
+
+  SmallVector<ValueDecl *, 4> CurModuleResults;
+  P.SF.getParentModule()->lookupValue(
+      {}, P.Context.getIdentifier(GlobalDeclName), NLKind::UnqualifiedLookup,
+      CurModuleResults);
+  // Bail-out on clang-imported globals.
+  if (CurModuleResults.empty())
+    return nullptr;
+
+  // private and fileprivate globals of the same name may be merged into a
+  // single SIL module. Find the declaration with the correct type and
+  // linkage. (If multiple globals have the same type and linkage then it
+  // doesn't matter which declaration we use).
+  for (ValueDecl *ValDecl : CurModuleResults) {
+    auto *VD = cast<VarDecl>(ValDecl);
+    CanType DeclTy = VD->getType()->getCanonicalType();
+    if (DeclTy == GlobalType.getASTType()
+        && getDeclSILLinkage(VD) == GlobalLinkage) {
+      return VD;
+    }
+  }
+  return None;
+}
+
 /// decl-sil-global: [[only in SIL mode]]
 ///   'sil_global' sil-linkage @name : sil-type [external]
 bool SILParserTUState::parseSILGlobal(Parser &P) {
@@ -5406,11 +5460,16 @@
   if (!GlobalLinkage.hasValue())
     GlobalLinkage = SILLinkage::DefaultForDefinition;
 
-  // FIXME: check for existing global variable?
-  auto *GV = SILGlobalVariable::create(M, GlobalLinkage.getValue(),
-                                       isSerialized,
-                                       GlobalName.str(),GlobalType,
-                                       RegularLocation(NameLoc));
+  // Lookup the global variable declaration for this sil_global.
+  auto VD =
+      lookupGlobalDecl(GlobalName, GlobalLinkage.getValue(), GlobalType, P);
+  if (!VD) {
+    P.diagnose(NameLoc, diag::sil_global_variable_not_found, GlobalName);
+    return true;
+  }
+  auto *GV = SILGlobalVariable::create(
+      M, GlobalLinkage.getValue(), isSerialized, GlobalName.str(), GlobalType,
+      RegularLocation(NameLoc), VD.getValue());
 
   GV->setLet(isLet);
   // Parse static initializer if exists.
diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp
index a70ccab..fc54291 100644
--- a/lib/RemoteAST/RemoteAST.cpp
+++ b/lib/RemoteAST/RemoteAST.cpp
@@ -754,7 +754,17 @@
       if (HadError) return;
       if (decl == Result) return;
       if (!Result) {
-        Result = cast<NominalTypeDecl>(decl);
+        // A synthesized type from the Clang importer may resolve to a
+        // compatibility alias.
+        if (auto resultAlias = dyn_cast<TypeAliasDecl>(decl)) {
+          if (resultAlias->isCompatibilityAlias()) {
+            Result = resultAlias->getUnderlyingTypeLoc().getType()
+                                ->getAnyNominal();
+          }
+        } else {
+          Result = dyn_cast<NominalTypeDecl>(decl);
+        }
+        HadError |= !Result;
       } else {
         HadError = true;
         Result = nullptr;
diff --git a/lib/SIL/MemAccessUtils.cpp b/lib/SIL/MemAccessUtils.cpp
index cb58844..9e5ca29 100644
--- a/lib/SIL/MemAccessUtils.cpp
+++ b/lib/SIL/MemAccessUtils.cpp
@@ -13,6 +13,7 @@
 #define DEBUG_TYPE "sil-access-utils"
 
 #include "swift/SIL/MemAccessUtils.h"
+#include "swift/SIL/SILGlobalVariable.h"
 #include "swift/SIL/SILUndef.h"
 
 using namespace swift;
@@ -28,6 +29,14 @@
     return Stack;
   case ValueKind::GlobalAddrInst:
     return Global;
+  case ValueKind::ApplyInst: {
+    FullApplySite apply(cast<ApplyInst>(base));
+    if (auto *funcRef = apply.getReferencedFunction()) {
+      if (getVariableOfGlobalInit(funcRef))
+        return Global;
+    }
+    return Unidentified;
+  }
   case ValueKind::RefElementAddrInst:
     return Class;
   // A function argument is effectively a nested access, enforced
@@ -67,7 +76,19 @@
     paramIndex = cast<SILFunctionArgument>(base)->getIndex();
     break;
   case Global:
-    global = cast<GlobalAddrInst>(base)->getReferencedGlobal();
+    if (auto *GAI = dyn_cast<GlobalAddrInst>(base))
+      global = GAI->getReferencedGlobal();
+    else {
+      FullApplySite apply(cast<ApplyInst>(base));
+      auto *funcRef = apply.getReferencedFunction();
+      assert(funcRef);
+      global = getVariableOfGlobalInit(funcRef);
+      assert(global);
+      // Require a decl for all formally accessed globals defined in this
+      // module. (Access of globals defined elsewhere has Unidentified storage).
+      // AccessEnforcementWMO requires this.
+      assert(global->getDecl());
+    }
     break;
   case Class: {
     // Do a best-effort to find the identity of the object being projected
@@ -149,6 +170,17 @@
 
 void AccessedStorage::dump() const { print(llvm::dbgs()); }
 
+// Return true if the given apply invokes a global addressor defined in another
+// module.
+static bool isExternalGlobalAddressor(ApplyInst *AI) {
+  FullApplySite apply(AI);
+  auto *funcRef = apply.getReferencedFunction();
+  if (!funcRef)
+    return false;
+  
+  return funcRef->isGlobalInit() && funcRef->isExternalDeclaration();
+}
+
 // Given an address base is a block argument, verify that it is actually a box
 // projected from a switch_enum. This is a valid pattern at any SIL stage
 // resulting in a block-type phi. In later SIL stages, the optimizer may form
@@ -186,12 +218,16 @@
   }
 }
 
+// AccessEnforcementWMO makes a strong assumption that all accesses are either
+// identified or are *not* accessing a global variable or class property defined
+// in this module. Consequently, we cannot simply bail out on
+// PointerToAddressInst as an Unidentified access.
 AccessedStorage swift::findAccessedStorage(SILValue sourceAddr) {
   SILValue address = sourceAddr;
   while (true) {
     AccessedStorage::Kind kind = AccessedStorage::classify(address);
-    // First handle identified cases: these are always valid as the base of a
-    // formal access.
+    // First handle identified cases: these are always valid as the base of
+    // a formal access.
     if (kind != AccessedStorage::Unidentified)
       return AccessedStorage(address, kind);
 
@@ -202,10 +238,16 @@
         return AccessedStorage(address, AccessedStorage::Unidentified);
       return AccessedStorage();
 
-    case ValueKind::PointerToAddressInst:
     case ValueKind::SILUndef:
       return AccessedStorage(address, AccessedStorage::Unidentified);
 
+    case ValueKind::ApplyInst:
+      if (isExternalGlobalAddressor(cast<ApplyInst>(address)))
+        return AccessedStorage(address, AccessedStorage::Unidentified);
+
+      // Don't currently allow any other calls to return an accessed address.
+      return AccessedStorage();
+
     // A block argument may be a box value projected out of
     // switch_enum. Address-type block arguments are not allowed.
     case ValueKind::SILPHIArgument:
@@ -218,17 +260,22 @@
     // Load a box from an indirect payload of an opaque enum.
     // We must have peeked past the project_box earlier in this loop.
     // (the indirectness makes it a box, the load is for address-only).
-    // 
+    //
     // %payload_adr = unchecked_take_enum_data_addr %enum : $*Enum, #Enum.case
     // %box = load [take] %payload_adr : $*{ var Enum }
     //
     // FIXME: this case should go away with opaque values.
+    //
+    // Otherwise return invalid AccessedStorage.
     case ValueKind::LoadInst: {
-      assert(address->getType().is<SILBoxType>());
-      address = cast<LoadInst>(address)->getOperand();
-      assert(isa<UncheckedTakeEnumDataAddrInst>(address));
-      continue;
+      if (address->getType().is<SILBoxType>()) {
+        address = cast<LoadInst>(address)->getOperand();
+        assert(isa<UncheckedTakeEnumDataAddrInst>(address));
+        continue;
+      }
+      return AccessedStorage();
     }
+
     // Inductive cases:
     // Look through address casts to find the source address.
     case ValueKind::MarkUninitializedInst:
@@ -249,6 +296,30 @@
       address = cast<SingleValueInstruction>(address)->getOperand(0);
       continue;
 
+    // Access to a Builtin.RawPointer. Treat this like the inductive cases
+    // above because some RawPointer's originate from identified locations. See
+    // the special case for global addressors, which return RawPointer above.
+    //
+    // If the inductive search does not find a valid addressor, it will
+    // eventually reach the default case that returns in invalid location. This
+    // is correct for RawPointer because, although accessing a RawPointer is
+    // legal SIL, there is no way to guarantee that it doesn't access class or
+    // global storage, so returning a valid unidentified storage object would be
+    // incorrect. It is the caller's responsibility to know that formal access
+    // to such a location can be safely ignored.
+    //
+    // For example:
+    //
+    // - KeyPath Builtins access RawPointer. However, the caller can check
+    // that the access `isFromBuilin` and ignore the storage.
+    //
+    // - lldb generates RawPointer access for debugger variables, but SILGen
+    // marks debug VarDecl access as 'Unsafe' and SIL passes don't need the
+    // AccessedStorage for 'Unsafe' access.
+    case ValueKind::PointerToAddressInst:
+      address = cast<SingleValueInstruction>(address)->getOperand(0);
+      continue;
+
     // Subobject projections.
     case ValueKind::StructElementAddrInst:
     case ValueKind::TupleElementAddrInst:
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index a6ff85e..b4fad5c 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -62,8 +62,9 @@
   auto params = FTI->getParameters();
   auto newParams = params.slice(0, params.size() - argCount);
 
-  auto extInfo = FTI->getExtInfo().withRepresentation(
-      SILFunctionType::Representation::Thick);
+  auto extInfo = FTI->getExtInfo()
+    .withRepresentation(SILFunctionType::Representation::Thick)
+    .withIsPseudogeneric(false);
 
   // If the original method has an @unowned_inner_pointer return, the partial
   // application thunk will lifetime-extend 'self' for us, converting the
@@ -263,7 +264,8 @@
       isa<RetainValueInst>(Inst) || isa<UnownedRetainInst>(Inst) ||
       isa<UnownedReleaseInst>(Inst) || isa<StrongRetainUnownedInst>(Inst) ||
       isa<StoreWeakInst>(Inst) || isa<StrongRetainInst>(Inst) ||
-      isa<AllocStackInst>(Inst) || isa<DeallocStackInst>(Inst))
+      isa<AllocStackInst>(Inst) || isa<DeallocStackInst>(Inst) ||
+      isa<CopyUnownedValueInst>(Inst))
     return false;
 
   // Assign and copyaddr of trivial types cannot drop refcounts, and 'inits'
diff --git a/lib/SIL/SILDebugScope.cpp b/lib/SIL/SILDebugScope.cpp
index 18214aa..6cac6e9 100644
--- a/lib/SIL/SILDebugScope.cpp
+++ b/lib/SIL/SILDebugScope.cpp
@@ -23,7 +23,7 @@
 using namespace swift;
 
 SILDebugScope::SILDebugScope(SILLocation Loc, SILFunction *SILFn,
-                             const SILDebugScope *ParentScope ,
+                             const SILDebugScope *ParentScope,
                              const SILDebugScope *InlinedCallSite)
     : Loc(Loc), InlinedCallSite(InlinedCallSite) {
   if (ParentScope)
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index 6c61fa5..cc07bc9 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -775,6 +775,10 @@
   if (isThunk() || isForeign)
     return SubclassScope::NotApplicable;
 
+  // Default arg generators only need to be visible in Swift 3.
+  if (isDefaultArgGenerator() && !context->getASTContext().isSwiftVersion3())
+    return SubclassScope::NotApplicable;
+
   auto *classType = context->getAsClassOrClassExtensionContext();
   if (!classType || classType->isFinal())
     return SubclassScope::NotApplicable;
diff --git a/lib/SIL/SILGlobalVariable.cpp b/lib/SIL/SILGlobalVariable.cpp
index a7eb1ff..bb02b95 100644
--- a/lib/SIL/SILGlobalVariable.cpp
+++ b/lib/SIL/SILGlobalVariable.cpp
@@ -10,7 +10,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "swift/SIL/SILFunction.h"
 #include "swift/SIL/SILGlobalVariable.h"
+#include "swift/SIL/SILInstruction.h"
 #include "swift/SIL/SILLinkage.h"
 #include "swift/SIL/SILModule.h"
 
@@ -137,3 +139,132 @@
 const clang::Decl *SILGlobalVariable::getClangDecl() const {
   return (VDecl ? VDecl->getClangDecl() : nullptr);
 }
+
+//===----------------------------------------------------------------------===//
+// Utilities for verification and optimization.
+//===----------------------------------------------------------------------===//
+
+static SILGlobalVariable *getStaticallyInitializedVariable(SILFunction *AddrF) {
+  if (AddrF->isExternalDeclaration())
+    return nullptr;
+
+  auto *RetInst = cast<ReturnInst>(AddrF->findReturnBB()->getTerminator());
+  auto *API = dyn_cast<AddressToPointerInst>(RetInst->getOperand());
+  if (!API)
+    return nullptr;
+  auto *GAI = dyn_cast<GlobalAddrInst>(API->getOperand());
+  if (!GAI)
+    return nullptr;
+
+  return GAI->getReferencedGlobal();
+}
+
+SILGlobalVariable *swift::getVariableOfGlobalInit(SILFunction *AddrF) {
+  if (!AddrF->isGlobalInit())
+    return nullptr;
+
+  if (auto *SILG = getStaticallyInitializedVariable(AddrF))
+    return SILG;
+
+  // If the addressor contains a single "once" call, it calls globalinit_func,
+  // and the globalinit_func is called by "once" from a single location,
+  // continue; otherwise bail.
+  BuiltinInst *CallToOnce;
+  auto *InitF = findInitializer(&AddrF->getModule(), AddrF, CallToOnce);
+
+  if (!InitF || !InitF->getName().startswith("globalinit_"))
+    return nullptr;
+
+  // If the globalinit_func is trivial, continue; otherwise bail.
+  SingleValueInstruction *dummyInitVal;
+  auto *SILG = getVariableOfStaticInitializer(InitF, dummyInitVal);
+
+  return SILG;
+}
+
+SILFunction *swift::getCalleeOfOnceCall(BuiltinInst *BI) {
+  assert(BI->getNumOperands() == 2 && "once call should have 2 operands.");
+
+  auto Callee = BI->getOperand(1);
+  assert(Callee->getType().castTo<SILFunctionType>()->getRepresentation()
+           == SILFunctionTypeRepresentation::CFunctionPointer &&
+         "Expected C function representation!");
+
+  if (auto *FR = dyn_cast<FunctionRefInst>(Callee))
+    return FR->getReferencedFunction();
+
+  return nullptr;
+}
+
+// Find the globalinit_func by analyzing the body of the addressor.
+SILFunction *swift::findInitializer(SILModule *Module, SILFunction *AddrF,
+                             BuiltinInst *&CallToOnce) {
+  // We only handle a single SILBasicBlock for now.
+  if (AddrF->size() != 1)
+    return nullptr;
+
+  CallToOnce = nullptr;
+  SILBasicBlock *BB = &AddrF->front();
+  for (auto &I : *BB) {
+    // Find the builtin "once" call.
+    if (auto *BI = dyn_cast<BuiltinInst>(&I)) {
+      const BuiltinInfo &Builtin =
+        BI->getModule().getBuiltinInfo(BI->getName());
+      if (Builtin.ID != BuiltinValueKind::Once)
+        continue;
+
+      // Bail if we have multiple "once" calls in the addressor.
+      if (CallToOnce)
+        return nullptr;
+
+      CallToOnce = BI;
+    }
+  }
+  if (!CallToOnce)
+    return nullptr;
+  return getCalleeOfOnceCall(CallToOnce);
+}
+
+SILGlobalVariable *
+swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
+                                      SingleValueInstruction *&InitVal) {
+  InitVal = nullptr;
+  SILGlobalVariable *GVar = nullptr;
+  // We only handle a single SILBasicBlock for now.
+  if (InitFunc->size() != 1)
+    return nullptr;
+
+  SILBasicBlock *BB = &InitFunc->front();
+  GlobalAddrInst *SGA = nullptr;
+  bool HasStore = false;
+  for (auto &I : *BB) {
+    // Make sure we have a single GlobalAddrInst and a single StoreInst.
+    // And the StoreInst writes to the GlobalAddrInst.
+    if (isa<AllocGlobalInst>(&I) || isa<ReturnInst>(&I)
+        || isa<DebugValueInst>(&I)) {
+      continue;
+    } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
+      if (SGA)
+        return nullptr;
+      SGA = sga;
+      GVar = SGA->getReferencedGlobal();
+    } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
+      if (HasStore || SI->getDest() != SGA)
+        return nullptr;
+      HasStore = true;
+      SILValue value = SI->getSrc();
+
+      // We only handle StructInst and TupleInst being stored to a
+      // global variable for now.
+      if (!isa<StructInst>(value) && !isa<TupleInst>(value))
+        return nullptr;
+      InitVal = cast<SingleValueInstruction>(value);
+    } else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
+                                                             I.getModule())) {
+      return nullptr;
+    }
+  }
+  if (!InitVal)
+    return nullptr;
+  return GVar;
+}
diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp
index b8ecb7f..b942edd 100644
--- a/lib/SIL/SILModule.cpp
+++ b/lib/SIL/SILModule.cpp
@@ -855,3 +855,22 @@
   return prop;
 }
 
+// Definition from SILLinkage.h.
+SILLinkage swift::getDeclSILLinkage(const ValueDecl *decl) {
+  AccessLevel access = decl->getEffectiveAccess();
+  SILLinkage linkage;
+  switch (access) {
+  case AccessLevel::Private:
+  case AccessLevel::FilePrivate:
+    linkage = SILLinkage::Private;
+    break;
+  case AccessLevel::Internal:
+    linkage = SILLinkage::Hidden;
+    break;
+  case AccessLevel::Public:
+  case AccessLevel::Open:
+    linkage = SILLinkage::Public;
+    break;
+  }
+  return linkage;
+}
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 50e8441..9e39ec4 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -1581,17 +1581,21 @@
             "category");
   }
 
+  template <class AI>
+  void checkAccessEnforcement(AI *AccessInst) {
+    if (AccessInst->getModule().getStage() != SILStage::Raw) {
+      require(AccessInst->getEnforcement() != SILAccessEnforcement::Unknown,
+              "access must have known enforcement outside raw stage");
+    }
+  }
+
   void checkBeginAccessInst(BeginAccessInst *BAI) {
-    auto sourceOper = BAI->getOperand();
-    requireSameType(BAI->getType(), sourceOper->getType(),
+    requireSameType(BAI->getType(), BAI->getSource()->getType(),
                     "result must be same type as operand");
     require(BAI->getType().isAddress(),
             "begin_access operand must have address type");
 
-    if (BAI->getModule().getStage() != SILStage::Raw) {
-      require(BAI->getEnforcement() != SILAccessEnforcement::Unknown,
-              "access must have known enforcement outside raw stage");
-    }
+    checkAccessEnforcement(BAI);
 
     switch (BAI->getAccessKind()) {
     case SILAccessKind::Init:
@@ -1605,10 +1609,28 @@
       break;
     }
 
-    // For dynamic Read/Modify access, AccessEnforcementWMO assumes a valid
-    // AccessedStorage and runs very late in the optimizer pipeline.
-    // TODO: eventually, make this true for any kind of access.
-    findAccessedStorage(sourceOper);
+    // Verify that all formal accesses patterns are recognized as part of a
+    // whitelist. The presence of an unknown pattern means that analysis will
+    // silently fail, and the compiler may be introducing undefined behavior
+    // with no other way to detect it.
+    //
+    // For example, AccessEnforcementWMO runs very late in the
+    // pipeline and assumes valid storage for all dynamic Read/Modify access. It
+    // also requires that Unidentified access fit a whitelist on known
+    // non-internal globals or class properties.
+    //
+    // First check that findAccessedStorage returns without asserting. For
+    // Unsafe enforcement, that is sufficient. For any other enforcement
+    // level also require that it returns a valid AccessedStorage object.
+    // Unsafe enforcement is used for some unrecognizable access patterns,
+    // like debugger variables. The compiler never cares about the source of
+    // those accesses.
+    findAccessedStorage(BAI->getSource());
+    // FIXME: Also require that a valid storage location is returned.
+    //
+    // AccessedStorage storage = findAccessedStorage(BAI->getSource());
+    // if (BAI->getEnforcement() != SILAccessEnforcement::Unsafe)
+    //  require(storage, "Unknown formal access pattern");
   }
 
   void checkEndAccessInst(EndAccessInst *EAI) {
@@ -1623,13 +1645,37 @@
     }
   }
 
-  void checkBeginUnpairedAccessInst(BeginUnpairedAccessInst *I) {
-    require(I->getEnforcement() != SILAccessEnforcement::Unknown,
+  void checkBeginUnpairedAccessInst(BeginUnpairedAccessInst *BUAI) {
+    require(BUAI->getEnforcement() != SILAccessEnforcement::Unknown,
             "unpaired access can never use unknown enforcement");
-    require(I->getSource()->getType().isAddress(),
+    require(BUAI->getSource()->getType().isAddress(),
             "address operand must have address type");
-    requireAddressType(BuiltinUnsafeValueBufferType, I->getBuffer(),
+    requireAddressType(BuiltinUnsafeValueBufferType, BUAI->getBuffer(),
                        "scratch buffer operand");
+
+    checkAccessEnforcement(BUAI);
+
+    switch (BUAI->getAccessKind()) {
+    case SILAccessKind::Init:
+    case SILAccessKind::Deinit:
+      require(BUAI->getEnforcement() == SILAccessEnforcement::Static,
+              "init/deinit accesses cannot use non-static enforcement");
+      break;
+    case SILAccessKind::Read:
+    case SILAccessKind::Modify:
+      break;
+    }
+
+    // First check that findAccessedStorage never asserts.
+    findAccessedStorage(BUAI->getSource());
+    // FIXME: Also require that a valid storage location is returned.
+    //
+    // Only allow Unsafe and Builtin access to have invalid storage.
+    // AccessedStorage storage = findAccessedStorage(BAI->getSource());
+    // if (BUAI->getEnforcement() != SILAccessEnforcement::Unsafe
+    //     && !BUAI->isFromBuiltin()) {
+    //   require(storage, "Unknown formal access pattern");
+    // }
   }
 
   void checkEndUnpairedAccessInst(EndUnpairedAccessInst *I) {
@@ -1637,6 +1683,8 @@
             "unpaired access can never use unknown enforcement");
     requireAddressType(BuiltinUnsafeValueBufferType, I->getBuffer(),
                        "scratch buffer operand");
+
+    checkAccessEnforcement(I);
   }
 
   void checkStoreInst(StoreInst *SI) {
@@ -1868,9 +1916,8 @@
                                          "Operand of unowned_retain");
     require(unownedType->isLoadable(ResilienceExpansion::Maximal),
             "unowned_retain requires unowned type to be loadable");
-    require(F.hasQualifiedOwnership(),
-            "copy_unowned_value is only valid in functions with qualified "
-            "ownership");
+    // *NOTE* We allow copy_unowned_value to be used throughout the entire
+    // pipeline even though it is a higher level instruction.
   }
 
   void checkDestroyValueInst(DestroyValueInst *I) {
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 15edaf1..9575a81 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -507,7 +507,7 @@
   // escaped by storing a withoutActuallyEscaping closure in the block and after
   // the block is ultimately destroyed checking that the closure is uniquely
   // referenced.
-  bool useWithoutEscapingVerifcation = false;
+  bool useWithoutEscapingVerification = false;
 	ManagedValue escaping;
   if (loweredFuncTy->isNoEscape()) {
     auto escapingTy = loweredFuncTy->getWithExtInfo(
@@ -520,7 +520,7 @@
         funcType.withExtInfo(funcType->getExtInfo().withNoEscape(false));
     funcType = escapingAnyTy;
     fn = B.createCopyValue(loc, escaping);
-    useWithoutEscapingVerifcation = true;
+    useWithoutEscapingVerification = true;
   }
 
   // Build the invoke function signature. The block will capture the original
@@ -590,7 +590,7 @@
     // another reference for the is_escaping sentinel.
     buildFuncToBlockInvokeBody(thunkSGF, loc, funcType, blockType,
                                loweredFuncTy, loweredBlockTy, storageTy,
-                               useWithoutEscapingVerifcation);
+                               useWithoutEscapingVerification);
   }
 
   // Form the block on the stack.
@@ -610,7 +610,7 @@
   // copy_block_without_escaping %block withoutEscaping %closure instruction.
   // A mandatory SIL pass will replace this instruction by the required
   // verification instruction sequence.
-  auto heapBlock = useWithoutEscapingVerifcation
+  auto heapBlock = useWithoutEscapingVerification
                        ? SILValue(B.createCopyBlockWithoutEscaping(
                              loc, stackBlock, escaping.forward(*this)))
                        : SILValue(B.createCopyBlock(loc, stackBlock));
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index 24edce0..50c389f 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -441,7 +441,8 @@
   void enterDebugScope(SILLocation Loc) {
     auto *Parent =
         DebugScopeStack.size() ? DebugScopeStack.back() : F.getDebugScope();
-    auto *DS = new (SGM.M) SILDebugScope(Loc, &getFunction(), Parent);
+    auto *DS = new (SGM.M)
+        SILDebugScope(Loc.getAsRegularLocation(), &getFunction(), Parent);
     DebugScopeStack.push_back(DS);
     B.setCurrentDebugScope(DS);
   }
diff --git a/lib/SILOptimizer/ARC/CMakeLists.txt b/lib/SILOptimizer/ARC/CMakeLists.txt
index 7181360..2a05a36 100644
--- a/lib/SILOptimizer/ARC/CMakeLists.txt
+++ b/lib/SILOptimizer/ARC/CMakeLists.txt
@@ -1,12 +1,12 @@
-set(ARC_SOURCES
-  ARC/ARCBBState.cpp
-  ARC/ARCLoopOpts.cpp
-  ARC/ARCMatchingSet.cpp
-  ARC/ARCRegionState.cpp
-  ARC/ARCSequenceOpts.cpp
-  ARC/GlobalARCSequenceDataflow.cpp
-  ARC/GlobalLoopARCSequenceDataflow.cpp
-  ARC/RCStateTransition.cpp
-  ARC/RCStateTransitionVisitors.cpp
-  ARC/RefCountState.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  ARCBBState.cpp
+  ARCLoopOpts.cpp
+  ARCMatchingSet.cpp
+  ARCRegionState.cpp
+  ARCSequenceOpts.cpp
+  GlobalARCSequenceDataflow.cpp
+  GlobalLoopARCSequenceDataflow.cpp
+  RCStateTransition.cpp
+  RCStateTransitionVisitors.cpp
+  RefCountState.cpp
+)
diff --git a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
index 9bd8b54..ca9fc0c 100644
--- a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
@@ -68,13 +68,15 @@
     switch (user->getKind()) {
     case SILInstructionKind::BeginAccessInst: {
       auto *BAI = cast<BeginAccessInst>(user);
-      const IndexTrieNode *subPath = findSubPathAccessed(BAI);
-      summary.mergeWith(BAI->getAccessKind(), BAI->getLoc(), subPath);
-      // We don't add the users of the begin_access to the worklist because
-      // even if these users eventually begin an access to the address
-      // or a projection from it, that access can't begin more exclusive
-      // access than this access -- otherwise it will be diagnosed
-      // elsewhere.
+      if (BAI->getEnforcement() != SILAccessEnforcement::Unsafe) {
+        const IndexTrieNode *subPath = findSubPathAccessed(BAI);
+        summary.mergeWith(BAI->getAccessKind(), BAI->getLoc(), subPath);
+        // We don't add the users of the begin_access to the worklist because
+        // even if these users eventually begin an access to the address
+        // or a projection from it, that access can't begin more exclusive
+        // access than this access -- otherwise it will be diagnosed
+        // elsewhere.
+      }
       break;
     }
     case SILInstructionKind::EndUnpairedAccessInst:
diff --git a/lib/SILOptimizer/Analysis/CMakeLists.txt b/lib/SILOptimizer/Analysis/CMakeLists.txt
index 06b6226..7344019 100644
--- a/lib/SILOptimizer/Analysis/CMakeLists.txt
+++ b/lib/SILOptimizer/Analysis/CMakeLists.txt
@@ -1,28 +1,28 @@
-set(ANALYSIS_SOURCES
-  Analysis/ARCAnalysis.cpp
-  Analysis/AccessSummaryAnalysis.cpp
-  Analysis/AccessedStorageAnalysis.cpp
-  Analysis/AliasAnalysis.cpp
-  Analysis/Analysis.cpp
-  Analysis/ArraySemantic.cpp
-  Analysis/BasicCalleeAnalysis.cpp
-  Analysis/CallerAnalysis.cpp
-  Analysis/CFG.cpp
-  Analysis/ClassHierarchyAnalysis.cpp
-  Analysis/ClosureScope.cpp
-  Analysis/ColdBlockInfo.cpp
-  Analysis/DestructorAnalysis.cpp
-  Analysis/EscapeAnalysis.cpp
-  Analysis/EpilogueARCAnalysis.cpp
-  Analysis/FunctionOrder.cpp
-  Analysis/IVAnalysis.cpp
-  Analysis/LoopAnalysis.cpp
-  Analysis/LoopRegionAnalysis.cpp
-  Analysis/MemoryBehavior.cpp
-  Analysis/ProtocolConformanceAnalysis.cpp
-  Analysis/RCIdentityAnalysis.cpp
-  Analysis/SideEffectAnalysis.cpp
-  Analysis/SimplifyInstruction.cpp
-  Analysis/TypeExpansionAnalysis.cpp
-  Analysis/ValueTracking.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  ARCAnalysis.cpp
+  AccessSummaryAnalysis.cpp
+  AccessedStorageAnalysis.cpp
+  AliasAnalysis.cpp
+  Analysis.cpp
+  ArraySemantic.cpp
+  BasicCalleeAnalysis.cpp
+  CallerAnalysis.cpp
+  CFG.cpp
+  ClassHierarchyAnalysis.cpp
+  ClosureScope.cpp
+  ColdBlockInfo.cpp
+  DestructorAnalysis.cpp
+  EscapeAnalysis.cpp
+  EpilogueARCAnalysis.cpp
+  FunctionOrder.cpp
+  IVAnalysis.cpp
+  LoopAnalysis.cpp
+  LoopRegionAnalysis.cpp
+  MemoryBehavior.cpp
+  ProtocolConformanceAnalysis.cpp
+  RCIdentityAnalysis.cpp
+  SideEffectAnalysis.cpp
+  SimplifyInstruction.cpp
+  TypeExpansionAnalysis.cpp
+  ValueTracking.cpp
+)
diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
index 14b48be..f3ff765 100644
--- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
@@ -1372,6 +1372,7 @@
     case SILInstructionKind::DeallocStackInst:
     case SILInstructionKind::StrongRetainInst:
     case SILInstructionKind::StrongRetainUnownedInst:
+    case SILInstructionKind::CopyUnownedValueInst:
     case SILInstructionKind::RetainValueInst:
     case SILInstructionKind::UnownedRetainInst:
     case SILInstructionKind::BranchInst:
diff --git a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
index 0b255a6..a0cf8ce 100644
--- a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
+++ b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
@@ -152,6 +152,7 @@
   }
   REFCOUNTINC_MEMBEHAVIOR_INST(StrongRetainInst)
   REFCOUNTINC_MEMBEHAVIOR_INST(StrongRetainUnownedInst)
+  REFCOUNTINC_MEMBEHAVIOR_INST(CopyUnownedValueInst)
   REFCOUNTINC_MEMBEHAVIOR_INST(UnownedRetainInst)
   REFCOUNTINC_MEMBEHAVIOR_INST(RetainValueInst)
 #undef REFCOUNTINC_MEMBEHAVIOR_INST
diff --git a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
index 720f21d..b35d14f 100644
--- a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
@@ -483,6 +483,7 @@
     return;
   case SILInstructionKind::StrongRetainInst:
   case SILInstructionKind::StrongRetainUnownedInst:
+  case SILInstructionKind::CopyUnownedValueInst:
   case SILInstructionKind::RetainValueInst:
   case SILInstructionKind::UnownedRetainInst:
     getEffectsOn(I->getOperand(0))->Retains = true;
diff --git a/lib/SILOptimizer/CMakeLists.txt b/lib/SILOptimizer/CMakeLists.txt
index e3a24e8..13a620f 100644
--- a/lib/SILOptimizer/CMakeLists.txt
+++ b/lib/SILOptimizer/CMakeLists.txt
@@ -1,3 +1,26 @@
+
+set(SILOPTIMIZER_SOURCES)
+
+function(_list_transform newvar)
+  set(sources ${ARGN})
+  set(dir ${CMAKE_CURRENT_SOURCE_DIR})
+  set(tmp)
+  foreach (s ${sources})
+    list(APPEND tmp "${dir}/${s}")
+  endforeach()
+  set(${newvar} "${tmp}" PARENT_SCOPE)
+endfunction()
+
+macro(silopt_register_sources)
+  precondition(new_transformed_sources
+    NEGATE
+    MESSAGE "Expected this to be empty since we clear after each run")
+  _list_transform(new_transformed_sources ${ARGN})
+  list_union("${SILOPTIMIZER_SOURCES}" "${new_transformed_sources}" out)
+  set(SILOPTIMIZER_SOURCES "${out}" PARENT_SCOPE)
+  set(new_transformed_sources)
+endmacro()
+
 add_subdirectory(ARC)
 add_subdirectory(Analysis)
 add_subdirectory(FunctionSignatureTransforms)
@@ -9,16 +32,7 @@
 add_subdirectory(Transforms)
 add_subdirectory(UtilityPasses)
 add_subdirectory(Utils)
+
 add_swift_library(swiftSILOptimizer STATIC
-  ${ARC_SOURCES}
-  ${ANALYSIS_SOURCES}
-  ${SILCOMBINER_SOURCES}
-  ${UTILITYPASSES_SOURCES}
-  ${UTILS_SOURCES}
-  ${PASSMANAGER_SOURCES}
-  ${LOOPTRANSFORMS_SOURCES}
-  ${MANDATORY_SOURCES}
-  ${TRANSFORMS_SOURCES}
-  ${IPO_SOURCES}
-  ${FUNCTIONSIGNATURETRANSFORMS_SOURCES}
+  ${SILOPTIMIZER_SOURCES}
   LINK_LIBRARIES swiftSIL)
diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/CMakeLists.txt b/lib/SILOptimizer/FunctionSignatureTransforms/CMakeLists.txt
index ec13b66..720da74 100644
--- a/lib/SILOptimizer/FunctionSignatureTransforms/CMakeLists.txt
+++ b/lib/SILOptimizer/FunctionSignatureTransforms/CMakeLists.txt
@@ -1,6 +1,6 @@
-set(FUNCTIONSIGNATURETRANSFORMS_SOURCES
-  FunctionSignatureTransforms/FunctionSignatureOpts.cpp
-  FunctionSignatureTransforms/DeadArgumentTransform.cpp
-  FunctionSignatureTransforms/ArgumentExplosionTransform.cpp
-  FunctionSignatureTransforms/OwnedToGuaranteedTransform.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  FunctionSignatureOpts.cpp
+  DeadArgumentTransform.cpp
+  ArgumentExplosionTransform.cpp
+  OwnedToGuaranteedTransform.cpp
+)
diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp
index 93bd6f4..69bb6dd 100644
--- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp
+++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp
@@ -496,11 +496,14 @@
     NewFGenericEnv = nullptr;
   }
 
+  // The specialized function is an internal detail, so we need to disconnect it
+  // from a parent class, if one exists, thus the override of the
+  // classSubclassScope.
   TransformDescriptor.OptimizedFunction = M.createFunction(
       linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(),
       F->isTransparent(), F->isSerialized(), F->getEntryCount(), F->isThunk(),
-      F->getClassSubclassScope(), F->getInlineStrategy(), F->getEffectsKind(),
-      nullptr, F->getDebugScope());
+      /*classSubclassScope=*/SubclassScope::NotApplicable,
+      F->getInlineStrategy(), F->getEffectsKind(), nullptr, F->getDebugScope());
   SILFunction *NewF = TransformDescriptor.OptimizedFunction.get();
   if (!F->hasQualifiedOwnership()) {
     NewF->setUnqualifiedOwnership();
@@ -544,7 +547,7 @@
     ThunkBody->createFunctionArgument(ArgDesc.Arg->getType(), ArgDesc.Decl);
   }
 
-  SILLocation Loc = ThunkBody->getParent()->getLocation();
+  SILLocation Loc = RegularLocation::getAutoGeneratedLocation();
   SILBuilder Builder(ThunkBody);
   Builder.setCurrentDebugScope(ThunkBody->getParent()->getDebugScope());
 
diff --git a/lib/SILOptimizer/IPO/CMakeLists.txt b/lib/SILOptimizer/IPO/CMakeLists.txt
index 0a1abda..ea6b83f 100644
--- a/lib/SILOptimizer/IPO/CMakeLists.txt
+++ b/lib/SILOptimizer/IPO/CMakeLists.txt
@@ -1,11 +1,10 @@
-set(IPO_SOURCES
-  IPO/CapturePromotion.cpp
-  IPO/CapturePropagation.cpp
-  IPO/ClosureSpecializer.cpp
-  IPO/DeadFunctionElimination.cpp
-  IPO/EagerSpecializer.cpp
-  IPO/GlobalOpt.cpp
-  IPO/GlobalPropertyOpt.cpp
-  IPO/LetPropertiesOpts.cpp
-  IPO/UsePrespecialized.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  CapturePromotion.cpp
+  CapturePropagation.cpp
+  ClosureSpecializer.cpp
+  DeadFunctionElimination.cpp
+  EagerSpecializer.cpp
+  GlobalOpt.cpp
+  GlobalPropertyOpt.cpp
+  LetPropertiesOpts.cpp
+  UsePrespecialized.cpp)
diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
index 7f2bfc4..1989c32 100644
--- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
+++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
@@ -371,6 +371,13 @@
   }
 
   /// Retrieve the visibility information from the AST.
+  ///
+  /// This differs from SILModule::isVisibleExternally(VarDecl *) because of
+  /// it's handling of class methods. It returns true for methods whose
+  /// declarations are not directly visible externally, but have been imported
+  /// from another module. This ensures that entries aren't deleted from vtables
+  /// imported from the stdlib.
+  /// FIXME: Passes should not embed special logic for handling linkage.
   bool isVisibleExternally(const ValueDecl *decl) {
     AccessLevel access = decl->getEffectiveAccess();
     SILLinkage linkage;
@@ -390,9 +397,7 @@
     if (isPossiblyUsedExternally(linkage, Module->isWholeModule()))
       return true;
 
-    // If a vtable or witness table (method) is only visible in another module
-    // it can be accessed inside that module and we don't see this access.
-    // We hit this case e.g. if a table is imported from the stdlib.
+    // Special case for vtable visibility.
     if (decl->getDeclContext()->getParentModule() != Module->getSwiftModule())
       return true;
 
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 31fafa0..5156bdd 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -14,6 +14,7 @@
 #include "swift/Demangling/Demangle.h"
 #include "swift/SIL/CFG.h"
 #include "swift/SIL/DebugUtils.h"
+#include "swift/SIL/SILGlobalVariable.h"
 #include "swift/SIL/SILInstruction.h"
 #include "swift/SILOptimizer/Analysis/ColdBlockInfo.h"
 #include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
@@ -113,8 +114,6 @@
   /// This is the main entrypoint for collecting global accesses.
   void collectGlobalAccess(GlobalAddrInst *GAI);
 
-  SILGlobalVariable *getVariableOfGlobalInit(SILFunction *AddrF);
-
   /// Returns true if we think that \p CurBB is inside a loop.
   bool isInLoop(SILBasicBlock *CurBB);
 
@@ -349,21 +348,6 @@
   GlobalVarStore[SILG] = SI;
 }
 
-/// Return the callee of a once call.
-static SILFunction *getCalleeOfOnceCall(BuiltinInst *BI) {
-  assert(BI->getNumOperands() == 2 && "once call should have 2 operands.");
-
-  auto Callee = BI->getOperand(1);
-  assert(Callee->getType().castTo<SILFunctionType>()->getRepresentation()
-           == SILFunctionTypeRepresentation::CFunctionPointer &&
-         "Expected C function representation!");
-
-  if (auto *FR = dyn_cast<FunctionRefInst>(Callee))
-    return FR->getReferencedFunction();
-
-  return nullptr;
-}
-
 // Update UnhandledOnceCallee and InitializerCount by going through all "once"
 // calls.
 void SILGlobalOpt::collectOnceCall(BuiltinInst *BI) {
@@ -596,34 +580,6 @@
   return GetterF;
 }
 
-/// Find the globalinit_func by analyzing the body of the addressor.
-static SILFunction *findInitializer(SILModule *Module, SILFunction *AddrF,
-                                    BuiltinInst *&CallToOnce) {
-  // We only handle a single SILBasicBlock for now.
-  if (AddrF->size() != 1)
-    return nullptr;
-
-  CallToOnce = nullptr;
-  SILBasicBlock *BB = &AddrF->front();
-  for (auto &I : *BB) {
-    // Find the builtin "once" call.
-    if (auto *BI = dyn_cast<BuiltinInst>(&I)) {
-      const BuiltinInfo &Builtin = Module->getBuiltinInfo(BI->getName());
-      if (Builtin.ID != BuiltinValueKind::Once)
-        continue;
-
-      // Bail if we have multiple "once" calls in the addressor.
-      if (CallToOnce)
-        return nullptr;
-
-      CallToOnce = BI;
-    }
-  }
-  if (!CallToOnce)
-    return nullptr;
-  return getCalleeOfOnceCall(CallToOnce);
-}
-
 /// Checks if a given global variable is assigned only once.
 static bool isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG) {
   if (SILG->isLet())
@@ -669,49 +625,6 @@
   return nullptr;
 }
 
-static SILGlobalVariable *getVariableOfStaticInitializer(SILFunction *InitFunc,
-                                             SingleValueInstruction *&InitVal) {
-  InitVal = nullptr;
-  SILGlobalVariable *GVar = nullptr;
-  // We only handle a single SILBasicBlock for now.
-  if (InitFunc->size() != 1)
-    return nullptr;
-
-  SILBasicBlock *BB = &InitFunc->front();
-  GlobalAddrInst *SGA = nullptr;
-  bool HasStore = false;
-  for (auto &I : *BB) {
-    // Make sure we have a single GlobalAddrInst and a single StoreInst.
-    // And the StoreInst writes to the GlobalAddrInst.
-    if (isa<AllocGlobalInst>(&I) || isa<ReturnInst>(&I)
-        || isa<DebugValueInst>(&I)) {
-      continue;
-    } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
-      if (SGA)
-        return nullptr;
-      SGA = sga;
-      GVar = SGA->getReferencedGlobal();
-    } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
-      if (HasStore || SI->getDest() != SGA)
-        return nullptr;
-      HasStore = true;
-      SILValue value = SI->getSrc();
-
-      // We only handle StructInst and TupleInst being stored to a
-      // global variable for now.
-      if (!isa<StructInst>(value) && !isa<TupleInst>(value))
-        return nullptr;
-      InitVal = cast<SingleValueInstruction>(value);
-    } else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
-                                                             I.getModule())) {
-      return nullptr;
-    }
-  }
-  if (!InitVal)
-    return nullptr;
-  return GVar;
-}
-
 /// Replace loads from a global variable by the known value.
 void SILGlobalOpt::
 replaceLoadsByKnownValue(BuiltinInst *CallToOnce, SILFunction *AddrF,
@@ -822,29 +735,6 @@
   HasChanged = true;
 }
 
-SILGlobalVariable *SILGlobalOpt::getVariableOfGlobalInit(SILFunction *AddrF) {
-  if (!AddrF->isGlobalInit())
-    return nullptr;
-
-  // If the addressor contains a single "once" call, it calls globalinit_func,
-  // and the globalinit_func is called by "once" from a single location,
-  // continue; otherwise bail.
-  BuiltinInst *CallToOnce;
-  auto *InitF = findInitializer(Module, AddrF, CallToOnce);
-
-  if (!InitF || !InitF->getName().startswith("globalinit_")
-      || InitializerCount[InitF] > 1)
-    return nullptr;
-
-  // If the globalinit_func is trivial, continue; otherwise bail.
-  SingleValueInstruction *dummyInitVal;
-  auto *SILG = getVariableOfStaticInitializer(InitF, dummyInitVal);
-  if (!SILG || !SILG->isDefinition())
-    return nullptr;
-
-  return SILG;
-}
-
 static bool canBeChangedExternally(SILGlobalVariable *SILG) {
   // Don't assume anything about globals which are imported from other modules.
   if (isAvailableExternally(SILG->getLinkage()))
diff --git a/lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp b/lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp
index 9dc68e1..c0b281d 100644
--- a/lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp
@@ -128,25 +128,6 @@
     return false;
   }
 
-  bool isVisibleExternally(VarDecl *decl) {
-    AccessLevel access = decl->getEffectiveAccess();
-    SILLinkage linkage;
-    switch (access) {
-      case AccessLevel::Private:
-      case AccessLevel::FilePrivate:
-        linkage = SILLinkage::Private;
-        break;
-      case AccessLevel::Internal:
-        linkage = SILLinkage::Hidden;
-        break;
-      case AccessLevel::Public:
-      case AccessLevel::Open:
-        linkage = SILLinkage::Public;
-        break;
-    }
-    return isPossiblyUsedExternally(linkage, M.isWholeModule());
-  }
-  
   static bool canAddressEscape(SILValue V, bool acceptStore);
 
   /// Gets the entry for a struct or class field.
@@ -154,7 +135,7 @@
     Entry * &entry = FieldEntries[Field];
     if (!entry) {
       entry = new (EntryAllocator.Allocate()) Entry(SILValue(), Field);
-      if (isVisibleExternally(Field))
+      if (M.isVisibleExternally(Field))
         setAddressEscapes(entry);
     }
     return entry;
diff --git a/lib/SILOptimizer/IPO/LetPropertiesOpts.cpp b/lib/SILOptimizer/IPO/LetPropertiesOpts.cpp
index eb014e5..f8142dd 100644
--- a/lib/SILOptimizer/IPO/LetPropertiesOpts.cpp
+++ b/lib/SILOptimizer/IPO/LetPropertiesOpts.cpp
@@ -284,28 +284,7 @@
 
 /// Check if a given let property can be assigned externally.
 static bool isAssignableExternally(VarDecl *Property, SILModule *Module) {
-  AccessLevel access = Property->getEffectiveAccess();
-  SILLinkage linkage;
-  switch (access) {
-  case AccessLevel::Private:
-  case AccessLevel::FilePrivate:
-    linkage = SILLinkage::Private;
-    DEBUG(llvm::dbgs() << "Property " << *Property << " has private access\n");
-    break;
-  case AccessLevel::Internal:
-    linkage = SILLinkage::Hidden;
-    DEBUG(llvm::dbgs() << "Property " << *Property << " has internal access\n");
-    break;
-  case AccessLevel::Public:
-  case AccessLevel::Open:
-    linkage = SILLinkage::Public;
-    DEBUG(llvm::dbgs() << "Property " << *Property << " has public access\n");
-    break;
-  }
-
-  DEBUG(llvm::dbgs() << "Module of " << *Property << " WMO mode is: " << Module->isWholeModule() << "\n");
-
-  if (isPossiblyUsedExternally(linkage, Module->isWholeModule())) {
+  if (Module->isVisibleExternally(Property)) {
     // If at least one of the properties of the enclosing type cannot be
     // used externally, then no initializer can be implemented externally as
     // it wouldn't be able to initialize such a property.
diff --git a/lib/SILOptimizer/LoopTransforms/CMakeLists.txt b/lib/SILOptimizer/LoopTransforms/CMakeLists.txt
index 928fb8e..ecd44b2 100644
--- a/lib/SILOptimizer/LoopTransforms/CMakeLists.txt
+++ b/lib/SILOptimizer/LoopTransforms/CMakeLists.txt
@@ -1,7 +1,7 @@
-set(LOOPTRANSFORMS_SOURCES
-  LoopTransforms/ArrayBoundsCheckOpts.cpp
-  LoopTransforms/COWArrayOpt.cpp
-  LoopTransforms/LoopRotate.cpp
-  LoopTransforms/LoopUnroll.cpp
-  LoopTransforms/LICM.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  ArrayBoundsCheckOpts.cpp
+  COWArrayOpt.cpp
+  LoopRotate.cpp
+  LoopUnroll.cpp
+  LICM.cpp
+)
diff --git a/lib/SILOptimizer/LoopTransforms/LICM.cpp b/lib/SILOptimizer/LoopTransforms/LICM.cpp
index 8949e2e..285e456 100644
--- a/lib/SILOptimizer/LoopTransforms/LICM.cpp
+++ b/lib/SILOptimizer/LoopTransforms/LICM.cpp
@@ -13,21 +13,22 @@
 #define DEBUG_TYPE "sil-licm"
 
 #include "swift/SIL/Dominance.h"
+#include "swift/SIL/InstructionUtils.h"
+#include "swift/SIL/MemAccessUtils.h"
+#include "swift/SIL/SILArgument.h"
+#include "swift/SIL/SILBuilder.h"
+#include "swift/SIL/SILInstruction.h"
 #include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
 #include "swift/SILOptimizer/Analysis/Analysis.h"
+#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
 #include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
 #include "swift/SILOptimizer/Analysis/LoopAnalysis.h"
-#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
 #include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 #include "swift/SILOptimizer/Utils/CFG.h"
-#include "swift/SILOptimizer/Utils/SILSSAUpdater.h"
 #include "swift/SILOptimizer/Utils/Local.h"
-#include "swift/SIL/SILArgument.h"
-#include "swift/SIL/SILBuilder.h"
-#include "swift/SIL/SILInstruction.h"
-#include "swift/SIL/InstructionUtils.h"
+#include "swift/SILOptimizer/Utils/SILSSAUpdater.h"
 
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -37,19 +38,22 @@
 
 using namespace swift;
 
-/// Instructions which read from memory, e.g. loads, or function calls without
-/// side effects.
-using ReadSet = llvm::SmallPtrSet<SILInstruction *, 8>;
+/// Instructions which can be hoisted:
+/// loads, function calls without side effects and (some) exclusivity checks
+using InstSet = llvm::SmallPtrSet<SILInstruction *, 8>;
 
-/// Instructions which (potentially) write memory.
-using WriteSet = SmallVector<SILInstruction *, 8>;
+/// A subset of instruction which may have side effects.
+/// Doesn't contain ones that have special handling (e.g. fix_lifetime)
+using WriteSet = SmallPtrSet<SILInstruction *, 8>;
 
 /// Returns true if the \p MayWrites set contains any memory writes which may
 /// alias with the memory addressed by \a LI.
-static bool mayWriteTo(AliasAnalysis *AA, WriteSet &MayWrites, LoadInst *LI) {
+template <SILInstructionKind K, typename T>
+static bool mayWriteTo(AliasAnalysis *AA, WriteSet &MayWrites,
+                       UnaryInstructionBase<K, T> *Inst) {
   for (auto *W : MayWrites)
-    if (AA->mayWriteToMemory(W, LI->getOperand())) {
-      DEBUG(llvm::dbgs() << "  mayWriteTo\n" << *W << " to " << *LI << "\n");
+    if (AA->mayWriteToMemory(W, Inst->getOperand())) {
+      DEBUG(llvm::dbgs() << "  mayWriteTo\n" << *W << " to " << *Inst << "\n");
       return true;
     }
   return false;
@@ -57,6 +61,7 @@
 
 /// Returns true if the \p MayWrites set contains any memory writes which may
 /// alias with any memory which is read by \p AI.
+/// Note: This function should only be called on a read-only apply!
 static bool mayWriteTo(AliasAnalysis *AA, SideEffectAnalysis *SEA,
                        WriteSet &MayWrites, ApplyInst *AI) {
   FunctionSideEffects E;
@@ -64,11 +69,8 @@
   assert(E.getMemBehavior(RetainObserveKind::IgnoreRetains) <=
          SILInstruction::MemoryBehavior::MayRead &&
          "apply should only read from memory");
-  if (E.getGlobalEffects().mayRead() && !MayWrites.empty()) {
-    // We don't know which memory is read in the callee. Therefore we bail if
-    // there are any writes in the loop.
-    return true;
-  }
+  assert(!E.getGlobalEffects().mayRead() &&
+         "apply should not have global effects");
 
   for (unsigned Idx = 0, End = AI->getNumArguments(); Idx < End; ++Idx) {
     auto &ArgEffect = E.getParameterEffects()[Idx];
@@ -89,25 +91,6 @@
   return false;
 }
 
-static void removeWrittenTo(AliasAnalysis *AA, ReadSet &Reads,
-                            SILInstruction *ByInst) {
-
-  // We can ignore retains, cond_fails, and dealloc_stacks.
-  if (isa<StrongRetainInst>(ByInst) || isa<RetainValueInst>(ByInst) ||
-      isa<CondFailInst>(ByInst) || isa<DeallocStackInst>(ByInst))
-    return;
-
-  SmallVector<SILInstruction *, 8> RS(Reads.begin(), Reads.end());
-  for (auto R : RS) {
-    auto *LI = dyn_cast<LoadInst>(R);
-    if (LI && !AA->mayWriteToMemory(ByInst, LI->getOperand()))
-      continue;
-
-    DEBUG(llvm::dbgs() << "  mayWriteTo\n" << *ByInst << " to " << *R << "\n");
-    Reads.erase(R);
-  }
-}
-
 static bool hasLoopInvariantOperands(SILInstruction *I, SILLoop *L) {
   auto Opds = I->getAllOperands();
 
@@ -125,64 +108,12 @@
   });
 }
 
-/// Checks if \p Inst has no side effects which prevent hoisting.
-/// The \a SafeReads set contain instructions which we already proved to have
-/// no such side effects.
-static bool hasNoSideEffect(SILInstruction *Inst, ReadSet &SafeReads) {
-  // We can (and must) hoist cond_fail instructions if the operand is
-  // invariant. We must hoist them so that we preserve memory safety. A
-  // cond_fail that would have protected (executed before) a memory access
-  // must - after hoisting - also be executed before said access.
-  if (isa<CondFailInst>(Inst))
-    return true;
-  
-  // Can't hoist if the instruction could read from memory and is not marked
-  // as safe.
-  if (SafeReads.count(Inst))
-    return true;
-
-  if (Inst->getMemoryBehavior() == SILInstruction::MemoryBehavior::None)
-    return true;
-  
-  return false;
-}
-
-static bool canHoistInstruction(SILInstruction *Inst, SILLoop *Loop,
-                                ReadSet &SafeReads) {
-  // Can't hoist terminators.
-  if (isa<TermInst>(Inst))
-    return false;
-  
-  // Can't hoist allocation and dealloc stacks.
-  if (isa<AllocationInst>(Inst) || isa<DeallocStackInst>(Inst))
-    return false;
-
-  // Can't hoist instructions which may have side effects.
-  if (!hasNoSideEffect(Inst, SafeReads))
-    return false;
-
-  // The operands need to be loop invariant.
-  if (!hasLoopInvariantOperands(Inst, Loop)) {
-    DEBUG(llvm::dbgs() << "   loop variant operands\n");
-    return false;
-  }
-  
-  return true;
-}
-
-static bool hoistInstructions(SILLoop *Loop, DominanceInfo *DT,
-                              ReadSet &SafeReads, bool RunsOnHighLevelSil) {
-  auto Preheader = Loop->getLoopPreheader();
-  if (!Preheader)
-    return false;
-
-  DEBUG(llvm::dbgs() << " Hoisting instructions.\n");
-
+// When Hoisting / Sinking,
+// Don't descend into control-dependent code.
+// Only traverse into basic blocks that dominate all exits.
+static void getDominatingBlocks(SmallVectorImpl<SILBasicBlock *> &domBlocks,
+                                SILLoop *Loop, DominanceInfo *DT) {
   auto HeaderBB = Loop->getHeader();
-  bool Changed = false;
-
-  // Traverse the dominator tree starting at the loop header. Hoisting
-  // instructions as we go.
   auto DTRoot = DT->getNode(HeaderBB);
   SmallVector<SILBasicBlock *, 8> ExitingBBs;
   Loop->getExitingBlocks(ExitingBBs);
@@ -201,96 +132,54 @@
       It.skipChildren();
       continue;
     }
-
-    // We now that the block is guaranteed to be executed. Hoist if we can.
-    for (auto InstIt = CurBB->begin(), E = CurBB->end(); InstIt != E; ) {
-      SILInstruction *Inst = &*InstIt;
-      ++InstIt;
-      DEBUG(llvm::dbgs() << "  looking at " << *Inst);
-      if (canHoistInstruction(Inst, Loop, SafeReads)) {
-        DEBUG(llvm::dbgs() << "   hoisting to preheader.\n");
-        Changed = true;
-        Inst->moveBefore(Preheader->getTerminator());
-      } else if (RunsOnHighLevelSil) {
-        ArraySemanticsCall semCall(Inst);
-        switch (semCall.getKind()) {
-        case ArrayCallKind::kGetCount:
-        case ArrayCallKind::kGetCapacity:
-          if (hasLoopInvariantOperands(Inst, Loop) &&
-              semCall.canHoist(Preheader->getTerminator(), DT)) {
-            Changed = true;
-            semCall.hoist(Preheader->getTerminator(), DT);
-          }
-          break;
-        default:
-          break;
-        }
-      }
-    }
-
+    domBlocks.push_back(CurBB);
     // Next block in dominator tree.
     ++It;
   }
-  return Changed;
 }
 
-static bool sinkFixLifetime(SILLoop *Loop, DominanceInfo *DomTree,
-                            SILLoopInfo *LI) {
-  DEBUG(llvm::errs() << " Sink fix_lifetime attempt\n");
-  auto Preheader = Loop->getLoopPreheader();
-  if (!Preheader)
+static bool hoistInstruction(DominanceInfo *DT, SILInstruction *Inst,
+                             SILLoop *Loop, SILBasicBlock *&Preheader) {
+  if (!hasLoopInvariantOperands(Inst, Loop)) {
+    DEBUG(llvm::dbgs() << "   loop variant operands\n");
     return false;
-
-  // Only handle innermost loops for now.
-  if (!Loop->getSubLoops().empty())
-    return false;
-
-  // Only handle single exit blocks for now.
-  auto *ExitBB = Loop->getExitBlock();
-  if (!ExitBB)
-    return false;
-  auto *ExitingBB = Loop->getExitingBlock();
-  if (!ExitingBB)
-    return false;
-
-  // We can sink fix_lifetime instructions if there are no reference counting
-  // instructions in the loop.
-  SmallVector<FixLifetimeInst *, 16> FixLifetimeInsts;
-  for (auto *BB : Loop->getBlocks()) {
-    for (auto &Inst : *BB) {
-      if (auto FLI = dyn_cast<FixLifetimeInst>(&Inst)) {
-        FixLifetimeInsts.push_back(FLI);
-      } else if (Inst.mayHaveSideEffects() && !isa<LoadInst>(&Inst) &&
-                 !isa<StoreInst>(&Inst)) {
-        DEBUG(llvm::errs() << "  mayhavesideeffects because of" << Inst);
-        DEBUG(Inst.getParent()->dump());
-        return false;
-      }
-    }
   }
 
-  // Sink the fix_lifetime instruction.
+  auto mvBefore = Preheader->getTerminator();
+  ArraySemanticsCall semCall(Inst);
+  if (semCall.canHoist(mvBefore, DT)) {
+    semCall.hoist(mvBefore, DT);
+  } else {
+    Inst->moveBefore(mvBefore);
+  }
+  return true;
+}
+
+static bool hoistInstructions(SILLoop *Loop, DominanceInfo *DT,
+                              InstSet &HoistUpSet) {
+  DEBUG(llvm::dbgs() << " Hoisting instructions.\n");
+  auto Preheader = Loop->getLoopPreheader();
+  assert(Preheader && "Expected a preheader");
   bool Changed = false;
-  for (auto *FLI : FixLifetimeInsts)
-    if (DomTree->dominates(FLI->getOperand()->getParentBlock(),
-                           Preheader)) {
-      auto Succs = ExitingBB->getSuccessors();
-      for (unsigned EdgeIdx = 0; EdgeIdx <  Succs.size(); ++EdgeIdx) {
-        SILBasicBlock *BB = Succs[EdgeIdx];
-        if (BB == ExitBB) {
-          auto *SplitBB = splitCriticalEdge(ExitingBB->getTerminator(), EdgeIdx,
-                                            DomTree, LI);
-          auto *OutsideBB = SplitBB ? SplitBB : ExitBB;
-          // Update the ExitBB.
-          ExitBB = OutsideBB;
-          DEBUG(llvm::errs() << "  moving fix_lifetime to exit BB " << *FLI);
-          FLI->moveBefore(&*OutsideBB->begin());
-          Changed = true;
-        }
+  SmallVector<SILBasicBlock *, 8> domBlocks;
+  getDominatingBlocks(domBlocks, Loop, DT);
+
+  for (auto *CurBB : domBlocks) {
+    // We know that the block is guaranteed to be executed. Hoist if we can.
+    for (auto InstIt = CurBB->begin(), E = CurBB->end(); InstIt != E;) {
+      SILInstruction *Inst = &*InstIt;
+      ++InstIt;
+      DEBUG(llvm::dbgs() << "  looking at " << *Inst);
+      if (!HoistUpSet.count(Inst)) {
+        continue;
       }
-    } else {
-      DEBUG(llvm::errs() << "  does not dominate " << *FLI);
+      if (!hoistInstruction(DT, Inst, Loop, Preheader)) {
+        continue;
+      }
+      DEBUG(llvm::dbgs() << "Hoisted " << *Inst);
+      Changed = true;
     }
+  }
 
   return Changed;
 }
@@ -306,7 +195,7 @@
 
 
   void copySummary(LoopNestSummary &Other) {
-    MayWrites.append(Other.MayWrites.begin(), Other.MayWrites.end());
+    MayWrites.insert(Other.MayWrites.begin(), Other.MayWrites.end());
   }
 
   LoopNestSummary(const LoopNestSummary &) = delete;
@@ -314,6 +203,149 @@
   LoopNestSummary(LoopNestSummary &&) = delete;
 };
 
+static unsigned getEdgeIndex(SILBasicBlock *BB, SILBasicBlock *ExitingBB) {
+  auto Succs = ExitingBB->getSuccessors();
+  for (unsigned EdgeIdx = 0; EdgeIdx < Succs.size(); ++EdgeIdx) {
+    SILBasicBlock *CurrBB = Succs[EdgeIdx];
+    if (CurrBB == BB) {
+      return EdgeIdx;
+    }
+  }
+  llvm_unreachable("BB is not a Successor");
+}
+
+static bool sinkInstruction(DominanceInfo *DT,
+                            std::unique_ptr<LoopNestSummary> &LoopSummary,
+                            SILInstruction *Inst, SILLoopInfo *LI) {
+  auto *Loop = LoopSummary->Loop;
+  SmallVector<SILBasicBlock *, 8> ExitBBs;
+  Loop->getExitBlocks(ExitBBs);
+  SmallVector<SILBasicBlock *, 8> NewExitBBs;
+  SmallVector<SILBasicBlock *, 8> ExitingBBs;
+  Loop->getExitingBlocks(ExitingBBs);
+  auto *ExitBB = Loop->getExitBlock();
+
+  bool Changed = false;
+  for (auto *ExitingBB : ExitingBBs) {
+    SmallVector<SILBasicBlock *, 8> BBSuccessors;
+    auto Succs = ExitingBB->getSuccessors();
+    for (unsigned EdgeIdx = 0; EdgeIdx < Succs.size(); ++EdgeIdx) {
+      SILBasicBlock *BB = Succs[EdgeIdx];
+      BBSuccessors.push_back(BB);
+    }
+    while (!BBSuccessors.empty()) {
+      SILBasicBlock *BB = BBSuccessors.pop_back_val();
+      if (std::find(NewExitBBs.begin(), NewExitBBs.end(), BB) !=
+          NewExitBBs.end()) {
+        // Already got a copy there
+        continue;
+      }
+      auto EdgeIdx = getEdgeIndex(BB, ExitingBB);
+      SILBasicBlock *OutsideBB = nullptr;
+      if (std::find(ExitBBs.begin(), ExitBBs.end(), BB) != ExitBBs.end()) {
+        auto *SplitBB =
+            splitCriticalEdge(ExitingBB->getTerminator(), EdgeIdx, DT, LI);
+        OutsideBB = SplitBB ? SplitBB : BB;
+        NewExitBBs.push_back(OutsideBB);
+      }
+      if (!OutsideBB) {
+        continue;
+      }
+      // If OutsideBB already contains Inst -> skip
+      // This might happen if we have a conditional control flow
+      // And a pair
+      // We hoisted the first part, we can safely ignore sinking
+      auto matchPred = [&](SILInstruction &CurrIns) {
+        return Inst->isIdenticalTo(&CurrIns);
+      };
+      if (std::find_if(OutsideBB->begin(), OutsideBB->end(), matchPred) !=
+          OutsideBB->end()) {
+        DEBUG(llvm::errs() << "  instruction already at exit BB " << *Inst);
+        ExitBB = nullptr;
+      } else if (ExitBB) {
+        // easy case
+        DEBUG(llvm::errs() << "  moving instruction to exit BB " << *Inst);
+        Inst->moveBefore(&*OutsideBB->begin());
+      } else {
+        DEBUG(llvm::errs() << "  cloning instruction to exit BB " << *Inst);
+        Inst->clone(&*OutsideBB->begin());
+      }
+      Changed = true;
+    }
+  }
+  if (Changed && !ExitBB) {
+    // Created clones of instruction
+    // Remove it from the may write set - dangling pointer
+    LoopSummary->MayWrites.erase(Inst);
+    Inst->getParent()->erase(Inst);
+  }
+  return Changed;
+}
+
+static bool sinkInstructions(std::unique_ptr<LoopNestSummary> &LoopSummary,
+                             DominanceInfo *DT, SILLoopInfo *LI,
+                             InstSet &SinkDownSet) {
+  auto *Loop = LoopSummary->Loop;
+  DEBUG(llvm::errs() << " Sink instructions attempt\n");
+  SmallVector<SILBasicBlock *, 8> domBlocks;
+  getDominatingBlocks(domBlocks, Loop, DT);
+
+  bool Changed = false;
+  for (auto *Inst : SinkDownSet) {
+    // only sink if the block is guaranteed to be executed.
+    if (std::find(domBlocks.begin(), domBlocks.end(), Inst->getParent()) ==
+        domBlocks.end()) {
+      continue;
+    }
+    Changed |= sinkInstruction(DT, LoopSummary, Inst, LI);
+  }
+
+  return Changed;
+}
+
+static void getEndAccesses(BeginAccessInst *BI,
+                           SmallVectorImpl<EndAccessInst *> &EndAccesses) {
+  for (auto Use : BI->getUses()) {
+    auto *User = Use->getUser();
+    auto *EI = dyn_cast<EndAccessInst>(User);
+    if (!EI) {
+      continue;
+    }
+    EndAccesses.push_back(EI);
+  }
+}
+
+static bool
+hoistSpecialInstruction(std::unique_ptr<LoopNestSummary> &LoopSummary,
+                        DominanceInfo *DT, SILLoopInfo *LI, InstSet &Special) {
+  auto *Loop = LoopSummary->Loop;
+  DEBUG(llvm::errs() << " Hoist and Sink pairs attempt\n");
+  auto Preheader = Loop->getLoopPreheader();
+  assert(Preheader && "Expected a preheader");
+
+  bool Changed = false;
+
+  for (auto *Inst : Special) {
+    auto *BI = dyn_cast<BeginAccessInst>(Inst);
+    assert(BI && "Only BeginAccessInst are supported");
+    SmallVector<EndAccessInst *, 2> Ends;
+    getEndAccesses(BI, Ends);
+    if (!hoistInstruction(DT, BI, Loop, Preheader)) {
+      continue;
+    }
+    DEBUG(llvm::dbgs() << "Hoisted " << *BI);
+    for (auto *instSink : Ends) {
+      if (!sinkInstruction(DT, LoopSummary, instSink, LI)) {
+        llvm_unreachable("LICM: Could not perform must-sink instruction");
+      }
+    }
+    DEBUG(llvm::errs() << " Successfully hosited and sank pair\n");
+    Changed = true;
+  }
+
+  return Changed;
+}
+
 /// \brief Optimize the loop tree bottom up propagating loop's summaries up the
 /// loop tree.
 class LoopTreeOptimization {
@@ -328,15 +360,24 @@
 
   /// True if LICM is done on high-level SIL, i.e. semantic calls are not
   /// inlined yet. In this case some semantic calls can be hoisted.
-  bool RunsOnHighLevelSil;
+  bool RunsOnHighLevelSIL;
+
+  /// Instructions that we may be able to hoist up
+  InstSet HoistUp;
+
+  /// Instructions that we may be able to sink down
+  InstSet SinkDown;
+
+  /// Hoistable Instructions that need special treatment
+  /// e.g. begin_access
+  InstSet SpecialHoist;
 
 public:
   LoopTreeOptimization(SILLoop *TopLevelLoop, SILLoopInfo *LI,
                        AliasAnalysis *AA, SideEffectAnalysis *SEA,
-                       DominanceInfo *DT,
-                       bool RunsOnHighLevelSil)
+                       DominanceInfo *DT, bool RunsOnHighLevelSil)
       : LoopInfo(LI), AA(AA), SEA(SEA), DomTree(DT), Changed(false),
-        RunsOnHighLevelSil(RunsOnHighLevelSil) {
+        RunsOnHighLevelSIL(RunsOnHighLevelSil) {
     // Collect loops for a recursive bottom-up traversal in the loop tree.
     BotUpWorkList.push_back(TopLevelLoop);
     for (unsigned i = 0; i < BotUpWorkList.size(); ++i) {
@@ -353,12 +394,11 @@
   /// \brief Propagate the sub-loops' summaries up to the current loop.
   void propagateSummaries(std::unique_ptr<LoopNestSummary> &CurrSummary);
 
-  /// \brief Collect a set of reads that can be hoisted to the loop's preheader.
-  void analyzeCurrentLoop(std::unique_ptr<LoopNestSummary> &CurrSummary,
-                          ReadSet &SafeReads);
+  /// \brief Collect a set of instructions that can be hoisted
+  void analyzeCurrentLoop(std::unique_ptr<LoopNestSummary> &CurrSummary);
 
   /// \brief Optimize the current loop nest.
-  void optimizeLoop(SILLoop *CurrentLoop, ReadSet &SafeReads);
+  bool optimizeLoop(std::unique_ptr<LoopNestSummary> &CurrSummary);
 };
 } // end anonymous namespace
 
@@ -374,11 +414,23 @@
     auto CurrLoopSummary = llvm::make_unique<LoopNestSummary>(CurrentLoop);
     propagateSummaries(CurrLoopSummary);
 
-    // Analyze the current loop for reads that can be hoisted.
-    ReadSet SafeReads;
-    analyzeCurrentLoop(CurrLoopSummary, SafeReads);
+    // If the current loop changed, then we might reveal more instr to hoist
+    // For example, a fix_lifetime's operand, if hoisted outside,
+    // Might allow us to sink the instruction out of the loop
+    bool currChanged = false;
+    do {
+      currChanged = false;
 
-    optimizeLoop(CurrentLoop, SafeReads);
+      // Analyze the current loop for instructions that can be hoisted.
+      analyzeCurrentLoop(CurrLoopSummary);
+
+      currChanged = optimizeLoop(CurrLoopSummary);
+
+      // Reset the data structures for next loop in the list
+      HoistUp.clear();
+      SinkDown.clear();
+      SpecialHoist.clear();
+    } while (currChanged);
 
     // Store the summary for parent loops to use.
     LoopNestSummaryMap[CurrentLoop] = std::move(CurrLoopSummary);
@@ -395,56 +447,234 @@
   }
 }
 
+static bool isSafeReadOnlyApply(SideEffectAnalysis *SEA, ApplyInst *AI) {
+  FunctionSideEffects E;
+  SEA->getCalleeEffects(E, AI);
+
+  if (E.getGlobalEffects().mayRead()) {
+    // If we have Global effects,
+    // we don't know which memory is read in the callee.
+    // Therefore we bail for safety
+    return false;
+  }
+
+  auto MB = E.getMemBehavior(RetainObserveKind::ObserveRetains);
+  return (MB <= SILInstruction::MemoryBehavior::MayRead);
+}
+
+static void checkSideEffects(swift::SILInstruction &Inst, WriteSet &MayWrites) {
+  if (Inst.mayHaveSideEffects()) {
+    MayWrites.insert(&Inst);
+  }
+}
+
+/// Returns true if the \p Inst follows the default hoisting heuristic
+static bool canHoistUpDefault(SILInstruction *inst, SILLoop *Loop,
+                              DominanceInfo *DT, bool RunsOnHighLevelSil) {
+  auto Preheader = Loop->getLoopPreheader();
+  if (!Preheader) {
+    return false;
+  }
+
+  if (isa<TermInst>(inst) || isa<AllocationInst>(inst) ||
+      isa<DeallocationInst>(inst)) {
+    return false;
+  }
+
+  if (inst->getMemoryBehavior() == SILInstruction::MemoryBehavior::None) {
+    return true;
+  }
+
+  if (!RunsOnHighLevelSil) {
+    return false;
+  }
+
+  // We can’t hoist everything that is hoist-able
+  // The canHoist method does not do all the required analysis
+  // Some of the work is done at COW Array Opt
+  // TODO: Refactor COW Array Opt + canHoist - radar 41601468
+  ArraySemanticsCall semCall(inst);
+  switch (semCall.getKind()) {
+  case ArrayCallKind::kGetCount:
+  case ArrayCallKind::kGetCapacity:
+    return semCall.canHoist(Preheader->getTerminator(), DT);
+  default:
+    return false;
+  }
+}
+
+// Check If all the end accesses of the given begin do not prevent hoisting
+// There are only two legal placements for the end access instructions:
+// 1) Inside the same loop (sink to loop exists)
+// Potential TODO: At loop exit block
+static bool handledEndAccesses(BeginAccessInst *BI, SILLoop *Loop) {
+  SmallVector<EndAccessInst *, 2> AllEnds;
+  getEndAccesses(BI, AllEnds);
+  if (AllEnds.empty()) {
+    return false;
+  }
+  for (auto *User : AllEnds) {
+    auto *BB = User->getParent();
+    if (Loop->getBlocksSet().count(BB) != 0) {
+      continue;
+    }
+    return false;
+  }
+  return true;
+}
+
+static bool
+analyzeBeginAccess(BeginAccessInst *BI,
+                   SmallVector<BeginAccessInst *, 8> &BeginAccesses) {
+  if (BI->getEnforcement() != SILAccessEnforcement::Dynamic) {
+    return false;
+  }
+
+  const AccessedStorage &storage =
+      findAccessedStorageNonNested(BI->getSource());
+  if (!storage) {
+    return false;
+  }
+
+  auto BIAccessedStorageNonNested = findAccessedStorageNonNested(BI);
+  auto safeBeginPred = [&](BeginAccessInst *OtherBI) {
+    if (BI == OtherBI) {
+      return true;
+    }
+    return BIAccessedStorageNonNested.isDistinctFrom(
+        findAccessedStorageNonNested(OtherBI));
+  };
+
+  return (
+      std::all_of(BeginAccesses.begin(), BeginAccesses.end(), safeBeginPred));
+}
+
+// Analyzes current loop for hosting/sinking potential:
+// Computes set of instructions we may be able to move out of the loop
+// Important Note:
+// We can't bail out of this method! we have to run it on all loops.
+// We *need* to discover all MayWrites -
+// even if the loop is otherwise skipped!
+// This is because outer loops will depend on the inner loop's writes.
 void LoopTreeOptimization::analyzeCurrentLoop(
-    std::unique_ptr<LoopNestSummary> &CurrSummary, ReadSet &SafeReads) {
+    std::unique_ptr<LoopNestSummary> &CurrSummary) {
   WriteSet &MayWrites = CurrSummary->MayWrites;
   SILLoop *Loop = CurrSummary->Loop;
   DEBUG(llvm::dbgs() << " Analyzing accesses.\n");
 
   // Contains function calls in the loop, which only read from memory.
   SmallVector<ApplyInst *, 8> ReadOnlyApplies;
+  // Contains Loads inside the loop.
+  SmallVector<LoadInst *, 8> Loads;
+  // Contains fix_lifetime, we might be able to sink them.
+  SmallVector<FixLifetimeInst *, 8> FixLifetimes;
+  // Contains begin_access, we might be able to hoist them.
+  SmallVector<BeginAccessInst *, 8> BeginAccesses;
 
   for (auto *BB : Loop->getBlocks()) {
     for (auto &Inst : *BB) {
-      // Ignore fix_lifetime instructions.
-      if (isa<FixLifetimeInst>(&Inst))
-        continue;
-
-      // Collect loads.
-      auto LI = dyn_cast<LoadInst>(&Inst);
-      if (LI) {
-        if (!mayWriteTo(AA, MayWrites, LI))
-          SafeReads.insert(LI);
-        continue;
+      switch (Inst.getKind()) {
+      case SILInstructionKind::FixLifetimeInst: {
+        auto *FL = dyn_cast<FixLifetimeInst>(&Inst);
+        assert(FL && "Expected a FixLifetime instruction");
+        FixLifetimes.push_back(FL);
+        // We can ignore the side effects of FixLifetimes
+        break;
       }
-      if (auto *AI = dyn_cast<ApplyInst>(&Inst)) {
-        // In contrast to load instructions, we first collect all read-only
-        // function calls and add them later to SafeReads.
-        FunctionSideEffects E;
-        SEA->getCalleeEffects(E, AI);
-
-        auto MB = E.getMemBehavior(RetainObserveKind::ObserveRetains);
-        if (MB <= SILInstruction::MemoryBehavior::MayRead)
+      case SILInstructionKind::LoadInst: {
+        auto *LI = dyn_cast<LoadInst>(&Inst);
+        assert(LI && "Expected a Load instruction");
+        Loads.push_back(LI);
+        break;
+      }
+      case SILInstructionKind::BeginAccessInst: {
+        auto *BI = dyn_cast<BeginAccessInst>(&Inst);
+        assert(BI && "Expected a Begin Access");
+        BeginAccesses.push_back(BI);
+        checkSideEffects(Inst, MayWrites);
+        break;
+      }
+      case swift::SILInstructionKind::CondFailInst: {
+        // We can (and must) hoist cond_fail instructions if the operand is
+        // invariant. We must hoist them so that we preserve memory safety. A
+        // cond_fail that would have protected (executed before) a memory access
+        // must - after hoisting - also be executed before said access.
+        HoistUp.insert(&Inst);
+        checkSideEffects(Inst, MayWrites);
+        break;
+      }
+      case SILInstructionKind::ApplyInst: {
+        auto *AI = dyn_cast<ApplyInst>(&Inst);
+        assert(AI && "Expected an Apply Instruction");
+        if (isSafeReadOnlyApply(SEA, AI)) {
           ReadOnlyApplies.push_back(AI);
+        }
+        // check for array semantics and side effects - same as default
+        LLVM_FALLTHROUGH;
       }
-      if (Inst.mayHaveSideEffects()) {
-        MayWrites.push_back(&Inst);
-        // Remove clobbered loads we have seen before.
-        removeWrittenTo(AA, SafeReads, &Inst);
+      default: {
+        checkSideEffects(Inst, MayWrites);
+        if (canHoistUpDefault(&Inst, Loop, DomTree, RunsOnHighLevelSIL)) {
+          HoistUp.insert(&Inst);
+        }
+        break;
+      }
       }
     }
   }
+
+  auto *Preheader = Loop->getLoopPreheader();
+  if (!Preheader) {
+    // Can't hoist/sink instructions
+    return;
+  }
   for (auto *AI : ReadOnlyApplies) {
-    if (!mayWriteTo(AA, SEA, MayWrites, AI))
-      SafeReads.insert(AI);
+    if (!mayWriteTo(AA, SEA, MayWrites, AI)) {
+      HoistUp.insert(AI);
+    }
+  }
+  for (auto *LI : Loads) {
+    if (!mayWriteTo(AA, MayWrites, LI)) {
+      HoistUp.insert(LI);
+    }
+  }
+  bool mayWritesMayRelease =
+      std::any_of(MayWrites.begin(), MayWrites.end(),
+                  [&](SILInstruction *W) { return W->mayRelease(); });
+  for (auto *FL : FixLifetimes) {
+    if (!DomTree->dominates(FL->getOperand()->getParentBlock(), Preheader)) {
+      continue;
+    }
+    if (!mayWriteTo(AA, MayWrites, FL) || !mayWritesMayRelease) {
+      SinkDown.insert(FL);
+    }
+  }
+  for (auto *BI : BeginAccesses) {
+    if (!handledEndAccesses(BI, Loop)) {
+      DEBUG(llvm::dbgs() << "Skipping: " << *BI);
+      DEBUG(llvm::dbgs() << "Some end accesses can't be handled"
+                         << "\n");
+      continue;
+    }
+    if (analyzeBeginAccess(BI, BeginAccesses)) {
+      SpecialHoist.insert(BI);
+    }
   }
 }
 
-void LoopTreeOptimization::optimizeLoop(SILLoop *CurrentLoop,
-                                        ReadSet &SafeReads) {
-  Changed |= hoistInstructions(CurrentLoop, DomTree, SafeReads,
-                               RunsOnHighLevelSil);
-  Changed |= sinkFixLifetime(CurrentLoop, DomTree, LoopInfo);
+bool LoopTreeOptimization::optimizeLoop(
+    std::unique_ptr<LoopNestSummary> &CurrSummary) {
+  auto *CurrentLoop = CurrSummary->Loop;
+  // We only support Loops with a preheader
+  if (!CurrentLoop->getLoopPreheader())
+    return false;
+  bool currChanged = false;
+  currChanged |= hoistInstructions(CurrentLoop, DomTree, HoistUp);
+  currChanged |= sinkInstructions(CurrSummary, DomTree, LoopInfo, SinkDown);
+  currChanged |=
+      hoistSpecialInstruction(CurrSummary, DomTree, LoopInfo, SpecialHoist);
+  Changed |= currChanged;
+  return currChanged;
 }
 
 namespace {
diff --git a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
index 7f1c121..c477e27 100644
--- a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
@@ -18,13 +18,6 @@
 /// This is an always-on pass for temporary bootstrapping. It allows running
 /// test cases through the pipeline and exercising SIL verification before all
 /// passes support access markers.
-///
-/// This must only run before inlining _semantic calls. If we inline and drop
-/// the @_semantics("optimize.sil.preserve_exclusivity") attribute, the inlined
-/// markers will be eliminated, but the noninlined markers will not. This would
-/// result in inconsistent begin/end_unpaired_access resulting in unpredictable,
-/// potentially catastrophic runtime behavior.
-///
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "access-marker-elim"
@@ -39,9 +32,6 @@
 // This temporary option allows markers during optimization passes. Enabling
 // this flag causes this pass to preserve only dynamic checks when dynamic
 // checking is enabled. Otherwise, this pass removes all checks.
-//
-// This is currently unsupported because tail duplication results in
-// address-type block arguments.
 llvm::cl::opt<bool> EnableOptimizedAccessMarkers(
     "sil-optimized-access-markers", llvm::cl::init(true),
     llvm::cl::desc("Enable memory access markers during optimization passes."));
diff --git a/lib/SILOptimizer/Mandatory/CMakeLists.txt b/lib/SILOptimizer/Mandatory/CMakeLists.txt
index 780876c..88dd651 100644
--- a/lib/SILOptimizer/Mandatory/CMakeLists.txt
+++ b/lib/SILOptimizer/Mandatory/CMakeLists.txt
@@ -1,21 +1,21 @@
-set(MANDATORY_SOURCES
-  Mandatory/AccessEnforcementSelection.cpp
-  Mandatory/AccessMarkerElimination.cpp
-  Mandatory/AddressLowering.cpp
-  Mandatory/ConstantPropagation.cpp
-  Mandatory/DefiniteInitialization.cpp
-  Mandatory/DIMemoryUseCollectorOwnership.cpp
-  Mandatory/DataflowDiagnostics.cpp
-  Mandatory/DiagnoseInfiniteRecursion.cpp
-  Mandatory/DiagnoseStaticExclusivity.cpp
-  Mandatory/DiagnoseUnreachable.cpp
-  Mandatory/GuaranteedARCOpts.cpp
-  Mandatory/IRGenPrepare.cpp
-  Mandatory/MandatoryInlining.cpp
-  Mandatory/PredictableMemOpt.cpp
-  Mandatory/PMOMemoryUseCollector.cpp
-  Mandatory/SemanticARCOpts.cpp
-  Mandatory/ClosureLifetimeFixup.cpp
-  Mandatory/RawSILInstLowering.cpp
-  Mandatory/MandatoryOptUtils.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  AccessEnforcementSelection.cpp
+  AccessMarkerElimination.cpp
+  AddressLowering.cpp
+  ConstantPropagation.cpp
+  DefiniteInitialization.cpp
+  DIMemoryUseCollectorOwnership.cpp
+  DataflowDiagnostics.cpp
+  DiagnoseInfiniteRecursion.cpp
+  DiagnoseStaticExclusivity.cpp
+  DiagnoseUnreachable.cpp
+  GuaranteedARCOpts.cpp
+  IRGenPrepare.cpp
+  MandatoryInlining.cpp
+  PredictableMemOpt.cpp
+  PMOMemoryUseCollector.cpp
+  SemanticARCOpts.cpp
+  ClosureLifetimeFixup.cpp
+  RawSILInstLowering.cpp
+  MandatoryOptUtils.cpp
+)
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index aeb5d34..7a57f2d 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -950,16 +950,6 @@
       continue;
     }
 
-    // unchecked_take_enum_data_addr takes the address of the payload of the
-    // optional, which could be used to update the payload. So, visit the
-    // users of this instruction and ensure that there are no overwrites to an
-    // immutable optional. Note that this special handling is for checking
-    // immutability and is not for checking initialization before use.
-    if (auto *enumDataAddr = dyn_cast<UncheckedTakeEnumDataAddrInst>(User)) {
-      collectUses(enumDataAddr, BaseEltNo);
-      continue;
-    }
-
     // We model destroy_addr as a release of the entire value.
     if (isa<DestroyAddrInst>(User)) {
       trackDestroy(User);
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index a7e4e6e..e0f2601 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -1239,14 +1239,18 @@
     noteUninitializedMembers(Use);
     return;
   }
+ 
 
   Diag<StringRef, bool> DiagMessage;
-  if (Inst->getLoc().isASTNode<AbstractClosureExpr>()) {
-    DiagMessage = diag::variable_closure_use_uninit;
-  } else if (isa<MarkFunctionEscapeInst>(Inst)) {
-    DiagMessage = diag::variable_function_use_uninit;
-  } else {
+  if (isa<MarkFunctionEscapeInst>(Inst)) {
+    if (Inst->getLoc().isASTNode<AbstractClosureExpr>())
+      DiagMessage = diag::variable_closure_use_uninit;
+    else
+      DiagMessage = diag::variable_function_use_uninit;
+  } else if (isa<UncheckedTakeEnumDataAddrInst>(Inst)) {
     DiagMessage = diag::variable_used_before_initialized;
+  } else {
+    DiagMessage = diag::variable_closure_use_uninit;
   }
 
   diagnoseInitError(Use, DiagMessage);
@@ -1704,11 +1708,10 @@
   // If this is a load into a promoted closure capture, diagnose properly as
   // a capture.
   if ((isa<LoadInst>(Inst) || isa<LoadBorrowInst>(Inst)) &&
-      Inst->getLoc().isASTNode<AbstractClosureExpr>()) {
+      Inst->getLoc().isASTNode<AbstractClosureExpr>())
     diagnoseInitError(Use, diag::variable_closure_use_uninit);
-  } else {
+  else
     diagnoseInitError(Use, diag::variable_used_before_initialized);
-  }
 }
 
 /// handleSelfInitUse - When processing a 'self' argument on a class, this is
diff --git a/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp b/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
index 6474fe1..93a9c79 100644
--- a/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
+++ b/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
@@ -811,6 +811,9 @@
 static void checkForViolationsAtInstruction(SILInstruction &I,
                                             AccessState &State) {
   if (auto *BAI = dyn_cast<BeginAccessInst>(&I)) {
+    if (BAI->getEnforcement() == SILAccessEnforcement::Unsafe)
+      return;
+
     SILAccessKind Kind = BAI->getAccessKind();
     const AccessedStorage &Storage =
       findValidAccessedStorage(BAI->getSource());
@@ -826,6 +829,9 @@
   }
 
   if (auto *EAI = dyn_cast<EndAccessInst>(&I)) {
+    if (EAI->getBeginAccess()->getEnforcement() == SILAccessEnforcement::Unsafe)
+      return;
+
     auto It =
       State.Accesses->find(findValidAccessedStorage(EAI->getSource()));
     AccessInfo &Info = It->getSecond();
@@ -1080,6 +1086,9 @@
   // Otherwise, the address base should be an in-scope begin_access.
   if (storage.getKind() == AccessedStorage::Nested) {
     auto *BAI = cast<BeginAccessInst>(storage.getValue());
+    if (BAI->getEnforcement() == SILAccessEnforcement::Unsafe)
+      return;
+
     const AccessedStorage &Storage = findValidAccessedStorage(BAI->getSource());
     AccessInfo &Info = Accesses[Storage];
     if (!Info.hasAccessesInProgress())
diff --git a/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp b/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
index 1381cd1..2691259 100644
--- a/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
+++ b/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
@@ -75,6 +75,7 @@
   if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
       isa<RetainValueInst>(Inst) || isa<UnownedRetainInst>(Inst) ||
       isa<UnownedReleaseInst>(Inst) || isa<StrongRetainUnownedInst>(Inst) ||
+      isa<CopyUnownedValueInst>(Inst) ||
       isa<StoreWeakInst>(Inst) || isa<StrongRetainInst>(Inst) ||
       isa<AllocStackInst>(Inst) || isa<DeallocStackInst>(Inst) ||
       isa<BeginAccessInst>(Inst) || isa<EndAccessInst>(Inst) ||
diff --git a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
index de4bc11..3fec285 100644
--- a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
+++ b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
@@ -231,10 +231,6 @@
   /// element we attribute an access to.
   bool InStructSubElement = false;
 
-  /// When walking the use list, if we index into an enum slice, keep track
-  /// of this.
-  bool InEnumSubElement = false;
-
 public:
   ElementUseCollector(const PMOMemoryObjectInfo &TheMemory,
                       SmallVectorImpl<PMOMemoryUse> &Uses,
@@ -294,7 +290,7 @@
   // If we're in a subelement of a struct or enum, just mark the struct, not
   // things that come after it in a parent tuple.
   unsigned NumElements = 1;
-  if (TheMemory.NumElements != 1 && !InStructSubElement && !InEnumSubElement)
+  if (TheMemory.NumElements != 1 && !InStructSubElement)
     NumElements = getElementCountRec(Module, UseTy);
 
   Uses.push_back(PMOMemoryUse(User, Kind, BaseEltNo, NumElements));
@@ -309,7 +305,7 @@
   // If we're walking into a tuple within a struct or enum, don't adjust the
   // BaseElt.  The uses hanging off the tuple_element_addr are going to be
   // counted as uses of the struct or enum itself.
-  if (InStructSubElement || InEnumSubElement)
+  if (InStructSubElement)
     return collectUses(TEAI, BaseEltNo);
 
   // tuple_element_addr P, 42 indexes into the current tuple element.
@@ -554,26 +550,6 @@
       llvm_unreachable("bad parameter convention");
     }
 
-    // init_enum_data_addr is treated like a tuple_element_addr or other
-    // instruction that is looking into the memory object (i.e., the memory
-    // object needs to be explicitly initialized by a copy_addr or some other
-    // use of the projected address).
-    if (auto I = dyn_cast<InitEnumDataAddrInst>(User)) {
-      // If we are in a struct already, bail. With proper analysis, we should be
-      // able to do this optimization.
-      if (InStructSubElement) {
-        return false;
-      }
-
-      // Keep track of the fact that we're inside of an enum.  This informs our
-      // recursion that tuple stores are not scalarized outside, and that stores
-      // should not be treated as partial stores.
-      llvm::SaveAndRestore<bool> X(InEnumSubElement, true);
-      if (!collectUses(I, BaseEltNo))
-        return false;
-      continue;
-    }
-
     // init_existential_addr is modeled as an initialization store.
     if (isa<InitExistentialAddrInst>(User)) {
       // init_existential_addr should not apply to struct subelements.
@@ -585,17 +561,6 @@
       continue;
     }
 
-    // inject_enum_addr is modeled as an initialization store.
-    if (isa<InjectEnumAddrInst>(User)) {
-      // inject_enum_addr the subelement of a struct unless in a ctor.
-      if (InStructSubElement) {
-        return false;
-      }
-      Uses.push_back(
-          PMOMemoryUse(User, PMOUseKind::Initialization, BaseEltNo, 1));
-      continue;
-    }
-
     // open_existential_addr is a use of the protocol value,
     // so it is modeled as a load.
     if (isa<OpenExistentialAddrInst>(User)) {
diff --git a/lib/SILOptimizer/PassManager/CMakeLists.txt b/lib/SILOptimizer/PassManager/CMakeLists.txt
index ec38c5b..80a438a 100644
--- a/lib/SILOptimizer/PassManager/CMakeLists.txt
+++ b/lib/SILOptimizer/PassManager/CMakeLists.txt
@@ -1,6 +1,6 @@
-set(PASSMANAGER_SOURCES
-  PassManager/PassManager.cpp
-  PassManager/Passes.cpp
-  PassManager/PassPipeline.cpp
-  PassManager/PrettyStackTrace.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  PassManager.cpp
+  Passes.cpp
+  PassPipeline.cpp
+  PrettyStackTrace.cpp
+)
diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp
index 1c782b9..e837dc4 100644
--- a/lib/SILOptimizer/PassManager/PassPipeline.cpp
+++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp
@@ -193,7 +193,12 @@
   P.addHighLevelCSE();
   P.addSILCombine();
   P.addSimplifyCFG();
+  // Optimize access markers for better LICM: might merge accesses
+  // It will also set the no_nested_conflict for dynamic accesses
+  P.addAccessEnforcementOpts();
   P.addHighLevelLICM();
+  // Simplify CFG after LICM that creates new exit blocks
+  P.addSimplifyCFG();
   // Start of loop unrolling passes.
   P.addArrayCountPropagation();
   // To simplify induction variable.
@@ -446,7 +451,12 @@
 
   // Perform the final lowering transformations.
   P.addCodeSinking();
+  // Optimize access markers for better LICM: might merge accesses
+  // It will also set the no_nested_conflict for dynamic accesses
+  P.addAccessEnforcementOpts();
   P.addLICM();
+  // Simplify CFG after LICM that creates new exit blocks
+  P.addSimplifyCFG();
 
   // Optimize overflow checks.
   P.addRedundantOverflowCheckRemoval();
diff --git a/lib/SILOptimizer/SILCombiner/CMakeLists.txt b/lib/SILOptimizer/SILCombiner/CMakeLists.txt
index 650aa46..64cc710 100644
--- a/lib/SILOptimizer/SILCombiner/CMakeLists.txt
+++ b/lib/SILOptimizer/SILCombiner/CMakeLists.txt
@@ -1,7 +1,7 @@
-set(SILCOMBINER_SOURCES
-  SILCombiner/SILCombine.cpp
-  SILCombiner/SILCombinerApplyVisitors.cpp
-  SILCombiner/SILCombinerBuiltinVisitors.cpp
-  SILCombiner/SILCombinerCastVisitors.cpp
-  SILCombiner/SILCombinerMiscVisitors.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  SILCombine.cpp
+  SILCombinerApplyVisitors.cpp
+  SILCombinerBuiltinVisitors.cpp
+  SILCombinerCastVisitors.cpp
+  SILCombinerMiscVisitors.cpp
+)
diff --git a/lib/SILOptimizer/SILCombiner/SILCombiner.h b/lib/SILOptimizer/SILCombiner/SILCombiner.h
index fcfd0d8..b2cae23 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombiner.h
+++ b/lib/SILOptimizer/SILCombiner/SILCombiner.h
@@ -26,6 +26,7 @@
 #include "swift/SIL/SILValue.h"
 #include "swift/SIL/SILVisitor.h"
 #include "swift/SILOptimizer/Utils/CastOptimizer.h"
+#include "swift/SILOptimizer/Utils/Existential.h"
 #include "swift/SILOptimizer/Utils/Local.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
@@ -279,24 +280,16 @@
                                        StringRef FInverseName, StringRef FName);
 
 private:
-  SILInstruction * createApplyWithConcreteType(FullApplySite AI,
-                                               SILValue NewSelf,
-                                               SILValue Self,
-                                               CanType ConcreteType,
-                                               SILValue ConcreteTypeDef,
-                                               ProtocolConformanceRef Conformance,
-                                               ArchetypeType *OpenedArchetype);
-
   FullApplySite rewriteApplyCallee(FullApplySite apply, SILValue callee);
 
-  SILInstruction *
-  propagateConcreteTypeOfInitExistential(FullApplySite AI,
-      ProtocolDecl *Protocol,
-      llvm::function_ref<void(CanType, ProtocolConformanceRef)> Propagate);
+  SILInstruction *createApplyWithConcreteType(FullApplySite Apply,
+                                              const ConcreteExistentialInfo &CEI,
+                                              SILBuilderContext &BuilderCtx);
 
-  SILInstruction *propagateConcreteTypeOfInitExistential(FullApplySite AI,
-                                                         WitnessMethodInst *WMI);
-  SILInstruction *propagateConcreteTypeOfInitExistential(FullApplySite AI);
+  SILInstruction *
+  propagateConcreteTypeOfInitExistential(FullApplySite Apply,
+                                         WitnessMethodInst *WMI);
+  SILInstruction *propagateConcreteTypeOfInitExistential(FullApplySite Apply);
 
   /// Perform one SILCombine iteration.
   bool doOneIteration(SILFunction &F, unsigned Iteration);
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 4181afb..2ac6fc2 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -13,6 +13,7 @@
 #define DEBUG_TYPE "sil-combine"
 #include "SILCombiner.h"
 #include "swift/AST/GenericSignature.h"
+#include "swift/AST/Module.h"
 #include "swift/AST/SubstitutionMap.h"
 #include "swift/Basic/Range.h"
 #include "swift/SIL/DebugUtils.h"
@@ -601,189 +602,31 @@
   return tryToConcatenateStrings(AI, Builder);
 }
 
-/// Create a new apply instructions that uses the concrete type instead
-/// of the existential type.
-SILInstruction *
-SILCombiner::createApplyWithConcreteType(FullApplySite AI,
-                                         SILValue NewSelf,
-                                         SILValue Self,
-                                         CanType ConcreteType,
-                                         SILValue ConcreteTypeDef,
-                                         ProtocolConformanceRef Conformance,
-                                         ArchetypeType *OpenedArchetype) {
-  // Create a set of arguments.
-  SmallVector<SILValue, 8> Args;
-  for (auto Arg : AI.getArgumentsWithoutSelf()) {
-    Args.push_back(Arg);
-  }
-  Args.push_back(NewSelf);
+/// Given an Apply and an argument value produced by InitExistentialAddrInst,
+/// return true if the argument can be replaced by a copy of its value.
+///
+/// FIXME: remove this helper when we can assume SIL opaque values.
+static bool canReplaceCopiedSelf(FullApplySite Apply,
+                                 SILInstruction *InitExistential,
+                                 DominanceAnalysis *DA) {
+  // If the witness method mutates self, we cannot replace self with
+  // the source of a copy. Otherwise the call would modify another value than
+  // the original self.
+  if (Apply.getOrigCalleeType()->getSelfParameter().isIndirectMutating())
+    return false;
 
-  auto FnTy = AI.getCallee()->getType().castTo<SILFunctionType>();
-  SILType SubstCalleeType = AI.getSubstCalleeSILType();
-  SILType NewSubstCalleeType;
+  auto *DT = DA->get(Apply.getFunction());
+  auto *AI = Apply.getInstruction();
+  // Only init_existential_addr may be copied.
+  SILValue existentialAddr =
+      cast<InitExistentialAddrInst>(InitExistential)->getOperand();
 
-  // Form a new set of substitutions where Self is
-  // replaced by a concrete type.
-  SubstitutionMap Substitutions;
-  if (FnTy->isPolymorphic()) {
-    auto FnSubsMap = AI.getSubstitutionMap();
-    Substitutions = FnSubsMap.subst(
-        [&](SubstitutableType *type) -> Type {
-          if (type == OpenedArchetype)
-            return ConcreteType;
-          return type;
-        },
-        [&](CanType origTy, Type substTy,
-            ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> {
-          if (substTy->isEqual(ConcreteType)) {
-            assert(proto == Conformance.getRequirement());
-            return Conformance;
-          }
-          return ProtocolConformanceRef(proto);
-        });
-    
-    // Handle polymorphic functions by properly substituting
-    // their parameter types.
-    CanSILFunctionType SFT = FnTy->substGenericArgs(
-                                        AI.getModule(),
-                                        Substitutions);
-    NewSubstCalleeType = SILType::getPrimitiveObjectType(SFT);
-  } else {
-    NewSubstCalleeType =
-      SubstCalleeType.subst(AI.getModule(),
-                            [&](SubstitutableType *type) -> Type {
-                              if (type == OpenedArchetype)
-                                return ConcreteType;
-                              return type;
-                            },
-                            MakeAbstractConformanceForGenericType());
-  }
-
-  FullApplySite NewAI;
-  Builder.setCurrentDebugScope(AI.getDebugScope());
-  Builder.addOpenedArchetypeOperands(AI.getInstruction());
-
-  if (auto *TAI = dyn_cast<TryApplyInst>(AI))
-    NewAI = Builder.createTryApply(AI.getLoc(), AI.getCallee(), Substitutions,
-                                   Args, TAI->getNormalBB(), TAI->getErrorBB());
-  else
-    NewAI = Builder.createApply(AI.getLoc(), AI.getCallee(), Substitutions,
-                                Args, cast<ApplyInst>(AI)->isNonThrowing());
-
-  if (auto apply = dyn_cast<ApplyInst>(NewAI))
-    replaceInstUsesWith(*cast<ApplyInst>(AI.getInstruction()), apply);
-  eraseInstFromFunction(*AI.getInstruction());
-
-  return NewAI.getInstruction();
-}
-
-namespace {
-/// Record conformance and concrete type info derived from init_existential.
-struct ConformanceAndConcreteType {
-  Optional<ProtocolConformanceRef> Conformance;
-  // Concrete type of self from the found init_existential.
-  CanType ConcreteType;
-  // For opened existentials, record the type definition.
-  SingleValueInstruction *ConcreteTypeDef = nullptr;
-  // The value of concrete type used to initialize the existential.
-  SILValue NewSelf;
-  // The value that owns the lifetime of NewSelf.
-  // init_existential_addr's source address.
-  // init_existential_ref's defined value.
-  SILValue NewSelfOwner;
-  ArrayRef<ProtocolConformanceRef> Conformances;
-
-  ConformanceAndConcreteType(ASTContext &Ctx, FullApplySite AI,
-                             SILInstruction *InitExistential,
-                             ProtocolDecl *Protocol);
-
-  bool isValid() const {
-    return Conformance.hasValue() && ConcreteType && NewSelf;
-  }
-
-  ProtocolConformanceRef getConformance() const {
-    return Conformance.getValue();
-  }
-};
-} // namespace
-
-/// Derive a concrete type of self and conformance from the init_existential
-/// instruction.
-/// If successful, initializes a valid ConformanceAndConcreteType.
-ConformanceAndConcreteType::ConformanceAndConcreteType(
-    ASTContext &Ctx, FullApplySite AI, SILInstruction *InitExistential,
-    ProtocolDecl *Protocol) {
-
-  // The existential type result of the found init_existential.
-  CanType ExistentialType;
-
-  // FIXME: Factor this out. All we really need here is the ExistentialSig
-  // below, which should be stored directly in the SILInstruction.
-  if (auto IE = dyn_cast<InitExistentialAddrInst>(InitExistential)) {
-    Conformances = IE->getConformances();
-    ConcreteType = IE->getFormalConcreteType();
-    NewSelf = IE;
-    ExistentialType = IE->getOperand()->getType().getASTType();
-  } else if (auto IER = dyn_cast<InitExistentialRefInst>(InitExistential)) {
-    Conformances = IER->getConformances();
-    ConcreteType = IER->getFormalConcreteType();
-    NewSelf = IER->getOperand();
-    ExistentialType = IER->getType().getASTType();
-  } else if (auto IEM = dyn_cast<InitExistentialMetatypeInst>(InitExistential)){
-    Conformances = IEM->getConformances();
-    NewSelf = IEM->getOperand();
-    ConcreteType = NewSelf->getType().getASTType();
-    ExistentialType = IEM->getType().getASTType();
-    while (auto InstanceType = dyn_cast<ExistentialMetatypeType>(ExistentialType)) {
-      ExistentialType = InstanceType.getInstanceType();
-      ConcreteType = cast<MetatypeType>(ConcreteType).getInstanceType();
-    }
-  } else {
-    assert(!isValid());
-    return;
-  }
-
-  // Construct a substitution map from the existential type's generic
-  // parameter to the concrete type.
-  auto ExistentialSig = Ctx.getExistentialSignature(ExistentialType,
-                                                    AI.getModule().getSwiftModule());
-
-  auto SubMap = SubstitutionMap::get(ExistentialSig, { ConcreteType },
-                                     Conformances);
-
-  // If the requirement is in a base protocol that is refined by the
-  // conforming protocol, fish out the exact conformance for the base
-  // protocol using the substitution map.
-  Conformance = SubMap.lookupConformance(
-      CanType(ExistentialSig->getGenericParams()[0]), Protocol);
-
-  // If the concrete type is another existential, we're "forwarding" an
-  // opened existential type, so we must keep track of the original
-  // defining instruction.
-  if (ConcreteType->isOpenedExistential()) {
-    if (InitExistential->getTypeDependentOperands().empty()) {
-      auto op = InitExistential->getOperand(0);
-      assert(op->getType().hasOpenedExistential() &&
-             "init_existential is supposed to have a typedef operand");
-      ConcreteTypeDef = cast<SingleValueInstruction>(op);
-    } else {
-      ConcreteTypeDef = cast<SingleValueInstruction>(
-          InitExistential->getTypeDependentOperands()[0].get());
-    }
-  }
-  assert(isValid());
-}
-
-// Return true if the given value is guaranteed to be initialized across the
-// given call site.
-//
-// It's possible for an address to be initialized/deinitialized/reinitialized.
-// Rather than keeping track of liveness, we very conservatively check that all
-// deinitialization occures after the call.
-//
-// FIXME: Rather than whitelisting, use a common AllocStackAnalyzer.
-static bool isAddressInitializedAtCall(SILValue addr, SILInstruction *AI,
-                                       DominanceInfo *DT) {
+  // Return true only if the given value is guaranteed to be initialized across
+  // the given call site.
+  //
+  // It's possible for an address to be initialized/deinitialized/reinitialized.
+  // Rather than keeping track of liveness, we very conservatively check that
+  // all deinitialization occures after the call.
   auto isDestroy = [](Operand *use) {
     switch (use->getUser()->getKind()) {
     default:
@@ -797,7 +640,7 @@
     }
     }
   };
-  for (auto use : addr->getUses()) {
+  for (auto use : existentialAddr->getUses()) {
     SILInstruction *user = use->getUser();
     if (isDestroy(use)) {
       if (!DT->properlyDominates(AI, user))
@@ -812,97 +655,112 @@
   return true;
 }
 
-/// Scoped registration of opened archetypes.
-class RAIIOpenedArchetypesTracker {
-  SILBuilder &B;
-  // The original tracker may be null.
-  SILOpenedArchetypesTracker *OldOpenedArchetypesTracker;
-  SILOpenedArchetypesTracker OpenedArchetypesTracker;
-
-public:
-  RAIIOpenedArchetypesTracker(SILBuilder &B)
-    : B(B), OldOpenedArchetypesTracker(B.getOpenedArchetypesTracker()),
-    OpenedArchetypesTracker(&B.getFunction()) {
-    B.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
-  }
-
-  SILOpenedArchetypesTracker &getTracker() {
-    return OpenedArchetypesTracker;
-  }
-
-  ~RAIIOpenedArchetypesTracker() {
-    B.setOpenedArchetypesTracker(OldOpenedArchetypesTracker);
-  }
-};
-
-/// Propagate information about a concrete type from init_existential_addr
-/// or init_existential_ref into witness_method conformances and into
-/// apply instructions.
-/// This helps the devirtualizer to replace witness_method by
+/// Rewrite the given method apply instruction in terms of the provided conrete
+/// type information.
+///
+/// If the rewrite is successful, the original apply will be removed and the new
+/// apply is returned. Otherwise, the original apply will not be removed and
+/// nullptr is returned.
+///
+/// Creates a new apply instruction that uses the concrete type instead of the
+/// existential type. Type substitution will be performed from all occurrences
+/// of CEI.OpenedArchetype to the replacement type CEI.ConcreteType within the
+/// applied function type. The single self argument of the apply will be
+/// rewritten. This helps the devirtualizer to replace witness_method by
 /// class_method instructions and then devirtualize.
-SILInstruction *SILCombiner::propagateConcreteTypeOfInitExistential(
-    FullApplySite Apply, ProtocolDecl *Protocol,
-    llvm::function_ref<void(CanType, ProtocolConformanceRef)> Propagate) {
+///
+/// Note that the substituted type, CEI.OpenedArchetype, is the same type as the
+/// self argument for nonstatic methods, but for static methods self is the
+/// metatype instead. For witness methods, CEI.OpenedArchetype is usually the
+/// same as WMI->getLookupType() but differs in the unusual situation in which
+/// the witness method is looked up using a different opened archetype.
+///
+/// FIXME: Protocol methods (witness or default) that return Self will be given
+/// a new return type. This implementation fails to update the type signature of
+/// SSA uses in those cases. Currently we bail out on methods that return Self.
+SILInstruction *
+SILCombiner::createApplyWithConcreteType(FullApplySite Apply,
+                                         const ConcreteExistentialInfo &CEI,
+                                         SILBuilderContext &BuilderCtx) {
+  assert(Apply.getOrigCalleeType()->isPolymorphic());
 
-  ASTContext &Ctx = Builder.getASTContext();
-
-  // Get the self argument.
-  assert(Apply.hasSelfArgument() && "Self argument should be present");
-  SILValue Self = Apply.getSelfArgument();
-
-  // Try to find the init_existential, which could be used to
-  // determine a concrete type of the self.
-  ArchetypeType *OpenedArchetype = nullptr;
-  SILValue OpenedArchetypeDef;
-  bool isCopied = false;
-  SILInstruction *InitExistential = findInitExistential(
-      Apply, Self, OpenedArchetype, OpenedArchetypeDef, isCopied);
-  if (!InitExistential)
+  // Don't specialize apply instructions that return the callee's Self type,
+  // because this optimization does not know how to substitute types in the
+  // users of this apply. In the function type substitution below, all
+  // references to OpenedArchetype will be substituted. So walk to type to find
+  // all possible references, such as returning Optional<Self>.
+  if (Apply.getType().getASTType().findIf(
+          [&CEI](Type t) -> bool { return t->isEqual(CEI.OpenedArchetype); })) {
     return nullptr;
-
-  // Try to derive the concrete type of self and a related conformance from
-  // the found init_existential.
-  ConformanceAndConcreteType CCT(Ctx, Apply, InitExistential, Protocol);
-  if (!CCT.isValid())
-    return nullptr;
-
-  RAIIOpenedArchetypesTracker tempTracker(Builder);
-  if (CCT.ConcreteType->isOpenedExistential()) {
-    // Temporarily record this opened existential def. Don't permanently record
-    // in the Builder's tracker because this opened existential's original
-    // dominating def may not have been recorded yet.
-    // FIXME: Redesign the tracker. This is not robust.
-    tempTracker.getTracker().addOpenedArchetypeDef(
-        cast<ArchetypeType>(CCT.ConcreteType), CCT.ConcreteTypeDef);
   }
-
-  // Propagate the concrete type into the callee-operand if required.
-  Propagate(CCT.ConcreteType, CCT.getConformance());
-
-  auto canReplaceCopiedSelf = [&]() {
-    // If the witness method is mutating self, we cannot replace self with
-    // the source of a copy. Otherwise the call would modify another value than
-    // the original self.
-    if (Apply.getOrigCalleeType()->getSelfParameter().isIndirectMutating())
-      return false;
-
-    auto *DT = DA->get(Apply.getFunction());
-    auto *AI = Apply.getInstruction();
-    // Only init_existential_addr may be copied.
-    SILValue existentialAddr =
-        cast<InitExistentialAddrInst>(InitExistential)->getOperand();
-    return isAddressInitializedAtCall(existentialAddr, AI, DT);
-  };
-  if (isCopied && !canReplaceCopiedSelf())
+  // Bail out if any non-self arguments or indirect result that refer to the
+  // OpenedArchetype. The following optimization substitutes all occurrences of
+  // OpenedArchetype in the function signature, but will only rewrite the self
+  // operand.
+  //
+  // Note that the language does not allow Self to occur in contravariant
+  // position. However, SIL does allow this and it can happen as a result of
+  // upstream transformations. Since this is bail-out logic, it must handle all
+  // verifiable SIL.
+  for (auto Arg : Apply.getArgumentsWithoutSelf()) {
+    if (Arg->getType().getASTType().findIf([&CEI](Type t) -> bool {
+          return t->isEqual(CEI.OpenedArchetype);
+        })) {
+      return nullptr;
+    }
+  }
+  // The apply can only be rewritten in terms of the concrete value if it is
+  // legal to pass that value as the self argument.
+  if (CEI.isCopied && !canReplaceCopiedSelf(Apply, CEI.InitExistential, DA))
     return nullptr;
 
-  // Create a new apply instruction that uses the concrete type instead
-  // of the existential type.
-  auto *NewAI = createApplyWithConcreteType(
-      Apply, CCT.NewSelf, Self, CCT.ConcreteType, CCT.ConcreteTypeDef,
-      CCT.getConformance(), OpenedArchetype);
+  // Create a set of arguments.
+  SmallVector<SILValue, 8> NewArgs;
+  for (auto Arg : Apply.getArgumentsWithoutSelf()) {
+    NewArgs.push_back(Arg);
+  }
+  NewArgs.push_back(CEI.ConcreteValue);
 
-  return NewAI;
+  assert(Apply.getOrigCalleeType()->isPolymorphic());
+
+  // Form a new set of substitutions where Self is
+  // replaced by a concrete type.
+  SubstitutionMap OrigCallSubs = Apply.getSubstitutionMap();
+  SubstitutionMap NewCallSubs = OrigCallSubs.subst(
+      [&](SubstitutableType *type) -> Type {
+        if (type == CEI.OpenedArchetype)
+          return CEI.ConcreteType;
+        return type;
+      },
+      [&](CanType origTy, Type substTy,
+          ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> {
+        if (origTy->isEqual(CEI.OpenedArchetype)) {
+          assert(substTy->isEqual(CEI.ConcreteType));
+          // Do a conformance lookup on this witness requirement using the
+          // existential's conformances. The witness requirement may be a base
+          // type of the existential's requirements.
+          return CEI.lookupExistentialConformance(proto).getValue();
+        }
+        return ProtocolConformanceRef(proto);
+      });
+
+  SILBuilderWithScope ApplyBuilder(Apply.getInstruction(), BuilderCtx);
+  FullApplySite NewApply;
+  if (auto *TAI = dyn_cast<TryApplyInst>(Apply))
+    NewApply = ApplyBuilder.createTryApply(
+        Apply.getLoc(), Apply.getCallee(), NewCallSubs, NewArgs,
+        TAI->getNormalBB(), TAI->getErrorBB());
+  else
+    NewApply = ApplyBuilder.createApply(
+        Apply.getLoc(), Apply.getCallee(), NewCallSubs, NewArgs,
+        cast<ApplyInst>(Apply)->isNonThrowing());
+
+  if (auto NewAI = dyn_cast<ApplyInst>(NewApply))
+    replaceInstUsesWith(*cast<ApplyInst>(Apply.getInstruction()), NewAI);
+
+  eraseInstFromFunction(*Apply.getInstruction());
+
+  return NewApply.getInstruction();
 }
 
 /// Rewrite a witness method's lookup type from an archetype to a concrete type.
@@ -915,116 +773,107 @@
 ///
 /// ==> apply %witness<Concrete : Protocol>(%existential)
 SILInstruction *
-SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
+SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite Apply,
                                                     WitnessMethodInst *WMI) {
   // Check if it is legal to perform the propagation.
   if (WMI->getConformance().isConcrete())
     return nullptr;
 
-  // Don't specialize Apply instructions that return the Self type.
-  // Notice that it is sufficient to compare the return type to the
-  // substituted type because types that depend on the Self type are
-  // not allowed (for example [Self] is not allowed).
-  if (AI.getType().getASTType() == WMI->getLookupType())
-    return nullptr;
 
-  // We need to handle the Self return type.
-  // In we find arguments that are not the 'self' argument and if
-  // they are of the Self type then we abort the optimization.
-  for (auto Arg : AI.getArgumentsWithoutSelf()) {
-    if (Arg->getType().getASTType() == WMI->getLookupType())
-      return nullptr;
-  }
-
-  // The lookup type is not an opened existential type,
-  // thus it cannot be made more concrete.
+  // If the lookup type is not an opened existential type,
+  // it cannot be made more concrete.
   if (!WMI->getLookupType()->isOpenedExistential())
     return nullptr;
 
-  // Obtain the protocol which should be used by the conformance.
-  auto *PD = WMI->getLookupProtocol();
+  // Try to derive the concrete type of self and the related conformance by
+  // searching for a preceding init_existential.
+  const ConcreteExistentialInfo CEI(Apply.getSelfArgumentOperand());
+  if (!CEI.isValid())
+    return nullptr;
 
+  // Get the conformance of the init_existential type, which is passed as the
+  // self argument, on the witness' protocol.
+  ProtocolConformanceRef SelfConformance =
+      *CEI.lookupExistentialConformance(WMI->getLookupProtocol());
+
+  SILBuilderContext BuilderCtx(Builder.getModule(), Builder.getTrackingList());
+  SILOpenedArchetypesTracker OpenedArchetypesTracker(&Builder.getFunction());
+  BuilderCtx.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
+  if (CEI.ConcreteType->isOpenedExistential()) {
+    // Temporarily record this opened existential def in this local
+    // BuilderContext before rewriting the witness method.
+    OpenedArchetypesTracker.addOpenedArchetypeDef(
+        cast<ArchetypeType>(CEI.ConcreteType), CEI.ConcreteTypeDef);
+  }
   // Propagate the concrete type into a callee-operand, which is a
-  // witness_method instruction.
-  auto PropagateIntoOperand = [this, &WMI, &AI](
-      CanType ConcreteType, ProtocolConformanceRef Conformance) {
-    if (ConcreteType == WMI->getLookupType() &&
-        Conformance == WMI->getConformance()) {
-      // If we create a new instruction that’s the same as the old one we’ll
-      // cause an infinite loop:
-      // NewWMI will be added to the Builder’s tracker list.
-      // SILCombine, in turn, uses the tracker list to populate the worklist
-      // As such, if we don’t remove the witness method later on in the pass, we
-      // are stuck:
-      // We will re-create the same instruction and re-populate the worklist
-      // with it
-      return;
-    }
+  // witness_method instruction. It's ok to rewrite the witness method in terms
+  // of a concrete type without rewriting the apply itself. In fact, doing so
+  // may allow the Devirtualizer pass to finish the job.
+  //
+  // If we create a new instruction that’s the same as the old one we’ll
+  // cause an infinite loop:
+  // NewWMI will be added to the Builder’s tracker list.
+  // SILCombine, in turn, uses the tracker list to populate the worklist
+  // As such, if we don’t remove the witness method later on in the pass, we
+  // are stuck:
+  // We will re-create the same instruction and re-populate the worklist
+  // with it.
+  if (CEI.ConcreteType != WMI->getLookupType()
+      || SelfConformance != WMI->getConformance()) {
+    SILBuilderWithScope WMIBuilder(WMI, BuilderCtx);
     // Keep around the dependence on the open instruction unless we've
     // actually eliminated the use.
-    auto *NewWMI = Builder.createWitnessMethod(WMI->getLoc(),
-                                                ConcreteType,
-                                                Conformance, WMI->getMember(),
-                                                WMI->getType());
-    // Replace only uses of the witness_method in the apply that is going to
-    // be changed.
-    MutableArrayRef<Operand> Operands = AI.getInstruction()->getAllOperands();
+    auto *NewWMI = WMIBuilder.createWitnessMethod(
+        WMI->getLoc(), CEI.ConcreteType, SelfConformance, WMI->getMember(),
+        WMI->getType());
+    // Replace only uses of the witness_method in the apply that was analyzed by
+    // ConcreteExistentialInfo.
+    MutableArrayRef<Operand> Operands =
+        Apply.getInstruction()->getAllOperands();
     for (auto &Op : Operands) {
       if (Op.get() == WMI)
         Op.set(NewWMI);
     }
     if (WMI->use_empty())
       eraseInstFromFunction(*WMI);
-  };
-
-  // Try to perform the propagation.
-  return propagateConcreteTypeOfInitExistential(AI, PD, PropagateIntoOperand);
+  }
+  // Try to rewrite the apply.
+  return createApplyWithConcreteType(Apply, CEI, BuilderCtx);
 }
 
-
+/// Rewrite a protocol extension lookup type from an archetype to a concrete
+/// type.
+/// Example:
+///   %ref = alloc_ref $C
+///   %existential = init_existential_ref %ref : $C : $C, $P
+///   %opened = open_existential_ref %existential : $P to $@opened
+///   %f = function_ref @defaultMethod
+///   apply %f<@opened P>(%opened)
+///
+/// ==> apply %f<C : P>(%ref)
 SILInstruction *
-SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI) {
-  // Check if it is legal to perform the propagation.
-  if (!AI.hasSubstitutions())
-    return nullptr;
-  auto *Callee = AI.getReferencedFunction();
-  if (!Callee || !Callee->getDeclContext())
+SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite Apply) {
+  // This optimization requires a generic self argument.
+  if (!Apply.hasSelfArgument() || !Apply.hasSubstitutions())
     return nullptr;
 
-  // Bail, if there is no self argument.
-  SILValue Self;
-  if (auto *Apply = dyn_cast<ApplyInst>(AI)) {
-    if (Apply->hasSelfArgument())
-      Self = Apply->getSelfArgument();
-  } else if (auto *Apply = dyn_cast<TryApplyInst>(AI)) {
-    if (Apply->hasSelfArgument())
-      Self = Apply->getSelfArgument();
+  // Try to derive the concrete type of self and a related conformance from
+  // the found init_existential.
+  const ConcreteExistentialInfo CEI(Apply.getSelfArgumentOperand());
+  if (!CEI.isValid())
+    return nullptr;
+
+  SILBuilderContext BuilderCtx(Builder.getModule(), Builder.getTrackingList());
+  SILOpenedArchetypesTracker OpenedArchetypesTracker(&Builder.getFunction());
+  BuilderCtx.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
+  if (CEI.ConcreteType->isOpenedExistential()) {
+    // Temporarily record this opened existential def in this local
+    // BuilderContext before rewriting the witness method.
+    OpenedArchetypesTracker.addOpenedArchetypeDef(
+        cast<ArchetypeType>(CEI.ConcreteType), CEI.ConcreteTypeDef);
   }
-  if (!Self)
-    return nullptr;
-
-  // We need to handle the Self return type.
-  // In we find arguments that are not the 'self' argument and if
-  // they are of the Self type then we abort the optimization.
-  for (auto Arg : AI.getArgumentsWithoutSelf()) {
-    if (Arg->getType().getASTType() ==
-        AI.getArguments().back()->getType().getASTType())
-      return nullptr;
-  }
-
-  // Obtain the protocol which should be used by the conformance.
-  auto *AFD = dyn_cast<AbstractFunctionDecl>(Callee->getDeclContext());
-  if (!AFD)
-    return nullptr;
-  auto *PD = AFD->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
-
-
-  // No need to propagate anything into the callee operand.
-  auto PropagateIntoOperand = [] (CanType ConcreteType,
-                                  ProtocolConformanceRef Conformance) {};
-
-  // Try to perform the propagation.
-  return propagateConcreteTypeOfInitExistential(AI, PD, PropagateIntoOperand);
+  // Perform the transformation by rewriting the apply.
+  return createApplyWithConcreteType(Apply, CEI, BuilderCtx);
 }
 
 /// \brief Check that all users of the apply are retain/release ignoring one
diff --git a/lib/SILOptimizer/Transforms/CMakeLists.txt b/lib/SILOptimizer/Transforms/CMakeLists.txt
index 1fc0585..e4d6c74 100644
--- a/lib/SILOptimizer/Transforms/CMakeLists.txt
+++ b/lib/SILOptimizer/Transforms/CMakeLists.txt
@@ -1,35 +1,35 @@
-set(TRANSFORMS_SOURCES
-  Transforms/ARCCodeMotion.cpp
-  Transforms/AccessEnforcementOpts.cpp
-  Transforms/AllocBoxToStack.cpp
-  Transforms/ArrayCountPropagation.cpp
-  Transforms/ArrayElementValuePropagation.cpp
-  Transforms/AssumeSingleThreaded.cpp
-  Transforms/CSE.cpp
-  Transforms/ConditionForwarding.cpp
-  Transforms/CopyForwarding.cpp
-  Transforms/DeadCodeElimination.cpp
-  Transforms/DeadObjectElimination.cpp
-  Transforms/DeadStoreElimination.cpp
-  Transforms/Devirtualizer.cpp
-  Transforms/GenericSpecializer.cpp
-  Transforms/MergeCondFail.cpp
-  Transforms/MarkUninitializedFixup.cpp
-  Transforms/Outliner.cpp
-  Transforms/ObjectOutliner.cpp
-  Transforms/OwnershipModelEliminator.cpp
-  Transforms/PerformanceInliner.cpp
-  Transforms/RedundantLoadElimination.cpp
-  Transforms/RedundantOverflowCheckRemoval.cpp
-  Transforms/ReleaseDevirtualizer.cpp
-  Transforms/RemovePin.cpp
-  Transforms/SILCodeMotion.cpp
-  Transforms/SILLowerAggregateInstrs.cpp
-  Transforms/SILMem2Reg.cpp
-  Transforms/SILSROA.cpp
-  Transforms/SimplifyCFG.cpp
-  Transforms/Sink.cpp
-  Transforms/SpeculativeDevirtualizer.cpp
-  Transforms/StackPromotion.cpp
-  Transforms/UnsafeGuaranteedPeephole.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  ARCCodeMotion.cpp
+  AccessEnforcementOpts.cpp
+  AllocBoxToStack.cpp
+  ArrayCountPropagation.cpp
+  ArrayElementValuePropagation.cpp
+  AssumeSingleThreaded.cpp
+  CSE.cpp
+  ConditionForwarding.cpp
+  CopyForwarding.cpp
+  DeadCodeElimination.cpp
+  DeadObjectElimination.cpp
+  DeadStoreElimination.cpp
+  Devirtualizer.cpp
+  GenericSpecializer.cpp
+  MergeCondFail.cpp
+  MarkUninitializedFixup.cpp
+  Outliner.cpp
+  ObjectOutliner.cpp
+  OwnershipModelEliminator.cpp
+  PerformanceInliner.cpp
+  RedundantLoadElimination.cpp
+  RedundantOverflowCheckRemoval.cpp
+  ReleaseDevirtualizer.cpp
+  RemovePin.cpp
+  SILCodeMotion.cpp
+  SILLowerAggregateInstrs.cpp
+  SILMem2Reg.cpp
+  SILSROA.cpp
+  SimplifyCFG.cpp
+  Sink.cpp
+  SpeculativeDevirtualizer.cpp
+  StackPromotion.cpp
+  UnsafeGuaranteedPeephole.cpp
+)
diff --git a/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp b/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp
index c59d7bf..f222139 100644
--- a/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp
+++ b/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp
@@ -149,6 +149,7 @@
   switch (Inst->getKind()) {
   case SILInstructionKind::StrongRetainInst:
   case SILInstructionKind::StrongRetainUnownedInst:
+  case SILInstructionKind::CopyUnownedValueInst:
   case SILInstructionKind::UnownedRetainInst:
   case SILInstructionKind::RetainValueInst:
   case SILInstructionKind::DeallocStackInst:
diff --git a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
index c330ee3..a83d85f 100644
--- a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
+++ b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
@@ -57,7 +57,6 @@
   bool visitStoreInst(StoreInst *SI);
   bool visitStoreBorrowInst(StoreBorrowInst *SI);
   bool visitCopyValueInst(CopyValueInst *CVI);
-  bool visitCopyUnownedValueInst(CopyUnownedValueInst *CVI);
   bool visitDestroyValueInst(DestroyValueInst *DVI);
   bool visitLoadBorrowInst(LoadBorrowInst *LBI);
   bool visitBeginBorrowInst(BeginBorrowInst *BBI) {
@@ -160,19 +159,6 @@
   return true;
 }
 
-bool OwnershipModelEliminatorVisitor::visitCopyUnownedValueInst(
-    CopyUnownedValueInst *CVI) {
-  B.createStrongRetainUnowned(CVI->getLoc(), CVI->getOperand(),
-                              B.getDefaultAtomicity());
-  // Users of copy_value_unowned expect an owned value. So we need to convert
-  // our unowned value to a ref.
-  auto *UTRI =
-      B.createUnownedToRef(CVI->getLoc(), CVI->getOperand(), CVI->getType());
-  CVI->replaceAllUsesWith(UTRI);
-  CVI->eraseFromParent();
-  return true;
-}
-
 bool OwnershipModelEliminatorVisitor::visitUnmanagedRetainValueInst(
     UnmanagedRetainValueInst *URVI) {
   // Now that we have set the unqualified ownership flag, destroy value
diff --git a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp
index 8707aee..d1fa5b5 100644
--- a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp
+++ b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp
@@ -156,6 +156,7 @@
   case SILInstructionKind::IsUniqueInst:
   case SILInstructionKind::IsUniqueOrPinnedInst:
   case SILInstructionKind::FixLifetimeInst:
+  case SILInstructionKind::CopyUnownedValueInst:
     return true;
   default:
     return false;
diff --git a/lib/SILOptimizer/UtilityPasses/CMakeLists.txt b/lib/SILOptimizer/UtilityPasses/CMakeLists.txt
index 4681be8..461b8a5 100644
--- a/lib/SILOptimizer/UtilityPasses/CMakeLists.txt
+++ b/lib/SILOptimizer/UtilityPasses/CMakeLists.txt
@@ -1,31 +1,31 @@
-set(UTILITYPASSES_SOURCES
-  UtilityPasses/AADumper.cpp
-  UtilityPasses/AccessSummaryDumper.cpp
-  UtilityPasses/AccessedStorageDumper.cpp
-  UtilityPasses/BasicCalleePrinter.cpp
-  UtilityPasses/BasicInstructionPropertyDumper.cpp
-  UtilityPasses/BugReducerTester.cpp
-  UtilityPasses/CFGPrinter.cpp
-  UtilityPasses/CallerAnalysisPrinter.cpp
-  UtilityPasses/ComputeDominanceInfo.cpp
-  UtilityPasses/ComputeLoopInfo.cpp
-  UtilityPasses/EpilogueARCMatcherDumper.cpp
-  UtilityPasses/EpilogueRetainReleaseMatcherDumper.cpp
-  UtilityPasses/EscapeAnalysisDumper.cpp
-  UtilityPasses/FunctionOrderPrinter.cpp
-  UtilityPasses/IVInfoPrinter.cpp
-  UtilityPasses/InstCount.cpp
-  UtilityPasses/LSLocationPrinter.cpp
-  UtilityPasses/Link.cpp
-  UtilityPasses/LoopCanonicalizer.cpp
-  UtilityPasses/LoopInfoPrinter.cpp
-  UtilityPasses/LoopRegionPrinter.cpp
-  UtilityPasses/MemBehaviorDumper.cpp
-  UtilityPasses/RCIdentityDumper.cpp
-  UtilityPasses/SerializeSILPass.cpp
-  UtilityPasses/SILDebugInfoGenerator.cpp
-  UtilityPasses/SideEffectsDumper.cpp
-  UtilityPasses/SimplifyUnreachableContainingBlocks.cpp
-  UtilityPasses/StripDebugInfo.cpp
-  UtilityPasses/ValueOwnershipKindDumper.cpp
-  PARENT_SCOPE)
+silopt_register_sources(
+  AADumper.cpp
+  AccessSummaryDumper.cpp
+  AccessedStorageDumper.cpp
+  BasicCalleePrinter.cpp
+  BasicInstructionPropertyDumper.cpp
+  BugReducerTester.cpp
+  CFGPrinter.cpp
+  CallerAnalysisPrinter.cpp
+  ComputeDominanceInfo.cpp
+  ComputeLoopInfo.cpp
+  EpilogueARCMatcherDumper.cpp
+  EpilogueRetainReleaseMatcherDumper.cpp
+  EscapeAnalysisDumper.cpp
+  FunctionOrderPrinter.cpp
+  IVInfoPrinter.cpp
+  InstCount.cpp
+  LSLocationPrinter.cpp
+  Link.cpp
+  LoopCanonicalizer.cpp
+  LoopInfoPrinter.cpp
+  LoopRegionPrinter.cpp
+  MemBehaviorDumper.cpp
+  RCIdentityDumper.cpp
+  SerializeSILPass.cpp
+  SILDebugInfoGenerator.cpp
+  SideEffectsDumper.cpp
+  SimplifyUnreachableContainingBlocks.cpp
+  StripDebugInfo.cpp
+  ValueOwnershipKindDumper.cpp
+)
diff --git a/lib/SILOptimizer/Utils/CMakeLists.txt b/lib/SILOptimizer/Utils/CMakeLists.txt
index 34dc870..6fb50c6 100644
--- a/lib/SILOptimizer/Utils/CMakeLists.txt
+++ b/lib/SILOptimizer/Utils/CMakeLists.txt
@@ -1,20 +1,19 @@
-set(UTILS_SOURCES
-  Utils/CFG.cpp
-  Utils/CastOptimizer.cpp
-  Utils/CheckedCastBrJumpThreading.cpp
-  Utils/ConstantFolding.cpp
-  Utils/Devirtualize.cpp
-  Utils/Existential.cpp
-  Utils/GenericCloner.cpp
-  Utils/Generics.cpp
-  Utils/LoadStoreOptUtils.cpp
-  Utils/Local.cpp
-  Utils/LoopUtils.cpp
-  Utils/OptimizerStatsUtils.cpp
-  Utils/PerformanceInlinerUtils.cpp
-  Utils/SILInliner.cpp
-  Utils/SILSSAUpdater.cpp
-  Utils/SpecializationMangler.cpp
-  Utils/StackNesting.cpp
-  PARENT_SCOPE)
-
+silopt_register_sources(
+  CFG.cpp
+  CastOptimizer.cpp
+  CheckedCastBrJumpThreading.cpp
+  ConstantFolding.cpp
+  Devirtualize.cpp
+  Existential.cpp
+  GenericCloner.cpp
+  Generics.cpp
+  LoadStoreOptUtils.cpp
+  Local.cpp
+  LoopUtils.cpp
+  OptimizerStatsUtils.cpp
+  PerformanceInlinerUtils.cpp
+  SILInliner.cpp
+  SILSSAUpdater.cpp
+  SpecializationMangler.cpp
+  StackNesting.cpp
+)
diff --git a/lib/SILOptimizer/Utils/Existential.cpp b/lib/SILOptimizer/Utils/Existential.cpp
index abc840a..2c35f85 100644
--- a/lib/SILOptimizer/Utils/Existential.cpp
+++ b/lib/SILOptimizer/Utils/Existential.cpp
@@ -141,16 +141,17 @@
 /// type of the \p Self.
 /// If the value is copied from another stack location, \p isCopied is set to
 /// true.
-SILInstruction *swift::findInitExistential(FullApplySite AI, SILValue Self,
+SILInstruction *swift::findInitExistential(Operand &openedUse,
                                            ArchetypeType *&OpenedArchetype,
                                            SILValue &OpenedArchetypeDef,
                                            bool &isCopied) {
+  SILValue Self = openedUse.get();
+  SILInstruction *User = openedUse.getUser();
   isCopied = false;
   if (auto *Instance = dyn_cast<AllocStackInst>(Self)) {
     // In case the Self operand is an alloc_stack where a copy_addr copies the
     // result of an open_existential_addr to this stack location.
-    if (SILValue Src =
-            getAddressOfStackInit(Instance, AI.getInstruction(), isCopied))
+    if (SILValue Src = getAddressOfStackInit(Instance, User, isCopied))
       Self = Src;
   }
 
@@ -195,3 +196,65 @@
   }
   return nullptr;
 }
+
+/// Derive a concrete type of self and conformance from the init_existential
+/// instruction.
+/// If successful, initializes a valid ConformanceAndConcreteType.
+ConcreteExistentialInfo::ConcreteExistentialInfo(Operand &openedUse) {
+  // Try to find the init_existential, which could be used to
+  // determine a concrete type of the self.
+  // Returns: InitExistential, OpenedArchetype, OpenedArchetypeDef, isCopied.
+  InitExistential = findInitExistential(openedUse, OpenedArchetype,
+                                        OpenedArchetypeDef, isCopied);
+  if (!InitExistential)
+    return;
+
+  if (auto IE = dyn_cast<InitExistentialAddrInst>(InitExistential)) {
+    ExistentialType = IE->getOperand()->getType().getASTType();
+    ExistentialConformances = IE->getConformances();
+    ConcreteType = IE->getFormalConcreteType();
+    ConcreteValue = IE;
+  } else if (auto IER = dyn_cast<InitExistentialRefInst>(InitExistential)) {
+    ExistentialType = IER->getType().getASTType();
+    ExistentialConformances = IER->getConformances();
+    ConcreteType = IER->getFormalConcreteType();
+    ConcreteValue = IER->getOperand();
+  } else if (auto IEM =
+                 dyn_cast<InitExistentialMetatypeInst>(InitExistential)) {
+    ExistentialType = IEM->getType().getASTType();
+    ExistentialConformances = IEM->getConformances();
+    ConcreteValue = IEM->getOperand();
+    ConcreteType = ConcreteValue->getType().getASTType();
+    while (auto InstanceType =
+               dyn_cast<ExistentialMetatypeType>(ExistentialType)) {
+      ExistentialType = InstanceType.getInstanceType();
+      ConcreteType = cast<MetatypeType>(ConcreteType).getInstanceType();
+    }
+  } else {
+    assert(!isValid());
+    return;
+  }
+  // Construct a single-generic-parameter substitution map directly to the
+  // ConcreteType with this existential's full list of conformances.
+  SILModule &M = InitExistential->getModule();
+  CanGenericSignature ExistentialSig =
+      M.getASTContext().getExistentialSignature(ExistentialType,
+                                                M.getSwiftModule());
+  ExistentialSubs = SubstitutionMap::get(ExistentialSig, {ConcreteType},
+                                         ExistentialConformances);
+  // If the concrete type is another existential, we're "forwarding" an
+  // opened existential type, so we must keep track of the original
+  // defining instruction.
+  if (ConcreteType->isOpenedExistential()) {
+    if (InitExistential->getTypeDependentOperands().empty()) {
+      auto op = InitExistential->getOperand(0);
+      assert(op->getType().hasOpenedExistential()
+             && "init_existential is supposed to have a typedef operand");
+      ConcreteTypeDef = cast<SingleValueInstruction>(op);
+    } else {
+      ConcreteTypeDef = cast<SingleValueInstruction>(
+          InitExistential->getTypeDependentOperands()[0].get());
+    }
+  }
+  assert(isValid());
+}
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index b289663..8df9f26 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -435,9 +435,10 @@
   auto &M = getBuilder().getFunction().getModule();
   auto InlinedAt =
       getOrCreateInlineScope(CalleeScope->InlinedCallSite);
+  auto ParentScope = CalleeScope->Parent.dyn_cast<const SILDebugScope *>();
   auto *InlinedScope = new (M) SILDebugScope(
       CalleeScope->Loc, CalleeScope->Parent.dyn_cast<SILFunction *>(),
-      CalleeScope->Parent.dyn_cast<const SILDebugScope *>(), InlinedAt);
+      ParentScope ? getOrCreateInlineScope(ParentScope) : nullptr, InlinedAt);
   InlinedScopeCache.insert({CalleeScope, InlinedScope});
   return InlinedScope;
 }
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 602bff0..d64ae88 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -2799,8 +2799,8 @@
       auto locator = CS.getConstraintLocator(expr);
       auto projectedTy = CS.createTypeVariable(locator,
                                                TVO_CanBindToLValue);
-      CS.addKeyPathApplicationConstraint(expr->getKeyPath()->getType(),
-                                         expr->getBase()->getType(),
+      CS.addKeyPathApplicationConstraint(CS.getType(expr->getKeyPath()),
+                                         CS.getType(expr->getBase()),
                                          projectedTy,
                                          locator);
       return projectedTy;
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 42c1d9d..78f1c80 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -372,6 +372,10 @@
     auto *param = paramList->get(paramNum);
     return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
   }
+  if (auto *ee = dyn_cast<EnumElementDecl>(decl)) {
+    auto *param = ee->getParameterList()->get(paramNum);
+    return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
+  }
 
   auto *subscript = cast<SubscriptDecl>(decl);
   auto *index = subscript->getIndices()->get(paramNum);
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index feb74c9..dab83ec 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -3927,6 +3927,62 @@
   const_cast<Expr *>(E)->walk(Walker);
 }
 
+static void diagnoseDeprecatedWritableKeyPath(TypeChecker &TC, const Expr *E,
+                                              const DeclContext *DC) {
+  if (!E || isa<ErrorExpr>(E) || !E->getType())
+    return;
+
+  class DeprecatedWritableKeyPathWalker : public ASTWalker {
+    TypeChecker &TC;
+    const DeclContext *DC;
+
+    void visitKeyPathApplicationExpr(KeyPathApplicationExpr *E) {
+      if (E->hasLValueAccessKind() &&
+          E->getLValueAccessKind() == AccessKind::Read)
+        return;
+
+      if (auto *keyPathExpr = dyn_cast<KeyPathExpr>(E->getKeyPath())) {
+        auto *decl = keyPathExpr->getType()->getNominalOrBoundGenericNominal();
+        if (decl != TC.Context.getWritableKeyPathDecl() &&
+            decl != TC.Context.getReferenceWritableKeyPathDecl())
+          return;
+
+        assert(keyPathExpr->getComponents().size() > 0);
+        auto &component = keyPathExpr->getComponents().back();
+        if (component.getKind() == KeyPathExpr::Component::Kind::Property) {
+          auto *storage =
+            cast<AbstractStorageDecl>(component.getDeclRef().getDecl());
+          if (!storage->isSettable(nullptr) ||
+              !storage->isSetterAccessibleFrom(DC)) {
+            TC.diagnose(keyPathExpr->getLoc(),
+                        swift::diag::expr_deprecated_writable_keypath,
+                        storage->getFullName());
+          }
+        }
+      }
+    }
+
+    std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
+      if (!E || isa<ErrorExpr>(E) || !E->getType())
+        return {false, E};
+
+      if (auto *KPAE = dyn_cast<KeyPathApplicationExpr>(E)) {
+        visitKeyPathApplicationExpr(KPAE);
+        return {true, E};
+      }
+
+      return {true, E};
+    }
+
+  public:
+    DeprecatedWritableKeyPathWalker(TypeChecker &TC, const DeclContext *DC)
+        : TC(TC), DC(DC) {}
+  };
+
+  DeprecatedWritableKeyPathWalker Walker(TC, DC);
+  const_cast<Expr *>(E)->walk(Walker);
+}
+
 //===----------------------------------------------------------------------===//
 // High-level entry points.
 //===----------------------------------------------------------------------===//
@@ -3940,6 +3996,8 @@
   diagRecursivePropertyAccess(TC, E, DC);
   diagnoseImplicitSelfUseInClosure(TC, E, DC);
   diagnoseUnintendedOptionalBehavior(TC, E, DC);
+  if (!TC.Context.isSwiftVersionAtLeast(5))
+    diagnoseDeprecatedWritableKeyPath(TC, E, DC);
   if (!TC.getLangOpts().DisableAvailabilityChecking)
     diagAvailability(TC, E, const_cast<DeclContext*>(DC));
   if (TC.Context.LangOpts.EnableObjCInterop)
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 2a9ceda..ef7a897 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -569,6 +569,60 @@
 
   // FIXME: Need to refactor the way we build an AST node from a lookup result!
 
+  SmallVector<ValueDecl*, 4> ResultValues;
+  ValueDecl *localDeclAfterUse = nullptr;
+  auto isValid = [&](ValueDecl *D) {
+    // FIXME: The source-location checks won't make sense once
+    // EnableASTScopeLookup is the default.
+    if (Loc.isValid() && D->getLoc().isValid() &&
+        D->getDeclContext()->isLocalContext() &&
+        D->getDeclContext() == DC &&
+        Context.SourceMgr.isBeforeInBuffer(Loc, D->getLoc())) {
+      localDeclAfterUse = D;
+      return false;
+    }
+    return true;
+  };
+  bool AllDeclRefs = findNonMembers(
+      *this, Lookup.innerResults(), UDRE->getRefKind(), /*breakOnMember=*/true,
+      ResultValues, isValid);
+
+  // If local declaration after use is found, check outer results for
+  // better matching candidates.
+  if (localDeclAfterUse) {
+    auto innerDecl = localDeclAfterUse;
+
+    // Perform a thorough lookup if outer results was not included before.
+    if (!lookupOptions.contains(NameLookupFlags::IncludeOuterResults)) {
+      auto option = lookupOptions;
+      option |= NameLookupFlags::IncludeOuterResults;
+      Lookup = lookupUnqualified(DC, Name, Loc, option);
+    }
+
+    while (localDeclAfterUse) {
+      if (Lookup.outerResults().empty()) {
+        diagnose(Loc, diag::use_local_before_declaration, Name);
+        diagnose(innerDecl, diag::decl_declared_here, Name);
+        Expr *error = new (Context) ErrorExpr(UDRE->getSourceRange());
+        return error;
+      }
+
+      Lookup.shiftDownResults();
+      ResultValues.clear();
+      localDeclAfterUse = nullptr;
+      AllDeclRefs = findNonMembers(
+          *this, Lookup.innerResults(), UDRE->getRefKind(), /*breakOnMember=*/true,
+          ResultValues, isValid);
+    }
+
+    // Drop outer results if they are not supposed to be included.
+    if (!lookupOptions.contains(NameLookupFlags::IncludeOuterResults)) {
+      Lookup.filter([&](LookupResultEntry Result, bool isOuter) {
+          return !isOuter;
+      });
+    }
+  }
+
   // If we have an unambiguous reference to a type decl, form a TypeExpr.
   if (Lookup.size() == 1 && UDRE->getRefKind() == DeclRefKind::Ordinary &&
       isa<TypeDecl>(Lookup[0].getValueDecl())) {
@@ -586,27 +640,6 @@
                                    UDRE->isImplicit());
   }
 
-  SmallVector<ValueDecl*, 4> ResultValues;
-  Expr *error = nullptr;
-  bool AllDeclRefs = findNonMembers(
-      *this, Lookup.innerResults(), UDRE->getRefKind(), /*breakOnMember=*/true,
-      ResultValues, [&](ValueDecl *D) {
-        // FIXME: The source-location checks won't make sense once
-        // EnableASTScopeLookup is the default.
-        if (Loc.isValid() && D->getLoc().isValid() &&
-            D->getDeclContext()->isLocalContext() &&
-            D->getDeclContext() == DC &&
-            Context.SourceMgr.isBeforeInBuffer(Loc, D->getLoc())) {
-          diagnose(Loc, diag::use_local_before_declaration, Name);
-          diagnose(D, diag::decl_declared_here, Name);
-          error = new (Context) ErrorExpr(UDRE->getSourceRange());
-          return false;
-        }
-        return true;
-      });
-  if (error)
-    return error;
-
   if (AllDeclRefs) {
     // Diagnose uses of operators that found no matching candidates.
     if (ResultValues.empty()) {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 5805238..01b2215 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -238,6 +238,11 @@
            SuperclassTypeRequest(const_cast<ClassDecl *>(classDecl)));
 }
 
+Type TypeChecker::getSuperclass(const ProtocolDecl *protocolDecl) {
+  return Context.evaluator(
+           SuperclassTypeRequest(const_cast<ProtocolDecl *>(protocolDecl)));
+}
+
 Type TypeChecker::getRawType(EnumDecl *enumDecl) {
   return Context.evaluator(EnumRawTypeRequest(enumDecl));
 }
@@ -624,7 +629,7 @@
     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().str());
+          diagnose(proto, diag::circular_protocol_def, proto->getName());
           diagnosedCircularity = true;
         }
 
@@ -692,7 +697,7 @@
 /// Check for circular inheritance.
 template<typename T>
 static void checkCircularity(TypeChecker &tc, T *decl,
-                             Diag<StringRef> circularDiag,
+                             Diag<Identifier> circularDiag,
                              DescriptiveDeclKind declKind,
                              SmallVectorImpl<T *> &path) {
   switch (decl->getCircularityCheck()) {
@@ -716,7 +721,7 @@
     if (path.end() - cycleStart == 1) {
       tc.diagnose(path.back()->getLoc(),
                   circularDiag,
-                  path.back()->getName().str());
+                  path.back()->getName());
 
       decl->setInvalid();
       decl->setInterfaceType(ErrorType::get(tc.Context));
@@ -724,17 +729,9 @@
       break;
     }
 
-    // Form the textual path illustrating the cycle.
-    llvm::SmallString<128> pathStr;
-    for (auto i = cycleStart, iEnd = path.end(); i != iEnd; ++i) {
-      if (!pathStr.empty())
-        pathStr += " -> ";
-      pathStr += ("'" + (*i)->getName().str() + "'").str();
-    }
-    pathStr += (" -> '" + decl->getName().str() + "'").str();
-
     // Diagnose the cycle.
-    tc.diagnose(decl->getLoc(), circularDiag, pathStr);
+    tc.diagnose(decl->getLoc(), circularDiag,
+                (*cycleStart)->getName());
     for (auto i = cycleStart + 1, iEnd = path.end(); i != iEnd; ++i) {
       tc.diagnose(*i, diag::kind_identifier_declared_here,
                   declKind, (*i)->getName());
@@ -1565,8 +1562,21 @@
   if (isa<DestructorDecl>(decl))
     return;
 
+  assert(decl->isObjC() && "Must be known to be @objc");
   auto attr = decl->getAttrs().getAttribute<ObjCAttr>();
-  assert(attr && "should only be called on decls already marked @objc");
+
+  /// Set the @objc name.
+  auto setObjCName = [&](ObjCSelector selector) {
+    // If there already is an @objc attribute, update its name.
+    if (attr) {
+      const_cast<ObjCAttr *>(attr)->setName(selector, /*implicit=*/true);
+      return;
+    }
+
+    // Otherwise, create an @objc attribute with the implicit name.
+    attr = ObjCAttr::create(tc.Context, selector, /*implicitName=*/true);
+    decl->getAttrs().add(attr);
+  };
 
   // If this declaration overrides an @objc declaration, use its name.
   if (auto overridden = decl->getOverriddenDecl()) {
@@ -1577,8 +1587,8 @@
         ObjCSelector overriddenSelector = overriddenFunc->getObjCSelector();
 
         // Determine whether there is a name conflict.
-        bool shouldFixName = !attr->hasName();
-        if (attr->hasName() && *attr->getName() != overriddenSelector) {
+        bool shouldFixName = !attr || !attr->hasName();
+        if (attr && attr->hasName() && *attr->getName() != overriddenSelector) {
           // If the user explicitly wrote the incorrect name, complain.
           if (!attr->isNameImplicit()) {
             {
@@ -1598,8 +1608,7 @@
         // If we have to set the name, do so.
         if (shouldFixName) {
           // Override the name on the attribute.
-          const_cast<ObjCAttr *>(attr)->setName(overriddenSelector,
-                                                /*implicit=*/true);
+          setObjCName(overriddenSelector);
         }
         return;
       }
@@ -1610,8 +1619,9 @@
         ObjCSelector overriddenNameAsSel(tc.Context, 0, overriddenName);
 
         // Determine whether there is a name conflict.
-        bool shouldFixName = !attr->hasName();
-        if (attr->hasName() && *attr->getName() != overriddenNameAsSel) {
+        bool shouldFixName = !attr || !attr->hasName();
+        if (attr && attr->hasName() &&
+            *attr->getName() != overriddenNameAsSel) {
           // If the user explicitly wrote the wrong name, complain.
           if (!attr->isNameImplicit()) {
             tc.diagnose(attr->AtLoc,
@@ -1629,8 +1639,7 @@
 
         // Fix the name, if needed.
         if (shouldFixName) {
-          const_cast<ObjCAttr *>(attr)->setName(overriddenNameAsSel,
-                                                /*implicit=*/true);
+          setObjCName(overriddenNameAsSel);
         }
         return;
       }
@@ -1639,7 +1648,7 @@
 
   // If the decl already has a name, do nothing; the protocol conformance
   // checker will handle any mismatches.
-  if (attr->hasName()) return;
+  if (attr && attr->hasName()) return;
 
   // When no override determined the Objective-C name, look for
   // requirements for which this declaration is a witness.
@@ -1683,8 +1692,7 @@
 
   // If we have a name, install it via an @objc attribute.
   if (requirementObjCName) {
-    const_cast<ObjCAttr *>(attr)->setName(*requirementObjCName,
-                                          /*implicit=*/true);
+    setObjCName(*requirementObjCName);
   }
 }
 
@@ -1832,6 +1840,10 @@
     // Mark the attribute as having used Swift 3 inference, or create an
     // implicit @objc for that purpose.
     auto attr = D->getAttrs().getAttribute<ObjCAttr>();
+    if (!attr) {
+      attr = ObjCAttr::createUnnamedImplicit(TC.Context);
+      D->getAttrs().add(attr);
+    }
     attr->setSwift3Inferred();
   }
 }
@@ -5204,6 +5216,13 @@
       ACC.checkGenericParamAccess(ED->getGenericParams(), ED,
                                   desiredAccessScope, access);
     }
+
+    // Trigger the creation of all of the conformances associated with this
+    // nominal type.
+    // FIXME: This is a hack to make sure that the type checker precomputes
+    // enough information for later passes that might query conformances.
+    if (auto nominal = ED->getAsNominalTypeOrNominalTypeExtensionContext())
+      (void)nominal->getAllConformances();
   }
 
   void visitTopLevelCodeDecl(TopLevelCodeDecl *TLCD) {
@@ -6350,12 +6369,13 @@
           if (!isObjC) {
             // Make this accessor @objc because its property is @objc.
             isObjC = ObjCReason::Accessor;
-          } else {
+          } else if (auto storageObjCAttr =
+                       storage->getAttrs().getAttribute<ObjCAttr>()) {
             // If @objc on the storage declaration was inferred using a
             // deprecated rule, but this accessor is @objc in its own right,
             // complain.
-            auto storageObjCAttr = storage->getAttrs().getAttribute<ObjCAttr>();
-            if (storageObjCAttr->isSwift3Inferred() &&
+            ;
+            if (storageObjCAttr && storageObjCAttr->isSwift3Inferred() &&
                 shouldDiagnoseObjCReason(*isObjC, Context)) {
               diagnose(storage, diag::accessor_swift3_objc_inference,
                        storage->getDescriptiveKind(), storage->getFullName(),
@@ -6629,7 +6649,10 @@
 
     // Destructors are always @objc, because their Objective-C entry point is
     // -dealloc.
-    markAsObjC(*this, DD, ObjCReason::ImplicitlyObjC);
+    if (Context.LangOpts.EnableObjCInterop)
+      markAsObjC(*this, DD, ObjCReason::ImplicitlyObjC);
+    else
+      DD->setIsObjC(false);
 
     break;
   }
@@ -8042,7 +8065,7 @@
   // default-initializable.
   if (isa<ClassDecl>(decl)) {
     // We need to look for a default constructor.
-    if (auto superTy = getSuperClassOf(decl->getDeclaredInterfaceType())) {
+    if (auto superTy = decl->getDeclaredInterfaceType()->getSuperclass()) {
       // If there are no default ctors for our supertype, we can't do anything.
       auto ctors = lookupConstructors(decl, superTy);
       if (!ctors)
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index c838e12..ad1d913 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -47,6 +47,26 @@
                 Results.end());
 }
 
+void LookupResult::shiftDownResults() {
+  // Remove inner results.
+  Results.erase(Results.begin(), Results.begin() + IndexOfFirstOuterResult);
+  IndexOfFirstOuterResult = 0;
+
+  if (Results.empty())
+    return;
+
+  // Compute IndexOfFirstOuterResult.
+  const DeclContext *dcInner = Results.front().getValueDecl()->getDeclContext();
+  for (auto &&result : Results) {
+    const DeclContext *dc = result.getValueDecl()->getDeclContext();
+    if (dc == dcInner ||
+        (dc->isModuleScopeContext() && dcInner->isModuleScopeContext()))
+      ++IndexOfFirstOuterResult;
+    else
+      break;
+  }
+}
+
 namespace {
   /// Builder that helps construct a lookup result from the raw lookup
   /// data.
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index f3c8185..dcff3cf 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -3115,7 +3115,7 @@
   for (auto candidate : candidates) {
     // Skip nested generic types.
     if (auto *genericDecl = dyn_cast<GenericTypeDecl>(candidate.Member))
-      if (genericDecl->getGenericParams())
+      if (genericDecl->isGeneric())
         continue;
 
     // Skip typealiases with an unbound generic type as their underlying type.
diff --git a/lib/Sema/TypeCheckRequests.cpp b/lib/Sema/TypeCheckRequests.cpp
index 079537c..70d76c8 100644
--- a/lib/Sema/TypeCheckRequests.cpp
+++ b/lib/Sema/TypeCheckRequests.cpp
@@ -148,9 +148,11 @@
 // Superclass computation.
 //----------------------------------------------------------------------------//
 Type SuperclassTypeRequest::operator()(Evaluator &evaluator,
-                                       ClassDecl *classDecl) const {
-  for (unsigned int idx : indices(classDecl->getInherited())) {
-    Type inheritedType = evaluator(InheritedTypeRequest{classDecl, idx});
+                                       NominalTypeDecl *nominalDecl) const {
+  assert(isa<ClassDecl>(nominalDecl) || isa<ProtocolDecl>(nominalDecl));
+
+  for (unsigned int idx : indices(nominalDecl->getInherited())) {
+    Type inheritedType = evaluator(InheritedTypeRequest{nominalDecl, idx});
     if (!inheritedType) continue;
 
     // If we found a class, return it.
@@ -181,28 +183,39 @@
 
 void SuperclassTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
   // FIXME: Improve this diagnostic.
-  auto classDecl = std::get<0>(getStorage());
-  std::string className = "'" + std::string(classDecl->getNameStr()) + "'";
-  diags.diagnose(classDecl, diag::circular_class_inheritance, className);
+  auto nominalDecl = std::get<0>(getStorage());
+  diags.diagnose(nominalDecl, diag::circular_class_inheritance,
+                 nominalDecl->getName());
 }
 
 void SuperclassTypeRequest::noteCycleStep(DiagnosticEngine &diags) const {
-  auto classDecl = std::get<0>(getStorage());
+  auto nominalDecl = std::get<0>(getStorage());
   // FIXME: Customize this further.
-  diags.diagnose(classDecl, diag::circular_reference_through);
+  diags.diagnose(nominalDecl, diag::circular_reference_through);
 }
 
 Optional<Type> SuperclassTypeRequest::getCachedResult() const {
-  auto classDecl = std::get<0>(getStorage());
-  if (classDecl->LazySemanticInfo.Superclass.getInt())
-    return classDecl->LazySemanticInfo.Superclass.getPointer();
+  auto nominalDecl = std::get<0>(getStorage());
+
+  if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
+    if (classDecl->LazySemanticInfo.Superclass.getInt())
+      return classDecl->LazySemanticInfo.Superclass.getPointer();
+
+  if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
+    if (protocolDecl->LazySemanticInfo.Superclass.getInt())
+      return protocolDecl->LazySemanticInfo.Superclass.getPointer();
 
   return None;
 }
 
 void SuperclassTypeRequest::cacheResult(Type value) const {
-  auto classDecl = std::get<0>(getStorage());
-  classDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
+  auto nominalDecl = std::get<0>(getStorage());
+
+  if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
+    classDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
+
+  if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
+    protocolDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
 }
 
 //----------------------------------------------------------------------------//
@@ -231,8 +244,7 @@
 void EnumRawTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
   // FIXME: Improve this diagnostic.
   auto enumDecl = std::get<0>(getStorage());
-  std::string className = "'" + std::string(enumDecl->getNameStr()) + "'";
-  diags.diagnose(enumDecl, diag::circular_enum_inheritance, className);
+  diags.diagnose(enumDecl, diag::circular_enum_inheritance, enumDecl->getName());
 }
 
 void EnumRawTypeRequest::noteCycleStep(DiagnosticEngine &diags) const {
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 6e34e24..58b4762 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
@@ -948,7 +948,7 @@
 
       // If the previous case fellthrough, similarly check that that case's bindings
       // includes our first label item's pattern bindings and types.
-      if (PreviousFallthrough) {
+      if (PreviousFallthrough && previousBlock) {
         auto firstPattern = caseBlock->getCaseLabelItems()[0].getPattern();
         SmallVector<VarDecl *, 4> Vars;
         firstPattern->collectVariables(Vars);
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 4045d5a..cbfa4eb 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -954,7 +954,7 @@
         auto decl = parentType->getAnyNominal();
         if (decl) {
           tc.diagnose(decl->getLoc(), diag::circular_class_inheritance,
-                      decl->getNameStr());
+                      decl->getName());
           return ErrorType::get(tc.Context);
         }
       }
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index e2b70ed..b38b88d 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -148,6 +148,11 @@
   /// Filter out any results that aren't accepted by the given predicate.
   void
   filter(llvm::function_ref<bool(LookupResultEntry, /*isOuter*/ bool)> pred);
+
+  /// Shift down results by dropping inner results while keeping outer
+  /// results (if any), the innermost of which are recogized as inner
+  /// results afterwards.
+  void shiftDownResults();
 };
 
 /// An individual result of a name lookup for a type.
@@ -1542,6 +1547,9 @@
   /// Get the superclass of the given class.
   Type getSuperclass(const ClassDecl *classDecl) override;
 
+  /// Get the superclass of the given protocol.
+  Type getSuperclass(const ProtocolDecl *protocolDecl) override;
+
   /// Get the raw type of the given enum.
   Type getRawType(EnumDecl *enumDecl) override;
 
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 45967a7..b7eadfe 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -129,17 +129,6 @@
 const char ExtensionError::ID = '\0';
 void ExtensionError::anchor() {}
 
-LLVM_NODISCARD
-static std::unique_ptr<llvm::ErrorInfoBase> takeErrorInfo(llvm::Error error) {
-  std::unique_ptr<llvm::ErrorInfoBase> result;
-  llvm::handleAllErrors(std::move(error),
-                        [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
-    result = std::move(info);
-  });
-  return result;
-}
-
-
 /// Skips a single record in the bitstream.
 ///
 /// Returns true if the next entry is a record of type \p recordKind.
@@ -2692,13 +2681,14 @@
     IdentifierID nameID;
     DeclContextID contextID;
     bool isImplicit;
+    bool isObjC;
     GenericEnvironmentID genericEnvID;
     uint8_t rawAccessLevel;
     unsigned numConformances;
     ArrayRef<uint64_t> rawInheritedIDs;
 
     decls_block::StructLayout::readRecord(scratch, nameID, contextID,
-                                          isImplicit, genericEnvID,
+                                          isImplicit, isObjC, genericEnvID,
                                           rawAccessLevel,
                                           numConformances,
                                           rawInheritedIDs);
@@ -2728,6 +2718,7 @@
 
     if (isImplicit)
       theStruct->setImplicit();
+    theStruct->setIsObjC(isObjC);
 
     theStruct->computeType();
 
@@ -2867,6 +2858,7 @@
 
     if (isImplicit)
       ctor->setImplicit();
+    ctor->setIsObjC(isObjC);
     if (hasStubImplementation)
       ctor->setStubImplementation(true);
     if (initKind.hasValue())
@@ -2999,6 +2991,7 @@
 
     if (isImplicit)
       var->setImplicit();
+    var->setIsObjC(isObjC);
 
     if (auto overriddenVar = cast_or_null<VarDecl>(overridden.get())) {
       var->setOverriddenDecl(overriddenVar);
@@ -3269,6 +3262,7 @@
     fn->setStatic(isStatic);
     if (isImplicit)
       fn->setImplicit();
+    fn->setIsObjC(isObjC);
     fn->setDynamicSelf(hasDynamicSelf);
     fn->setForcedStaticDispatch(hasForcedStaticDispatch);
     fn->setNeedsNewVTableEntry(needsNewVTableEntry);
@@ -3347,14 +3341,15 @@
     DeclContextID contextID;
     bool isImplicit, isClassBounded, isObjC, existentialTypeSupported;
     GenericEnvironmentID genericEnvID;
+    TypeID superclassID;
     uint8_t rawAccessLevel;
     ArrayRef<uint64_t> rawInheritedIDs;
 
     decls_block::ProtocolLayout::readRecord(scratch, nameID, contextID,
                                             isImplicit, isClassBounded, isObjC,
                                             existentialTypeSupported,
-                                            genericEnvID, rawAccessLevel,
-                                            rawInheritedIDs);
+                                            genericEnvID, superclassID,
+                                            rawAccessLevel, rawInheritedIDs);
 
     auto DC = getDeclContext(contextID);
     if (declOrOffset.isComplete())
@@ -3365,6 +3360,7 @@
                                           /*TrailingWhere=*/nullptr);
     declOrOffset = proto;
 
+    proto->setSuperclass(getType(superclassID));
     proto->setRequiresClass(isClassBounded);
     proto->setExistentialTypeSupported(existentialTypeSupported);
 
@@ -3385,6 +3381,8 @@
 
     if (isImplicit)
       proto->setImplicit();
+    proto->setIsObjC(isObjC);
+
     proto->computeType();
 
     proto->setCircularityCheck(CircularityCheck::Checked);
@@ -3566,6 +3564,7 @@
     theClass->setAddedImplicitInitializers();
     if (isImplicit)
       theClass->setImplicit();
+    theClass->setIsObjC(isObjC);
     theClass->setSuperclass(getType(superclassID));
     if (requiresStoredPropertyInits)
       theClass->setRequiresStoredPropertyInits(true);
@@ -3592,6 +3591,7 @@
     IdentifierID nameID;
     DeclContextID contextID;
     bool isImplicit;
+    bool isObjC;
     GenericEnvironmentID genericEnvID;
     TypeID rawTypeID;
     uint8_t rawAccessLevel;
@@ -3599,8 +3599,8 @@
     ArrayRef<uint64_t> rawInheritedAndDependencyIDs;
 
     decls_block::EnumLayout::readRecord(scratch, nameID, contextID,
-                                        isImplicit, genericEnvID, rawTypeID,
-                                        rawAccessLevel,
+                                        isImplicit, isObjC, genericEnvID,
+                                        rawTypeID, rawAccessLevel,
                                         numConformances, numInheritedTypes,
                                         rawInheritedAndDependencyIDs);
 
@@ -3638,6 +3638,8 @@
 
     if (isImplicit)
       theEnum->setImplicit();
+    theEnum->setIsObjC(isObjC);
+
     theEnum->setRawType(getType(rawTypeID));
 
     theEnum->computeType();
@@ -3830,6 +3832,7 @@
 
     if (isImplicit)
       subscript->setImplicit();
+    subscript->setIsObjC(isObjC);
     if (auto overriddenSub = cast_or_null<SubscriptDecl>(overridden.get())) {
       subscript->setOverriddenDecl(overriddenSub);
       AddAttribute(new (ctx) OverrideAttr(SourceLoc()));
@@ -3951,6 +3954,7 @@
 
     if (isImplicit)
       dtor->setImplicit();
+    dtor->setIsObjC(isObjC);
 
     break;
   }
@@ -4756,27 +4760,42 @@
     }
 
     auto processParameter = [&](TypeID typeID, uint64_t rawConvention)
-                                  -> Optional<SILParameterInfo> {
+                                  -> llvm::Expected<SILParameterInfo> {
       auto convention = getActualParameterConvention(rawConvention);
-      auto type = getType(typeID);
-      if (!convention || !type) return None;
-      return SILParameterInfo(type->getCanonicalType(), *convention);
+      if (!convention) {
+        error();
+        llvm_unreachable("an error is a fatal exit at this point");
+      }
+      auto type = getTypeChecked(typeID);
+      if (!type)
+        return type.takeError();
+      return SILParameterInfo(type.get()->getCanonicalType(), *convention);
     };
 
     auto processYield = [&](TypeID typeID, uint64_t rawConvention)
-                                  -> Optional<SILYieldInfo> {
+                                  -> llvm::Expected<SILYieldInfo> {
       auto convention = getActualParameterConvention(rawConvention);
-      auto type = getType(typeID);
-      if (!convention || !type) return None;
-      return SILYieldInfo(type->getCanonicalType(), *convention);
+      if (!convention) {
+        error();
+        llvm_unreachable("an error is a fatal exit at this point");
+      }
+      auto type = getTypeChecked(typeID);
+      if (!type)
+        return type.takeError();
+      return SILYieldInfo(type.get()->getCanonicalType(), *convention);
     };
 
     auto processResult = [&](TypeID typeID, uint64_t rawConvention)
-                               -> Optional<SILResultInfo> {
+                               -> llvm::Expected<SILResultInfo> {
       auto convention = getActualResultConvention(rawConvention);
-      auto type = getType(typeID);
-      if (!convention || !type) return None;
-      return SILResultInfo(type->getCanonicalType(), *convention);
+      if (!convention) {
+        error();
+        llvm_unreachable("an error is a fatal exit at this point");
+      }
+      auto type = getTypeChecked(typeID);
+      if (!type)
+        return type.takeError();
+      return SILResultInfo(type.get()->getCanonicalType(), *convention);
     };
 
     // Bounds check.  FIXME: overflow
@@ -4795,11 +4814,9 @@
       auto typeID = variableData[nextVariableDataIndex++];
       auto rawConvention = variableData[nextVariableDataIndex++];
       auto param = processParameter(typeID, rawConvention);
-      if (!param) {
-        error();
-        return nullptr;
-      }
-      allParams.push_back(*param);
+      if (!param)
+        return param.takeError();
+      allParams.push_back(param.get());
     }
 
     // Process the yields.
@@ -4809,11 +4826,9 @@
       auto typeID = variableData[nextVariableDataIndex++];
       auto rawConvention = variableData[nextVariableDataIndex++];
       auto yield = processYield(typeID, rawConvention);
-      if (!yield) {
-        error();
-        return nullptr;
-      }
-      allYields.push_back(*yield);
+      if (!yield)
+        return yield.takeError();
+      allYields.push_back(yield.get());
     }
 
     // Process the results.
@@ -4823,11 +4838,9 @@
       auto typeID = variableData[nextVariableDataIndex++];
       auto rawConvention = variableData[nextVariableDataIndex++];
       auto result = processResult(typeID, rawConvention);
-      if (!result) {
-        error();
-        return nullptr;
-      }
-      allResults.push_back(*result);
+      if (!result)
+        return result.takeError();
+      allResults.push_back(result.get());
     }
 
     // Process the error result.
@@ -4835,11 +4848,10 @@
     if (hasErrorResult) {
       auto typeID = variableData[nextVariableDataIndex++];
       auto rawConvention = variableData[nextVariableDataIndex++];
-      errorResult = processResult(typeID, rawConvention);
-      if (!errorResult) {
-        error();
-        return nullptr;
-      }
+      auto maybeErrorResult = processResult(typeID, rawConvention);
+      if (!maybeErrorResult)
+        return maybeErrorResult.takeError();
+      errorResult = maybeErrorResult.get();
     }
 
     Optional<ProtocolConformanceRef> witnessMethodConformance;
diff --git a/lib/Serialization/DeserializationErrors.h b/lib/Serialization/DeserializationErrors.h
index 1722e9f..2d3b8f9 100644
--- a/lib/Serialization/DeserializationErrors.h
+++ b/lib/Serialization/DeserializationErrors.h
@@ -355,6 +355,41 @@
   }
 };
 
+class SILEntityError : public llvm::ErrorInfo<SILEntityError> {
+  friend ErrorInfo;
+  static const char ID;
+  void anchor() override;
+
+  std::unique_ptr<ErrorInfoBase> underlyingReason;
+  StringRef name;
+public:
+  SILEntityError(StringRef name, std::unique_ptr<ErrorInfoBase> reason)
+      : underlyingReason(std::move(reason)), name(name) {}
+
+  void log(raw_ostream &OS) const override {
+    OS << "could not deserialize SIL entity '" << name << "'";
+    if (underlyingReason) {
+      OS << ": ";
+      underlyingReason->log(OS);
+    }
+  }
+
+  std::error_code convertToErrorCode() const override {
+    return llvm::inconvertibleErrorCode();
+  }
+};
+
+LLVM_NODISCARD
+static inline std::unique_ptr<llvm::ErrorInfoBase>
+takeErrorInfo(llvm::Error error) {
+  std::unique_ptr<llvm::ErrorInfoBase> result;
+  llvm::handleAllErrors(std::move(error),
+                        [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
+    result = std::move(info);
+  });
+  return result;
+}
+
 class PrettyStackTraceModuleFile : public llvm::PrettyStackTraceEntry {
   const char *Action;
   const ModuleFile &MF;
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index b372abd..bd6b9af 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -12,13 +12,16 @@
 
 #define DEBUG_TYPE "deserialize"
 #include "DeserializeSIL.h"
+
+#include "DeserializationErrors.h"
+#include "SILFormat.h"
+
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/PrettyStackTrace.h"
 #include "swift/AST/GenericSignature.h"
 #include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/PrettyStackTrace.h"
 #include "swift/Serialization/ModuleFile.h"
-#include "SILFormat.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILBuilder.h"
 #include "swift/SIL/SILDebugScope.h"
@@ -38,6 +41,9 @@
 using namespace swift::serialization::sil_block;
 using namespace llvm::support;
 
+const char SILEntityError::ID = '\0';
+void SILEntityError::anchor() {}
+
 STATISTIC(NumDeserializedFunc, "Number of deserialized SIL functions");
 
 static Optional<StringLiteralInst::Encoding>
@@ -339,7 +345,14 @@
     // Otherwise, look for a function with this name in the module.
     auto iter = FuncTable->find(name);
     if (iter != FuncTable->end()) {
-      fn = readSILFunction(*iter, nullptr, name, /*declarationOnly*/ true);
+      auto maybeFn = readSILFunctionChecked(*iter, nullptr, name,
+                                            /*declarationOnly*/ true);
+      if (maybeFn) {
+        fn = maybeFn.get();
+      } else {
+        // Ignore the failure; we'll synthesize a bogus function instead.
+        llvm::consumeError(maybeFn.takeError());
+      }
     }
   }
 
@@ -362,7 +375,15 @@
   if (iter == FuncTable->end())
     return nullptr;
 
-  return readSILFunction(*iter, nullptr, name, /*declarationOnly*/ true);
+  auto maybeFn = readSILFunctionChecked(*iter, nullptr, name,
+                                        /*declarationOnly*/ true);
+  if (!maybeFn) {
+    // Ignore the failure and just pretend the function doesn't exist
+    llvm::consumeError(maybeFn.takeError());
+    return nullptr;
+  }
+
+  return maybeFn.get();
 }
 
 /// Helper function to find a SILGlobalVariable given its name. It first checks
@@ -386,6 +407,19 @@
                                               StringRef name,
                                               bool declarationOnly,
                                               bool errorIfEmptyBody) {
+  llvm::Expected<SILFunction *> deserialized =
+      readSILFunctionChecked(FID, existingFn, name, declarationOnly,
+                             errorIfEmptyBody);
+  if (!deserialized) {
+    MF->fatal(deserialized.takeError());
+  }
+  return deserialized.get();
+}
+
+llvm::Expected<SILFunction *>
+SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
+                                        StringRef name, bool declarationOnly,
+                                        bool errorIfEmptyBody) {
   // We can't deserialize function bodies after IRGen lowering passes have
   // happened since other definitions in the module will no longer be in
   // canonical SIL form.
@@ -444,7 +478,16 @@
     MF->error();
     return nullptr;
   }
-  auto ty = getSILType(MF->getType(funcTyID), SILValueCategory::Object);
+  auto astType = MF->getTypeChecked(funcTyID);
+  if (!astType) {
+    if (!existingFn || errorIfEmptyBody) {
+      return llvm::make_error<SILEntityError>(
+          name, takeErrorInfo(astType.takeError()));
+    }
+    llvm::consumeError(astType.takeError());
+    return existingFn;
+  }
+  auto ty = getSILType(astType.get(), SILValueCategory::Object);
   if (!ty.is<SILFunctionType>()) {
     DEBUG(llvm::dbgs() << "not a function type for SILFunction\n");
     MF->error();
@@ -2396,14 +2439,21 @@
   if (iter == FuncTable->end())
     return nullptr;
 
-  auto Func = readSILFunction(*iter, InFunc, name, /*declarationOnly*/ false);
-  if (Func) {
-    DEBUG(llvm::dbgs() << "Deserialize SIL:\n";
-          Func->dump());
-    assert(InFunc->getName() == Func->getName());
+  auto maybeFunc = readSILFunctionChecked(*iter, InFunc, name,
+                                          /*declarationOnly*/ false);
+  if (!maybeFunc) {
+    // Ignore the error; treat it as if we didn't have a definition.
+    llvm::consumeError(maybeFunc.takeError());
+    return nullptr;
   }
 
-  return Func;
+  if (maybeFunc.get()) {
+    DEBUG(llvm::dbgs() << "Deserialize SIL:\n";
+          maybeFunc.get()->dump());
+    assert(InFunc->getName() == maybeFunc.get()->getName());
+  }
+
+  return maybeFunc.get();
 }
 
 /// Check for existence of a function with a given name and required linkage.
@@ -2480,11 +2530,20 @@
   if (iter == FuncTable->end())
     return nullptr;
 
-  auto Func = readSILFunction(*iter, nullptr, name, declarationOnly);
-  if (Func)
+  auto maybeFunc = readSILFunctionChecked(*iter, nullptr, name,
+                                          declarationOnly);
+
+  if (!maybeFunc) {
+    // Ignore the error; treat it as if we didn't have a definition.
+    llvm::consumeError(maybeFunc.takeError());
+    return nullptr;
+  }
+
+  if (maybeFunc.get()) {
     DEBUG(llvm::dbgs() << "Deserialize SIL:\n";
-          Func->dump());
-  return Func;
+          maybeFunc.get()->dump());
+  }
+  return maybeFunc.get();
 }
 
 SILGlobalVariable *SILDeserializer::readGlobalVar(StringRef Name) {
@@ -2580,8 +2639,12 @@
     auto DI = FuncTable->find(*KI);
     assert(DI != FuncTable->end() && "There should never be a key without data.");
 
-    readSILFunction(*DI, nullptr, *KI, false,
-                    false/*errorIfEmptyBody*/);
+    auto maybeFunc = readSILFunctionChecked(*DI, nullptr, *KI, false,
+                                            false/*errorIfEmptyBody*/);
+    if (!maybeFunc) {
+      // Ignore the error; treat it as if we didn't have a definition.
+      llvm::consumeError(maybeFunc.takeError());
+    }
   }
 }
 
diff --git a/lib/Serialization/DeserializeSIL.h b/lib/Serialization/DeserializeSIL.h
index 2a17168..5eb5ce3 100644
--- a/lib/Serialization/DeserializeSIL.h
+++ b/lib/Serialization/DeserializeSIL.h
@@ -81,6 +81,12 @@
     SILFunction *readSILFunction(serialization::DeclID, SILFunction *InFunc,
                                  StringRef Name, bool declarationOnly,
                                  bool errorIfEmptyBody = true);
+    /// Read a SIL function.
+    llvm::Expected<SILFunction *>
+    readSILFunctionChecked(serialization::DeclID, SILFunction *InFunc,
+                           StringRef Name, bool declarationOnly,
+                           bool errorIfEmptyBody = true);
+
     /// Read a SIL basic block within a given SIL function.
     SILBasicBlock *readSILBasicBlock(SILFunction *Fn,
                                      SILBasicBlock *Prev,
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 5d608cb..a48e467 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -2952,6 +2952,7 @@
                              addDeclBaseNameRef(theStruct->getName()),
                              contextID,
                              theStruct->isImplicit(),
+                             theStruct->isObjC(),
                              addGenericEnvironmentRef(
                                             theStruct->getGenericEnvironment()),
                              rawAccessLevel,
@@ -3002,6 +3003,7 @@
                             addDeclBaseNameRef(theEnum->getName()),
                             contextID,
                             theEnum->isImplicit(),
+                            theEnum->isObjC(),
                             addGenericEnvironmentRef(
                                              theEnum->getGenericEnvironment()),
                             addTypeRef(theEnum->getRawType()),
@@ -3084,6 +3086,7 @@
                                  /*resolver=*/nullptr),
                                addGenericEnvironmentRef(
                                                 proto->getGenericEnvironment()),
+                               addTypeRef(proto->getSuperclass()),
                                rawAccessLevel,
                                inherited);
 
diff --git a/stdlib/private/StdlibUnittest/MinimalTypes.swift b/stdlib/private/StdlibUnittest/MinimalTypes.swift
index ad03648..e538e19 100644
--- a/stdlib/private/StdlibUnittest/MinimalTypes.swift
+++ b/stdlib/private/StdlibUnittest/MinimalTypes.swift
@@ -220,7 +220,7 @@
     fatalError("GenericMinimalHashableValue_equalImpl is not set yet")
   })
 public var GenericMinimalHashableValue_hashIntoImpl =
-  ResettableValue<(Any, inout Hasher) -> Void>({ _ in
+  ResettableValue<(Any, inout Hasher) -> Void>({ (_,_) in
     fatalError("GenericMinimalHashableValue_hashIntoImpl is not set yet")
   })
 
@@ -276,7 +276,7 @@
     fatalError("GenericMinimalHashableClass_equalImpl is not set yet")
   })
 public var GenericMinimalHashableClass_hashIntoImpl =
-  ResettableValue<(Any, inout Hasher) -> Void>({ _ in
+  ResettableValue<(Any, inout Hasher) -> Void>({ (_,_) in
     fatalError("GenericMinimalHashableClass_hashIntoImpl is not set yet")
   })
 
diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift b/stdlib/private/StdlibUnittest/StdlibUnittest.swift
index 99798f3..4d9ca53 100644
--- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift
+++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift
@@ -1775,15 +1775,15 @@
 }
 
 func _getOSVersion() -> OSVersion {
-#if os(iOS) && (arch(i386) || arch(x86_64))
+#if os(iOS) && targetEnvironment(simulator)
   // On simulator, the plist file that we try to read turns out to be host's
   // plist file, which indicates OS X.
   //
   // FIXME: how to get the simulator version *without* UIKit?
   return .iOSSimulator
-#elseif os(tvOS) && (arch(i386) || arch(x86_64))
+#elseif os(tvOS) && targetEnvironment(simulator)
   return .tvOSSimulator
-#elseif os(watchOS) && (arch(i386) || arch(x86_64))
+#elseif os(watchOS) && targetEnvironment(simulator)
   return .watchOSSimulator
 #elseif os(Linux)
   return .linux
diff --git a/stdlib/public/SDK/AppKit/AppKit.swift b/stdlib/public/SDK/AppKit/AppKit.swift
index ffb9f7d..a716201 100644
--- a/stdlib/public/SDK/AppKit/AppKit.swift
+++ b/stdlib/public/SDK/AppKit/AppKit.swift
@@ -13,7 +13,7 @@
 import Foundation
 @_exported import AppKit
 
-extension NSCursor : _DefaultCustomPlaygroundQuickLookable {
+extension NSCursor : __DefaultCustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "NSCursor._defaultCustomPlaygroundQuickLook will be removed in a future Swift version")
   public var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook {
     return .image(image)
@@ -24,7 +24,7 @@
   static var views = Set<NSView>()
 }
 
-extension NSView : _DefaultCustomPlaygroundQuickLookable {
+extension NSView : __DefaultCustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "NSView._defaultCustomPlaygroundQuickLook will be removed in a future Swift version")
   public var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook {
     // if you set NSView.needsDisplay, you can get yourself in a recursive scenario where the same view
diff --git a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
index 1ce4f6b..69623cd 100644
--- a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
+++ b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
@@ -228,11 +228,13 @@
   }
 }
 
-extension CGPoint : CustomReflectable, CustomPlaygroundQuickLookable {
+extension CGPoint : CustomReflectable {
   public var customMirror: Mirror {
     return Mirror(self, children: ["x": x, "y": y], displayStyle: .`struct`)
   }
+}
 
+extension CGPoint : _CustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "CGPoint.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .point(Double(x), Double(y))
@@ -293,14 +295,16 @@
   }
 }
 
-extension CGSize : CustomReflectable, CustomPlaygroundQuickLookable {
+extension CGSize : CustomReflectable {
   public var customMirror: Mirror {
     return Mirror(
       self,
       children: ["width": width, "height": height],
       displayStyle: .`struct`)
   }
+}
 
+extension CGSize : _CustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "CGSize.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .size(Double(width), Double(height))
@@ -431,14 +435,16 @@
   public var y: CGFloat { return minY }
 }
 
-extension CGRect : CustomReflectable, CustomPlaygroundQuickLookable {
+extension CGRect : CustomReflectable {
   public var customMirror: Mirror {
     return Mirror(
       self,
       children: ["origin": origin, "size": size],
       displayStyle: .`struct`)
   }
+}
 
+extension CGRect : _CustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "CGRect.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .rectangle(
diff --git a/stdlib/public/SDK/Foundation/Date.swift b/stdlib/public/SDK/Foundation/Date.swift
index 967b158..7231a6d 100644
--- a/stdlib/public/SDK/Foundation/Date.swift
+++ b/stdlib/public/SDK/Foundation/Date.swift
@@ -272,7 +272,7 @@
     }
 }
 
-extension Date : CustomPlaygroundQuickLookable {
+extension Date : _CustomPlaygroundQuickLookable {
     var summary: String {
         let df = DateFormatter()
         df.dateStyle = .medium
diff --git a/stdlib/public/SDK/Foundation/NSCoder.swift b/stdlib/public/SDK/Foundation/NSCoder.swift
index 0086f9f..8c57d1a 100644
--- a/stdlib/public/SDK/Foundation/NSCoder.swift
+++ b/stdlib/public/SDK/Foundation/NSCoder.swift
@@ -172,7 +172,7 @@
   @available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
   public static func unarchivedObject<DecodedObjectType>(ofClass cls: DecodedObjectType.Type, from data: Data) throws -> DecodedObjectType? where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
     var error: NSError?
-    let result = __NSKeyedUnarchiverSecureUnarchiveObjectOfClass(cls as! AnyClass, data, &error)
+    let result = __NSKeyedUnarchiverSecureUnarchiveObjectOfClass(cls as AnyClass, data, &error)
     try resolveError(error)
     return result as? DecodedObjectType
   }
diff --git a/stdlib/public/SDK/Foundation/NSDate.swift b/stdlib/public/SDK/Foundation/NSDate.swift
index 4896e9d..2c4a0be 100644
--- a/stdlib/public/SDK/Foundation/NSDate.swift
+++ b/stdlib/public/SDK/Foundation/NSDate.swift
@@ -12,7 +12,7 @@
 
 @_exported import Foundation // Clang module
 
-extension NSDate : CustomPlaygroundQuickLookable {
+extension NSDate : _CustomPlaygroundQuickLookable {
   @nonobjc
   var summary: String {
     let df = DateFormatter()
diff --git a/stdlib/public/SDK/Foundation/NSRange.swift b/stdlib/public/SDK/Foundation/NSRange.swift
index 85228fc..f4943c0 100644
--- a/stdlib/public/SDK/Foundation/NSRange.swift
+++ b/stdlib/public/SDK/Foundation/NSRange.swift
@@ -197,7 +197,7 @@
     }
 }
 
-extension NSRange : CustomPlaygroundQuickLookable {
+extension NSRange : _CustomPlaygroundQuickLookable {
     @available(*, deprecated, message: "NSRange.customPlaygroundQuickLook will be removed in a future Swift version")
     public var customPlaygroundQuickLook: PlaygroundQuickLook {
         return .range(Int64(location), Int64(length))
diff --git a/stdlib/public/SDK/Foundation/NSString.swift b/stdlib/public/SDK/Foundation/NSString.swift
index d04e178..9bff141 100644
--- a/stdlib/public/SDK/Foundation/NSString.swift
+++ b/stdlib/public/SDK/Foundation/NSString.swift
@@ -107,7 +107,7 @@
   }
 }
 
-extension NSString : CustomPlaygroundQuickLookable {
+extension NSString : _CustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "NSString.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     return .text(self as String)
diff --git a/stdlib/public/SDK/Foundation/NSURL.swift b/stdlib/public/SDK/Foundation/NSURL.swift
index 6cf6522..6dacb8b 100644
--- a/stdlib/public/SDK/Foundation/NSURL.swift
+++ b/stdlib/public/SDK/Foundation/NSURL.swift
@@ -12,7 +12,7 @@
 
 @_exported import Foundation // Clang module
 
-extension NSURL : CustomPlaygroundQuickLookable {
+extension NSURL : _CustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "NSURL.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     guard let str = absoluteString else { return .text("Unknown URL") }
diff --git a/stdlib/public/SDK/Foundation/URL.swift b/stdlib/public/SDK/Foundation/URL.swift
index f176a9f..63a1731 100644
--- a/stdlib/public/SDK/Foundation/URL.swift
+++ b/stdlib/public/SDK/Foundation/URL.swift
@@ -1210,7 +1210,7 @@
     }
 }
 
-extension URL : CustomPlaygroundQuickLookable {
+extension URL : _CustomPlaygroundQuickLookable {
     @available(*, deprecated, message: "URL.customPlaygroundQuickLook will be removed in a future Swift version")
     public var customPlaygroundQuickLook: PlaygroundQuickLook {
         return .url(absoluteString)
diff --git a/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb b/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
index 5a0893b..69a7aeb 100644
--- a/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
+++ b/stdlib/public/SDK/SpriteKit/SpriteKitQuickLooks.swift.gyb
@@ -14,7 +14,7 @@
 
 % for Self in ['SKShapeNode', 'SKSpriteNode', 'SKTextureAtlas', 'SKTexture']:
 
-extension ${Self} : CustomPlaygroundQuickLookable {
+extension ${Self} : _CustomPlaygroundQuickLookable {
   @available(*, deprecated, message: "${Self}.customPlaygroundQuickLook will be removed in a future Swift version")
   public var customPlaygroundQuickLook: PlaygroundQuickLook {
     let data = (self as AnyObject)._copyImageData?() as Data?
diff --git a/stdlib/public/SwiftOnoneSupport/CMakeLists.txt b/stdlib/public/SwiftOnoneSupport/CMakeLists.txt
index 018b02b..0cfd611 100644
--- a/stdlib/public/SwiftOnoneSupport/CMakeLists.txt
+++ b/stdlib/public/SwiftOnoneSupport/CMakeLists.txt
@@ -2,6 +2,10 @@
   # This file should be listed the first.  Module name is inferred from the
   # filename.
   SwiftOnoneSupport.swift
-  SWIFT_COMPILE_FLAGS "-parse-stdlib" "-Xllvm" "-sil-inline-generics=false" "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
+  # We have to disable validation of TBD files, because this module is
+  # _explicitly_ special-cased to result in extra symbols generated by the
+  # optimizer, meaning TBDGen can't (and shouldn't: it has to run
+  # pre-optimization for performance) list them.
+  SWIFT_COMPILE_FLAGS "-parse-stdlib" "-Xllvm" "-sil-inline-generics=false" "-Xfrontend" "-validate-tbd-against-ir=none" "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   INSTALL_IN_COMPONENT stdlib)
diff --git a/stdlib/public/core/Algorithm.swift b/stdlib/public/core/Algorithm.swift
index df836fe..72bf086 100644
--- a/stdlib/public/core/Algorithm.swift
+++ b/stdlib/public/core/Algorithm.swift
@@ -158,6 +158,3 @@
     return Iterator(_base: _base.makeIterator())
   }
 }
-
-@available(*, deprecated: 4.2, renamed: "EnumeratedSequence.Iterator")
-public typealias EnumeratedIterator<T: Sequence> = EnumeratedSequence<T>.Iterator
diff --git a/stdlib/public/core/BidirectionalCollection.swift b/stdlib/public/core/BidirectionalCollection.swift
index 3665c56..b2c83bc 100644
--- a/stdlib/public/core/BidirectionalCollection.swift
+++ b/stdlib/public/core/BidirectionalCollection.swift
@@ -10,15 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-/// A type that provides subscript access to its elements, with bidirectional
-/// index traversal.
-///
-/// In most cases, it's best to ignore this protocol and use the
-/// `BidirectionalCollection` protocol instead, because it has a more complete
-/// interface.
-@available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'BidirectionalCollection' instead")
-public typealias BidirectionalIndexable = BidirectionalCollection
-
 /// A collection that supports backward as well as forward traversal.
 ///
 /// Bidirectional collections offer traversal backward from any valid index,
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 41545b5..e17f92a 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -73,7 +73,6 @@
   Hashing.swift
   HeapBuffer.swift
   ICU.swift
-  ImplicitlyUnwrappedOptional.swift
   Indices.swift
   InputStream.swift
   IntegerParsing.swift
@@ -123,7 +122,6 @@
   Sort.swift.gyb
   StaticString.swift
   Stride.swift.gyb
-  StringCharacterView.swift # ORDER DEPENDENCY: Must precede String.swift
   StringHashable.swift  # ORDER DEPENDENCY: Must precede String.swift
   String.swift
   StringBridge.swift
@@ -168,6 +166,7 @@
   StringGraphemeBreaking.swift # ORDER DEPENDENCY: Must follow UTF16.swift
   ValidUTF8Buffer.swift
   WriteBackMutableSlice.swift
+  MigrationSupport.swift
   )
 
 # The complete list of sources in the core standard library.  Includes
diff --git a/stdlib/public/core/ClosedRange.swift b/stdlib/public/core/ClosedRange.swift
index 7b4cf52..f7a80c0 100644
--- a/stdlib/public/core/ClosedRange.swift
+++ b/stdlib/public/core/ClosedRange.swift
@@ -459,16 +459,7 @@
   }
 }
 
-extension ClosedRange where Bound: Strideable, Bound.Stride : SignedInteger {
-  /// Now that Range is conditionally a collection when Bound: Strideable,
-  /// CountableRange is no longer needed. This is a deprecated initializer
-  /// for any remaining uses of Range(countableRange).
-  @available(*,deprecated: 4.2, 
-    message: "CountableRange is now Range. No need to convert any more.")
-  public init(_ other: ClosedRange<Bound>) {
-    self = other
-  }  
-  
+extension ClosedRange where Bound: Strideable, Bound.Stride : SignedInteger {  
   /// Creates an instance equivalent to the given `Range`.
   ///
   /// - Parameter other: A `Range` to convert to a `ClosedRange` instance.
@@ -495,8 +486,7 @@
   }
 }
 
-@available(*, deprecated, renamed: "ClosedRange.Index")
-public typealias ClosedRangeIndex<T> = ClosedRange<T>.Index where T: Strideable, T.Stride: SignedInteger
-
+// Note: this is not for compatibility only, it is considered a useful
+// shorthand. TODO: Add documentation
 public typealias CountableClosedRange<Bound: Strideable> = ClosedRange<Bound>
   where Bound.Stride : SignedInteger
diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift
index 879625c..df12f4b 100644
--- a/stdlib/public/core/Collection.swift
+++ b/stdlib/public/core/Collection.swift
@@ -10,22 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-/// A type that provides subscript access to its elements, with forward
-/// index traversal.
-///
-/// In most cases, it's best to ignore this protocol and use the `Collection`
-/// protocol instead, because it has a more complete interface.
-@available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'Collection' instead")
-public typealias IndexableBase = Collection
-
-/// A type that provides subscript access to its elements, with forward index
-/// traversal.
-///
-/// In most cases, it's best to ignore this protocol and use the `Collection`
-/// protocol instead, because it has a more complete interface.
-@available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'Collection' instead")
-public typealias Indexable = Collection
-
 /// A type that iterates over a collection using its indices.
 ///
 /// The `IndexingIterator` type is the default iterator for any collection that
@@ -349,6 +333,11 @@
 /// the number of contained elements, accessing its `count` property is an
 /// O(*n*) operation.
 public protocol Collection: Sequence where SubSequence: Collection {
+  // FIXME: ideally this would be in MigrationSupport.swift, but it needs
+  // to be on the protocol instead of as an extension
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
+  typealias IndexDistance = Int  
+
   // FIXME(ABI): Associated type inference requires this.
   associatedtype Element
 
@@ -826,9 +815,6 @@
   __consuming func randomElement<T: RandomNumberGenerator>(
     using generator: inout T
   ) -> Element?
-
-  @available(*, deprecated, message: "all index distances are now of type Int")
-  typealias IndexDistance = Int
 }
 
 /// Default implementation for forward collections.
@@ -1803,35 +1789,3 @@
     return try preprocess()
   }
 }
-
-extension Collection {
-  // FIXME: <rdar://problem/34142121>
-  // This typealias should be removed as it predates the source compatibility
-  // guarantees of Swift 3, but it cannot due to a bug.
-  @available(*, unavailable, renamed: "Iterator")
-  public typealias Generator = Iterator
-
-  @available(swift, deprecated: 3.2, renamed: "Element")
-  public typealias _Element = Element
-
-  @available(*, deprecated, message: "all index distances are now of type Int")
-  public func index<T: BinaryInteger>(_ i: Index, offsetBy n: T) -> Index {
-    return index(i, offsetBy: Int(n))
-  }
-  @available(*, deprecated, message: "all index distances are now of type Int")
-  public func formIndex<T: BinaryInteger>(_ i: inout Index, offsetBy n: T) {
-    return formIndex(&i, offsetBy: Int(n))
-  }
-  @available(*, deprecated, message: "all index distances are now of type Int")
-  public func index<T: BinaryInteger>(_ i: Index, offsetBy n: T, limitedBy limit: Index) -> Index? {
-    return index(i, offsetBy: Int(n), limitedBy: limit)
-  }
-  @available(*, deprecated, message: "all index distances are now of type Int")
-  public func formIndex<T: BinaryInteger>(_ i: inout Index, offsetBy n: T, limitedBy limit: Index) -> Bool {
-    return formIndex(&i, offsetBy: Int(n), limitedBy: limit)
-  }
-  @available(*, deprecated, message: "all index distances are now of type Int")
-  public func distance<T: BinaryInteger>(from start: Index, to end: Index) -> T {
-    return numericCast(distance(from: start, to: end) as Int)
-  }
-}
diff --git a/stdlib/public/core/CollectionOfOne.swift b/stdlib/public/core/CollectionOfOne.swift
index 2fd1ca4..575ff5f 100644
--- a/stdlib/public/core/CollectionOfOne.swift
+++ b/stdlib/public/core/CollectionOfOne.swift
@@ -170,6 +170,3 @@
     return Mirror(self, children: ["element": _element])
   }
 }
-
-@available(*,deprecated: 4.2,renamed: "CollectionOfOne.Iterator")
-public typealias IteratorOverOne<T> = CollectionOfOne<T>.Iterator
\ No newline at end of file
diff --git a/stdlib/public/core/CompilerProtocols.swift b/stdlib/public/core/CompilerProtocols.swift
index d49be2c..3bd0b9f 100644
--- a/stdlib/public/core/CompilerProtocols.swift
+++ b/stdlib/public/core/CompilerProtocols.swift
@@ -723,7 +723,7 @@
 ///
 /// The `ExpressibleByStringInterpolation` protocol is deprecated. Do not add
 /// new conformances to the protocol.
-@available(*, deprecated, message: "it will be replaced or redesigned in Swift 4.0.  Instead of conforming to 'ExpressibleByStringInterpolation', consider adding an 'init(_:String)'")
+@available(*, deprecated, message: "it will be replaced or redesigned in Swift 5.0.  Instead of conforming to 'ExpressibleByStringInterpolation', consider adding an 'init(_:String)'")
 public typealias ExpressibleByStringInterpolation = _ExpressibleByStringInterpolation
 public protocol _ExpressibleByStringInterpolation {
   /// Creates an instance by concatenating the given values.
@@ -773,18 +773,6 @@
   init(_colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float)
 }
 
-extension _ExpressibleByColorLiteral {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 4.0,
-    message: "This initializer is only meant to be used by color literals")
-  public init(
-    colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float
-  ) {
-    self.init(
-      _colorLiteralRed: red, green: green, blue: blue, alpha: alpha)
-  }
-}
-
 /// A type that can be initialized using an image literal (e.g.
 /// `#imageLiteral(resourceName: "hi.png")`).
 public protocol _ExpressibleByImageLiteral {
@@ -819,67 +807,3 @@
 /// then Array would no longer be a _DestructorSafeContainer.
 public protocol _DestructorSafeContainer {
 }
-
-// Deprecated by SE-0115.
-
-@available(*, deprecated, renamed: "ExpressibleByNilLiteral")
-public typealias NilLiteralConvertible
-  = ExpressibleByNilLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinIntegerLiteral")
-public typealias _BuiltinIntegerLiteralConvertible
-  = _ExpressibleByBuiltinIntegerLiteral
-@available(*, deprecated, renamed: "ExpressibleByIntegerLiteral")
-public typealias IntegerLiteralConvertible
-  = ExpressibleByIntegerLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinFloatLiteral")
-public typealias _BuiltinFloatLiteralConvertible
-  = _ExpressibleByBuiltinFloatLiteral
-@available(*, deprecated, renamed: "ExpressibleByFloatLiteral")
-public typealias FloatLiteralConvertible
-  = ExpressibleByFloatLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinBooleanLiteral")
-public typealias _BuiltinBooleanLiteralConvertible
-  = _ExpressibleByBuiltinBooleanLiteral
-@available(*, deprecated, renamed: "ExpressibleByBooleanLiteral")
-public typealias BooleanLiteralConvertible
-  = ExpressibleByBooleanLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinUnicodeScalarLiteral")
-public typealias _BuiltinUnicodeScalarLiteralConvertible
-  = _ExpressibleByBuiltinUnicodeScalarLiteral
-@available(*, deprecated, renamed: "ExpressibleByUnicodeScalarLiteral")
-public typealias UnicodeScalarLiteralConvertible
-  = ExpressibleByUnicodeScalarLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinExtendedGraphemeClusterLiteral")
-public typealias _BuiltinExtendedGraphemeClusterLiteralConvertible
-  = _ExpressibleByBuiltinExtendedGraphemeClusterLiteral
-@available(*, deprecated, renamed: "ExpressibleByExtendedGraphemeClusterLiteral")
-public typealias ExtendedGraphemeClusterLiteralConvertible
-  = ExpressibleByExtendedGraphemeClusterLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinStringLiteral")
-public typealias _BuiltinStringLiteralConvertible
-  = _ExpressibleByBuiltinStringLiteral
-@available(*, deprecated, renamed: "_ExpressibleByBuiltinUTF16StringLiteral")
-public typealias _BuiltinUTF16StringLiteralConvertible
-  = _ExpressibleByBuiltinUTF16StringLiteral
-@available(*, deprecated, renamed: "ExpressibleByStringLiteral")
-public typealias StringLiteralConvertible
-  = ExpressibleByStringLiteral
-@available(*, deprecated, renamed: "ExpressibleByArrayLiteral")
-public typealias ArrayLiteralConvertible
-  = ExpressibleByArrayLiteral
-@available(*, deprecated, renamed: "ExpressibleByDictionaryLiteral")
-public typealias DictionaryLiteralConvertible
-  = ExpressibleByDictionaryLiteral
-@available(*, deprecated, message: "it will be replaced or redesigned in Swift 4.0.  Instead of conforming to 'StringInterpolationConvertible', consider adding an 'init(_:String)'")
-public typealias StringInterpolationConvertible
-  = ExpressibleByStringInterpolation
-@available(*, deprecated, renamed: "_ExpressibleByColorLiteral")
-public typealias _ColorLiteralConvertible
-  = _ExpressibleByColorLiteral
-@available(*, deprecated, renamed: "_ExpressibleByImageLiteral")
-public typealias _ImageLiteralConvertible
-  = _ExpressibleByImageLiteral
-@available(*, deprecated, renamed: "_ExpressibleByFileReferenceLiteral")
-public typealias _FileReferenceLiteralConvertible
-  = _ExpressibleByFileReferenceLiteral
-
diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift
index 2a4bdb3..376f903 100644
--- a/stdlib/public/core/Dictionary.swift
+++ b/stdlib/public/core/Dictionary.swift
@@ -1153,53 +1153,6 @@
   }
 }
 
-// Maintain old `keys` and `values` types in Swift 3 mode.
-
-extension Dictionary {
-  /// A collection containing just the keys of the dictionary.
-  ///
-  /// When iterated over, keys appear in this collection in the same order as
-  /// they occur in the dictionary's key-value pairs. Each key in the keys
-  /// collection has a unique value.
-  ///
-  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
-  ///     print(countryCodes)
-  ///     // Prints "["BR": "Brazil", "JP": "Japan", "GH": "Ghana"]"
-  ///
-  ///     for k in countryCodes.keys {
-  ///         print(k)
-  ///     }
-  ///     // Prints "BR"
-  ///     // Prints "JP"
-  ///     // Prints "GH"
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4.0)
-  public var keys: LazyMapCollection<[Key: Value], Key> {
-    return self.lazy.map { $0.key }
-  }
-
-  /// A collection containing just the values of the dictionary.
-  ///
-  /// When iterated over, values appear in this collection in the same order as
-  /// they occur in the dictionary's key-value pairs.
-  ///
-  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
-  ///     print(countryCodes)
-  ///     // Prints "["BR": "Brazil", "JP": "Japan", "GH": "Ghana"]"
-  ///
-  ///     for v in countryCodes.values {
-  ///         print(v)
-  ///     }
-  ///     // Prints "Brazil"
-  ///     // Prints "Japan"
-  ///     // Prints "Ghana"
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4.0)
-  public var values: LazyMapCollection<[Key: Value], Value> {
-    return self.lazy.map { $0.value }
-  }
-}
-
 extension Dictionary {
   /// A collection containing just the keys of the dictionary.
   ///
@@ -4736,20 +4689,6 @@
     return remove(at: startIndex)
   }
 
-  @inlinable
-  @available(swift, obsoleted: 4.0)
-  public func filter(
-    _ isIncluded: (Element) throws -> Bool, obsoletedInSwift4: () = ()
-  ) rethrows -> [Element] {
-    var result: [Element] = []
-    for x in self {
-      if try isIncluded(x) {
-        result.append(x)
-      }
-    }
-    return result
-  }
-
   /// The total number of key-value pairs that the dictionary can contain without
   /// allocating new storage.
   @inlinable // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/DropWhile.swift b/stdlib/public/core/DropWhile.swift
index bc7538e..8c78847 100644
--- a/stdlib/public/core/DropWhile.swift
+++ b/stdlib/public/core/DropWhile.swift
@@ -256,10 +256,3 @@
   }
 }
 
-@available(*, deprecated, renamed: "LazyDropWhileSequence.Iterator")
-public typealias LazyDropWhileIterator<T> = LazyDropWhileSequence<T>.Iterator where T: Sequence
-@available(*, deprecated, renamed: "LazyDropWhileCollection.Index")
-public typealias LazyDropWhileIndex<T> = LazyDropWhileCollection<T>.Index where T: Collection
-@available(*, deprecated, renamed: "LazyDropWhileCollection")
-public typealias LazyDropWhileBidirectionalCollection<T> = LazyDropWhileCollection<T> where T: BidirectionalCollection
-
diff --git a/stdlib/public/core/EmptyCollection.swift b/stdlib/public/core/EmptyCollection.swift
index 5bd6312..d4605fe 100644
--- a/stdlib/public/core/EmptyCollection.swift
+++ b/stdlib/public/core/EmptyCollection.swift
@@ -172,6 +172,3 @@
     return true
   }
 }
-
-@available(*, deprecated: 4.2, renamed: "EmptyCollection.Iterator")
-public typealias EmptyIterator<T> = EmptyCollection<T>.Iterator
diff --git a/stdlib/public/core/Filter.swift b/stdlib/public/core/Filter.swift
index 8ccee84..edff25e 100644
--- a/stdlib/public/core/Filter.swift
+++ b/stdlib/public/core/Filter.swift
@@ -408,11 +408,3 @@
     }
   }
 }
-
-// @available(*, deprecated, renamed: "LazyFilterSequence.Iterator")
-public typealias LazyFilterIterator<T: Sequence> = LazyFilterSequence<T>.Iterator
-// @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use Base.Index")
-public typealias LazyFilterIndex<Base: Collection> = Base.Index
-@available(*, deprecated, renamed: "LazyFilterCollection")
-public typealias LazyFilterBidirectionalCollection<T> = LazyFilterCollection<T> where T : BidirectionalCollection
-
diff --git a/stdlib/public/core/FlatMap.swift b/stdlib/public/core/FlatMap.swift
index 1c40708..3ece0b8 100644
--- a/stdlib/public/core/FlatMap.swift
+++ b/stdlib/public/core/FlatMap.swift
@@ -48,29 +48,6 @@
   > {
     return self.map(transform).filter { $0 != nil }.map { $0! }
   }
-
-  /// Returns the non-`nil` results of mapping the given transformation over
-  /// this sequence.
-  ///
-  /// Use this method to receive a sequence of nonoptional values when your
-  /// transformation produces an optional value.
-  ///
-  /// - Parameter transform: A closure that accepts an element of this sequence
-  ///   as its argument and returns an optional value.
-  ///
-  /// - Complexity: O(1)
-  @inline(__always)
-  @available(swift, deprecated: 4.1, renamed: "compactMap(_:)",
-    message: "Please use compactMap(_:) for the case where closure returns an optional value")
-  public func flatMap<ElementOfResult>(
-    _ transform: @escaping (Elements.Element) -> ElementOfResult?
-  ) -> LazyMapSequence<
-    LazyFilterSequence<
-      LazyMapSequence<Elements, ElementOfResult?>>,
-    ElementOfResult
-  > {
-    return self.compactMap(transform)
-  }
 }
 
 extension LazyCollectionProtocol {
@@ -113,27 +90,4 @@
   > {
     return self.map(transform).filter { $0 != nil }.map { $0! }
   }
-
-  /// Returns the non-`nil` results of mapping the given transformation over
-  /// this collection.
-  ///
-  /// Use this method to receive a collection of nonoptional values when your
-  /// transformation produces an optional value.
-  ///
-  /// - Parameter transform: A closure that accepts an element of this
-  ///   collection as its argument and returns an optional value.
-  ///
-  /// - Complexity: O(1)
-  @available(swift, deprecated: 4.1, renamed: "compactMap(_:)",
-    message: "Please use compactMap(_:) for the case where closure returns an optional value")
-  @inlinable // FIXME(sil-serialize-all)
-  public func flatMap<ElementOfResult>(
-    _ transform: @escaping (Elements.Element) -> ElementOfResult?
-  ) -> LazyMapCollection<
-    LazyFilterCollection<
-      LazyMapCollection<Elements, ElementOfResult?>>,
-    ElementOfResult
-  > {
-    return self.map(transform).filter { $0 != nil }.map { $0! }
-  }
 }
diff --git a/stdlib/public/core/Flatten.swift b/stdlib/public/core/Flatten.swift
index 4ec2081..09b217d 100644
--- a/stdlib/public/core/Flatten.swift
+++ b/stdlib/public/core/Flatten.swift
@@ -525,10 +525,3 @@
     return FlattenCollection(elements).lazy
   }
 }
-
-// @available(*, deprecated, renamed: "FlattenCollection.Index")
-public typealias FlattenCollectionIndex<T> = FlattenCollection<T>.Index where T : Collection, T.Element : Collection
-@available(*, deprecated, renamed: "FlattenCollection.Index")
-public typealias FlattenBidirectionalCollectionIndex<T> = FlattenCollection<T>.Index where T : BidirectionalCollection, T.Element : BidirectionalCollection
-@available(*, deprecated, renamed: "FlattenCollection")
-public typealias FlattenBidirectionalCollection<T> = FlattenCollection<T> where T : BidirectionalCollection, T.Element : BidirectionalCollection
diff --git a/stdlib/public/core/FloatingPoint.swift.gyb b/stdlib/public/core/FloatingPoint.swift.gyb
index b4419c8..2fb08da 100644
--- a/stdlib/public/core/FloatingPoint.swift.gyb
+++ b/stdlib/public/core/FloatingPoint.swift.gyb
@@ -2501,93 +2501,6 @@
 
 % end
 
-extension FloatingPoint {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public func negated() -> Self {
-    return -self
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public func adding(_ other: Self) -> Self {
-    return self + other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public mutating func add(_ other: Self) {
-    self += other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public func subtracting(_ other: Self) -> Self {
-    return self - other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public mutating func subtract(_ other: Self) {
-    self -= other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public func multiplied(by other: Self) -> Self {
-    return self * other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public mutating func multiply(by other: Self) {
-    self *= other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public func divided(by other: Self) -> Self {
-    return self / other
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use operators instead.")
-  public mutating func divide(by other: Self) {
-    self /= other
-  }
-}
-
-extension FloatingPoint {
-  @available(*, unavailable, message: "Use bitPattern property instead")
-  public func _toBitPattern() -> UInt {
-    fatalError("unavailable")
-  }
-
-  @available(*, unavailable, message: "Use init(bitPattern:) instead")
-  public static func _fromBitPattern(_ bits: UInt) -> Self {
-    fatalError("unavailable")
-  }
-}
-
-extension BinaryFloatingPoint {
-  @available(*, unavailable, renamed: "isSignalingNaN")
-  public var isSignaling: Bool {
-    fatalError("unavailable")
-  }
-
-  @available(*, unavailable, renamed: "nan")
-  public var NaN: Bool {
-    fatalError("unavailable")
-  }
-  @available(*, unavailable, renamed: "nan")
-  public var quietNaN: Bool {
-    fatalError("unavailable")
-  }
-}
-
-@available(*, unavailable, renamed: "FloatingPoint")
-public typealias FloatingPointType = FloatingPoint
-
 // ${'Local Variables'}:
 // eval: (read-only-mode 1)
 // End:
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index d780d6c..6aa17d9 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -1813,40 +1813,6 @@
 // Deprecated operators
 //===----------------------------------------------------------------------===//
 
-@_transparent
-@available(*, unavailable, message: "use += 1")
-@discardableResult
-public prefix func ++ (rhs: inout ${Self}) -> ${Self} {
-  fatalError("++ is not available")
-}
-@_transparent
-@available(*, unavailable, message: "use -= 1")
-@discardableResult
-public prefix func -- (rhs: inout ${Self}) -> ${Self} {
-  fatalError("-- is not available")
-}
-@_transparent
-@available(*, unavailable, message: "use += 1")
-@discardableResult
-public postfix func ++ (lhs: inout ${Self}) -> ${Self} {
-  fatalError("++ is not available")
-}
-@_transparent
-@available(*, unavailable, message: "use -= 1")
-@discardableResult
-public postfix func -- (lhs: inout ${Self}) -> ${Self} {
-  fatalError("-- is not available")
-}
-
-extension ${Self} {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Please use the `abs(_:)` free function")
-  @_transparent
-  public static func abs(_ x: ${Self}) -> ${Self} {
-    return x.magnitude
-  }
-}
-
 % if bits == 80:
 #else
 
diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json
index 09dfc6b..73acf81 100644
--- a/stdlib/public/core/GroupInfo.json
+++ b/stdlib/public/core/GroupInfo.json
@@ -14,7 +14,6 @@
     "StaticString.swift",
     "String.swift",
     "StringBridge.swift",
-    "StringCharacterView.swift",
     "StringComparable.swift",
     "StringComparison.swift",
     "StringObject.swift",
@@ -145,7 +144,6 @@
       "FloatingPointTypes.swift"]}
   ],
   "Optional": [
-    "ImplicitlyUnwrappedOptional.swift",
     "Optional.swift"
   ],
   "Pointer": [
@@ -193,6 +191,7 @@
     "Equatable.swift",
     "Comparable.swift",
     "Hashable.swift",
-    "Codable.swift"
+    "Codable.swift",
+    "MigrationSupport.swift"
   ]
 }
diff --git a/stdlib/public/core/ImplicitlyUnwrappedOptional.swift b/stdlib/public/core/ImplicitlyUnwrappedOptional.swift
deleted file mode 100644
index 289a0d1..0000000
--- a/stdlib/public/core/ImplicitlyUnwrappedOptional.swift
+++ /dev/null
@@ -1,25 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-
-/// An optional type that allows implicit member access.
-///
-/// The `ImplicitlyUnwrappedOptional` type is deprecated. To create an optional
-/// value that is implicitly unwrapped, place an exclamation mark (`!`) after
-/// the type that you want to denote as optional.
-///
-///     // An implicitly unwrapped optional integer
-///     let guaranteedNumber: Int! = 6
-///
-///     // An optional integer
-///     let possibleNumber: Int? = 5
-@available(*, unavailable, renamed: "Optional")
-public typealias ImplicitlyUnwrappedOptional<Wrapped> = Optional<Wrapped>
diff --git a/stdlib/public/core/Indices.swift b/stdlib/public/core/Indices.swift
index 018c19e..0a45f88 100644
--- a/stdlib/public/core/Indices.swift
+++ b/stdlib/public/core/Indices.swift
@@ -127,8 +127,3 @@
       endIndex: self.endIndex)
   }
 }
-
-@available(*, deprecated, renamed: "DefaultIndices")
-public typealias DefaultBidirectionalIndices<T> = DefaultIndices<T> where T : BidirectionalCollection
-@available(*, deprecated, renamed: "DefaultIndices")
-public typealias DefaultRandomAccessIndices<T> = DefaultIndices<T> where T : RandomAccessCollection
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index c1203ff..1b160e6 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -2270,7 +2270,7 @@
 /// methods, the standard library provides default implementations for all
 /// other arithmetic methods and operators.
 public protocol FixedWidthInteger :
-  BinaryInteger, LosslessStringConvertible, _BitwiseOperations
+  BinaryInteger, LosslessStringConvertible
   where Magnitude : FixedWidthInteger
 {
   /// The number of bits used for the underlying binary representation of
@@ -2428,11 +2428,6 @@
 }
 
 extension FixedWidthInteger {
-  /// The empty bitset.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use 0")
-  public static var allZeros: Self { return 0 }
-
   /// The number of bits in the binary representation of this value.
   @inlinable
   public var bitWidth: Int { return Self.bitWidth }
@@ -4109,48 +4104,6 @@
 #endif
 }
 
-// Swift 3 compatibility APIs
-
-@available(swift, obsoleted: 4, renamed: "BinaryInteger")
-public typealias Integer = BinaryInteger
-
-@available(swift, obsoleted: 4, renamed: "BinaryInteger")
-public typealias IntegerArithmetic = BinaryInteger
-
-@available(swift, obsoleted: 4, message: "Please use 'SignedNumeric & Comparable' instead.")
-public typealias SignedNumber = SignedNumeric & Comparable
-
-@available(swift, obsoleted: 4, message: "Please use 'SignedNumeric & Comparable' instead.")
-public typealias AbsoluteValuable = SignedNumeric & Comparable
-
-@available(swift, obsoleted: 4, renamed: "SignedInteger")
-public typealias _SignedInteger = SignedInteger
-
-extension SignedNumeric where Self : Comparable {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "Please use the 'abs(_:)' free function.")
-  @_transparent
-  public static func abs(_ x: Self) -> Self {
-    return Swift.abs(x)
-  }
-}
-
-extension BinaryInteger {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public func toIntMax() -> Int64 {
-    return Int64(self)
-  }
-}
-
-extension UnsignedInteger {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public func toUIntMax() -> UInt64 {
-    return UInt64(self)
-  }
-}
-
 // FIXME(integers): These overloads allow expressions like the following in
 // Swift 3 compatibility mode:
 //    let x = 1 << i32
diff --git a/stdlib/public/core/Join.swift b/stdlib/public/core/Join.swift
index 4dbc3b5..b17908a 100644
--- a/stdlib/public/core/Join.swift
+++ b/stdlib/public/core/Join.swift
@@ -191,6 +191,3 @@
     return JoinedSequence(base: self, separator: separator)
   }
 }
-
-// @available(*, deprecated, renamed: "JoinedSequence.Iterator")
-public typealias JoinedIterator<T: Sequence> = JoinedSequence<T>.Iterator where T.Element: Sequence
diff --git a/stdlib/public/core/LazyCollection.swift b/stdlib/public/core/LazyCollection.swift
index d5dd497..b9ce84e 100644
--- a/stdlib/public/core/LazyCollection.swift
+++ b/stdlib/public/core/LazyCollection.swift
@@ -263,8 +263,3 @@
 extension Slice: LazyCollectionProtocol where Base: LazyCollectionProtocol { }
 extension ReversedCollection: LazySequenceProtocol where Base: LazySequenceProtocol { }
 extension ReversedCollection: LazyCollectionProtocol where Base: LazyCollectionProtocol { }
-
-@available(*, deprecated, renamed: "LazyCollection")
-public typealias LazyBidirectionalCollection<T> = LazyCollection<T> where T : BidirectionalCollection
-@available(*, deprecated, renamed: "LazyCollection")
-public typealias LazyRandomAccessCollection<T> = LazyCollection<T> where T : RandomAccessCollection
diff --git a/stdlib/public/core/Map.swift b/stdlib/public/core/Map.swift
index 9f2ef4c..9ca87ec 100644
--- a/stdlib/public/core/Map.swift
+++ b/stdlib/public/core/Map.swift
@@ -257,22 +257,6 @@
   }
 }
 
-extension LazyMapCollection {
-  // This overload is needed to re-enable Swift 3 source compatibility related
-  // to a bugfix in ranking behavior of the constraint solver.
-  @available(swift, obsoleted: 4.0)
-  public static func + <
-    Other : LazyCollectionProtocol
-  >(lhs: LazyMapCollection, rhs: Other) -> [Element]
-  where Other.Element == Element {
-    var result: [Element] = []
-    result.reserveCapacity(numericCast(lhs.count + rhs.count))
-    result.append(contentsOf: lhs)
-    result.append(contentsOf: rhs)
-    return result
-  }
-}
-
 extension LazyMapSequence {
   @inlinable
   @available(swift, introduced: 5)
@@ -296,10 +280,3 @@
       transform: {transform(self._transform($0))})
   }
 }
-
-// @available(*, deprecated, renamed: "LazyMapSequence.Iterator")
-public typealias LazyMapIterator<T, E> = LazyMapSequence<T, E>.Iterator where T: Sequence
-@available(*, deprecated, renamed: "LazyMapCollection")
-public typealias LazyMapBidirectionalCollection<T, E> = LazyMapCollection<T, E> where T : BidirectionalCollection
-@available(*, deprecated, renamed: "LazyMapCollection")
-public typealias LazyMapRandomAccessCollection<T, E> = LazyMapCollection<T, E> where T : RandomAccessCollection
diff --git a/stdlib/public/core/MigrationSupport.swift b/stdlib/public/core/MigrationSupport.swift
new file mode 100644
index 0000000..9f9e8ad
--- /dev/null
+++ b/stdlib/public/core/MigrationSupport.swift
@@ -0,0 +1,1288 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+// This file contains only support for types deprecated from previous versions
+// of Swift
+
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "BidirectionalCollection", message: "it will be removed in Swift 5.0.  Please use 'BidirectionalCollection' instead")
+public typealias BidirectionalIndexable = BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Collection", message: "it will be removed in Swift 5.0.  Please use 'Collection' instead")
+public typealias IndexableBase = Collection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Collection", message: "it will be removed in Swift 5.0.  Please use 'Collection' instead")
+public typealias Indexable = Collection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "MutableCollection", message: "it will be removed in Swift 5.0.  Please use 'MutableCollection' instead")
+public typealias MutableIndexable = MutableCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "RandomAccessCollection", message: "it will be removed in Swift 5.0.  Please use 'RandomAccessCollection' instead")
+public typealias RandomAccessIndexable = RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "RangeReplaceableIndexable", message: "it will be removed in Swift 5.0.  Please use 'RangeReplaceableCollection' instead")
+public typealias RangeReplaceableIndexable = RangeReplaceableCollection
+@available(*, deprecated: 4.2, renamed: "EnumeratedSequence.Iterator")
+public typealias EnumeratedIterator<T: Sequence> = EnumeratedSequence<T>.Iterator
+@available(*,deprecated: 4.2/*, obsoleted: 5.0*/, renamed: "CollectionOfOne.Iterator")
+public typealias IteratorOverOne<T> = CollectionOfOne<T>.Iterator
+@available(*, deprecated: 4.2/*, obsoleted: 5.0*/, renamed: "EmptyCollection.Iterator")
+public typealias EmptyIterator<T> = EmptyCollection<T>.Iterator
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyFilterSequence.Iterator")
+public typealias LazyFilterIterator<T: Sequence> = LazyFilterSequence<T>.Iterator
+@available(swift, deprecated: 3.1/*, obsoleted: 5.0*/, message: "Use Base.Index")
+public typealias LazyFilterIndex<Base: Collection> = Base.Index
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyDropWhileSequence.Iterator")
+public typealias LazyDropWhileIterator<T> = LazyDropWhileSequence<T>.Iterator where T: Sequence
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyDropWhileCollection.Index")
+public typealias LazyDropWhileIndex<T> = LazyDropWhileCollection<T>.Index where T: Collection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyDropWhileCollection")
+public typealias LazyDropWhileBidirectionalCollection<T> = LazyDropWhileCollection<T> where T: BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyFilterCollection")
+public typealias LazyFilterBidirectionalCollection<T> = LazyFilterCollection<T> where T : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyMapSequence.Iterator")
+public typealias LazyMapIterator<T, E> = LazyMapSequence<T, E>.Iterator where T: Sequence
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyMapCollection")
+public typealias LazyMapBidirectionalCollection<T, E> = LazyMapCollection<T, E> where T : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyMapCollection")
+public typealias LazyMapRandomAccessCollection<T, E> = LazyMapCollection<T, E> where T : RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyCollection")
+public typealias LazyBidirectionalCollection<T> = LazyCollection<T> where T : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyCollection")
+public typealias LazyRandomAccessCollection<T> = LazyCollection<T> where T : RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "FlattenCollection.Index")
+public typealias FlattenCollectionIndex<T> = FlattenCollection<T>.Index where T : Collection, T.Element : Collection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "FlattenCollection.Index")
+public typealias FlattenBidirectionalCollectionIndex<T> = FlattenCollection<T>.Index where T : BidirectionalCollection, T.Element : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "FlattenCollection")
+public typealias FlattenBidirectionalCollection<T> = FlattenCollection<T> where T : BidirectionalCollection, T.Element : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "JoinedSequence.Iterator")
+public typealias JoinedIterator<T: Sequence> = JoinedSequence<T>.Iterator where T.Element: Sequence
+@available(*, deprecated: 4.2/*, obsoleted: 5.0*/, renamed: "Zip2Sequence.Iterator")
+public typealias Zip2Iterator<T, U> = Zip2Sequence<T, U>.Iterator where T: Sequence, U: Sequence
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyDropWhileSequence.Iterator")
+public typealias LazyPrefixWhileIterator<T> = LazyPrefixWhileSequence<T>.Iterator where T: Sequence
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyDropWhileCollection.Index")
+public typealias LazyPrefixWhileIndex<T> = LazyPrefixWhileCollection<T>.Index where T: Collection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "LazyPrefixWhileCollection")
+public typealias LazyPrefixWhileBidirectionalCollection<T> = LazyPrefixWhileCollection<T> where T: BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ReversedCollection")
+public typealias ReversedRandomAccessCollection<T: RandomAccessCollection> = ReversedCollection<T>
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ReversedCollection.Index")
+public typealias ReversedIndex<T: BidirectionalCollection> = ReversedCollection<T>
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias BidirectionalSlice<T> = Slice<T> where T : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias RandomAccessSlice<T> = Slice<T> where T : RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias RangeReplaceableSlice<T> = Slice<T> where T : RangeReplaceableCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias RangeReplaceableBidirectionalSlice<T> = Slice<T> where T : RangeReplaceableCollection & BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias RangeReplaceableRandomAccessSlice<T> = Slice<T> where T : RangeReplaceableCollection & RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias MutableSlice<T> = Slice<T> where T : MutableCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias MutableBidirectionalSlice<T> = Slice<T> where T : MutableCollection & BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias MutableRandomAccessSlice<T> = Slice<T> where T : MutableCollection & RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias MutableRangeReplaceableSlice<T> = Slice<T> where T : MutableCollection & RangeReplaceableCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias MutableRangeReplaceableBidirectionalSlice<T> = Slice<T> where T : MutableCollection & RangeReplaceableCollection & BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Slice")
+public typealias MutableRangeReplaceableRandomAccessSlice<T> = Slice<T> where T : MutableCollection & RangeReplaceableCollection & RandomAccessCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "DefaultIndices")
+public typealias DefaultBidirectionalIndices<T> = DefaultIndices<T> where T : BidirectionalCollection
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "DefaultIndices")
+public typealias DefaultRandomAccessIndices<T> = DefaultIndices<T> where T : RandomAccessCollection
+
+// Deprecated by SE-0115.
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByNilLiteral")
+public typealias NilLiteralConvertible = ExpressibleByNilLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinIntegerLiteral")
+public typealias _BuiltinIntegerLiteralConvertible = _ExpressibleByBuiltinIntegerLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByIntegerLiteral")
+public typealias IntegerLiteralConvertible = ExpressibleByIntegerLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinFloatLiteral")
+public typealias _BuiltinFloatLiteralConvertible = _ExpressibleByBuiltinFloatLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByFloatLiteral")
+public typealias FloatLiteralConvertible = ExpressibleByFloatLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinBooleanLiteral")
+public typealias _BuiltinBooleanLiteralConvertible = _ExpressibleByBuiltinBooleanLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByBooleanLiteral")
+public typealias BooleanLiteralConvertible = ExpressibleByBooleanLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinUnicodeScalarLiteral")
+public typealias _BuiltinUnicodeScalarLiteralConvertible = _ExpressibleByBuiltinUnicodeScalarLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByUnicodeScalarLiteral")
+public typealias UnicodeScalarLiteralConvertible = ExpressibleByUnicodeScalarLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinExtendedGraphemeClusterLiteral")
+public typealias _BuiltinExtendedGraphemeClusterLiteralConvertible = _ExpressibleByBuiltinExtendedGraphemeClusterLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByExtendedGraphemeClusterLiteral")
+public typealias ExtendedGraphemeClusterLiteralConvertible = ExpressibleByExtendedGraphemeClusterLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinStringLiteral")
+public typealias _BuiltinStringLiteralConvertible = _ExpressibleByBuiltinStringLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByBuiltinUTF16StringLiteral")
+public typealias _BuiltinUTF16StringLiteralConvertible = _ExpressibleByBuiltinUTF16StringLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByStringLiteral")
+public typealias StringLiteralConvertible = ExpressibleByStringLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByArrayLiteral")
+public typealias ArrayLiteralConvertible = ExpressibleByArrayLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "ExpressibleByDictionaryLiteral")
+public typealias DictionaryLiteralConvertible = ExpressibleByDictionaryLiteral
+@available(*, deprecated, message: "it will be replaced or redesigned in Swift 4.0.  Instead of conforming to 'StringInterpolationConvertible', consider adding an 'init(_:String)'")
+public typealias StringInterpolationConvertible = ExpressibleByStringInterpolation
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByColorLiteral")
+public typealias _ColorLiteralConvertible = _ExpressibleByColorLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByImageLiteral")
+public typealias _ImageLiteralConvertible = _ExpressibleByImageLiteral
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "_ExpressibleByFileReferenceLiteral")
+public typealias _FileReferenceLiteralConvertible = _ExpressibleByFileReferenceLiteral
+
+@available(*, deprecated, obsoleted: 5.0, renamed: "ClosedRange.Index")
+public typealias ClosedRangeIndex<T> = ClosedRange<T>.Index where T: Strideable, T.Stride: SignedInteger
+
+/// An optional type that allows implicit member access.
+///
+/// The `ImplicitlyUnwrappedOptional` type is deprecated. To create an optional
+/// value that is implicitly unwrapped, place an exclamation mark (`!`) after
+/// the type that you want to denote as optional.
+///
+///     // An implicitly unwrapped optional integer
+///     let guaranteedNumber: Int! = 6
+///
+///     // An optional integer
+///     let possibleNumber: Int? = 5
+@available(*, unavailable, renamed: "Optional")
+public typealias ImplicitlyUnwrappedOptional<Wrapped> = Optional<Wrapped>
+
+@available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use FixedWidthInteger protocol instead")
+public typealias BitwiseOperations = _BitwiseOperations
+
+public protocol _BitwiseOperations {
+  static func & (lhs: Self, rhs: Self) -> Self
+  static func | (lhs: Self, rhs: Self) -> Self
+  static func ^ (lhs: Self, rhs: Self) -> Self
+  static prefix func ~ (x: Self) -> Self
+  static var allZeros: Self { get }
+}
+
+extension _BitwiseOperations {  
+    @available(swift, obsoleted: 4.1)
+    public static func |= (lhs: inout Self, rhs: Self) {
+      lhs = lhs | rhs
+    }
+
+    @available(swift, obsoleted: 4.1)
+    public static func &= (lhs: inout Self, rhs: Self) {
+      lhs = lhs & rhs
+    }
+
+    @available(swift, obsoleted: 4.1)
+    public static func ^= (lhs: inout Self, rhs: Self) {
+      lhs = lhs ^ rhs
+    }
+}
+
+extension FloatingPoint {
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public func negated() -> Self {
+    return -self
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public func adding(_ other: Self) -> Self {
+    return self + other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public mutating func add(_ other: Self) {
+    self += other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public func subtracting(_ other: Self) -> Self {
+    return self - other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public mutating func subtract(_ other: Self) {
+    self -= other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public func multiplied(by other: Self) -> Self {
+    return self * other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public mutating func multiply(by other: Self) {
+    self *= other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public func divided(by other: Self) -> Self {
+    return self / other
+  }
+
+  @available(swift, obsoleted: 4, message: "Please use operators instead.")
+  public mutating func divide(by other: Self) {
+    self /= other
+  }
+}
+
+extension FloatingPoint {
+  @available(*, unavailable, message: "Use bitPattern property instead")
+  public func _toBitPattern() -> UInt {
+    fatalError("unavailable")
+  }
+
+  @available(*, unavailable, message: "Use init(bitPattern:) instead")
+  public static func _fromBitPattern(_ bits: UInt) -> Self {
+    fatalError("unavailable")
+  }
+}
+
+extension BinaryFloatingPoint {
+  @available(*, unavailable, renamed: "isSignalingNaN")
+  public var isSignaling: Bool {
+    fatalError("unavailable")
+  }
+
+  @available(*, unavailable, renamed: "nan")
+  public var NaN: Bool {
+    fatalError("unavailable")
+  }
+  @available(*, unavailable, renamed: "nan")
+  public var quietNaN: Bool {
+    fatalError("unavailable")
+  }
+}
+
+@available(*, unavailable, renamed: "FloatingPoint")
+public typealias FloatingPointType = FloatingPoint
+
+// Swift 3 compatibility APIs
+@available(swift, obsoleted: 4, renamed: "BinaryInteger")
+public typealias Integer = BinaryInteger
+
+@available(swift, obsoleted: 4, renamed: "BinaryInteger")
+public typealias IntegerArithmetic = BinaryInteger
+
+@available(swift, obsoleted: 4, message: "Please use 'SignedNumeric & Comparable' instead.")
+public typealias SignedNumber = SignedNumeric & Comparable
+
+@available(swift, obsoleted: 4, message: "Please use 'SignedNumeric & Comparable' instead.")
+public typealias AbsoluteValuable = SignedNumeric & Comparable
+
+@available(swift, obsoleted: 4, renamed: "SignedInteger")
+public typealias _SignedInteger = SignedInteger
+
+extension SignedNumeric where Self : Comparable {
+  @available(swift, obsoleted: 4, message: "Please use the 'abs(_:)' free function.")
+  @_transparent
+  public static func abs(_ x: Self) -> Self {
+    return Swift.abs(x)
+  }
+}
+
+extension BinaryInteger {
+  @available(swift, obsoleted: 4)
+  public func toIntMax() -> Int64 {
+    return Int64(self)
+  }
+}
+
+extension UnsignedInteger {
+  @available(swift, obsoleted: 4)
+  public func toUIntMax() -> UInt64 {
+    return UInt64(self)
+  }
+}
+
+extension Range where Bound: Strideable, Bound.Stride : SignedInteger {
+  /// Now that Range is conditionally a collection when Bound: Strideable,
+  /// CountableRange is no longer needed. This is a deprecated initializer
+  /// for any remaining uses of Range(countableRange).
+  @available(*, deprecated: 4.2/*, obsoleted: 5.0*/, message: "CountableRange is now a Range. No need to convert any more.")
+  public init(_ other: Range<Bound>) {
+    self = other
+  }  
+}
+
+extension ClosedRange where Bound: Strideable, Bound.Stride : SignedInteger {
+  /// Now that Range is conditionally a collection when Bound: Strideable,
+  /// CountableRange is no longer needed. This is a deprecated initializer
+  /// for any remaining uses of Range(countableRange).
+  @available(*, deprecated: 4.2/*, obsoleted: 5.0*/, message: "CountableClosedRange is now a ClosedRange. No need to convert any more.")
+  public init(_ other: ClosedRange<Bound>) {
+    self = other
+  }  
+}
+
+extension _ExpressibleByColorLiteral {
+  @available(swift, deprecated: 3.2, obsoleted: 4.0, message: "This initializer is only meant to be used by color literals")
+  public init(colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float) {
+    self.init(_colorLiteralRed: red, green: green, blue: blue, alpha: alpha)
+  }
+}
+
+extension LazySequenceProtocol {
+  /// Returns the non-`nil` results of mapping the given transformation over
+  /// this sequence.
+  ///
+  /// Use this method to receive a sequence of nonoptional values when your
+  /// transformation produces an optional value.
+  ///
+  /// - Parameter transform: A closure that accepts an element of this sequence
+  ///   as its argument and returns an optional value.
+  ///
+  /// - Complexity: O(1)
+  @available(swift, deprecated: 4.1, renamed: "compactMap(_:)", message: "Please use compactMap(_:) for the case where closure returns an optional value")
+  public func flatMap<ElementOfResult>(
+    _ transform: @escaping (Elements.Element) -> ElementOfResult?
+  ) -> LazyMapSequence<
+    LazyFilterSequence<
+      LazyMapSequence<Elements, ElementOfResult?>>,
+    ElementOfResult
+  > {
+    return self.compactMap(transform)
+  }
+}
+
+extension LazyMapCollection {
+  // This overload is needed to re-enable Swift 3 source compatibility related
+  // to a bugfix in ranking behavior of the constraint solver.
+  @available(swift, obsoleted: 4.0)
+  public static func + <
+    Other : LazyCollectionProtocol
+  >(lhs: LazyMapCollection, rhs: Other) -> [Element]
+  where Other.Element == Element {
+    var result: [Element] = []
+    result.reserveCapacity(numericCast(lhs.count + rhs.count))
+    result.append(contentsOf: lhs)
+    result.append(contentsOf: rhs)
+    return result
+  }
+}
+
+@available(*, unavailable, message: "use += 1")
+@discardableResult
+public prefix func ++ <F: FloatingPoint>(rhs: inout F) -> F {
+  fatalError("++ is not available")
+}
+@available(*, unavailable, message: "use -= 1")
+@discardableResult
+public prefix func -- <F: FloatingPoint>(rhs: inout F) -> F {
+  fatalError("-- is not available")
+}
+@available(*, unavailable, message: "use += 1")
+@discardableResult
+public postfix func ++ <F: FloatingPoint>(lhs: inout F) -> F {
+  fatalError("++ is not available")
+}
+@available(*, unavailable, message: "use -= 1")
+@discardableResult
+public postfix func -- <F: FloatingPoint>(lhs: inout F) -> F {
+  fatalError("-- is not available")
+}
+
+extension FloatingPoint {
+  @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Please use the `abs(_:)` free function")
+  public static func abs(_ x: Self) -> Self {
+    return x.magnitude
+  }
+}
+
+extension FixedWidthInteger {
+  /// The empty bitset.
+  @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use 0")
+  public static var allZeros: Self { return 0 }
+}
+
+extension LazyCollectionProtocol {
+  /// Returns the non-`nil` results of mapping the given transformation over
+  /// this collection.
+  ///
+  /// Use this method to receive a collection of nonoptional values when your
+  /// transformation produces an optional value.
+  ///
+  /// - Parameter transform: A closure that accepts an element of this
+  ///   collection as its argument and returns an optional value.
+  ///
+  /// - Complexity: O(1)
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "compactMap(_:)",
+    message: "Please use compactMap(_:) for the case where closure returns an optional value")
+  public func flatMap<ElementOfResult>(
+    _ transform: @escaping (Elements.Element) -> ElementOfResult?
+  ) -> LazyMapCollection<
+    LazyFilterCollection<
+      LazyMapCollection<Elements, ElementOfResult?>>,
+    ElementOfResult
+  > {
+    return self.map(transform).filter { $0 != nil }.map { $0! }
+  }
+}
+
+extension String {
+  /// A view of a string's contents as a collection of characters.
+  ///
+  /// Previous versions of Swift provided this view since String
+  /// itself was not a collection. String is now a collection of
+  /// characters, so this type is now just an alias for String.
+  @available(swift, deprecated: 3.2, obsoleted: 5.0, message: "Please use String directly")
+  public typealias CharacterView = String
+
+  /// A view of the string's contents as a collection of characters.
+  ///
+  /// Previous versions of Swift provided this view since String
+  /// itself was not a collection. String is now a collection of
+  /// characters, so this type is now just an alias for String.
+  @available(swift, deprecated: 3.2, obsoleted: 5.0, message: "Please use String directly")
+  public var characters: String {
+    get {
+      return self
+    }
+    set {
+      self = newValue
+    }
+  }
+
+  /// Applies the given closure to a mutable view of the string's characters.
+  ///
+  /// Previous versions of Swift provided this view since String
+  /// itself was not a collection. String is now a collection of
+  /// characters, so this type is now just an alias for String.
+  @available(swift, deprecated: 3.2/*, obsoleted: 5.0*/, message: "Please mutate the String directly")
+  public mutating func withMutableCharacters<R>(
+    _ body: (inout String) -> R
+  ) -> R {
+    return body(&self)
+  }
+
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
+  public init?(_ utf16: UTF16View) {
+    // Attempt to recover the whole string, the better to implement the actual
+    // Swift 3.1 semantics, which are not as documented above!  Full Swift 3.1
+    // semantics may be impossible to preserve in the case of string literals,
+    // since we no longer have access to the length of the original string when
+    // there is no owner and elements are dropped from the end.
+    let wholeString = String(utf16._guts)
+    guard
+      let start = UTF16Index(encodedOffset: utf16._offset)
+        .samePosition(in: wholeString),
+      let end = UTF16Index(encodedOffset: utf16._offset + utf16._length)
+        .samePosition(in: wholeString)
+      else
+    {
+        return nil
+    }
+    self = String(wholeString[start..<end])
+  }
+  
+  @available(swift, deprecated: 3.2, message: "Failable initializer was removed in Swift 4. When upgrading to Swift 4, please use non-failable String.init(_:UTF8View)")
+  @available(swift, obsoleted: 4.0, message: "Please use non-failable String.init(_:UTF8View) instead")
+  public init?(_ utf8: UTF8View) {
+    if utf8.startIndex.transcodedOffset != 0
+      || utf8.endIndex.transcodedOffset != 0
+      || utf8._legacyPartialCharacters.start
+      || utf8._legacyPartialCharacters.end {
+      return nil
+    }
+    self = String(utf8._guts)
+  }
+}
+
+extension String { // RangeReplaceableCollection
+  // The defaulted argument prevents this initializer from satisfies the
+  // LosslessStringConvertible conformance.  You can satisfy a protocol
+  // requirement with something that's not yet available, but not with
+  // something that has become unavailable. Without this, the code won't
+  // compile as Swift 4.
+  @available(swift, obsoleted: 4, message: "String.init(_:String) is no longer failable")
+  public init?(_ other: String, obsoletedInSwift4: () = ()) {
+    self.init(other._guts)
+  }
+}
+
+extension String.UnicodeScalarView : _CustomPlaygroundQuickLookable {
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UnicodeScalarView.customPlaygroundQuickLook will be removed in Swift 5.0")
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
+    return .text(description)
+  }
+}
+
+// backward compatibility for index interchange.
+extension String.UnicodeScalarView {
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public func index(after i: Index?) -> Index {
+    return index(after: i!)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public func index(_ i: Index?,  offsetBy n: Int) -> Index {
+    return index(i!, offsetBy: n)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
+  public func distance(from i: Index?, to j: Index?) -> Int {
+    return distance(from: i!, to: j!)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public subscript(i: Index?) -> Unicode.Scalar {
+    return self[i!]
+  }
+}
+
+// backward compatibility for index interchange.
+extension String.UTF16View {
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public func index(after i: Index?) -> Index {
+    return index(after: i!)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public func index(_ i: Index?, offsetBy n: Int) -> Index {
+    return index(i!, offsetBy: n)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
+  public func distance(from i: Index?, to j: Index?) -> Int {
+    return distance(from: i!, to: j!)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public subscript(i: Index?) -> Unicode.UTF16.CodeUnit {
+    return self[i!]
+  }
+}
+
+// backward compatibility for index interchange.
+extension String.UTF8View {
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public func index(after i: Index?) -> Index {
+    return index(after: i!)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public func index(_ i: Index?, offsetBy n: Int) -> Index {
+    return index(i!, offsetBy: n)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
+  public func distance(from i: Index?, to j: Index?) -> Int {
+    return distance(from: i!, to: j!)
+  }
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
+  public subscript(i: Index?) -> Unicode.UTF8.CodeUnit {
+    return self[i!]
+  }
+}
+
+//===--- String/Substring Slicing Support ---------------------------------===//
+/// In Swift 3.2, in the absence of type context,
+///
+///     someString[someString.startIndex..<someString.endIndex]
+///
+/// was deduced to be of type `String`.  Therefore have a more-specific
+/// Swift-3-only `subscript` overload on `String` (and `Substring`) that
+/// continues to produce `String`.
+extension String {
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: Range<Index>) -> String {
+    _boundsCheck(bounds)
+    return String(Substring(_slice: Slice(base: self, bounds: bounds)))
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String {
+    let r = bounds.relative(to: self)
+    _boundsCheck(r)
+    return String(Substring(_slice: Slice(
+          base: self,
+          bounds: r)))
+  }
+}
+
+
+//===--- Slicing Support --------------------------------------------------===//
+// In Swift 3.2, in the absence of type context,
+//
+//   someString.unicodeScalars[
+//     someString.unicodeScalars.startIndex
+//     ..< someString.unicodeScalars.endIndex]
+//
+// was deduced to be of type `String.UnicodeScalarView`.  Provide a
+// more-specific Swift-3-only `subscript` overload that continues to produce
+// `String.UnicodeScalarView`.
+extension String.UnicodeScalarView {
+  private subscript(_bounds bounds: Range<Index>) -> String.UnicodeScalarView {
+    let rawSubRange: Range<Int> =
+      _toCoreIndex(bounds.lowerBound)..<_toCoreIndex(bounds.upperBound)
+    return String.UnicodeScalarView(
+      _guts._extractSlice(rawSubRange),
+      coreOffset: bounds.lowerBound.encodedOffset)
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: Range<Index>) -> String.UnicodeScalarView {
+    return self[_bounds: bounds]
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String.UnicodeScalarView {
+    return self[_bounds: bounds.relative(to: self)]
+  }
+}
+
+//===--- Slicing Support --------------------------------------------------===//
+// In Swift 3.2, in the absence of type context,
+//
+//   someString.utf16[someString.utf16.startIndex..<someString.utf16.endIndex]
+//
+// was deduced to be of type `String.UTF16View`.  Provide a more-specific
+// Swift-3-only `subscript` overload that continues to produce
+// `String.UTF16View`.
+extension String.UTF16View {
+  private subscript(_bounds bounds: Range<Index>) -> String.UTF16View {
+    return String.UTF16View(
+      _guts,
+      offset: _internalIndex(at: bounds.lowerBound.encodedOffset),
+      length: bounds.upperBound.encodedOffset - bounds.lowerBound.encodedOffset)
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: Range<Index>) -> String.UTF16View {
+    return self[_bounds: bounds]
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String.UTF16View {
+    return self[_bounds: bounds.relative(to: self)]
+  }
+}
+
+//===--- Slicing Support --------------------------------------------------===//
+/// In Swift 3.2, in the absence of type context,
+///
+///   someString.utf8[someString.utf8.startIndex..<someString.utf8.endIndex]
+///
+/// was deduced to be of type `String.UTF8View`.  Provide a more-specific
+/// Swift-3-only `subscript` overload that continues to produce
+/// `String.UTF8View`.
+extension String.UTF8View {
+  private subscript(_bounds bounds: Range<Index>) -> String.UTF8View {
+    let wholeString = String(_guts)
+    let legacyPartialCharacters = (
+      (self._legacyPartialCharacters.start &&
+        bounds.lowerBound.encodedOffset == 0) ||
+      bounds.lowerBound.samePosition(in: wholeString) == nil,
+      (self._legacyPartialCharacters.end &&
+        bounds.upperBound.encodedOffset == _guts.count) ||
+      bounds.upperBound.samePosition(in: wholeString) == nil)
+
+    if bounds.upperBound.transcodedOffset == 0 {
+      return String.UTF8View(
+        _guts._extractSlice(
+        bounds.lowerBound.encodedOffset..<bounds.upperBound.encodedOffset),
+        legacyOffsets: (bounds.lowerBound.transcodedOffset, 0),
+        legacyPartialCharacters: legacyPartialCharacters)
+    }
+
+    let b0 = bounds.upperBound.utf8Buffer!.first!
+    let scalarLength8 = (~b0).leadingZeroBitCount
+    let scalarLength16 = scalarLength8 == 4 ? 2 : 1
+    let coreEnd = bounds.upperBound.encodedOffset + scalarLength16
+    return String.UTF8View(
+      _guts._extractSlice(bounds.lowerBound.encodedOffset..<coreEnd),
+      legacyOffsets: (
+        bounds.lowerBound.transcodedOffset,
+        bounds.upperBound.transcodedOffset - scalarLength8),
+      legacyPartialCharacters: legacyPartialCharacters)
+  }
+  
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: Range<Index>) -> String.UTF8View {
+    return self[_bounds: bounds]
+  }
+  
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String.UTF8View {
+    return self[_bounds: bounds.relative(to: self)]
+  }
+}
+
+@available(swift,deprecated: 5.0, renamed: "Unicode.UTF8")
+public typealias UTF8 = Unicode.UTF8
+@available(swift, deprecated: 5.0, renamed: "Unicode.UTF16")
+public typealias UTF16 = Unicode.UTF16
+@available(swift, deprecated: 5.0, renamed: "Unicode.UTF32")
+public typealias UTF32 = Unicode.UTF32
+@available(swift, obsoleted: 5.0, renamed: "Unicode.Scalar")
+public typealias UnicodeScalar = Unicode.Scalar
+
+
+// popFirst() is only present when a collection is its own subsequence. This was
+// dropped in Swift 4.
+extension String {
+  @available(swift, deprecated: 3.2, obsoleted: 4, message: "Please use 'first', 'dropFirst()', or 'Substring.popFirst()'.")
+  public mutating func popFirst() -> String.Element? {
+    guard !isEmpty else { return nil }
+    let element = first!
+    let nextIdx = self.index(after: self.startIndex)
+    self = String(self[nextIdx...])
+    return element
+  }
+}
+
+extension String.UnicodeScalarView {
+  @available(swift, deprecated: 3.2, obsoleted: 4, message: "Please use 'first', 'dropFirst()', or 'Substring.UnicodeScalarView.popFirst()'.")
+  public mutating func popFirst() -> String.UnicodeScalarView.Element? {
+    guard !isEmpty else { return nil }
+    let element = first!
+    let nextIdx = self.index(after: self.startIndex)
+    self = String(self[nextIdx...]).unicodeScalars
+    return element
+  }
+}
+
+extension String.UTF16View : _CustomPlaygroundQuickLookable {
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UTF16View.customPlaygroundQuickLook will be removed in Swift 5.0")
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
+    return .text(description)
+  }
+}
+
+extension String.UTF8View : _CustomPlaygroundQuickLookable {
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UTF8View.customPlaygroundQuickLook will be removed in Swift 5.0")
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
+    return .text(description)
+  }
+}
+
+extension StringProtocol {
+  @available(swift, deprecated: 3.2, obsoleted: 4.0, renamed: "UTF8View.Index")
+  public typealias UTF8Index = UTF8View.Index
+  @available(swift, deprecated: 3.2, obsoleted: 4.0, renamed: "UTF16View.Index")
+  public typealias UTF16Index = UTF16View.Index
+  @available(swift, deprecated: 3.2, obsoleted: 4.0, renamed: "UnicodeScalarView.Index")
+  public typealias UnicodeScalarIndex = UnicodeScalarView.Index
+}
+
+extension Substring {
+  /// A view of a string's contents as a collection of characters.
+  ///
+  /// Previous versions of Swift provided this view since String
+  /// itself was not a collection. String is now a collection of
+  /// characters, so this type is now just an alias for String.
+  @available(swift, deprecated: 3.2, obsoleted: 5.0, message: "Please use Substring directly")
+  public typealias CharacterView = Substring
+
+  /// A view of the string's contents as a collection of characters.
+  @available(swift, deprecated: 3.2, obsoleted: 5.0, message: "Please use Substring directly")
+  public var characters: Substring {
+    get {
+      return self
+    }
+    set {
+      self = newValue
+    }
+  }
+
+  /// Applies the given closure to a mutable view of the string's characters.
+  ///
+  /// Previous versions of Swift provided this view since String
+  /// itself was not a collection. String is now a collection of
+  /// characters, so this type is now just an alias for String.
+  @available(swift, deprecated: 3.2/*, obsoleted: 5.0*/, message: "Please mutate the Substring directly")
+  public mutating func withMutableCharacters<R>(
+    _ body: (inout Substring) -> R
+  ) -> R {
+    return body(&self)
+  }
+  
+  private func _boundsCheck(_ range: Range<Index>) {
+    _precondition(range.lowerBound >= startIndex,
+      "String index range is out of bounds")
+    _precondition(range.upperBound <= endIndex,
+      "String index range is out of bounds")
+  }
+  
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String {
+    return String(self[bounds.relative(to: self)])
+  }
+}
+
+extension Substring : _CustomPlaygroundQuickLookable {
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "Substring.customPlaygroundQuickLook will be removed in Swift 5.0")
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
+    return String(self).customPlaygroundQuickLook
+  }
+}
+
+extension Collection {
+  // FIXME: <rdar://problem/34142121>
+  // This typealias should be removed as it predates the source compatibility
+  // guarantees of Swift 3, but it cannot due to a bug.
+  @available(*, unavailable, renamed: "Iterator")
+  public typealias Generator = Iterator
+
+  @available(swift, deprecated: 3.2, obsoleted: 5.0, renamed: "Element")
+  public typealias _Element = Element
+
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
+  public func index<T: BinaryInteger>(_ i: Index, offsetBy n: T) -> Index {
+    return index(i, offsetBy: Int(n))
+  }
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
+  public func formIndex<T: BinaryInteger>(_ i: inout Index, offsetBy n: T) {
+    return formIndex(&i, offsetBy: Int(n))
+  }
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
+  public func index<T: BinaryInteger>(_ i: Index, offsetBy n: T, limitedBy limit: Index) -> Index? {
+    return index(i, offsetBy: Int(n), limitedBy: limit)
+  }
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
+  public func formIndex<T: BinaryInteger>(_ i: inout Index, offsetBy n: T, limitedBy limit: Index) -> Bool {
+    return formIndex(&i, offsetBy: Int(n), limitedBy: limit)
+  }
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "all index distances are now of type Int")
+  public func distance<T: BinaryInteger>(from start: Index, to end: Index) -> T {
+    return numericCast(distance(from: start, to: end) as Int)
+  }
+}
+
+
+extension UnsafeMutablePointer {
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "initialize(repeating:count:)")
+  public func initialize(to newValue: Pointee, count: Int = 1) { 
+    initialize(repeating: newValue, count: count)
+  }
+
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, message: "the default argument to deinitialize(count:) has been removed, please specify the count explicitly") 
+  @discardableResult
+  public func deinitialize() -> UnsafeMutableRawPointer {
+    return deinitialize(count: 1)
+  }
+  
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
+  public func deallocate(capacity _: Int) { 
+    self.deallocate()
+  }
+
+  /// Initializes memory starting at this pointer's address with the elements
+  /// of the given collection.
+  ///
+  /// The region of memory starting at this pointer and covering `source.count`
+  /// instances of the pointer's `Pointee` type must be uninitialized or
+  /// `Pointee` must be a trivial type. After calling `initialize(from:)`, the
+  /// region is initialized.
+  ///
+  /// - Parameter source: A collection of elements of the pointer's `Pointee`
+  ///   type.
+  // This is fundamentally unsafe since collections can underreport their count.
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "it will be removed in Swift 5.0.  Please use 'UnsafeMutableBufferPointer.initialize(from:)' instead")
+  public func initialize<C : Collection>(from source: C)
+    where C.Element == Pointee {
+    let buf = UnsafeMutableBufferPointer(start: self, count: numericCast(source.count))
+    var (remainders,writtenUpTo) = source._copyContents(initializing: buf)
+    // ensure that exactly rhs.count elements were written
+    _precondition(remainders.next() == nil, "rhs underreported its count")
+    _precondition(writtenUpTo == buf.endIndex, "rhs overreported its count")
+  }
+}
+
+extension UnsafeRawPointer : _CustomPlaygroundQuickLookable {
+  internal var summary: String {
+    let ptrValue = UInt64(
+      bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
+    return ptrValue == 0
+    ? "UnsafeRawPointer(nil)"
+    : "UnsafeRawPointer(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
+  }
+
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UnsafeRawPointer.customPlaygroundQuickLook will be removed in a future Swift version")
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
+    return .text(summary)
+  }
+}
+
+extension UnsafeMutableRawPointer : _CustomPlaygroundQuickLookable {
+  private var summary: String {
+    let ptrValue = UInt64(
+      bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
+    return ptrValue == 0
+    ? "UnsafeMutableRawPointer(nil)"
+    : "UnsafeMutableRawPointer(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
+  }
+
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UnsafeMutableRawPointer.customPlaygroundQuickLook will be removed in a future Swift version")
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
+    return .text(summary)
+  }
+}
+
+extension UnsafePointer: _CustomPlaygroundQuickLookable {
+  private var summary: String {
+    let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
+    return ptrValue == 0 
+    ? "UnsafePointer(nil)" 
+    : "UnsafePointer(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
+  }
+
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UnsafePointer.customPlaygroundQuickLook will be removed in a future Swift version")
+  public var customPlaygroundQuickLook: PlaygroundQuickLook {
+    return .text(summary)
+  }
+}
+
+extension UnsafeMutablePointer: _CustomPlaygroundQuickLookable {
+  private var summary: String {
+    let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
+    return ptrValue == 0 
+    ? "UnsafeMutablePointer(nil)" 
+    : "UnsafeMutablePointer(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
+  }
+
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "UnsafeMutablePointer.customPlaygroundQuickLook will be removed in a future Swift version")
+  public var customPlaygroundQuickLook: PlaygroundQuickLook {
+    return .text(summary)
+  }
+}
+
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "UnsafeBufferPointer.Iterator")
+public typealias UnsafeBufferPointerIterator<T> = UnsafeBufferPointer<T>.Iterator
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "UnsafeRawBufferPointer.Iterator")
+public typealias UnsafeRawBufferPointerIterator<T> = UnsafeBufferPointer<T>.Iterator
+@available(*, deprecated/*, obsoleted: 5.0*/, renamed: "UnsafeRawBufferPointer.Iterator")
+public typealias UnsafeMutableRawBufferPointerIterator<T> = UnsafeBufferPointer<T>.Iterator
+
+extension UnsafeMutableRawPointer {
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "allocate(byteCount:alignment:)")
+  public static func allocate(
+    bytes size: Int, alignedTo alignment: Int
+  ) -> UnsafeMutableRawPointer {
+    return UnsafeMutableRawPointer.allocate(byteCount: size, alignment: alignment)
+  }
+  
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "deallocate()", message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
+  public func deallocate(bytes _: Int, alignedTo _: Int) { 
+    self.deallocate()
+  }
+
+  @available(swift, deprecated: 4.1, obsoleted: 5.0, renamed: "copyMemory(from:byteCount:)")
+  public func copyBytes(from source: UnsafeRawPointer, count: Int) {
+    copyMemory(from: source, byteCount: count)
+  }
+
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "initializeMemory(as:repeating:count:)")
+  @discardableResult
+  public func initializeMemory<T>(
+    as type: T.Type, at offset: Int = 0, count: Int = 1, to repeatedValue: T
+  ) -> UnsafeMutablePointer<T> { 
+    return (self + offset * MemoryLayout<T>.stride).initializeMemory(
+      as: type, repeating: repeatedValue, count: count)
+  }
+
+  @available(*, deprecated/*, obsoleted: 5.0*/, message: "it will be removed in Swift 5.0.  Please use 'UnsafeMutableRawBufferPointer.initialize(from:)' instead")
+  @discardableResult
+  public func initializeMemory<C : Collection>(
+    as type: C.Element.Type, from source: C
+  ) -> UnsafeMutablePointer<C.Element> {
+    // TODO: Optimize where `C` is a `ContiguousArrayBuffer`.
+    // Initialize and bind each element of the container.
+    var ptr = self
+    for element in source {
+      ptr.initializeMemory(as: C.Element.self, repeating: element, count: 1)
+      ptr += MemoryLayout<C.Element>.stride
+    }
+    return UnsafeMutablePointer(_rawValue)
+  }
+}
+
+extension UnsafeMutableRawBufferPointer {
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "allocate(byteCount:alignment:)")
+  public static func allocate(count: Int) -> UnsafeMutableRawBufferPointer { 
+    return UnsafeMutableRawBufferPointer.allocate(
+      byteCount: count, alignment: MemoryLayout<UInt>.alignment)
+  }
+
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "copyMemory(from:)")
+  public func copyBytes(from source: UnsafeRawBufferPointer) {
+    copyMemory(from: source)
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// The following overloads of flatMap are carefully crafted to allow the code
+// like the following:
+//   ["hello"].flatMap { $0 }
+// return an array of strings without any type context in Swift 3 mode, at the
+// same time allowing the following code snippet to compile:
+//   [0, 1].flatMap { x in
+//     if String(x) == "foo" { return "bar" } else { return nil }
+//   }
+// Note that the second overload is declared on a more specific protocol.
+// See: test/stdlib/StringFlatMap.swift for tests.
+extension Sequence {
+  @available(swift, deprecated: 4.1/*, obsoleted: 5.0*/, renamed: "compactMap(_:)",
+    message: "Please use compactMap(_:) for the case where closure returns an optional value")
+  public func flatMap<ElementOfResult>(
+    _ transform: (Element) throws -> ElementOfResult?
+  ) rethrows -> [ElementOfResult] {
+    return try _compactMap(transform)
+  }
+
+  @available(swift, obsoleted: 4)
+  public func flatMap(
+    _ transform: (Element) throws -> String
+  ) rethrows -> [String] {
+    return try map(transform)
+  }
+}
+
+extension Collection {
+  @available(swift, deprecated: 4.1, obsoleted: 5.0, renamed: "compactMap(_:)", message: "Please use compactMap(_:) for the case where closure returns an optional value")
+  public func flatMap(
+    _ transform: (Element) throws -> String?
+  ) rethrows -> [String] {
+    return try _compactMap(transform)
+  }
+}
+
+extension String.Index {
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
+  public init(_position: Int) {
+    self.init(encodedOffset: _position)
+  }
+
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
+  public init(_codeUnitOffset: Int) {
+    self.init(encodedOffset: _codeUnitOffset)
+  }
+
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
+  public var _utf16Index: Int {
+    return self.encodedOffset
+  }
+
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
+  public var _offset: Int {
+    return self.encodedOffset
+  }
+}
+
+// backward compatibility for index interchange.
+extension Optional where Wrapped == String.Index {
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
+  public static func ..<(
+    lhs: String.Index?, rhs: String.Index?
+  ) -> Range<String.Index> {
+    return lhs! ..< rhs!
+  }
+
+  @available(swift, obsoleted: 4.0, message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
+  public static func ...(
+    lhs: String.Index?, rhs: String.Index?
+  ) -> ClosedRange<String.Index> {
+    return lhs! ... rhs!
+  }
+}
+
+extension Zip2Sequence {
+  @available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Sequence1.Iterator")
+  public typealias Stream1 = Sequence1.Iterator
+  @available(*, deprecated/*, obsoleted: 5.0*/, renamed: "Sequence2.Iterator")
+  public typealias Stream2 = Sequence2.Iterator
+}
+
+
+//===--- QuickLooks -------------------------------------------------------===//
+
+/// The sum of types that can be used as a Quick Look representation.
+///
+/// The `PlaygroundQuickLook` protocol is deprecated, and will be removed from
+/// the standard library in a future Swift release. To customize the logging of
+/// your type in a playground, conform to the
+/// `CustomPlaygroundDisplayConvertible` protocol, which does not use the
+/// `PlaygroundQuickLook` enum.
+///
+/// If you need to provide a customized playground representation in Swift 4.0
+/// or Swift 3.2 or earlier, use a conditional compilation block:
+///
+///     #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
+///         // With Swift 4.1 and later (including Swift 3.3 and later), use
+///         // the CustomPlaygroundDisplayConvertible protocol.
+///     #else
+///         // With Swift 4.0 and Swift 3.2 and earlier, use PlaygroundQuickLook
+///         // and the CustomPlaygroundQuickLookable protocol.
+///     #endif
+@available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
+public typealias PlaygroundQuickLook = _PlaygroundQuickLook
+
+@_frozen // rdar://problem/38719739 - needed by LLDB
+public enum _PlaygroundQuickLook {
+  case text(String)
+  case int(Int64)
+  case uInt(UInt64)
+  case float(Float32)
+  case double(Float64)
+  case image(Any)
+  case sound(Any)
+  case color(Any)
+  case bezierPath(Any)
+  case attributedString(Any)
+  case rectangle(Float64, Float64, Float64, Float64)
+  case point(Float64, Float64)
+  case size(Float64, Float64)
+  case bool(Bool)
+  case range(Int64, Int64)
+  case view(Any)
+  case sprite(Any)
+  case url(String)
+  case _raw([UInt8], String)
+}
+
+// Maintain old `keys` and `values` types in Swift 3 mode.
+extension Dictionary {
+  /// A collection containing just the keys of the dictionary.
+  ///
+  /// When iterated over, keys appear in this collection in the same order as
+  /// they occur in the dictionary's key-value pairs. Each key in the keys
+  /// collection has a unique value.
+  ///
+  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
+  ///     print(countryCodes)
+  ///     // Prints "["BR": "Brazil", "JP": "Japan", "GH": "Ghana"]"
+  ///
+  ///     for k in countryCodes.keys {
+  ///         print(k)
+  ///     }
+  ///     // Prints "BR"
+  ///     // Prints "JP"
+  ///     // Prints "GH"
+  @available(swift, obsoleted: 4.0)
+  public var keys: LazyMapCollection<[Key: Value], Key> {
+    return self.lazy.map { $0.key }
+  }
+
+  /// A collection containing just the values of the dictionary.
+  ///
+  /// When iterated over, values appear in this collection in the same order as
+  /// they occur in the dictionary's key-value pairs.
+  ///
+  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
+  ///     print(countryCodes)
+  ///     // Prints "["BR": "Brazil", "JP": "Japan", "GH": "Ghana"]"
+  ///
+  ///     for v in countryCodes.values {
+  ///         print(v)
+  ///     }
+  ///     // Prints "Brazil"
+  ///     // Prints "Japan"
+  ///     // Prints "Ghana"
+  @available(swift, obsoleted: 4.0)
+  public var values: LazyMapCollection<[Key: Value], Value> {
+    return self.lazy.map { $0.value }
+  }
+
+  @available(swift, obsoleted: 4.0)
+  public func filter(
+    _ isIncluded: (Element) throws -> Bool, obsoletedInSwift4: () = ()
+  ) rethrows -> [Element] {
+    var result: [Element] = []
+    for x in self {
+      if try isIncluded(x) {
+        result.append(x)
+      }
+    }
+    return result
+  }
+}
+
+extension Set {
+  @available(swift, obsoleted: 4.0)
+  public func filter(
+    _ isIncluded: (Element) throws -> Bool, obsoletedInSwift4: () = ()
+  ) rethrows -> [Element] {
+    var result: [Element] = []
+    for x in self {
+      if try isIncluded(x) {
+        result.append(x)
+      }
+    }
+    return result
+  }  
+}
+
+extension _PlaygroundQuickLook {
+  /// Creates a new Quick Look for the given instance.
+  ///
+  /// If the dynamic type of `subject` conforms to
+  /// `CustomPlaygroundQuickLookable`, the result is found by calling its
+  /// `customPlaygroundQuickLook` property. Otherwise, the result is
+  /// synthesized by the language. In some cases, the synthesized result may
+  /// be `.text(String(reflecting: subject))`.
+  ///
+  /// - Note: If the dynamic type of `subject` has value semantics, subsequent
+  ///   mutations of `subject` will not observable in the Quick Look. In
+  ///   general, though, the observability of such mutations is unspecified.
+  ///
+  /// - Parameter subject: The instance to represent with the resulting Quick
+  ///   Look.
+  @available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version.")
+  public init(reflecting subject: Any) {
+    if let customized = subject as? CustomPlaygroundQuickLookable {
+      self = customized.customPlaygroundQuickLook
+    }
+    else if let customized = subject as? _DefaultCustomPlaygroundQuickLookable {
+      self = customized._defaultCustomPlaygroundQuickLook
+    }
+    else {
+      if let q = Mirror.quickLookObject(subject) {
+        self = q
+      }
+      else {
+        self = .text(String(reflecting: subject))
+      }
+    }
+  }
+}
+
+/// A type that explicitly supplies its own playground Quick Look.
+///
+/// The `CustomPlaygroundQuickLookable` protocol is deprecated, and will be
+/// removed from the standard library in a future Swift release. To customize
+/// the logging of your type in a playground, conform to the
+/// `CustomPlaygroundDisplayConvertible` protocol.
+///
+/// If you need to provide a customized playground representation in Swift 4.0
+/// or Swift 3.2 or earlier, use a conditional compilation block:
+///
+///     #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
+///         // With Swift 4.1 and later (including Swift 3.3 and later),
+///         // conform to CustomPlaygroundDisplayConvertible.
+///         extension MyType: CustomPlaygroundDisplayConvertible { /*...*/ }
+///     #else
+///         // Otherwise, on Swift 4.0 and Swift 3.2 and earlier,
+///         // conform to CustomPlaygroundQuickLookable.
+///         extension MyType: CustomPlaygroundQuickLookable { /*...*/ }
+///     #endif
+@available(*, deprecated/*, obsoleted: 5.0*/, message: "CustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
+public typealias CustomPlaygroundQuickLookable = _CustomPlaygroundQuickLookable
+
+public protocol _CustomPlaygroundQuickLookable {
+  /// A custom playground Quick Look for this instance.
+  ///
+  /// If this type has value semantics, the `PlaygroundQuickLook` instance
+  /// should be unaffected by subsequent mutations.
+  var customPlaygroundQuickLook: _PlaygroundQuickLook { get }
+}
+
+// Double-underscored real version allows us to keep using this in AppKit while
+// warning for non-SDK use. This is probably overkill but it doesn't cost
+// anything.
+@available(*, deprecated/*, obsoleted: 5.0*/, message: "_DefaultCustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
+public typealias _DefaultCustomPlaygroundQuickLookable = __DefaultCustomPlaygroundQuickLookable
+
+public protocol __DefaultCustomPlaygroundQuickLookable {
+  var _defaultCustomPlaygroundQuickLook: _PlaygroundQuickLook { get }
+}
diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift
index 2d500fd..68397a4 100644
--- a/stdlib/public/core/Mirror.swift
+++ b/stdlib/public/core/Mirror.swift
@@ -459,168 +459,6 @@
   }
 }
 
-//===--- QuickLooks -------------------------------------------------------===//
-
-/// The sum of types that can be used as a Quick Look representation.
-///
-/// The `PlaygroundQuickLook` protocol is deprecated, and will be removed from
-/// the standard library in a future Swift release. To customize the logging of
-/// your type in a playground, conform to the
-/// `CustomPlaygroundDisplayConvertible` protocol, which does not use the
-/// `PlaygroundQuickLook` enum.
-///
-/// If you need to provide a customized playground representation in Swift 4.0
-/// or Swift 3.2 or earlier, use a conditional compilation block:
-///
-///     #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
-///         // With Swift 4.1 and later (including Swift 3.3 and later), use
-///         // the CustomPlaygroundDisplayConvertible protocol.
-///     #else
-///         // With Swift 4.0 and Swift 3.2 and earlier, use PlaygroundQuickLook
-///         // and the CustomPlaygroundQuickLookable protocol.
-///     #endif
-@_frozen // rdar://problem/38719739 - needed by LLDB
-@available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
-public enum PlaygroundQuickLook {
-  /// Plain text.
-  case text(String)
-
-  /// An integer numeric value.
-  case int(Int64)
-
-  /// An unsigned integer numeric value.
-  case uInt(UInt64)
-
-  /// A single precision floating-point numeric value.
-  case float(Float32)
-
-  /// A double precision floating-point numeric value.
-  case double(Float64)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// An image.
-  case image(Any)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// A sound.
-  case sound(Any)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// A color.
-  case color(Any)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// A bezier path.
-  case bezierPath(Any)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// An attributed string.
-  case attributedString(Any)
-
-  // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type.
-  /// A rectangle.
-  case rectangle(Float64, Float64, Float64, Float64)
-
-  // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type.
-  /// A point.
-  case point(Float64, Float64)
-
-  // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type.
-  /// A size.
-  case size(Float64, Float64)
-
-  /// A boolean value.
-  case bool(Bool)
-
-  // FIXME: Uses explicit values to avoid coupling a particular Cocoa type.
-  /// A range.
-  case range(Int64, Int64)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// A GUI view.
-  case view(Any)
-
-  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
-  /// A graphical sprite.
-  case sprite(Any)
-
-  /// A Uniform Resource Locator.
-  case url(String)
-
-  /// Raw data that has already been encoded in a format the IDE understands.
-  case _raw([UInt8], String)
-}
-
-extension PlaygroundQuickLook {
-  /// Creates a new Quick Look for the given instance.
-  ///
-  /// If the dynamic type of `subject` conforms to
-  /// `CustomPlaygroundQuickLookable`, the result is found by calling its
-  /// `customPlaygroundQuickLook` property. Otherwise, the result is
-  /// synthesized by the language. In some cases, the synthesized result may
-  /// be `.text(String(reflecting: subject))`.
-  ///
-  /// - Note: If the dynamic type of `subject` has value semantics, subsequent
-  ///   mutations of `subject` will not observable in the Quick Look. In
-  ///   general, though, the observability of such mutations is unspecified.
-  ///
-  /// - Parameter subject: The instance to represent with the resulting Quick
-  ///   Look.
-  @available(*, deprecated, message: "PlaygroundQuickLook will be removed in a future Swift version.")
-  public init(reflecting subject: Any) {
-    if let customized = subject as? CustomPlaygroundQuickLookable {
-      self = customized.customPlaygroundQuickLook
-    }
-    else if let customized = subject as? _DefaultCustomPlaygroundQuickLookable {
-      self = customized._defaultCustomPlaygroundQuickLook
-    }
-    else {
-      if let q = Mirror.quickLookObject(subject) {
-        self = q
-      }
-      else {
-        self = .text(String(reflecting: subject))
-      }
-    }
-  }
-}
-
-/// A type that explicitly supplies its own playground Quick Look.
-///
-/// The `CustomPlaygroundQuickLookable` protocol is deprecated, and will be
-/// removed from the standard library in a future Swift release. To customize
-/// the logging of your type in a playground, conform to the
-/// `CustomPlaygroundDisplayConvertible` protocol.
-///
-/// If you need to provide a customized playground representation in Swift 4.0
-/// or Swift 3.2 or earlier, use a conditional compilation block:
-///
-///     #if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
-///         // With Swift 4.1 and later (including Swift 3.3 and later),
-///         // conform to CustomPlaygroundDisplayConvertible.
-///         extension MyType: CustomPlaygroundDisplayConvertible { /*...*/ }
-///     #else
-///         // Otherwise, on Swift 4.0 and Swift 3.2 and earlier,
-///         // conform to CustomPlaygroundQuickLookable.
-///         extension MyType: CustomPlaygroundQuickLookable { /*...*/ }
-///     #endif
-@available(*, deprecated, message: "CustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
-public protocol CustomPlaygroundQuickLookable {
-  /// A custom playground Quick Look for this instance.
-  ///
-  /// If this type has value semantics, the `PlaygroundQuickLook` instance
-  /// should be unaffected by subsequent mutations.
-  var customPlaygroundQuickLook: PlaygroundQuickLook { get }
-}
-
-
-// A workaround for <rdar://problem/26182650>
-// FIXME(ABI)#50 (Dynamic Dispatch for Class Extensions) though not if it moves out of stdlib.
-@available(*, deprecated, message: "_DefaultCustomPlaygroundQuickLookable will be removed in a future Swift version. For customizing how types are presented in playgrounds, use CustomPlaygroundDisplayConvertible instead.")
-public protocol _DefaultCustomPlaygroundQuickLookable {
-  var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook { get }
-}
-
 //===--- General Utilities ------------------------------------------------===//
 // This component could stand alone, but is used in Mirror's public interface.
 
diff --git a/stdlib/public/core/Mirrors.swift.gyb b/stdlib/public/core/Mirrors.swift.gyb
index 3c23082..26414ae 100644
--- a/stdlib/public/core/Mirrors.swift.gyb
+++ b/stdlib/public/core/Mirrors.swift.gyb
@@ -44,11 +44,11 @@
   }
 }
 
-extension ${Type[0]} : CustomPlaygroundQuickLookable {
+extension ${Type[0]} : _CustomPlaygroundQuickLookable {
   /// A custom playground Quick Look for the `${Type[0]}` instance.
   @inlinable // FIXME(sil-serialize-all)
   @available(*, deprecated, message: "${Type[0]}.customPlaygroundQuickLook will be removed in a future Swift version")
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
+  public var customPlaygroundQuickLook: _PlaygroundQuickLook {
     return ${Type[1]}(${Type[2]})
   }
 }
diff --git a/stdlib/public/core/MutableCollection.swift b/stdlib/public/core/MutableCollection.swift
index dc1f10b..5eceea4 100644
--- a/stdlib/public/core/MutableCollection.swift
+++ b/stdlib/public/core/MutableCollection.swift
@@ -10,14 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-/// A type that provides subscript access to its elements.
-///
-/// In most cases, it's best to ignore this protocol and use the
-/// `MutableCollection` protocol instead, because it has a more complete
-/// interface.
-@available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'MutableCollection' instead")
-public typealias MutableIndexable = MutableCollection
-
 /// A collection that supports subscript assignment.
 ///
 /// Collections that conform to `MutableCollection` gain the ability to
diff --git a/stdlib/public/core/Policy.swift b/stdlib/public/core/Policy.swift
index 327cdde..4c7787a 100644
--- a/stdlib/public/core/Policy.swift
+++ b/stdlib/public/core/Policy.swift
@@ -283,221 +283,6 @@
 ///     // Prints "nil"
 public typealias AnyClass = AnyObject.Type
 
-/// A type that supports standard bitwise arithmetic operators.
-///
-/// Types that conform to the `BitwiseOperations` protocol implement operators
-/// for bitwise arithmetic. The integer types in the standard library all
-/// conform to `BitwiseOperations` by default. When you use bitwise operators
-/// with an integer, you perform operations on the raw data bits that store
-/// the integer's value.
-///
-/// In the following examples, the binary representation of any values are
-/// shown in a comment to the right, like this:
-///
-///     let x: UInt8 = 5        // 0b00000101
-///
-/// Here are the required operators for the `BitwiseOperations` protocol:
-///
-/// - The bitwise OR operator (`|`) returns a value that has each bit set to
-///   `1` where *one or both* of its arguments had that bit set to `1`. This
-///   is equivalent to the union of two sets. For example:
-///
-///         let x: UInt8 = 5        // 0b00000101
-///         let y: UInt8 = 14       // 0b00001110
-///         let z = x | y           // 0b00001111
-///
-///   Performing a bitwise OR operation with a value and `allZeros` always
-///   returns the same value.
-///
-///         print(x | .allZeros)    // 0b00000101
-///         // Prints "5"
-///
-/// - The bitwise AND operator (`&`) returns a value that has each bit set to
-///   `1` where *both* of its arguments had that bit set to `1`. This is
-///   equivalent to the intersection of two sets. For example:
-///
-///         let x: UInt8 = 5        // 0b00000101
-///         let y: UInt8 = 14       // 0b00001110
-///         let z = x & y           // 0b00000100
-///
-///   Performing a bitwise AND operation with a value and `allZeros` always
-///   returns `allZeros`.
-///
-///         print(x & .allZeros)    // 0b00000000
-///         // Prints "0"
-///
-/// - The bitwise XOR operator (`^`), or exclusive OR operator, returns a value
-///   that has each bit set to `1` where *one or the other but not both* of
-///   its operators has that bit set to `1`. This is equivalent to the
-///   symmetric difference of two sets. For example:
-///
-///         let x: UInt8 = 5        // 0b00000101
-///         let y: UInt8 = 14       // 0b00001110
-///         let z = x ^ y           // 0b00001011
-///
-///   Performing a bitwise XOR operation with a value and `allZeros` always
-///   returns the same value.
-///
-///         print(x ^ .allZeros)    // 0b00000101
-///         // Prints "5"
-///
-/// - The bitwise NOT operator (`~`) is a prefix operator that returns a value
-///   where all the bits of its argument are flipped: Bits that are `1` in the
-///   argument are `0` in the result, and bits that are `0` in the argument
-///   are `1` in the result. This is equivalent to the inverse of a set. For
-///   example:
-///
-///         let x: UInt8 = 5        // 0b00000101
-///         let notX = ~x           // 0b11111010
-///
-///   Performing a bitwise NOT operation on `allZeros` returns a value with
-///   every bit set to `1`.
-///
-///         let allOnes = ~UInt8.allZeros   // 0b11111111
-///
-/// The `OptionSet` protocol uses a raw value that conforms to
-/// `BitwiseOperations` to provide mathematical set operations like
-/// `union(_:)`, `intersection(_:)` and `contains(_:)` with O(1) performance.
-///
-/// Conforming to the BitwiseOperations Protocol
-/// ============================================
-///
-/// To make your custom type conform to `BitwiseOperations`, add a static
-/// `allZeros` property and declare the four required operator functions. Any
-/// type that conforms to `BitwiseOperations`, where `x` is an instance of the
-/// conforming type, must satisfy the following conditions:
-///
-/// - `x | Self.allZeros == x`
-/// - `x ^ Self.allZeros == x`
-/// - `x & Self.allZeros == .allZeros`
-/// - `x & ~Self.allZeros == x`
-/// - `~x == x ^ ~Self.allZeros`
-@available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use FixedWidthInteger protocol instead")
-public typealias BitwiseOperations = _BitwiseOperations
-
-public protocol _BitwiseOperations {
-  /// Returns the intersection of bits set in the two arguments.
-  ///
-  /// The bitwise AND operator (`&`) returns a value that has each bit set to
-  /// `1` where *both* of its arguments had that bit set to `1`. This is
-  /// equivalent to the intersection of two sets. For example:
-  ///
-  ///     let x: UInt8 = 5        // 0b00000101
-  ///     let y: UInt8 = 14       // 0b00001110
-  ///     let z = x & y           // 0b00000100
-  ///
-  /// Performing a bitwise AND operation with a value and `allZeros` always
-  /// returns `allZeros`.
-  ///
-  ///     print(x & .allZeros)    // 0b00000000
-  ///     // Prints "0"
-  ///
-  /// - Complexity: O(1).
-  static func & (lhs: Self, rhs: Self) -> Self
-
-  /// Returns the union of bits set in the two arguments.
-  ///
-  /// The bitwise OR operator (`|`) returns a value that has each bit set to
-  /// `1` where *one or both* of its arguments had that bit set to `1`. For
-  /// example:
-  ///
-  ///     let x: UInt8 = 5        // 0b00000101
-  ///     let y: UInt8 = 14       // 0b00001110
-  ///     let z = x | y           // 0b00001111
-  ///
-  /// Performing a bitwise OR operation with a value and `allZeros` always
-  /// returns the same value.
-  ///
-  ///     print(x | .allZeros)    // 0b00000101
-  ///     // Prints "5"
-  ///
-  /// - Complexity: O(1).
-  static func | (lhs: Self, rhs: Self) -> Self
-
-  /// Returns the bits that are set in exactly one of the two arguments.
-  ///
-  /// The bitwise XOR operator (`^`), or exclusive OR operator, returns a value
-  /// that has each bit set to `1` where *one or the other but not both* of
-  /// its operators has that bit set to `1`. This is equivalent to the
-  /// symmetric difference of two sets. For example:
-  ///
-  ///     let x: UInt8 = 5        // 0b00000101
-  ///     let y: UInt8 = 14       // 0b00001110
-  ///     let z = x ^ y           // 0b00001011
-  ///
-  /// Performing a bitwise XOR with a value and `allZeros` always returns the
-  /// same value:
-  ///
-  ///     print(x ^ .allZeros)    // 0b00000101
-  ///     // Prints "5"
-  ///
-  /// - Complexity: O(1).
-  static func ^ (lhs: Self, rhs: Self) -> Self
-
-  /// Returns the inverse of the bits set in the argument.
-  ///
-  /// The bitwise NOT operator (`~`) is a prefix operator that returns a value
-  /// in which all the bits of its argument are flipped: Bits that are `1` in the
-  /// argument are `0` in the result, and bits that are `0` in the argument
-  /// are `1` in the result. This is equivalent to the inverse of a set. For
-  /// example:
-  ///
-  ///     let x: UInt8 = 5        // 0b00000101
-  ///     let notX = ~x           // 0b11111010
-  ///
-  /// Performing a bitwise NOT operation on `allZeros` returns a value with
-  /// every bit set to `1`.
-  ///
-  ///     let allOnes = ~UInt8.allZeros   // 0b11111111
-  ///
-  /// - Complexity: O(1).
-  static prefix func ~ (x: Self) -> Self
-
-  /// The empty bitset.
-  @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Use 0 or init() of a type conforming to FixedWidthInteger")
-  static var allZeros: Self { get }
-}
-
-extension _BitwiseOperations {
-  /// Calculates the union of bits sets in the two arguments and stores the result
-  /// in the first argument.
-  ///
-  /// - Parameters:
-  ///   - lhs: A value to update with the union of bits set in the two arguments.
-  ///   - rhs: Another value.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4.1)
-  public static func |= (lhs: inout Self, rhs: Self) {
-    lhs = lhs | rhs
-  }
-
-  /// Calculates the intersections of bits sets in the two arguments and stores
-  /// the result in the first argument.
-  ///
-  /// - Parameters:
-  ///   - lhs: A value to update with the intersections of bits set in the two
-  ///     arguments.
-  ///   - rhs: Another value.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4.1)
-  public static func &= (lhs: inout Self, rhs: Self) {
-    lhs = lhs & rhs
-  }
-
-  /// Calculates the bits that are set in exactly one of the two arguments and
-  /// stores the result in the first argument.
-  ///
-  /// - Parameters:
-  ///   - lhs: A value to update with the bits that are set in exactly one of the
-  ///     two arguments.
-  ///   - rhs: Another value.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4.1)
-  public static func ^= (lhs: inout Self, rhs: Self) {
-    lhs = lhs ^ rhs
-  }
-}
-
 //===----------------------------------------------------------------------===//
 // Standard pattern matching forms
 //===----------------------------------------------------------------------===//
diff --git a/stdlib/public/core/PrefixWhile.swift b/stdlib/public/core/PrefixWhile.swift
index a05419f..4c80aac 100644
--- a/stdlib/public/core/PrefixWhile.swift
+++ b/stdlib/public/core/PrefixWhile.swift
@@ -311,10 +311,3 @@
       _base: self.elements, predicate: predicate)
   }
 }
-
-@available(*, deprecated, renamed: "LazyDropWhileSequence.Iterator")
-public typealias LazyPrefixWhileIterator<T> = LazyPrefixWhileSequence<T>.Iterator where T: Sequence
-@available(*, deprecated, renamed: "LazyDropWhileCollection.Index")
-public typealias LazyPrefixWhileIndex<T> = LazyPrefixWhileCollection<T>.Index where T: Collection
-@available(*, deprecated, renamed: "LazyPrefixWhileCollection")
-public typealias LazyPrefixWhileBidirectionalCollection<T> = LazyPrefixWhileCollection<T> where T: BidirectionalCollection
diff --git a/stdlib/public/core/RandomAccessCollection.swift b/stdlib/public/core/RandomAccessCollection.swift
index 8e9f34e..8a28a20 100644
--- a/stdlib/public/core/RandomAccessCollection.swift
+++ b/stdlib/public/core/RandomAccessCollection.swift
@@ -12,14 +12,6 @@
 
 /// A collection that supports efficient random-access index traversal.
 ///
-/// In most cases, it's best to ignore this protocol and use the
-/// `RandomAccessCollection` protocol instead, because it has a more complete
-/// interface.
-@available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'RandomAccessCollection' instead")
-public typealias RandomAccessIndexable = RandomAccessCollection
-
-/// A collection that supports efficient random-access index traversal.
-///
 /// Random-access collections can move indices any distance and 
 /// measure the distance between indices in O(1) time. Therefore, the
 /// fundamental difference between random-access and bidirectional collections
diff --git a/stdlib/public/core/Range.swift b/stdlib/public/core/Range.swift
index 7993857..1741c5a 100644
--- a/stdlib/public/core/Range.swift
+++ b/stdlib/public/core/Range.swift
@@ -278,16 +278,7 @@
   }
 }
 
-extension Range where Bound: Strideable, Bound.Stride : SignedInteger {
-  /// Now that Range is conditionally a collection when Bound: Strideable,
-  /// CountableRange is no longer needed. This is a deprecated initializer
-  /// for any remaining uses of Range(countableRange).
-  @available(*,deprecated: 4.2, 
-    message: "CountableRange is now Range. No need to convert any more.")
-  public init(_ other: Range<Bound>) {
-    self = other
-  }  
-  
+extension Range where Bound: Strideable, Bound.Stride : SignedInteger {  
   /// Creates an instance equivalent to the given `ClosedRange`.
   ///
   /// - Parameter other: A closed range to convert to a `Range` instance.
@@ -849,6 +840,7 @@
     return self[startIndex...]
   }
 }
+
 extension MutableCollection {
   @inlinable
   public subscript<R: RangeExpression>(r: R) -> SubSequence
@@ -907,8 +899,12 @@
   }
 }
 
+// Note: this is not for compatibility only, it is considered a useful
+// shorthand. TODO: Add documentation
 public typealias CountableRange<Bound: Strideable> = Range<Bound>
   where Bound.Stride : SignedInteger
 
+// Note: this is not for compatibility only, it is considered a useful
+// shorthand. TODO: Add documentation
 public typealias CountablePartialRangeFrom<Bound: Strideable> = PartialRangeFrom<Bound>
   where Bound.Stride : SignedInteger
diff --git a/stdlib/public/core/RangeReplaceableCollection.swift b/stdlib/public/core/RangeReplaceableCollection.swift
index 367647c..5b6b259 100644
--- a/stdlib/public/core/RangeReplaceableCollection.swift
+++ b/stdlib/public/core/RangeReplaceableCollection.swift
@@ -14,15 +14,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-/// A type that supports replacement of an arbitrary subrange of elements with
-/// the elements of another collection.
-///
-/// In most cases, it's best to ignore this protocol and use the
-/// `RangeReplaceableCollection` protocol instead, because it has a more
-/// complete interface.
-@available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'RandomAccessCollection' instead")
-public typealias RangeReplaceableIndexable = RangeReplaceableCollection
-
 /// A collection that supports replacement of an arbitrary subrange of elements
 /// with the elements of another collection.
 ///
diff --git a/stdlib/public/core/ReflectionMirror.swift b/stdlib/public/core/ReflectionMirror.swift
index 4806ae6..6e516f4 100644
--- a/stdlib/public/core/ReflectionMirror.swift
+++ b/stdlib/public/core/ReflectionMirror.swift
@@ -55,7 +55,7 @@
 
 internal func _getClassPlaygroundQuickLook(
   _ object: AnyObject
-) -> PlaygroundQuickLook? {
+) -> _PlaygroundQuickLook? {
   if _is(object, kindOf: "NSNumber") {
     let number: _NSNumber = unsafeBitCast(object, to: _NSNumber.self)
     switch UInt8(number.objCType[0]) {
@@ -149,7 +149,7 @@
     self._defaultDescendantRepresentation = .generated
   }
   
-  internal static func quickLookObject(_ subject: Any) -> PlaygroundQuickLook? {
+  internal static func quickLookObject(_ subject: Any) -> _PlaygroundQuickLook? {
 #if _runtime(_ObjC)
     let object = _getQuickLookObject(subject)
     return object.flatMap(_getClassPlaygroundQuickLook)
diff --git a/stdlib/public/core/Reverse.swift b/stdlib/public/core/Reverse.swift
index b40bcae..4ba2e82 100644
--- a/stdlib/public/core/Reverse.swift
+++ b/stdlib/public/core/Reverse.swift
@@ -307,9 +307,3 @@
     return ReversedCollection(_base: elements).lazy
   }
 }
-
-// @available(*, deprecated, renamed: "ReversedCollection")
-public typealias ReversedRandomAccessCollection<T: RandomAccessCollection> = ReversedCollection<T>
-
-// @available(*, deprecated, renamed: "ReversedCollection.Index")
-public typealias ReversedIndex<T: BidirectionalCollection> = ReversedCollection<T>
diff --git a/stdlib/public/core/SequenceAlgorithms.swift b/stdlib/public/core/SequenceAlgorithms.swift
index 9850b26..583f071 100644
--- a/stdlib/public/core/SequenceAlgorithms.swift
+++ b/stdlib/public/core/SequenceAlgorithms.swift
@@ -749,39 +749,6 @@
     return try _compactMap(transform)
   }
 
-  /// Returns an array containing the non-`nil` results of calling the given
-  /// transformation with each element of this sequence.
-  ///
-  /// Use this method to receive an array of nonoptional values when your
-  /// transformation produces an optional value.
-  ///
-  /// In this example, note the difference in the result of using `map` and
-  /// `flatMap` with a transformation that returns an optional `Int` value.
-  ///
-  ///     let possibleNumbers = ["1", "2", "three", "///4///", "5"]
-  ///
-  ///     let mapped: [Int?] = possibleNumbers.map { str in Int(str) }
-  ///     // [1, 2, nil, nil, 5]
-  ///
-  ///     let flatMapped: [Int] = possibleNumbers.flatMap { str in Int(str) }
-  ///     // [1, 2, 5]
-  ///
-  /// - Parameter transform: A closure that accepts an element of this
-  ///   sequence as its argument and returns an optional value.
-  /// - Returns: An array of the non-`nil` results of calling `transform`
-  ///   with each element of the sequence.
-  ///
-  /// - Complexity: O(*m* + *n*), where *m* is the length of this sequence
-  ///   and *n* is the length of the result.
-  @inline(__always)
-  @available(swift, deprecated: 4.1, renamed: "compactMap(_:)",
-    message: "Please use compactMap(_:) for the case where closure returns an optional value")
-  public func flatMap<ElementOfResult>(
-    _ transform: (Element) throws -> ElementOfResult?
-  ) rethrows -> [ElementOfResult] {
-    return try _compactMap(transform)
-  }
-
   // The implementation of flatMap accepting a closure with an optional result.
   // Factored out into a separate functions in order to be used in multiple
   // overloads.
diff --git a/stdlib/public/core/Set.swift b/stdlib/public/core/Set.swift
index 7551284..c86f420 100644
--- a/stdlib/public/core/Set.swift
+++ b/stdlib/public/core/Set.swift
@@ -4003,20 +4003,6 @@
     return remove(at: startIndex)
   }
 
-  @inlinable
-  @available(swift, obsoleted: 4.0)
-  public func filter(
-    _ isIncluded: (Element) throws -> Bool, obsoletedInSwift4: () = ()
-  ) rethrows -> [Element] {
-    var result: [Element] = []
-    for x in self {
-      if try isIncluded(x) {
-        result.append(x)
-      }
-    }
-    return result
-  }
-
   /// The total number of elements that the set can contain without
   /// allocating new storage.
   @inlinable // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/Slice.swift b/stdlib/public/core/Slice.swift
index 57c8f54..139a52b 100644
--- a/stdlib/public/core/Slice.swift
+++ b/stdlib/public/core/Slice.swift
@@ -467,27 +467,3 @@
     }
   }
 }
-
-@available(*, deprecated, renamed: "Slice")
-public typealias BidirectionalSlice<T> = Slice<T> where T : BidirectionalCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias RandomAccessSlice<T> = Slice<T> where T : RandomAccessCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias RangeReplaceableSlice<T> = Slice<T> where T : RangeReplaceableCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias RangeReplaceableBidirectionalSlice<T> = Slice<T> where T : RangeReplaceableCollection & BidirectionalCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias RangeReplaceableRandomAccessSlice<T> = Slice<T> where T : RangeReplaceableCollection & RandomAccessCollection
-
-@available(*, deprecated, renamed: "Slice")
-public typealias MutableSlice<T> = Slice<T> where T : MutableCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias MutableBidirectionalSlice<T> = Slice<T> where T : MutableCollection & BidirectionalCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias MutableRandomAccessSlice<T> = Slice<T> where T : MutableCollection & RandomAccessCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias MutableRangeReplaceableSlice<T> = Slice<T> where T : MutableCollection & RangeReplaceableCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias MutableRangeReplaceableBidirectionalSlice<T> = Slice<T> where T : MutableCollection & RangeReplaceableCollection & BidirectionalCollection
-@available(*, deprecated, renamed: "Slice")
-public typealias MutableRangeReplaceableRandomAccessSlice<T> = Slice<T> where T : MutableCollection & RangeReplaceableCollection & RandomAccessCollection
diff --git a/stdlib/public/core/StringCharacterView.swift b/stdlib/public/core/StringCharacterView.swift
deleted file mode 100644
index d2baf42..0000000
--- a/stdlib/public/core/StringCharacterView.swift
+++ /dev/null
@@ -1,97 +0,0 @@
-//===--- StringCharacterView.swift - String's Collection of Characters ----===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-//
-//  String is-not-a Sequence or Collection, but it exposes a
-//  collection of characters.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME(ABI)#70 : The character string view should have a custom iterator type
-// to allow performance optimizations of linear traversals.
-
-import SwiftShims
-
-extension String {
-  /// A view of a string's contents as a collection of characters.
-  ///
-  /// Previous versions of Swift provided this view since String
-  /// itself was not a collection. String is now a collection of
-  /// characters, so this type is now just an alias for String.
-  @available(swift, deprecated: 3.2, obsoleted: 5.0, 
-    message: "Please use String directly")
-  public typealias CharacterView = String
-
-  /// A view of the string's contents as a collection of characters.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 5.0, 
-    message: "Please use String directly")
-  public var characters: String {
-    get {
-      return self
-    }
-    set {
-      self = newValue
-    }
-  }
-
-  /// Applies the given closure to a mutable view of the string's characters.
-  ///
-  /// Previous versions of Swift provided this view since String
-  /// itself was not a collection. String is now a collection of
-  /// characters, so this type is now just an alias for String.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 5.0, 
-    message: "Please mutate the String directly")
-  public mutating func withMutableCharacters<R>(
-    _ body: (inout String) -> R
-  ) -> R {
-    return body(&self)
-  }
-}
-
-extension Substring {
-  /// A view of a string's contents as a collection of characters.
-  ///
-  /// Previous versions of Swift provided this view since String
-  /// itself was not a collection. String is now a collection of
-  /// characters, so this type is now just an alias for String.
-  @available(swift, deprecated: 3.2, obsoleted: 5.0, 
-    message: "Please use Substring directly")
-  public typealias CharacterView = Substring
-
-  /// A view of the string's contents as a collection of characters.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 5.0,
-    message: "Please use Substring directly")
-  public var characters: Substring {
-    get {
-      return self
-    }
-    set {
-      self = newValue
-    }
-  }
-
-  /// Applies the given closure to a mutable view of the string's characters.
-  ///
-  /// Previous versions of Swift provided this view since String
-  /// itself was not a collection. String is now a collection of
-  /// characters, so this type is now just an alias for String.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 5.0, 
-    message: "Please mutate the Substring directly")
-  public mutating func withMutableCharacters<R>(
-    _ body: (inout Substring) -> R
-  ) -> R {
-    return body(&self)
-  }
-}
diff --git a/stdlib/public/core/StringGraphemeBreaking.swift b/stdlib/public/core/StringGraphemeBreaking.swift
index 9a021ad..2f4c67b 100644
--- a/stdlib/public/core/StringGraphemeBreaking.swift
+++ b/stdlib/public/core/StringGraphemeBreaking.swift
@@ -255,7 +255,7 @@
 
     // Nuclear option: copy out the rest of the string into a contiguous buffer.
     let longStart = UnsafeMutablePointer<UInt16>.allocate(capacity: count)
-    defer { longStart.deallocate(capacity: count) }
+    defer { longStart.deallocate() }
     self._copy(into: UnsafeMutableBufferPointer(start: longStart, count: count))
     return UTF16._measureFirstExtendedGraphemeCluster(
       in: UnsafeBufferPointer(start: longStart, count: count))
@@ -282,7 +282,7 @@
 
     // Nuclear option: copy out the rest of the string into a contiguous buffer.
     let longStart = UnsafeMutablePointer<UInt16>.allocate(capacity: count)
-    defer { longStart.deallocate(capacity: count) }
+    defer { longStart.deallocate() }
     self._copy(into: UnsafeMutableBufferPointer(start: longStart, count: count))
     return UTF16._measureLastExtendedGraphemeCluster(
       in: UnsafeBufferPointer(start: longStart, count: count))
diff --git a/stdlib/public/core/StringIndex.swift b/stdlib/public/core/StringIndex.swift
index 39c6f62..6a45ed9 100644
--- a/stdlib/public/core/StringIndex.swift
+++ b/stdlib/public/core/StringIndex.swift
@@ -139,64 +139,3 @@
     return Int(truncatingIfNeeded: _compoundOffset & 0x3)
   }
 }
-
-// SPI for Foundation
-extension String.Index {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2)
-  @available(swift, obsoleted: 4.0)
-  public // SPI(Foundation)
-  init(_position: Int) {
-    self.init(encodedOffset: _position)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2)
-  @available(swift, obsoleted: 4.0)
-  public // SPI(Foundation)
-  init(_codeUnitOffset: Int) {
-    self.init(encodedOffset: _codeUnitOffset)
-  }
-
-  /// The integer offset of this index in UTF-16 code units.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2)
-  @available(swift, obsoleted: 4.0)
-  public // SPI(Foundation)
-  var _utf16Index: Int {
-    return self.encodedOffset
-  }
-
-  /// The integer offset of this index in UTF-16 code units.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2)
-  @available(swift, obsoleted: 4.0)
-  public // SPI(Foundation)
-  var _offset: Int {
-    return self.encodedOffset
-  }
-}
-
-
-// backward compatibility for index interchange.
-extension Optional where Wrapped == String.Index {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
-  public static func ..<(
-    lhs: String.Index?, rhs: String.Index?
-  ) -> Range<String.Index> {
-    return lhs! ..< rhs!
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
-  public static func ...(
-    lhs: String.Index?, rhs: String.Index?
-  ) -> ClosedRange<String.Index> {
-    return lhs! ... rhs!
-  }
-}
diff --git a/stdlib/public/core/StringProtocol.swift b/stdlib/public/core/StringProtocol.swift
index 0dacf5a..8842115 100644
--- a/stdlib/public/core/StringProtocol.swift
+++ b/stdlib/public/core/StringProtocol.swift
@@ -126,18 +126,6 @@
   }
 }
 
-extension StringProtocol {
-  //@available(swift, deprecated: 3.2, obsoleted: 4.0, message: "Please use the StringProtocol itself")
-  //public var characters: Self { return self }
-
-  @available(swift, deprecated: 3.2, obsoleted: 4.0, renamed: "UTF8View.Index")
-  public typealias UTF8Index = UTF8View.Index
-  @available(swift, deprecated: 3.2, obsoleted: 4.0, renamed: "UTF16View.Index")
-  public typealias UTF16Index = UTF16View.Index
-  @available(swift, deprecated: 3.2, obsoleted: 4.0, renamed: "UnicodeScalarView.Index")
-  public typealias UnicodeScalarIndex = UnicodeScalarView.Index
-}
-
 /// A protocol that provides fast access to a known representation of String.
 ///
 /// Can be used to specialize generic functions that would otherwise end up
diff --git a/stdlib/public/core/StringRangeReplaceableCollection.swift b/stdlib/public/core/StringRangeReplaceableCollection.swift
index 000ac08..f943a22 100644
--- a/stdlib/public/core/StringRangeReplaceableCollection.swift
+++ b/stdlib/public/core/StringRangeReplaceableCollection.swift
@@ -65,17 +65,6 @@
     self = other.description
   }
 
-  // The defaulted argument prevents this initializer from satisfies the
-  // LosslessStringConvertible conformance.  You can satisfy a protocol
-  // requirement with something that's not yet available, but not with
-  // something that has become unavailable. Without this, the code won't
-  // compile as Swift 4.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4, message: "String.init(_:String) is no longer failable")
-  public init?(_ other: String, obsoletedInSwift4: () = ()) {
-    self.init(other._guts)
-  }
-
   /// The position of the first character in a nonempty string.
   ///
   /// In an empty string, `startIndex` is equal to `endIndex`.
@@ -522,37 +511,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// The following overloads of flatMap are carefully crafted to allow the code
-// like the following:
-//   ["hello"].flatMap { $0 }
-// return an array of strings without any type context in Swift 3 mode, at the
-// same time allowing the following code snippet to compile:
-//   [0, 1].flatMap { x in
-//     if String(x) == "foo" { return "bar" } else { return nil }
-//   }
-// Note that the second overload is declared on a more specific protocol.
-// See: test/stdlib/StringFlatMap.swift for tests.
-extension Sequence {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public func flatMap(
-    _ transform: (Element) throws -> String
-  ) rethrows -> [String] {
-    return try map(transform)
-  }
-}
-
-extension Collection {
-  @available(swift, deprecated: 4.1, renamed: "compactMap(_:)",
-    message: "Please use compactMap(_:) for the case where closure returns an optional value")
-  @inline(__always)
-  public func flatMap(
-    _ transform: (Element) throws -> String?
-  ) rethrows -> [String] {
-    return try _compactMap(transform)
-  }
-}
-//===----------------------------------------------------------------------===//
 
 extension Sequence where Element == String {
   @available(*, unavailable, message: "Operator '+' cannot be used to append a String to a sequence of strings")
diff --git a/stdlib/public/core/StringUTF16.swift b/stdlib/public/core/StringUTF16.swift
index e8d31e9..8c8c1f1 100644
--- a/stdlib/public/core/StringUTF16.swift
+++ b/stdlib/public/core/StringUTF16.swift
@@ -294,45 +294,6 @@
   }
 
   /// Creates a string corresponding to the given sequence of UTF-16 code units.
-  ///
-  /// If `utf16` contains unpaired UTF-16 surrogates, the result is `nil`.
-  ///
-  /// You can use this initializer to create a new string from a slice of
-  /// another string's `utf16` view.
-  ///
-  ///     let picnicGuest = "Deserving porcupine"
-  ///     if let i = picnicGuest.utf16.firstIndex(of: 32) {
-  ///         let adjective = String(picnicGuest.utf16[..<i])
-  ///         print(adjective)
-  ///     }
-  ///     // Prints "Optional(Deserving)"
-  ///
-  /// The `adjective` constant is created by calling this initializer with a
-  /// slice of the `picnicGuest.utf16` view.
-  ///
-  /// - Parameter utf16: A UTF-16 code sequence.
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 4.0)
-  public init?(_ utf16: UTF16View) {
-    // Attempt to recover the whole string, the better to implement the actual
-    // Swift 3.1 semantics, which are not as documented above!  Full Swift 3.1
-    // semantics may be impossible to preserve in the case of string literals,
-    // since we no longer have access to the length of the original string when
-    // there is no owner and elements are dropped from the end.
-    let wholeString = String(utf16._guts)
-    guard
-      let start = UTF16Index(encodedOffset: utf16._offset)
-        .samePosition(in: wholeString),
-      let end = UTF16Index(encodedOffset: utf16._offset + utf16._length)
-        .samePosition(in: wholeString)
-      else
-    {
-        return nil
-    }
-    self = wholeString[start..<end]
-  }
-
-  /// Creates a string corresponding to the given sequence of UTF-16 code units.
   @inlinable // FIXME(sil-serialize-all)
   @available(swift, introduced: 4.0)
   public init(_ utf16: UTF16View) {
@@ -434,14 +395,6 @@
   }
 }
 
-extension String.UTF16View : CustomPlaygroundQuickLookable {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(*, deprecated, message: "UTF16View.customPlaygroundQuickLook will be removed in a future Swift version")
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
-    return .text(description)
-  }
-}
-
 extension String.UTF16View.Indices : BidirectionalCollection {
   public typealias Index = String.UTF16View.Index
   public typealias Indices = String.UTF16View.Indices
@@ -534,39 +487,6 @@
   }
 }
 
-// backward compatibility for index interchange.
-extension String.UTF16View {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public func index(after i: Index?) -> Index {
-    return index(after: i!)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public func index(
-    _ i: Index?, offsetBy n: Int) -> Index {
-    return index(i!, offsetBy: n)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
-  public func distance(from i: Index?, to j: Index?) -> Int {
-    return distance(from: i!, to: j!)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public subscript(i: Index?) -> Unicode.UTF16.CodeUnit {
-    return self[i!]
-  }
-}
-
 //===--- Slicing Support --------------------------------------------------===//
 /// In Swift 3.2, in the absence of type context,
 ///
@@ -580,22 +500,7 @@
 
   @inlinable // FIXME(sil-serialize-all)
   @available(swift, introduced: 4)
-  public subscript(r: Range<Index>) -> String.UTF16View.SubSequence {
-    return String.UTF16View.SubSequence(self, _bounds: r)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: Range<Index>) -> String.UTF16View {
-    return String.UTF16View(
-      _guts,
-      offset: _internalIndex(at: bounds.lowerBound.encodedOffset),
-      length: bounds.upperBound.encodedOffset - bounds.lowerBound.encodedOffset)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: ClosedRange<Index>) -> String.UTF16View {
-    return self[bounds.relative(to: self)]
+  public subscript(bounds: Range<Index>) -> String.UTF16View.SubSequence {
+    return String.UTF16View.SubSequence(self, _bounds: bounds)
   }
 }
diff --git a/stdlib/public/core/StringUTF8.swift b/stdlib/public/core/StringUTF8.swift
index ab76cd2..65b155b 100644
--- a/stdlib/public/core/StringUTF8.swift
+++ b/stdlib/public/core/StringUTF8.swift
@@ -178,7 +178,7 @@
         _guts, range: (n..<count, performBoundsCheck: true),
         ascii: { _ in
           Builtin.unreachable()
-          return Index._UTF8Buffer() },
+          /* return Index._UTF8Buffer() */ },
         utf16: { utf16 in
           var i = utf16.makeIterator()
           return UTF8View._fillBuffer(from: &i) },
@@ -451,38 +451,6 @@
   }
 
   /// Creates a string corresponding to the given sequence of UTF-8 code units.
-  ///
-  /// If `utf8` is an ill-formed UTF-8 code sequence, the result is `nil`.
-  ///
-  /// You can use this initializer to create a new string from a slice of
-  /// another string's `utf8` view.
-  ///
-  ///     let picnicGuest = "Deserving porcupine"
-  ///     if let i = picnicGuest.utf8.firstIndex(of: 32) {
-  ///         let adjective = String(picnicGuest.utf8[..<i])
-  ///         print(adjective)
-  ///     }
-  ///     // Prints "Optional(Deserving)"
-  ///
-  /// The `adjective` constant is created by calling this initializer with a
-  /// slice of the `picnicGuest.utf8` view.
-  ///
-  /// - Parameter utf8: A UTF-8 code sequence.
-  @available(swift, deprecated: 3.2,
-    message: "Failable initializer was removed in Swift 4. When upgrading to Swift 4, please use non-failable String.init(_:UTF8View)")
-  @available(swift, obsoleted: 4.0,
-    message: "Please use non-failable String.init(_:UTF8View) instead")
-  public init?(_ utf8: UTF8View) {
-    if utf8.startIndex.transcodedOffset != 0
-      || utf8.endIndex.transcodedOffset != 0
-      || utf8._legacyPartialCharacters.start
-      || utf8._legacyPartialCharacters.end {
-      return nil
-    }
-    self = String(utf8._guts)
-  }
-
-  /// Creates a string corresponding to the given sequence of UTF-8 code units.
   @inlinable // FIXME(sil-serialize-all)
   @available(swift, introduced: 4.0, message:
     "Please use failable String.init?(_:UTF8View) when in Swift 3.2 mode")
@@ -722,47 +690,6 @@
   }
 }
 
-extension String.UTF8View : CustomPlaygroundQuickLookable {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(*, deprecated, message: "UTF8View.customPlaygroundQuickLook will be removed in a future Swift version")
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
-    return .text(description)
-  }
-}
-
-// backward compatibility for index interchange.
-extension String.UTF8View {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public func index(after i: Index?) -> Index {
-    return index(after: i!)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public func index(_ i: Index?, offsetBy n: Int) -> Index {
-    return index(i!, offsetBy: n)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
-  public func distance(
-    from i: Index?, to j: Index?) -> Int {
-    return distance(from: i!, to: j!)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public subscript(i: Index?) -> Unicode.UTF8.CodeUnit {
-    return self[i!]
-  }
-}
-
 //===--- Slicing Support --------------------------------------------------===//
 /// In Swift 3.2, in the absence of type context,
 ///
@@ -779,42 +706,6 @@
   public subscript(r: Range<Index>) -> String.UTF8View.SubSequence {
     return String.UTF8View.SubSequence(self, _bounds: r)
   }
-
-  @available(swift, obsoleted: 4)
-  public subscript(r: Range<Index>) -> String.UTF8View {
-    let wholeString = String(_guts)
-    let legacyPartialCharacters = (
-      (self._legacyPartialCharacters.start &&
-        r.lowerBound.encodedOffset == 0) ||
-      r.lowerBound.samePosition(in: wholeString) == nil,
-      (self._legacyPartialCharacters.end &&
-        r.upperBound.encodedOffset == _guts.count) ||
-      r.upperBound.samePosition(in: wholeString) == nil)
-
-    if r.upperBound.transcodedOffset == 0 {
-      return String.UTF8View(
-        _guts._extractSlice(
-        r.lowerBound.encodedOffset..<r.upperBound.encodedOffset),
-        legacyOffsets: (r.lowerBound.transcodedOffset, 0),
-        legacyPartialCharacters: legacyPartialCharacters)
-    }
-
-    let b0 = r.upperBound.utf8Buffer!.first!
-    let scalarLength8 = (~b0).leadingZeroBitCount
-    let scalarLength16 = scalarLength8 == 4 ? 2 : 1
-    let coreEnd = r.upperBound.encodedOffset + scalarLength16
-    return String.UTF8View(
-      _guts._extractSlice(r.lowerBound.encodedOffset..<coreEnd),
-      legacyOffsets: (
-        r.lowerBound.transcodedOffset,
-        r.upperBound.transcodedOffset - scalarLength8),
-      legacyPartialCharacters: legacyPartialCharacters)
-  }
-
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: ClosedRange<Index>) -> String.UTF8View {
-    return self[bounds.relative(to: self)]
-  }
 }
 
 extension String.UTF8View {
diff --git a/stdlib/public/core/StringUnicodeScalarView.swift b/stdlib/public/core/StringUnicodeScalarView.swift
index 586a9da..b0c047d 100644
--- a/stdlib/public/core/StringUnicodeScalarView.swift
+++ b/stdlib/public/core/StringUnicodeScalarView.swift
@@ -124,7 +124,7 @@
     public func index(after i: Index) -> Index {
       let offset = _toCoreIndex(i)
       let length: Int = _visitGuts(_guts, args: offset,
-        ascii: { _ -> Int in return 1 },
+        ascii: { (_,_) -> Int in return 1 },
         utf16: { utf16, offset in
           return utf16.unicodeScalarWidth(startingAt: offset) },
         opaque: { opaque, offset in
@@ -140,7 +140,7 @@
     public func index(before i: Index) -> Index {
       let offset = _toCoreIndex(i)
       let length: Int = _visitGuts(_guts, args: offset,
-        ascii: { _ -> Int in return 1 },
+        ascii: { (_,_) -> Int in return 1 },
         utf16: { utf16, offset in
           return utf16.unicodeScalarWidth(endingAt: offset) },
         opaque: { opaque, offset in
@@ -554,46 +554,6 @@
   }
 }
 
-extension String.UnicodeScalarView : CustomPlaygroundQuickLookable {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(*, deprecated, message: "UnicodeScalarView.customPlaygroundQuickLook will be removed in a future Swift version")
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
-    return .text(description)
-  }
-}
-
-// backward compatibility for index interchange.
-extension String.UnicodeScalarView {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public func index(after i: Index?) -> Index {
-    return index(after: i!)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public func index(_ i: Index?,  offsetBy n: Int) -> Index {
-    return index(i!, offsetBy: n)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional indices")
-  public func distance(from i: Index?, to j: Index?) -> Int {
-    return distance(from: i!, to: j!)
-  }
-  @inlinable // FIXME(sil-serialize-all)
-  @available(
-    swift, obsoleted: 4.0,
-    message: "Any String view index conversion can fail in Swift 4; please unwrap the optional index")
-  public subscript(i: Index?) -> Unicode.Scalar {
-    return self[i!]
-  }
-}
-
 //===--- Slicing Support --------------------------------------------------===//
 /// In Swift 3.2, in the absence of type context,
 ///
@@ -609,35 +569,7 @@
 
   @inlinable // FIXME(sil-serialize-all)
   @available(swift, introduced: 4)
-  public subscript(r: Range<Index>) -> String.UnicodeScalarView.SubSequence {
-    return String.UnicodeScalarView.SubSequence(self, _bounds: r)
-  }
-
-  /// Accesses the Unicode scalar values in the given range.
-  ///
-  /// The example below uses this subscript to access the scalar values up
-  /// to, but not including, the first comma (`","`) in the string.
-  ///
-  ///     let str = "All this happened, more or less."
-  ///     let i = str.unicodeScalars.firstIndex(of: ",")!
-  ///     let substring = str.unicodeScalars[str.unicodeScalars.startIndex ..< i]
-  ///     print(String(substring))
-  ///     // Prints "All this happened"
-  ///
-  /// - Complexity: O(*n*) if the underlying string is bridged from
-  ///   Objective-C, where *n* is the length of the string; otherwise, O(1).
-  @available(swift, obsoleted: 4)
-  public subscript(r: Range<Index>) -> String.UnicodeScalarView {
-    let rawSubRange: Range<Int> =
-      _toCoreIndex(r.lowerBound)..<_toCoreIndex(r.upperBound)
-    return String.UnicodeScalarView(
-      _guts._extractSlice(rawSubRange),
-      coreOffset: r.lowerBound.encodedOffset)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: ClosedRange<Index>) -> String.UnicodeScalarView {
-    return self[bounds.relative(to: self)]
+  public subscript(bounds: Range<Index>) -> String.UnicodeScalarView.SubSequence {
+    return String.UnicodeScalarView.SubSequence(self, _bounds: bounds)
   }
 }
diff --git a/stdlib/public/core/Substring.swift.gyb b/stdlib/public/core/Substring.swift.gyb
index f9038b0..2bd5684 100644
--- a/stdlib/public/core/Substring.swift.gyb
+++ b/stdlib/public/core/Substring.swift.gyb
@@ -330,14 +330,6 @@
   }
 }
 
-extension Substring : CustomPlaygroundQuickLookable {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(*, deprecated, message: "Substring.customPlaygroundQuickLook will be removed in a future Swift version")
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
-    return String(self).customPlaygroundQuickLook
-  }
-}
-
 extension Substring : CustomStringConvertible {
   @inlinable // FIXME(sil-serialize-all)
   public var description: String {
@@ -622,22 +614,6 @@
     return Substring(
       _slice: Slice(base: self, bounds: r))
   }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: Range<Index>) -> String {
-    _boundsCheck(bounds)
-    return String(Substring(_slice: Slice(base: self, bounds: bounds)))
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: ClosedRange<Index>) -> String {
-    _boundsCheck(bounds)
-    return String(Substring(_slice: Slice(
-          base: self,
-          bounds: bounds.relative(to: self))))
-  }
 }
 
 extension Substring {
@@ -646,46 +622,6 @@
   public subscript(r: Range<Index>) -> Substring {
     return Substring(_slice: _slice[r])
   }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: Range<Index>) -> String {
-    return String(Substring(_slice: _slice[bounds]))
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, obsoleted: 4)
-  public subscript(bounds: ClosedRange<Index>) -> String {
-    return self[bounds.relative(to: self)]
-  }
-}
-//===----------------------------------------------------------------------===//
-
-// popFirst() is only present when a collection is its own subsequence. This was
-// dropped in Swift 4.
-extension String {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 4, message:
-    "Please use 'first', 'dropFirst()', or 'Substring.popFirst()'.")
-  public mutating func popFirst() -> String.Element? {
-    guard !isEmpty else { return nil }
-    let element = first!
-    let nextIdx = self.index(after: self.startIndex)
-    self = String(self[nextIdx...])
-    return element
-  }
-}
-extension String.UnicodeScalarView {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(swift, deprecated: 3.2, obsoleted: 4, message:
-    "Please use 'first', 'dropFirst()', or 'Substring.UnicodeScalarView.popFirst()'.")
-  public mutating func popFirst() -> String.UnicodeScalarView.Element? {
-    guard !isEmpty else { return nil }
-    let element = first!
-    let nextIdx = self.index(after: self.startIndex)
-    self = String(self[nextIdx...]).unicodeScalars
-    return element
-  }
 }
 
 // ${'Local Variables'}:
diff --git a/stdlib/public/core/Unicode.swift b/stdlib/public/core/Unicode.swift
index 64ca5d1..768ec85 100644
--- a/stdlib/public/core/Unicode.swift
+++ b/stdlib/public/core/Unicode.swift
@@ -314,9 +314,6 @@
   }
 }
 
-// @available(swift, obsoleted: 4.0, renamed: "Unicode.UTF8")
-public typealias UTF8 = Unicode.UTF8
-
 /// A codec for translating between Unicode scalar values and UTF-16 code
 /// units.
 extension Unicode.UTF16 : UnicodeCodec {
@@ -428,8 +425,6 @@
     processCodeUnit(UInt16(truncatingIfNeeded: s))
   }
 }
-// @available(swift, obsoleted: 4.0, renamed: "Unicode.UTF16")
-public typealias UTF16 = Unicode.UTF16
 
 /// A codec for translating between Unicode scalar values and UTF-32 code
 /// units.
@@ -523,8 +518,6 @@
     processCodeUnit(UInt32(input))
   }
 }
-// @available(swift, obsoleted: 4.0, renamed: "Unicode.UTF32")
-public typealias UTF32 = Unicode.UTF32
 
 /// Translates the given input from one Unicode encoding to another by calling
 /// the given closure.
diff --git a/stdlib/public/core/UnicodeScalar.swift b/stdlib/public/core/UnicodeScalar.swift
index 7d095f6..9691523 100644
--- a/stdlib/public/core/UnicodeScalar.swift
+++ b/stdlib/public/core/UnicodeScalar.swift
@@ -466,6 +466,3 @@
     Builtin.unreachable()
   }
 }
-
-// @available(swift, obsoleted: 4.0, renamed: "Unicode.Scalar")
-public typealias UnicodeScalar = Unicode.Scalar
diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
index f6c7cf7..13c8031 100644
--- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
@@ -667,9 +667,6 @@
   }
 }
 
-@available(*, deprecated, renamed: "UnsafeBufferPointer.Iterator")
-public typealias UnsafeBufferPointerIterator<T> = UnsafeBufferPointer<T>.Iterator
-
 // ${'Local Variables'}:
 // eval: (read-only-mode 1)
 // End:
diff --git a/stdlib/public/core/UnsafePointer.swift.gyb b/stdlib/public/core/UnsafePointer.swift.gyb
index 51d619d..bd9584f 100644
--- a/stdlib/public/core/UnsafePointer.swift.gyb
+++ b/stdlib/public/core/UnsafePointer.swift.gyb
@@ -436,12 +436,6 @@
     Builtin.bindMemory(rawPtr, count._builtinWordValue, Pointee.self)
     return UnsafeMutablePointer(rawPtr)
   }
-  
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
-  public func deallocate(capacity _: Int) { 
-    self.deallocate()
-  }
-
 %  end
 
   /// Deallocates the memory block previously allocated at this pointer.
@@ -485,11 +479,6 @@
   }
 
 %  if mutable:
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "initialize(repeating:count:)")
-  public func initialize(to newValue: Pointee, count: Int = 1) { 
-    initialize(repeating: newValue, count: count)
-  }
-
   /// Initializes this pointer's memory with the specified number of
   /// consecutive copies of the given value.
   ///
@@ -683,28 +672,6 @@
     // }
   }
 
-  /// Initializes memory starting at this pointer's address with the elements
-  /// of the given collection.
-  ///
-  /// The region of memory starting at this pointer and covering `source.count`
-  /// instances of the pointer's `Pointee` type must be uninitialized or
-  /// `Pointee` must be a trivial type. After calling `initialize(from:)`, the
-  /// region is initialized.
-  ///
-  /// - Parameter source: A collection of elements of the pointer's `Pointee`
-  ///   type.
-  // This is fundamentally unsafe since collections can underreport their count.
-  @inlinable
-  @available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'UnsafeMutableBufferPointer.initialize(from:)' instead")
-  public func initialize<C : Collection>(from source: C)
-    where C.Element == Pointee {
-    let buf = UnsafeMutableBufferPointer(start: self, count: numericCast(source.count))
-    var (remainders,writtenUpTo) = source._copyContents(initializing: buf)
-    // ensure that exactly rhs.count elements were written
-    _precondition(remainders.next() == nil, "rhs underreported its count")
-    _precondition(writtenUpTo == buf.endIndex, "rhs overreported its count")
-  }
-
   /// Replaces the memory referenced by this pointer with the values
   /// starting at the given pointer, leaving the source memory uninitialized.
   ///
@@ -735,13 +702,6 @@
     // }
   }
   
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "the default argument to deinitialize(count:) has been removed, please specify the count explicitly") 
-  @inlinable
-  @discardableResult
-  public func deinitialize() -> UnsafeMutableRawPointer {
-    return deinitialize(count: 1)
-  }
-  
   /// Deinitializes the specified number of values starting at this pointer.
   ///
   /// The region of memory starting at this pointer and covering `count`
@@ -999,21 +959,6 @@
   }
 }
 
-extension ${Self} : CustomPlaygroundQuickLookable {
-  @inlinable // FIXME(sil-serialize-all)
-  internal var summary: String {
-    let selfType = "${Self}"
-    let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
-    return ptrValue == 0 ? "\(selfType)(nil)" : "\(selfType)(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @available(*, deprecated, message: "${Self}.customPlaygroundQuickLook will be removed in a future Swift version")
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
-    return .text(summary)
-  }
-}
-
 extension Int {
   /// Creates a new value with the bit pattern of the given pointer.
   ///
diff --git a/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb b/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
index 7abe817..cb3b501 100644
--- a/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb
@@ -263,12 +263,6 @@
 
 extension Unsafe${Mutable}RawBufferPointer {
 %  if mutable:
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "allocate(byteCount:alignment:)")
-  public static func allocate(count: Int) -> UnsafeMutableRawBufferPointer { 
-    return UnsafeMutableRawBufferPointer.allocate(
-      byteCount: count, alignment: MemoryLayout<UInt>.alignment)
-  }
-
   /// Returns a newly allocated buffer with the given size, in bytes.
   ///
   /// The memory referenced by the new buffer is allocated, but not
@@ -374,10 +368,6 @@
     baseAddress!.storeBytes(of: value, toByteOffset: offset, as: T.self)
   }
 
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "copyMemory(from:)")
-  public func copyBytes(from source: UnsafeRawBufferPointer) {
-    copyMemory(from: source)
-  }
   /// Copies the bytes from the given buffer to this buffer's memory.
   ///
   /// If the `source.count` bytes of memory referenced by this buffer are bound
@@ -814,12 +804,6 @@
   return try body(buffer)
 }
 
-// @available(*, deprecated, renamed: "UnsafeRawBufferPointer.Iterator")
-public typealias UnsafeRawBufferPointerIterator<T> = UnsafeBufferPointer<T>.Iterator
-
-// @available(*, deprecated, renamed: "UnsafeRawBufferPointer.Iterator")
-public typealias UnsafeMutableRawBufferPointerIterator<T> = UnsafeBufferPointer<T>.Iterator
-
 // ${'Local Variables'}:
 // eval: (read-only-mode 1)
 // End:
diff --git a/stdlib/public/core/UnsafeRawPointer.swift.gyb b/stdlib/public/core/UnsafeRawPointer.swift.gyb
index 5fc78d8..e52a332 100644
--- a/stdlib/public/core/UnsafeRawPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeRawPointer.swift.gyb
@@ -426,15 +426,6 @@
 %  end # !mutable
 
 %  if mutable:
-
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "allocate(byteCount:alignment:)")
-  @inlinable
-  public static func allocate(
-    bytes size: Int, alignedTo alignment: Int
-  ) -> UnsafeMutableRawPointer {
-    return UnsafeMutableRawPointer.allocate(byteCount: size, alignment: alignment)
-  }
-
   /// Allocates uninitialized memory with the specified size and alignment.
   ///
   /// You are in charge of managing the allocated memory. Be sure to deallocate
@@ -460,11 +451,6 @@
   }
 %  end # mutable
 
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
-  public func deallocate(bytes _: Int, alignedTo _: Int) { 
-    self.deallocate()
-  }
-
   /// Deallocates the previously allocated memory block referenced by this pointer.
   ///
   /// The memory to be deallocated must be uninitialized or initialized to a
@@ -537,17 +523,7 @@
     return Unsafe${Mutable}Pointer<T>(_rawValue)
   }
 
-%  if mutable:
-
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "initializeMemory(as:repeating:count:)")
-  @discardableResult
-  public func initializeMemory<T>(
-    as type: T.Type, at offset: Int = 0, count: Int = 1, to repeatedValue: T
-  ) -> UnsafeMutablePointer<T> { 
-    return (self + offset * MemoryLayout<T>.stride).initializeMemory(
-      as: type, repeating: repeatedValue, count: count)
-  }
-  
+%  if mutable:  
   /// Initializes the memory referenced by this pointer with the given value,
   /// binds the memory to the value's type, and returns a typed pointer to the
   /// initialized memory.
@@ -665,62 +641,6 @@
     return UnsafeMutablePointer(_rawValue)
   }
 
-  /// Initializes the memory referenced by this pointer with the values of the
-  /// given collection, binds the memory to the values' type, and returns a
-  /// typed pointer to the initialized memory.
-  ///
-  /// The memory referenced by this pointer must be uninitialized or
-  /// initialized to a trivial type, and must be properly aligned for
-  /// accessing `T`.
-  ///
-  /// The following example allocates enough raw memory to hold four instances
-  /// of `Int8`, and then uses the `initializeMemory(as:from:)` method to
-  /// initialize the allocated memory.
-  ///
-  ///     let count = 4
-  ///     let bytesPointer = UnsafeMutableRawPointer.allocate(
-  ///             bytes: count * MemoryLayout<Int8>.stride,
-  ///             alignedTo: MemoryLayout<Int8>.alignment)
-  ///     let values: [Int8] = [1, 2, 3, 4]
-  ///     let int8Pointer = bytesPointer.initializeMemory(
-  ///             as: Int8.self,
-  ///             from: values)
-  ///     // int8Pointer.pointee == 1
-  ///     // (int8Pointer + 3).pointee == 4
-  ///
-  ///     // After using 'int8Pointer':
-  ///     int8Pointer.deallocate(count)
-  ///
-  /// After calling this method on a raw pointer `p`, the region starting at
-  /// `p` and continuing up to `p + count * MemoryLayout<T>.stride` is bound
-  /// to type `T` and initialized. If `T` is a nontrivial type, you must
-  /// eventually deinitialize or move from the values in this region to avoid
-  /// leaks.
-  ///
-  /// - Parameters:
-  ///   - type: The type to bind this memory to.
-  ///   - source: A pointer to the values to copy. If `source` is an
-  ///     `UnsafeBufferPointer` or `UnsafeMutableBufferPointer` instance, the
-  ///     memory region referenced by `source` must not overlap the
-  ///     destination region.
-  /// - Returns: A typed pointer to the memory referenced by this raw pointer.
-  // This is fundamentally unsafe since collections can underreport their count.
-  @inlinable
-  @available(*, deprecated, message: "it will be removed in Swift 4.0.  Please use 'UnsafeMutableRawBufferPointer.initialize(from:)' instead")
-  @discardableResult
-  public func initializeMemory<C : Collection>(
-    as type: C.Element.Type, from source: C
-  ) -> UnsafeMutablePointer<C.Element> {
-    // TODO: Optimize where `C` is a `ContiguousArrayBuffer`.
-    // Initialize and bind each element of the container.
-    var ptr = self
-    for element in source {
-      ptr.initializeMemory(as: C.Element.self, repeating: element, count: 1)
-      ptr += MemoryLayout<C.Element>.stride
-    }
-    return UnsafeMutablePointer(_rawValue)
-  }
-
   /// Initializes the memory referenced by this pointer with the values
   /// starting at the given pointer, binds the memory to the values' type,
   /// deinitializes the source memory, and returns a typed pointer to the
@@ -864,11 +784,6 @@
         /*volatile:*/ false._value)
     }
   }
-
-  @available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "copyMemory(from:byteCount:)")
-  public func copyBytes(from source: UnsafeRawPointer, count: Int) {
-    copyMemory(from: source, byteCount: count)
-  }
   
   /// Copies the specified number of bytes from the given raw pointer's memory
   /// into this pointer's memory.
@@ -991,24 +906,6 @@
   }
 }
 
-extension Unsafe${Mutable}RawPointer : CustomPlaygroundQuickLookable {
-  @inlinable // FIXME(sil-serialize-all)
-  @available(*, deprecated, message: "Unsafe${Mutable}RawPointer.customPlaygroundQuickLook will be removed in a future Swift version")
-  internal var summary: String {
-    let selfType = "${Self}"
-    let ptrValue = UInt64(
-      bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
-    return ptrValue == 0
-    ? "\(selfType)(nil)"
-    : "\(selfType)(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  public var customPlaygroundQuickLook: PlaygroundQuickLook {
-    return .text(summary)
-  }
-}
-
 extension OpaquePointer {
   @inlinable
   public init(_ from: Unsafe${Mutable}RawPointer) {
diff --git a/stdlib/public/core/Zip.swift b/stdlib/public/core/Zip.swift
index eb6a6c8..5bb3dc5 100644
--- a/stdlib/public/core/Zip.swift
+++ b/stdlib/public/core/Zip.swift
@@ -74,11 +74,6 @@
   @usableFromInline // FIXME(sil-serialize-all)
   internal let _sequence2: Sequence2
 
-  @available(*, deprecated, renamed: "Sequence1.Iterator")
-  public typealias Stream1 = Sequence1.Iterator
-  @available(*, deprecated, renamed: "Sequence2.Iterator")
-  public typealias Stream2 = Sequence2.Iterator
-
   /// Creates an instance that makes pairs of elements from `sequence1` and
   /// `sequence2`.
   @inlinable // FIXME(sil-serialize-all)
@@ -151,6 +146,3 @@
       _sequence2.makeIterator())
   }
 }
-
-@available(*, deprecated: 4.2, renamed: "Zip2Sequence.Iterator")
-public typealias Zip2Iterator<T, U> = Zip2Sequence<T, U>.Iterator where T: Sequence, U: Sequence
diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp
index 07fb3fe..55aeb92 100644
--- a/stdlib/public/runtime/Demangle.cpp
+++ b/stdlib/public/runtime/Demangle.cpp
@@ -160,8 +160,14 @@
         
         auto typeNode = Dem.createNode(nodeKind);
         typeNode->addChild(node, Dem);
-        auto identifier = Dem.createNode(Node::Kind::Identifier, name);
-        typeNode->addChild(identifier, Dem);
+        auto nameNode = Dem.createNode(Node::Kind::Identifier, name);
+        if (type->isSynthesizedRelatedEntity()) {
+          auto relatedName = Dem.createNode(Node::Kind::RelatedEntityDeclName,
+                                    type->getSynthesizedDeclRelatedEntityTag());
+          relatedName->addChild(nameNode, Dem);
+          nameNode = relatedName;
+        }
+        typeNode->addChild(nameNode, Dem);
         node = typeNode;
         
         // Apply generic arguments if the context is generic.
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 903511d..70b3580 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -1473,7 +1473,20 @@
         && kind <= ContextDescriptorKind::Type_Last) {
       auto typeA = cast<TypeContextDescriptor>(a);
       auto typeB = cast<TypeContextDescriptor>(b);
-      return strcmp(typeA->Name.get(), typeB->Name.get()) == 0;
+      if (strcmp(typeA->Name.get(), typeB->Name.get()) != 0)
+        return false;
+      
+      // A synthesized entity has to match the related entity tag too.
+      if (typeA->isSynthesizedRelatedEntity()) {
+        if (!typeB->isSynthesizedRelatedEntity())
+          return false;
+        
+        if (typeA->getSynthesizedDeclRelatedEntityTag()
+            != typeB->getSynthesizedDeclRelatedEntityTag())
+          return false;
+      }
+      
+      return true;
     }
     
     // Otherwise, this runtime doesn't know anything about this context kind.
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index a239b0b..be28b62 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -264,14 +264,31 @@
         }
 
         auto nameNode = node->getChild(1);
-        if (nameNode->getKind() == Demangle::Node::Kind::PrivateDeclName)
-          return false;
-
-        if (nameNode->getText() != type->Name.get())
-          return false;
         
-        node = node->getChild(0);
-        break;
+        // Declarations synthesized by the Clang importer get a small tag
+        // string in addition to their name.
+        if (nameNode->getKind() == Demangle::Node::Kind::RelatedEntityDeclName){
+          if (nameNode->getText() != type->getSynthesizedDeclRelatedEntityTag())
+            return false;
+          
+          nameNode = nameNode->getChild(0);
+        } else if (type->isSynthesizedRelatedEntity()) {
+          return false;
+        }
+        
+        // We should only match public or internal declarations with stable
+        // names. The runtime metadata for private declarations would be
+        // anonymized.
+        if (nameNode->getKind() == Demangle::Node::Kind::Identifier) {
+          if (nameNode->getText() != type->Name.get())
+            return false;
+          
+          node = node->getChild(0);
+          break;
+        }
+        
+        return false;
+
       }
       
       // We don't know about this kind of context, or it doesn't have a stable
@@ -1166,7 +1183,7 @@
     if (typeInfo == nullptr) {
       typeInfo = TypeInfo(&METADATA_SYM(EMPTY_TUPLE_MANGLING), {});
       warning(0, "SWIFT RUNTIME BUG: unable to demangle type of field '%*s'. "
-                 "mangled type name is '%*s'",
+                 "mangled type name is '%*s'\n",
                  (int)name.size(), name.data(),
                  (int)typeName.size(), typeName.data());
     }
@@ -1214,6 +1231,17 @@
         return;
     }
   }
+
+  // If we failed to find the field descriptor metadata for the type, fall
+  // back to returning an empty tuple as a standin.
+  auto typeName = swift_getTypeName(base, /*qualified*/ true);
+  warning(0, "SWIFT RUNTIME BUG: unable to find field metadata for type '%*s'\n",
+             (int)typeName.length, typeName.data);
+  callback("unknown",
+           FieldType()
+             .withType(TypeInfo(&METADATA_SYM(EMPTY_TUPLE_MANGLING), {}))
+             .withIndirect(false)
+             .withWeak(false));
 }
 
 #define OVERRIDE_METADATALOOKUP COMPATIBILITY_OVERRIDE
diff --git a/test/ClangImporter/Inputs/custom-modules/AvailabilityExtras.h b/test/ClangImporter/Inputs/custom-modules/AvailabilityExtras.h
index eb2a7f2..9a27ab4 100644
--- a/test/ClangImporter/Inputs/custom-modules/AvailabilityExtras.h
+++ b/test/ClangImporter/Inputs/custom-modules/AvailabilityExtras.h
@@ -97,6 +97,10 @@
 @interface AccessorDeprecations: NSObject
 @property int fullyDeprecated __attribute__((deprecated));
 
+@property NSInteger fullyDeprecatedOnAccessors;
+- (NSInteger)fullyDeprecatedOnAccessors __attribute__((deprecated));
+- (void)setFullyDeprecatedOnAccessors:(NSInteger)fullyDeprecatedOnAccessors __attribute__((deprecated));
+
 @property int getterDeprecated;
 - (int)getterDeprecated __attribute__((deprecated));
 @property (class) int getterDeprecatedClass;
@@ -112,6 +116,10 @@
 @interface UnavailableAccessors: NSObject
 @property NSInteger fullyUnavailable __attribute__((unavailable));
 
+@property NSInteger fullyUnavailableOnAccessors;
+- (NSInteger)fullyUnavailableOnAccessors __attribute__((unavailable));
+- (void)setFullyUnavailableOnAccessors:(NSInteger)fullyUnavailableOnAccessors __attribute__((unavailable));
+
 @property NSInteger getterUnavailable;
 - (NSInteger)getterUnavailable __attribute__((unavailable));
 @property (class) NSInteger getterUnavailableClass;
@@ -122,3 +130,42 @@
 @property (class) NSInteger setterUnavailableClass;
 + (void)setSetterUnavailableClass:(NSInteger)setterUnavailable __attribute__((unavailable));
 @end
+
+
+@interface UnavailableSubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i __attribute__((unavailable("bad subscript getter")));
+- (void)setObject:(nonnull NSString *)obj atIndexedSubscript:(NSInteger)i __attribute__((unavailable("bad subscript setter")));
+@end
+
+@interface UnavailableGetterSubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i __attribute__((unavailable("bad subscript getter")));
+- (void)setObject:(nonnull NSString *)obj atIndexedSubscript:(NSInteger)i;
+@end
+
+@interface UnavailableSetterSubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i;
+- (void)setObject:(nonnull NSString *)obj atIndexedSubscript:(NSInteger)i __attribute__((unavailable("bad subscript setter")));
+@end
+
+@interface UnavailableReadOnlySubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i __attribute__((unavailable));
+@end
+
+@interface DeprecatedSubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i __attribute__((deprecated("bad subscript getter")));
+- (void)setObject:(nonnull NSString *)obj atIndexedSubscript:(NSInteger)i __attribute__((deprecated("bad subscript setter")));
+@end
+
+@interface DeprecatedGetterSubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i __attribute__((deprecated("bad subscript getter")));
+- (void)setObject:(nonnull NSString *)obj atIndexedSubscript:(NSInteger)i;
+@end
+
+@interface DeprecatedSetterSubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i;
+- (void)setObject:(nonnull NSString *)obj atIndexedSubscript:(NSInteger)i __attribute__((deprecated("bad subscript setter")));
+@end
+
+@interface DeprecatedReadOnlySubscript: NSObject
+- (nonnull NSString *)objectAtIndexedSubscript:(NSInteger)i __attribute__((deprecated));
+@end
diff --git a/test/ClangImporter/SceneKit_test.swift b/test/ClangImporter/SceneKit_test.swift
index 0841328..7c24a0b 100644
--- a/test/ClangImporter/SceneKit_test.swift
+++ b/test/ClangImporter/SceneKit_test.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -swift-version 3
+// RUN: %target-typecheck-verify-swift
 
 // REQUIRES: objc_interop
 // REQUIRES: OS=macosx
@@ -190,7 +190,7 @@
   let _ = SCNIKConstraint.inverseKinematicsConstraint(chainRootNode: node)
 
   let _ = geometry.material(named: "mat")
-  let _ = geometry.getGeometrySources(for: semantic)
+  let _ = geometry.sources(for: semantic)
   let geoSrc = SCNGeometrySource(data: data, semantic: semantic, vectorCount: 2,
                                  usesFloatComponents: false,
                                  componentsPerVector: 3,
diff --git a/test/ClangImporter/availability.swift b/test/ClangImporter/availability.swift
index 9e744f4..9dc6dc1 100644
--- a/test/ClangImporter/availability.swift
+++ b/test/ClangImporter/availability.swift
@@ -25,11 +25,19 @@
   NSDeallocateObject(x) // expected-error {{'NSDeallocateObject' is unavailable}}
 }
 
-func test_unavailable_accessors(_ obj: UnavailableAccessors) {
+func test_unavailable_accessors(_ obj: UnavailableAccessors,
+    _ sub: UnavailableSubscript,
+    _ subGetter: UnavailableGetterSubscript,
+    _ subSetter: UnavailableSetterSubscript,
+    _ subReadOnly: UnavailableReadOnlySubscript) {
   _ = obj.fullyUnavailable // expected-error {{'fullyUnavailable' is unavailable}}
   obj.fullyUnavailable = 0 // expected-error {{'fullyUnavailable' is unavailable}}
   obj.fullyUnavailable += 1 // expected-error {{'fullyUnavailable' is unavailable}}
 
+  _ = obj.fullyUnavailableOnAccessors // expected-error {{getter for 'fullyUnavailableOnAccessors' is unavailable}}
+  obj.fullyUnavailableOnAccessors = 0 // expected-error {{setter for 'fullyUnavailableOnAccessors' is unavailable}}
+  obj.fullyUnavailableOnAccessors += 1 // expected-error {{getter for 'fullyUnavailableOnAccessors' is unavailable}} expected-error {{setter for 'fullyUnavailableOnAccessors' is unavailable}}
+
   _ = obj.getterUnavailable // expected-error {{getter for 'getterUnavailable' is unavailable}}
   obj.getterUnavailable = 0
   obj.getterUnavailable += 1 // expected-error {{getter for 'getterUnavailable' is unavailable}}
@@ -45,15 +53,37 @@
   _ = UnavailableAccessors.setterUnavailableClass
   UnavailableAccessors.setterUnavailableClass = 0 // expected-error {{setter for 'setterUnavailableClass' is unavailable}}
   UnavailableAccessors.setterUnavailableClass += 1 // expected-error {{setter for 'setterUnavailableClass' is unavailable}}
+
+  _ = sub[0] // expected-error {{getter for 'subscript' is unavailable: bad subscript getter}}
+  sub[0] = "" // expected-error {{setter for 'subscript' is unavailable: bad subscript setter}}
+  sub[0] += "" // expected-error {{getter for 'subscript' is unavailable: bad subscript getter}} expected-error {{setter for 'subscript' is unavailable: bad subscript setter}}
+
+  _ = subGetter[0] // expected-error {{getter for 'subscript' is unavailable: bad subscript getter}}
+  subGetter[0] = ""
+  subGetter[0] += "" // expected-error {{getter for 'subscript' is unavailable: bad subscript getter}}
+
+  _ = subSetter[0]
+  subSetter[0] = "" // expected-error {{setter for 'subscript' is unavailable: bad subscript setter}}
+  subSetter[0] += "" // expected-error {{setter for 'subscript' is unavailable: bad subscript setter}}
+
+  _ = subReadOnly[0] // expected-error {{getter for 'subscript' is unavailable}}
 }
 
-func test_deprecated(_ s:UnsafeMutablePointer<CChar>, _ obj: AccessorDeprecations) {
+func test_deprecated(_ s:UnsafeMutablePointer<CChar>, _ obj: AccessorDeprecations,
+    _ sub: DeprecatedSubscript,
+    _ subGetter: DeprecatedGetterSubscript,
+    _ subSetter: DeprecatedSetterSubscript,
+    _ subReadOnly: DeprecatedReadOnlySubscript) {
   _ = tmpnam(s) // expected-warning {{'tmpnam' is deprecated: Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.}}
 
   _ = obj.fullyDeprecated // expected-warning {{'fullyDeprecated' is deprecated}}
   obj.fullyDeprecated = 0 // expected-warning {{'fullyDeprecated' is deprecated}}
   obj.fullyDeprecated += 1 // expected-warning {{'fullyDeprecated' is deprecated}}
 
+  _ = obj.fullyDeprecatedOnAccessors // expected-warning {{getter for 'fullyDeprecatedOnAccessors' is deprecated}}
+  obj.fullyDeprecatedOnAccessors = 0 // expected-warning {{setter for 'fullyDeprecatedOnAccessors' is deprecated}}
+  obj.fullyDeprecatedOnAccessors += 1 // expected-warning {{getter for 'fullyDeprecatedOnAccessors' is deprecated}} expected-warning {{setter for 'fullyDeprecatedOnAccessors' is deprecated}}
+
   _ = obj.getterDeprecated // expected-warning {{getter for 'getterDeprecated' is deprecated}}
   obj.getterDeprecated = 0
   obj.getterDeprecated += 1 // expected-warning {{getter for 'getterDeprecated' is deprecated}}
@@ -69,6 +99,20 @@
   _ = AccessorDeprecations.setterDeprecatedClass
   AccessorDeprecations.setterDeprecatedClass = 0 // expected-warning {{setter for 'setterDeprecatedClass' is deprecated}}
   AccessorDeprecations.setterDeprecatedClass += 1 // expected-warning {{setter for 'setterDeprecatedClass' is deprecated}}
+
+  _ = sub[0] // expected-warning {{getter for 'subscript' is deprecated: bad subscript getter}}
+  sub[0] = "" // expected-warning {{setter for 'subscript' is deprecated: bad subscript setter}}
+  sub[0] += "" // expected-warning {{getter for 'subscript' is deprecated: bad subscript getter}} expected-warning {{setter for 'subscript' is deprecated: bad subscript setter}}
+
+  _ = subGetter[0] // expected-warning {{getter for 'subscript' is deprecated: bad subscript getter}}
+  subGetter[0] = ""
+  subGetter[0] += "" // expected-warning {{getter for 'subscript' is deprecated: bad subscript getter}}
+
+  _ = subSetter[0]
+  subSetter[0] = "" // expected-warning {{setter for 'subscript' is deprecated: bad subscript setter}}
+  subSetter[0] += "" // expected-warning {{setter for 'subscript' is deprecated: bad subscript setter}}
+
+  _ = subReadOnly[0] // expected-warning {{getter for 'subscript' is deprecated}}
 }
 
 func test_NSInvocation(_ x: NSInvocation,         // expected-error {{'NSInvocation' is unavailable}}
diff --git a/test/ClangImporter/ctypes_parse.swift b/test/ClangImporter/ctypes_parse.swift
index 77145f6..d1f9501 100644
--- a/test/ClangImporter/ctypes_parse.swift
+++ b/test/ClangImporter/ctypes_parse.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift %clang-importer-sdk -swift-version 3
+// RUN: %target-typecheck-verify-swift %clang-importer-sdk
 
 import ctypes
 
@@ -227,7 +227,7 @@
   // It would also be nice to warn here about the arrays being too short, but
   // that's probably beyond us for a while.
   staticBoundsArray([])
-  staticBoundsArray(nil) // no-error
+  staticBoundsArray(nil) // expected-error {{'nil' is not compatible with expected argument type 'UnsafePointer<Int8>'}}
 }
 
 func testVaList() {
diff --git a/test/ClangImporter/foreign_errors.swift b/test/ClangImporter/foreign_errors.swift
index 51f4978..961f3ee 100644
--- a/test/ClangImporter/foreign_errors.swift
+++ b/test/ClangImporter/foreign_errors.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -parse-as-library -verify %s -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -O -parse-as-library -DEMIT_SIL %s -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -parse-as-library -verify %s
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -O -parse-as-library -DEMIT_SIL %s
 
 // REQUIRES: objc_interop
 
@@ -17,7 +17,7 @@
 func testAndReturnError() throws {
   try ErrorProne.fail()
   try ErrorProne.go()
-  try ErrorProne.tryAndReturnError() // collides with 'try' keyword
+  try ErrorProne.tryAndReturnError(()) // collides with 'try' keyword
 
   ErrorProne.messUpSignatureAndReturnError(nil) // wrong signature
 }
diff --git a/test/ClangImporter/objc_bridging_custom.swift b/test/ClangImporter/objc_bridging_custom.swift
index 8d8810e..6b72306 100644
--- a/test/ClangImporter/objc_bridging_custom.swift
+++ b/test/ClangImporter/objc_bridging_custom.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -I %S/../Inputs/ObjCBridging %S/../Inputs/ObjCBridging/Appliances.swift -module-name Appliances -o %t -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -I %S/../Inputs/ObjCBridging %S/../Inputs/ObjCBridging/Appliances.swift -module-name Appliances -o %t
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/../Inputs/ObjCBridging -I %t -parse-as-library -verify %s -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/../Inputs/ObjCBridging -I %t -parse-as-library -verify %s
 
 // REQUIRES: objc_interop
 
@@ -13,7 +13,7 @@
   _ = bridgedFridge as Refrigerator // no-warning
 }
 
-class Base : NSObject {
+@objcMembers class Base : NSObject {
   func test(a: Refrigerator, b: Refrigerator) -> Refrigerator? { // expected-note {{potential overridden instance method 'test(a:b:)' here}}
     return nil
   }
@@ -42,7 +42,7 @@
   var propGeneric: ManufacturerInfo<NSString> // expected-note {{attempt to override property here}}
 }
 
-class Sub : Base {
+@objcMembers class Sub : Base {
   // expected-note@+1 {{type does not match superclass instance method with type '(Refrigerator, Refrigerator) -> Refrigerator?'}} {{25-40=Refrigerator}} {{45-61=Refrigerator?}} {{66-81=Refrigerator}}
   override func test(a: APPRefrigerator, b: APPRefrigerator?) -> APPRefrigerator { // expected-error {{method does not override any method from its superclass}} {{none}}
     return a
@@ -108,7 +108,7 @@
   var propGeneric: ManufacturerInfo<NSString>? { get } // expected-note {{protocol requires}}
 }
 
-class TestProtoImpl : NSObject, TestProto { // expected-error {{type 'TestProtoImpl' does not conform to protocol 'TestProto'}}
+@objcMembers class TestProtoImpl : NSObject, TestProto { // expected-error {{type 'TestProtoImpl' does not conform to protocol 'TestProto'}}
   // expected-note@+1 {{candidate has non-matching type '(APPRefrigerator, APPRefrigerator?) -> APPRefrigerator'}} {{16-31=Refrigerator}} {{36-52=Refrigerator?}} {{57-72=Refrigerator}}
   func test(a: APPRefrigerator, b: APPRefrigerator?) -> APPRefrigerator {
     return a
@@ -166,7 +166,7 @@
   @objc optional var propGeneric: ManufacturerInfo<NSString>? { get } // expected-note {{here}} {{none}}
 }
 
-class TestObjCProtoImpl : NSObject, TestObjCProto {
+@objcMembers class TestObjCProtoImpl : NSObject, TestObjCProto {
   // expected-note@+2 {{private}} expected-note@+2 {{@nonobjc}} expected-note@+2 {{extension}}
   // expected-note@+1 {{candidate has non-matching type '(APPRefrigerator, APPRefrigerator?) -> APPRefrigerator'}} {{16-31=Refrigerator}} {{36-52=Refrigerator?}} {{57-72=Refrigerator}}
   func test(a: APPRefrigerator, b: APPRefrigerator?) -> APPRefrigerator { // expected-warning {{instance method 'test(a:b:)' nearly matches optional requirement 'test(a:b:)' of protocol 'TestObjCProto'}}
diff --git a/test/ClangImporter/objc_init_redundant.swift b/test/ClangImporter/objc_init_redundant.swift
index eaaf107..3afcd8c 100644
--- a/test/ClangImporter/objc_init_redundant.swift
+++ b/test/ClangImporter/objc_init_redundant.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %S/Inputs/custom-modules) -emit-sil %s -verify -swift-version 3
-// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %S/Inputs/custom-modules) -emit-sil %s -swift-version 3 > %t.log 2>&1
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %S/Inputs/custom-modules) -emit-sil %s -verify
+// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %S/Inputs/custom-modules) -emit-sil %s > %t.log 2>&1
 // RUN: %FileCheck %s < %t.log
 
 // REQUIRES: objc_interop
@@ -8,8 +8,8 @@
 
 // rdar://problem/17687082
 extension NSObject {
-  convenience init() { self.init() } // expected-error{{initializer 'init()' with Objective-C selector 'init' conflicts with previous declaration with the same Objective-C selector}}
-// CHECK: objc_init_redundant.swift:[[@LINE-1]]:15: error: initializer 'init()' with Objective-C selector 'init' conflicts
+  @objc convenience init() { self.init() } // expected-error{{initializer 'init()' with Objective-C selector 'init' conflicts with previous declaration with the same Objective-C selector}}
+// CHECK: objc_init_redundant.swift:[[@LINE-1]]:21: error: initializer 'init()' with Objective-C selector 'init' conflicts
 // CHECK: ObjectiveC.NSObject{{.*}}note: 'init' previously declared here
 }
 
diff --git a/test/ClangImporter/objc_ir.swift b/test/ClangImporter/objc_ir.swift
index 1bbccae..6102e05 100644
--- a/test/ClangImporter/objc_ir.swift
+++ b/test/ClangImporter/objc_ir.swift
@@ -1,7 +1,7 @@
 
 // RUN: %empty-directory(%t)
 // RUN: %build-clang-importer-objc-overlays
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -module-name objc_ir -I %S/Inputs/custom-modules -emit-ir -g -o - -primary-file %s -swift-version 3 | %FileCheck %s
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -module-name objc_ir -I %S/Inputs/custom-modules -emit-ir -g -o - -primary-file %s | %FileCheck %s
 
 // REQUIRES: objc_interop
 // REQUIRES: OS=macosx
@@ -119,7 +119,7 @@
   // CHECK: [[SWIFT_RESULT:%.+]] = call %swift.type* @swift_getObjCClassMetadata(%objc_class* [[CASTED_RESULT]])
   // CHECK-NOT: call void @swift_unknownRelease(%objc_object* %0)
   // CHECK: ret %swift.type* [[SWIFT_RESULT]]
-  let type = processFooType(type(of: p))
+  let type = processFooType(Swift.type(of: p))
   return type
 } // CHECK: }
 
@@ -136,7 +136,7 @@
   // CHECK: [[SWIFT_RESULT:%.+]] = call %swift.type* @swift_getObjCClassMetadata(%objc_class* [[CASTED_RESULT]])
   // CHECK-NOT: call void bitcast (void (%swift.refcounted*)* @swift_release to void (%T7objc_ir4ImplC*)*)(%T7objc_ir4ImplC* %0)
   // CHECK: ret %swift.type* [[SWIFT_RESULT]]
-  let type = processComboType(type(of: p))
+  let type = processComboType(Swift.type(of: p))
   return type
 } // CHECK: }
 
@@ -149,7 +149,7 @@
   // CHECK: [[SWIFT_RESULT:%.+]] = call %swift.type* @swift_getObjCClassMetadata(%objc_class* [[CASTED_RESULT]])
   // CHECK-NOT: @swift_release
   // CHECK: ret %swift.type* [[SWIFT_RESULT]]
-  let type = processComboType2(type(of: p))
+  let type = processComboType2(Swift.type(of: p))
   return type
 } // CHECK: }
 
diff --git a/test/ClangImporter/objc_override.swift b/test/ClangImporter/objc_override.swift
index 5923905..bf8bdd7 100644
--- a/test/ClangImporter/objc_override.swift
+++ b/test/ClangImporter/objc_override.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules %s -verify -verify-ignore-unknown -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules %s -verify -verify-ignore-unknown
 
 // REQUIRES: objc_interop
 
@@ -6,7 +6,7 @@
 import ObjCParseExtras
 
 class MyArray : DummyClass {
-  func setBoolProperty(_ x: Bool) { } // expected-error{{method 'setBoolProperty' with Objective-C selector 'setBoolProperty:' conflicts with setter for 'boolProperty' from superclass 'DummyClass' with the same Objective-C selector}}
+  @objc func setBoolProperty(_ x: Bool) { } // expected-error{{method 'setBoolProperty' with Objective-C selector 'setBoolProperty:' conflicts with setter for 'boolProperty' from superclass 'DummyClass' with the same Objective-C selector}}
 
   @objc(objectAtIndexedSubscript:)
   func getObjectAt(_ i: Int) { } // expected-error{{method 'getObjectAt' with Objective-C selector 'objectAtIndexedSubscript:' conflicts with method 'objectAtIndexedSubscript' from superclass 'DummyClass' with the same Objective-C selector}}
@@ -16,7 +16,7 @@
   init(string: String) { super.init(string: string) } // expected-error{{overriding declaration requires an 'override' keyword}}{{3-3=override }}
 
   // okay: should not conflict
-  func initWithString(_ string: String) { }
+  @objc func initWithString(_ string: String) { }
 
   var isEnabled: Bool { // expected-error{{overriding declaration requires an 'override' keyword}}
     get { return super.isEnabled }
diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift
index 2e6f2f4..81ae4ed 100644
--- a/test/ClangImporter/objc_parse.swift
+++ b/test/ClangImporter/objc_parse.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules %s -verify -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules %s -verify
 
 // REQUIRES: objc_interop
 
@@ -538,11 +538,11 @@
 
   _ = cell as NSObject
   _ = cell as NSObjectProtocol
-  _ = cell as NSCopying // expected-error {{'CopyableSomeCell' (aka 'SomeCell') is not convertible to 'NSCopying'; did you mean to use 'as!' to force downcast?}} {{12-14=as!}}
+  _ = cell as NSCopying
   _ = cell as SomeCell
   
   _ = plainObj as CopyableNSObject // expected-error {{'NSObject' is not convertible to 'CopyableNSObject' (aka 'NSCopying & NSObjectProtocol'); did you mean to use 'as!' to force downcast?}} {{16-18=as!}}
-  _ = plainCell as CopyableSomeCell // FIXME: This is not really typesafe.
+  _ = plainCell as CopyableSomeCell // expected-error {{'SomeCell' is not convertible to 'CopyableSomeCell' (aka 'SomeCell & NSCopying'); did you mean to use 'as!' to force downcast?}}
 }
 
 extension Printing {
diff --git a/test/ClangImporter/objc_protocol_renaming.swift b/test/ClangImporter/objc_protocol_renaming.swift
index 9f460e2..b2e4949 100644
--- a/test/ClangImporter/objc_protocol_renaming.swift
+++ b/test/ClangImporter/objc_protocol_renaming.swift
@@ -1,20 +1,21 @@
 // RUN: %empty-directory(%t)
 
 // FIXME: BEGIN -enable-source-import hackaround
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -emit-module -o %t %clang-importer-sdk-path/swift-modules/CoreGraphics.swift -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t %clang-importer-sdk-path/swift-modules/Foundation.swift -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -emit-module -o %t %clang-importer-sdk-path/swift-modules/CoreGraphics.swift
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t %clang-importer-sdk-path/swift-modules/Foundation.swift
 // FIXME: END -enable-source-import hackaround
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %S/Inputs/custom-modules -I %t) -emit-module -o %t %S/Inputs/ImplementProtoRenaming.swift -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %S/Inputs/custom-modules -I %t) -emit-module -o %t %S/Inputs/ImplementProtoRenaming.swift
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %S/Inputs/custom-modules -I %t) -typecheck %s -verify -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %S/Inputs/custom-modules -I %t) -typecheck %s -verify
 
 // REQUIRES: objc_interop
 
+import Foundation
 import ProtoRenaming
 import ImplementProtoRenaming
 
 // SR-3917: compiler crash when using an "old" name for an imported requirement
 class MyGraphViewSubclass : MyGraphView {
-	func doSomethingToGraphView(_ view: GraphView) { } // expected-error{{method 'doSomethingToGraphView' with Objective-C selector 'doSomethingToGraphView:' conflicts with method 'doSomething(to:)' from superclass 'MyGraphView' with the same Objective-C selector}}
+	@objc func doSomethingToGraphView(_ view: GraphView) { } // expected-error{{method 'doSomethingToGraphView' with Objective-C selector 'doSomethingToGraphView:' conflicts with method 'doSomething(to:)' from superclass 'MyGraphView' with the same Objective-C selector}}
 }
diff --git a/test/ClangImporter/typedef_with_generic_param.swift b/test/ClangImporter/typedef_with_generic_param.swift
index 63fc0e2..88a3e71 100644
--- a/test/ClangImporter/typedef_with_generic_param.swift
+++ b/test/ClangImporter/typedef_with_generic_param.swift
@@ -1,9 +1,8 @@
-// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/typedef-with-generic-param.h -swift-version 3 2>&1
+// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/typedef-with-generic-param.h 2>&1
 
 // REQUIRES: OS=macosx
 
-typealias Result<T> = (T?, Error?)
-typealias Handler<T> = (Result<T>) -> Void
+typealias Handler<T> = (T?, Error?) -> Void
 
 func foo<T>(_ handler: Handler<T>?) {}
 
diff --git a/test/Constraints/generic_super_constraint.swift b/test/Constraints/generic_super_constraint.swift
index c227519..4f46e93 100644
--- a/test/Constraints/generic_super_constraint.swift
+++ b/test/Constraints/generic_super_constraint.swift
@@ -17,3 +17,11 @@
   // expected-error@+1{{cannot convert return expression}}
   return (x, y)
 }
+
+// SR-7551 captures a crash on this code.
+class IntegerClass : ExpressibleByIntegerLiteral, Equatable {
+  required init(integerLiteral value: Int) { }
+  static func ==(lhs: IntegerClass, rhs: IntegerClass) -> Bool { return true }
+}
+
+func foo<T: IntegerClass>(_ num: T) { let _ =  num != 0 }
diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift
index 962935e..066f593 100644
--- a/test/Constraints/generics.swift
+++ b/test/Constraints/generics.swift
@@ -578,3 +578,17 @@
   var c = foo(default: 42.0, ["foo": Float(0)])
   c += 1 // ok
 }
+
+// https://bugs.swift.org/browse/SR-8075
+
+func sr8075() {
+  struct UIFont {
+    init(ofSize: Float) {}
+  }
+
+  func switchOnCategory<T>(_ categoryToValue: [Int: T]) -> T {
+    fatalError()
+  }
+
+  let _: UIFont = .init(ofSize: switchOnCategory([0: 15.5, 1: 20.5]))
+}
diff --git a/test/Constraints/keypath.swift b/test/Constraints/keypath.swift
index 6395cbe..ed72982 100644
--- a/test/Constraints/keypath.swift
+++ b/test/Constraints/keypath.swift
@@ -5,9 +5,17 @@
 
   init() {
     let _: WritableKeyPath<S, Int> = \.i // no error for Swift 3/4
+
+    S()[keyPath: \.i] = 1
+    // expected-error@-1 {{cannot assign to immutable expression}}
   }
 }
 
 func test() {
   let _: WritableKeyPath<C, Int> = \.i // no error for Swift 3/4
+
+  C()[keyPath: \.i] = 1   // warning on write with literal keypath
+  // expected-warning@-1 {{forming a writable keypath to property}}
+
+  let _ = C()[keyPath: \.i] // no warning for a read
 }
diff --git a/test/Constraints/keypath_swift_5.swift b/test/Constraints/keypath_swift_5.swift
index 390477e..fb29162 100644
--- a/test/Constraints/keypath_swift_5.swift
+++ b/test/Constraints/keypath_swift_5.swift
@@ -5,9 +5,17 @@
 
   init() {
     let _: WritableKeyPath<S, Int> = \.i // expected-error {{type of expression is ambiguous without more context}}
+
+    S()[keyPath: \.i] = 1
+    // expected-error@-1 {{cannot assign to immutable expression}}
   }
 }
 
 func test() {
   let _: WritableKeyPath<C, Int> = \.i // expected-error {{type of expression is ambiguous without more context}}
+
+  C()[keyPath: \.i] = 1
+  // expected-error@-1 {{cannot assign to immutable expression}}
+
+  let _ = C()[keyPath: \.i] // no warning for a read
 }
diff --git a/test/DebugInfo/DumpDeclFromMangledName.swift b/test/DebugInfo/DumpDeclFromMangledName.swift
index c13e950..4ca202f 100644
--- a/test/DebugInfo/DumpDeclFromMangledName.swift
+++ b/test/DebugInfo/DumpDeclFromMangledName.swift
@@ -49,6 +49,51 @@
 
 typealias Patatino<T> = Foo<T>
 
+public struct Outer<T> {
+  public struct Inner { }
+  public struct GenericInner<U> { }
+
+  public typealias Foo<U> = Outer<U>.Inner
+
+  public func blah() {
+    let foo: Foo<Int> = Outer<Int>.Inner()
+  }
+}
+
+extension Outer.GenericInner {
+  public typealias Bar = Int
+
+  public func useBar() {
+    let bar: Bar = 7
+  }
+}
+
+// Mangling for generic typealiases.
+protocol P {
+  associatedtype A
+}
+
+protocol Q {
+  associatedtype B: P
+  typealias ProtocolTypeAliasThing = B.A
+}
+
+struct ConformsToP: P {
+  typealias A = Int
+}
+
+struct ConformsToQ: Q {
+  typealias B = ConformsToP
+}
+
+struct Blah {
+  typealias SomeQ = ConformsToQ
+
+  func foo() {
+    let bar: SomeQ.ProtocolTypeAliasThing? = nil
+  }
+}
+
 func main() -> Int {
   var p : Patatino<Int> = Patatino(23);
   return 0
diff --git a/test/DebugInfo/DumpTypeFromMangledName.swift b/test/DebugInfo/DumpTypeFromMangledName.swift
index 1c9e16d..a376392 100644
--- a/test/DebugInfo/DumpTypeFromMangledName.swift
+++ b/test/DebugInfo/DumpTypeFromMangledName.swift
@@ -32,6 +32,16 @@
 
 typealias Patatino<T> = Foo<T>
 
+public struct Outer<T> {
+  public struct Inner { }
+
+  public typealias Foo<U> = Outer<U>.Inner
+
+  public func blah() {
+    let foo: Foo<Int> = Outer<Int>.Inner()
+  }
+}
+
 func main() -> Int {
   struct patatino {}
   var p : Patatino<Int> = Patatino(23);
diff --git a/test/DebugInfo/Inputs/decl-reconstr-names.txt b/test/DebugInfo/Inputs/decl-reconstr-names.txt
index c8357fd..2d67c0f 100644
--- a/test/DebugInfo/Inputs/decl-reconstr-names.txt
+++ b/test/DebugInfo/Inputs/decl-reconstr-names.txt
@@ -1,3 +1,5 @@
 $S12DeclReconstr8patatinoSiyF ---> func patatino() -> Int
 $S12DeclReconstr1SVACycfC ---> init()
 $S12DeclReconstr8PatatinoaySiGD ---> typealias Patatino<T> = Foo<T>
+$S12DeclReconstr5OuterV3Fooayx_SiGD ---> Can't resolve decl of $S12DeclReconstr5OuterV3Fooayx_SiGD
+$S12DeclReconstr5OuterV12GenericInnerV3Barayx_qd___GD ---> typealias Bar = Int
diff --git a/test/DebugInfo/Inputs/type-reconstr-names.txt b/test/DebugInfo/Inputs/type-reconstr-names.txt
index 856471b..7400ed1 100644
--- a/test/DebugInfo/Inputs/type-reconstr-names.txt
+++ b/test/DebugInfo/Inputs/type-reconstr-names.txt
@@ -11,3 +11,4 @@
 $S12EyeCandyCore11XPCListenerC14messageHandleryyAA13XPCConnectionV_AA10XPCMessageVxtcvpfiyAF_AHxtcfU_TA.4 ---> Can't resolve type of $S12EyeCandyCore11XPCListenerC14messageHandleryyAA13XPCConnectionV_AA10XPCMessageVxtcvpfiyAF_AHxtcfU_TA.4
 $Ss10CollectionP7ElementQa ---> Can't resolve type of $Ss10CollectionP7ElementQa
 $S12TypeReconstr8patatinoayAA5tinkyVGSgD ---> Optional<patatino>
+$S12TypeReconstr5OuterV3Fooayx_SiGD ---> Can't resolve type of $S12TypeReconstr5OuterV3Fooayx_SiGD
diff --git a/test/DebugInfo/WeakCapture.swift b/test/DebugInfo/WeakCapture.swift
index 951fe20..08c1eae 100644
--- a/test/DebugInfo/WeakCapture.swift
+++ b/test/DebugInfo/WeakCapture.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -g -o - -swift-version 3 | %FileCheck %s
+// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
 class A {
     init(handler: (() -> ())) { }
 }
@@ -15,7 +15,7 @@
   // CHECK: call void @llvm.dbg.{{.*}}(metadata %swift.weak*
   // CHECK-NOT:                        metadata [[B]]
   // CHECK: call
-    A(handler: { [weak b] _ in
+    A(handler: { [weak b] in
             if b != nil { }
         })
 }
diff --git a/test/DebugInfo/closure-arg-linetable.swift b/test/DebugInfo/closure-arg-linetable.swift
index 0bdf811..46d47db 100644
--- a/test/DebugInfo/closure-arg-linetable.swift
+++ b/test/DebugInfo/closure-arg-linetable.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -g -o - -swift-version 3 | %FileCheck %s
+// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
 
 public class C {
 
@@ -11,7 +11,7 @@
   // CHECK: ![[DBG]] = !DILocation(line: 0, scope: ![[CURRY_THUNK]])
   func someHandler() { }
 
-  func doSomethingWithHandler(_ theHandler: ((Void) -> Void)!) -> Void {
+  func doSomethingWithHandler(_ theHandler: (() -> Void)!) -> Void {
 	  theHandler()
   }
 
diff --git a/test/DebugInfo/guard-let.swift b/test/DebugInfo/guard-let.swift
index 2db51a4..ddf4ee3 100644
--- a/test/DebugInfo/guard-let.swift
+++ b/test/DebugInfo/guard-let.swift
@@ -21,9 +21,13 @@
   use(val)
 }
 
-// With large type optimizations the string is passed indirectly on i386 so
-// there is no shadow copy happening.
+// With large type optimizations the string is passed indirectly on the
+// following architectures so there is no shadow copy happening. As this
+// tests that we're emitting the DI correctly, we can skip running on them.
 // UNSUPPORTED: CPU=i386
+// UNSUPPORTED: CPU=armv7
+// UNSUPPORTED: CPU=armv7s
+// UNSUPPORTED: CPU=armv7k
 
 public func g(_ s : String?)
 {
diff --git a/test/DebugInfo/inlined-generics-basic.swift b/test/DebugInfo/inlined-generics-basic.swift
new file mode 100644
index 0000000..604ca19
--- /dev/null
+++ b/test/DebugInfo/inlined-generics-basic.swift
@@ -0,0 +1,51 @@
+// RUN: %target-swift-frontend -parse-as-library -module-name A -Xllvm -sil-print-debuginfo %s -g -O -o - -emit-sil | %FileCheck %s --check-prefix=SIL
+
+@inline(never)
+func yes() -> Bool { return true }
+
+#sourceLocation(file: "use.swift", line: 1)
+@inline(never) func use<V>(_ v: V) {}
+
+#sourceLocation(file: "h.swift", line: 1)
+@inline(__always) func h<U>(_ u: U) {
+  yes()
+  use(u)
+}
+
+#sourceLocation(file: "g.swift", line: 1)
+@inline(__always) func g<T>(_ t: T) {
+  if (yes()) {
+    h(t)
+  }
+}
+
+// SIL: sil_scope [[F:.*]] { {{.*}}parent @$S1A1CC1fyyqd__lF
+// SIL: sil_scope [[F1:.*]] { loc "f.swift":1:29 parent [[F]] }
+// SIL: sil_scope [[F1G:.*]] { loc "f.swift":5:5 parent [[F1]] }
+// SIL: sil_scope [[F1G1:.*]] { loc "g.swift":2:3 {{.*}}inlined_at [[F1G]] }
+// SIL: sil_scope [[F1G3:.*]] { loc "g.swift":3:5 {{.*}}inlined_at [[F1G]] }
+// SIL: sil_scope [[F1G3H:.*]] { loc "h.swift":1:24
+// SIL-SAME:                     parent @{{.*}}1h{{.*}} inlined_at [[F1G3]] }
+// SIL: sil_scope [[F1G3H1:.*]] { loc "h.swift":1:37
+// SIL-SAME:                      parent [[F1G3H]] inlined_at [[F1G3]] }
+// SIL: sil_scope [[F1G3H2:.*]] { loc "h.swift":3:3
+// SIL-SAME:                      parent [[F1G3H1]] inlined_at [[F1G3]] }
+// SIL: sil_scope [[F1G3H2_THUNK:.*]] { loc "use.swift":1:21
+// SIL-SAME:                            inlined_at [[F1G3H2]] }
+
+#sourceLocation(file: "C.swift", line: 1)
+public class C<R> {
+  let r : R
+  init(_ _r: R) { r = _r }
+
+  // SIL: // C.f<A>(_:)
+#sourceLocation(file: "f.swift", line: 1)
+  public func f<S> (_ s: S) {
+    // SIL: debug_value_addr %0 : $*S, let, name "s", argno 1,{{.*}} scope [[F]]
+    // SIL: function_ref {{.*}}yes{{.*}} scope [[F1G1]]
+    // SIL: function_ref {{.*}}use{{.*}}:0:0, scope [[F1G3H2_THUNK]]
+    g(s)
+    g(r)
+    g((s, s))
+  }
+}
diff --git a/test/DebugInfo/nostorage.swift b/test/DebugInfo/nostorage.swift
index b83c973..aa9923a 100644
--- a/test/DebugInfo/nostorage.swift
+++ b/test/DebugInfo/nostorage.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -emit-ir -g -o %t -swift-version 3
+// RUN: %target-swift-frontend %s -emit-ir -g -o %t
 // RUN: cat %t | %FileCheck %s --check-prefix=CHECK1
 // RUN: cat %t | %FileCheck %s --check-prefix=CHECK2
 // RUN: cat %t | %FileCheck %s --check-prefix=CHECK3
@@ -15,7 +15,7 @@
       // CHECK1-SAME:                         type: ![[METAFOO:[0-9]+]]
       // CHECK1: ![[METAFOO]] = !DICompositeType(tag: DW_TAG_structure_type,
       // CHECK1-SAME:                            flags:
-            let type = type(of: self)
+            let type = Swift.type(of: self)
             used(type)
         }()
     }
diff --git a/test/DebugInfo/objc_generic_class_debug_info.swift b/test/DebugInfo/objc_generic_class_debug_info.swift
index 078c2e2..bf6efc8 100644
--- a/test/DebugInfo/objc_generic_class_debug_info.swift
+++ b/test/DebugInfo/objc_generic_class_debug_info.swift
@@ -1,5 +1,5 @@
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -emit-ir -g -verify -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -emit-ir -g -verify
 
 // REQUIRES: objc_interop
 
@@ -8,8 +8,8 @@
 import objc_generics
 
 public extension GenericClass {
-  func method() {}
-  class func classMethod() {}
+  @objc func method() {}
+  @objc class func classMethod() {}
 }
 
 public func takesFunction<T : AnyObject>(fn: @escaping (GenericClass<T>) -> ()) -> (GenericClass<T>) -> () {
diff --git a/test/DebugInfo/test-foundation.swift b/test/DebugInfo/test-foundation.swift
index 1dfcce8..c265ae4 100644
--- a/test/DebugInfo/test-foundation.swift
+++ b/test/DebugInfo/test-foundation.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -emit-ir -g %s -o %t.ll -swift-version 3
+// RUN: %target-swift-frontend -emit-ir -g %s -o %t.ll
 // RUN: %FileCheck %s --check-prefix IMPORT-CHECK < %t.ll
 // RUN: %FileCheck %s --check-prefix LOC-CHECK < %t.ll
 // RUN: llc %t.ll -filetype=obj -o %t.o
@@ -15,21 +15,21 @@
   // LOC-CHECK: define {{.*}} @"$S4main8MyObjectC0B3ArrSo7NSArrayCvgTo"
   // LOC-CHECK: ret {{.*}}, !dbg ![[DBG:.*]]
   // LOC-CHECK: ret
-  var MyArr = NSArray()
+  @objc var MyArr = NSArray()
 // IMPORT-CHECK: filename: "test-foundation.swift"
 // IMPORT-CHECK-DAG: [[FOUNDATION:[0-9]+]] = !DIModule({{.*}} name: "Foundation",{{.*}} includePath:
   // IMPORT-CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "NSArray", scope: ![[NSARRAY:[0-9]+]]
   //  IMPORT-CHECK-DAG: ![[NSARRAY]] = !DIModule(scope: ![[FOUNDATION:[0-9]+]], name: "NSArray"
   // IMPORT-CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, {{.*}}entity: ![[FOUNDATION]]
 
-  func foo(_ obj: MyObject) {
+  @objc func foo(_ obj: MyObject) {
     return obj.foo(obj)
   }
 }
 
 // SANITY-DAG: !DISubprogram(name: "blah",{{.*}} line: [[@LINE+2]],{{.*}} isDefinition: true
 extension MyObject {
-  func blah() {
+  @objc func blah() {
     var _ = MyObject()
   }
 }
@@ -46,9 +46,9 @@
   // DWARF-CHECK: DW_AT_name ("NSError")
   // DWARF-CHECK: DW_AT_linkage_name{{.*}}$SSo7NSErrorC
   let _ = NSError(domain: "myDomain", code: 4, 
-                  userInfo: [AnyHashable("a"):1,
-                             AnyHashable("b"):2,
-                             AnyHashable("c"):3])
+                  userInfo: ["a":1,
+                             "b":2,
+                             "c":3])
 }
 
 // LOC-CHECK: define {{.*}}4date
diff --git a/test/DebugInfo/thunks.swift b/test/DebugInfo/thunks.swift
index 6295b93..9d03710 100644
--- a/test/DebugInfo/thunks.swift
+++ b/test/DebugInfo/thunks.swift
@@ -1,10 +1,10 @@
-// RUN: %target-swift-frontend -emit-ir -g %s -o - -swift-version 3 | %FileCheck %s
-// RUN: %target-swift-frontend -emit-sil -emit-verbose-sil -g %s -o - -swift-version 3 | %FileCheck %s --check-prefix=SIL-CHECK
+// RUN: %target-swift-frontend -emit-ir -g %s -o - | %FileCheck %s
+// RUN: %target-swift-frontend -emit-sil -emit-verbose-sil -g %s -o - | %FileCheck %s --check-prefix=SIL-CHECK
 // REQUIRES: objc_interop
 import Foundation
 
 class Foo : NSObject {
-  dynamic func foo(_ f: (Int64) -> Int64, x: Int64) -> Int64 {
+  @objc dynamic func foo(_ f: (Int64) -> Int64, x: Int64) -> Int64 {
     return f(x)
   }
 }
diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt
index 9edd0ba..26a4e09 100644
--- a/test/Demangle/Inputs/manglings.txt
+++ b/test/Demangle/Inputs/manglings.txt
@@ -313,5 +313,8 @@
 _$S3BBBBi0602365061_ ---> _$S3BBBBi0602365061_
 _$S3BBBBv0602365061_ ---> _$S3BBBBv0602365061_
 _T0lxxxmmmTk ---> _T0lxxxmmmTk
-$S4blah8PatatinoaySiGD -> blah.Patatino<Swift.Int>
-
+$S4blah8PatatinoaySiGD ---> blah.Patatino<Swift.Int>
+$SSiSHsWP ---> protocol witness table for Swift.Int : Swift.Hashable in Swift
+$S7TestMod5OuterV3Fooayx_SiGD ---> TestMod.Outer<A>.Foo<Swift.Int>
+$Ss17_VariantSetBufferO05CocoaC0ayx_GD ---> Swift._VariantSetBuffer<A>.CocoaBuffer
+$S2t21QP22ProtocolTypeAliasThingayAA4BlahV5SomeQa_GSgD ---> t2.Blah.SomeQ as t2.Q.ProtocolTypeAliasThing?
diff --git a/test/IDE/Inputs/AnyObject/bar_swift_module.swift b/test/IDE/Inputs/AnyObject/bar_swift_module.swift
index 4754147..3b8d1ef 100644
--- a/test/IDE/Inputs/AnyObject/bar_swift_module.swift
+++ b/test/IDE/Inputs/AnyObject/bar_swift_module.swift
@@ -1,13 +1,13 @@
 // Import this class in the test.
 @objc public class Bar_ImportedObjcClass {
-  public func bar_ImportedObjcClass_InstanceFunc1() {}
-  public class func bar_ImportedObjcClass_ClassFunc1() {}
-  public subscript(i: Bar_ImportedObjcClass) -> Int {
+  @objc public func bar_ImportedObjcClass_InstanceFunc1() {}
+  @objc public class func bar_ImportedObjcClass_ClassFunc1() {}
+  @objc public subscript(i: Bar_ImportedObjcClass) -> Int {
     get {
       return 0
     }
   }
-  public var bar_ImportedObjcClass_Property1: Int = 0
+  @objc public var bar_ImportedObjcClass_Property1: Int = 0
 }
 
 // Don't import this class in the test.
diff --git a/test/IDE/Inputs/AnyObject/foo_swift_module.swift b/test/IDE/Inputs/AnyObject/foo_swift_module.swift
index b883433..efc9880 100644
--- a/test/IDE/Inputs/AnyObject/foo_swift_module.swift
+++ b/test/IDE/Inputs/AnyObject/foo_swift_module.swift
@@ -1,12 +1,12 @@
 @objc public class Foo_TopLevelObjcClass {
-  public func foo_TopLevelObjcClass_InstanceFunc1() {}
-  public class func foo_TopLevelObjcClass_ClassFunc1() {}
-  public subscript(i: Int32) -> Int {
+  @objc public func foo_TopLevelObjcClass_InstanceFunc1() {}
+  @objc public class func foo_TopLevelObjcClass_ClassFunc1() {}
+  @objc public subscript(i: Int32) -> Int {
     get {
       return 0
     }
   }
-  public var foo_TopLevelObjcClass_Property1: Int = 0
+  @objc public var foo_TopLevelObjcClass_Property1: Int = 0
 
   internal func foo_TopLevelObjcClass_internalFunc_ERROR() {}
   private func foo_TopLevelObjcClass_privateFunc_ERROR() {}
@@ -24,10 +24,10 @@
 }
 
 @objc public protocol Foo_TopLevelObjcProtocol {
-  func foo_TopLevelObjcProtocol_InstanceFunc1()
-  static func foo_TopLevelObjcProtocol_ClassFunc1()
-  subscript(i: Foo_TopLevelObjcProtocol) -> Int { get set }
-  var foo_TopLevelObjcProtocol_Property1: Int { get }
+  @objc func foo_TopLevelObjcProtocol_InstanceFunc1()
+  @objc static func foo_TopLevelObjcProtocol_ClassFunc1()
+  @objc subscript(i: Foo_TopLevelObjcProtocol) -> Int { get set }
+  @objc var foo_TopLevelObjcProtocol_Property1: Int { get }
 }
 
 public class Foo_ContainerForNestedClass1 {
diff --git a/test/IDE/complete_crashes.swift b/test/IDE/complete_crashes.swift
index 8bdb0ef..91e1476 100644
--- a/test/IDE/complete_crashes.swift
+++ b/test/IDE/complete_crashes.swift
@@ -134,13 +134,12 @@
 }
 
 // rdar://problem/22688199
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RDAR_22688199 -swift-version 3 | %FileCheck %s -check-prefix=FLIP_CURRIED
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RDAR_22688199
 func curried(_ a: Int)(_ b1: Int, _ b2: Int) { }
 func flip<A, B, C>(_ f: A -> B -> C) -> B -> A -> C { }
 func rdar22688199() {
   let f = flip(curried)(#^RDAR_22688199^#
 }
-// FLIP_CURRIED: Pattern/CurrModule: ['(']{#(Int, Int)#}[')'][#(Int) -> ()#]
 
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RDAR_22836263
 func rdar22836263() {
@@ -221,10 +220,8 @@
 func foo_38149042(bar: Bar_38149042) {
   _ = bar.foo? #^RDAR_38149042^# .x
 }
-// RDAR_38149042: Begin completions, 4 items
+// RDAR_38149042: Begin completions, 2 items
 // RDAR_38149042-DAG: Decl[InstanceVar]/CurrNominal:                  .x[#Int#]; name=x
-// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']=== {#AnyObject?#}[#Bool#]; name==== AnyObject?
-// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']!== {#AnyObject?#}[#Bool#]; name=!== AnyObject?
 // RDAR_38149042-DAG: Keyword[self]/CurrNominal: .self[#Baz_38149042#]; name=self
 // RDAR_38149042: End completions
 
@@ -248,3 +245,54 @@
   bar_38272904(a: .foo() #^RDAR_38272904^#)
 }
 // RDAR_38272904: Begin completions
+
+// rdar://problem/41159258
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41159258_1 | %FileCheck %s -check-prefix=RDAR_41159258
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41159258_2 | %FileCheck %s -check-prefix=RDAR_41159258
+public func ==(lhs: RDAR41159258_MyResult1, rhs: RDAR41159258_MyResult1) -> Bool {
+  fatalError()
+}
+public func ==(lhs: RDAR41159258_MyResult2, rhs: RDAR41159258_MyResult2) -> Bool {
+  fatalError()
+}
+public enum RDAR41159258_MyResult1 {
+  case failure(Error)
+}
+public enum RDAR41159258_MyResult2 {
+  case failure(Error)
+}
+
+public struct RDAR41159258_MyError: Error {}
+
+func foo(x: RDAR41159258_MyResult1) {
+  let x: RDAR41159258_MyResult1
+  x = .failure(RDAR41159258_MyError()) #^RDAR41159258_1^#
+  let y: Bool
+  y = .failure(RDAR41159258_MyError()) #^RDAR41159258_2^#
+}
+// RDAR_41159258: Begin completions
+
+
+// rdar://problem/41232519
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519 | %FileCheck %s -check-prefix=RDAR_41232519
+public protocol IntProvider {
+  func nextInt() -> Int
+}
+
+public final class IntStore {
+  public var myInt: Int = 0
+  func readNextInt(from provider: IntProvider) {
+      myInt = provider.nextInt() #^RDAR41232519^#
+  }
+}
+// RDAR_41232519: Begin completions
+
+// rdar://problem/28188259
+// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_28188259 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_28188259
+func test_28188259(x: ((Int) -> Void) -> Void) {
+  x({_ in }#^RDAR_28188259^#)
+}
+// RDAR_28188259: Begin completions
+// RDAR_28188259-DAG: Pattern/CurrModule:                 ({#_#})[#Void#]; name=(_)
+// RDAR_28188259-DAG: Keyword[self]/CurrNominal:          .self[#(_) -> ()#]; name=self
+// RDAR_28188259: End completions
diff --git a/test/IDE/complete_dynamic_lookup.swift b/test/IDE/complete_dynamic_lookup.swift
index a15d0b2..1180f40 100644
--- a/test/IDE/complete_dynamic_lookup.swift
+++ b/test/IDE/complete_dynamic_lookup.swift
@@ -1,58 +1,58 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -disable-objc-attr-requires-foundation-module -swift-version 3 -o %t %S/Inputs/AnyObject/foo_swift_module.swift
-// RUN: %target-swift-frontend -emit-module -disable-objc-attr-requires-foundation-module -swift-version 3 -o %t %S/Inputs/AnyObject/bar_swift_module.swift
+// RUN: %target-swift-frontend -emit-module -disable-objc-attr-requires-foundation-module -o %t %S/Inputs/AnyObject/foo_swift_module.swift
+// RUN: %target-swift-frontend -emit-module -disable-objc-attr-requires-foundation-module -o %t %S/Inputs/AnyObject/bar_swift_module.swift
 // RUN: cp %S/Inputs/AnyObject/baz_clang_module.h %t
 // RUN: cp %S/Inputs/AnyObject/module.map %t
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_PARAM_NO_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_PARAM_NO_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_INSTANCE_NO_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_PARAM_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_PARAM_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_INSTANCE_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_VAR_NO_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_VAR_NO_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_INSTANCE_NO_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_VAR_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_VAR_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_INSTANCE_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_RETURN_VAL_NO_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_RETURN_VAL_NO_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_INSTANCE_NO_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_RETURN_VAL_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_RETURN_VAL_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_INSTANCE_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CALL_RETURN_VAL_NO_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CALL_RETURN_VAL_NO_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=TLOC_MEMBERS_NO_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CALL_RETURN_VAL_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CALL_RETURN_VAL_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=TLOC_MEMBERS_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_NAME_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_NAME_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_FUNC_NAME_1 < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_NAME_PAREN_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_NAME_PAREN_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_FUNC_NAME_PAREN_1 < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_NAME_BANG_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_FUNC_NAME_BANG_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_FUNC_NAME_BANG_1 < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CLASS_NO_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CLASS_NO_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_CLASS_NO_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CLASS_DOT_1 > %t.dl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -I %t -disable-objc-attr-requires-foundation-module -code-completion-token=DL_CLASS_DOT_1 > %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=DL_CLASS_DOT < %t.dl.txt
 // RUN: %FileCheck %s -check-prefix=GLOBAL_NEGATIVE < %t.dl.txt
 
@@ -249,27 +249,27 @@
 // Blocked by: rdar://15136550 Properties in protocols not implemented
 
 @objc class TopLevelObjcClass {
-  func returnsObjcClass(_ i: Int) -> TopLevelObjcClass {}
+  @objc func returnsObjcClass(_ i: Int) -> TopLevelObjcClass {}
 
-  func topLevelObjcClass_InstanceFunc1() {}
-  class func topLevelObjcClass_ClassFunc1() {}
-  subscript(i: Int8) -> Int {
+  @objc func topLevelObjcClass_InstanceFunc1() {}
+  @objc class func topLevelObjcClass_ClassFunc1() {}
+  @objc subscript(i: Int8) -> Int {
     get {
       return 0
     }
   }
-  var topLevelObjcClass_Property1: Int
+  @objc var topLevelObjcClass_Property1: Int
 }
 
 @objc class TopLevelObjcClass_DuplicateMembers {
-  func topLevelObjcClass_InstanceFunc1() {}
-  class func topLevelObjcClass_ClassFunc1() {}
-  subscript(i: Int8) -> Int {
+  @objc func topLevelObjcClass_InstanceFunc1() {}
+  @objc class func topLevelObjcClass_ClassFunc1() {}
+  @objc subscript(i: Int8) -> Int {
     get {
       return 0
     }
   }
-  var topLevelObjcClass_Property1: Int
+  @objc var topLevelObjcClass_Property1: Int
 }
 
 class TopLevelClass {
@@ -293,10 +293,10 @@
 }
 
 @objc protocol TopLevelObjcProtocol {
-  func topLevelObjcProtocol_InstanceFunc1()
-  class func topLevelObjcProtocol_ClassFunc1()
-  subscript (i: TopLevelObjcClass) -> Int { get set }
-  var topLevelObjcProtocol_Property1: Int { get set }
+  @objc func topLevelObjcProtocol_InstanceFunc1()
+  @objc class func topLevelObjcProtocol_ClassFunc1()
+  @objc subscript (i: TopLevelObjcClass) -> Int { get set }
+  @objc var topLevelObjcProtocol_Property1: Int { get set }
 }
 
 class ContainerForNestedClass1 {
@@ -336,7 +336,7 @@
 
 class GenericContainerForNestedClass1<T> {
   class Nested3 {
-    @objc func ERROR1() {}
+    func ERROR1() {}
     func ERROR2() {}
     class func ERROR3() {}
     typealias ERROR = Int
@@ -352,7 +352,7 @@
 
 struct GenericContainerForNestedClass2<T> {
   class Nested3 {
-    @objc func ERROR1() {}
+    func ERROR1() {}
     func ERROR2() {}
     class func ERROR3() {}
     typealias ERROR = Int
@@ -367,36 +367,36 @@
 }
 
 @objc class Base1 {
-  func base1_InstanceFunc1() {}
+  @objc func base1_InstanceFunc1() {}
 
-  func base1_InstanceFunc2(_ a: Derived) {}
+  @objc func base1_InstanceFunc2(_ a: Derived) {}
 
-  func base1_InstanceFunc3(_ a: Derived) {}
+  @objc func base1_InstanceFunc3(_ a: Derived) {}
 
-  func base1_InstanceFunc4() -> Base {}
+  @objc func base1_InstanceFunc4() -> Base {}
 
-  var base1_Property1: Int
+  @objc var base1_Property1: Int
 
-  var base1_Property2: Base
+  @objc var base1_Property2: Base
 }
 
 @objc class Derived1 : Base1 {
-  func base1_InstanceFunc1() {}
+  @objc func base1_InstanceFunc1() {}
 
-  func base1_InstanceFunc2(_ a: Derived) {}
+  @objc func base1_InstanceFunc2(_ a: Derived) {}
 
-  func base1_InstanceFunc3(_ a: Base) {}
+  @objc func base1_InstanceFunc3(_ a: Base) {}
 
-  func base1_InstanceFunc4() -> Derived {}
+  @objc func base1_InstanceFunc4() -> Derived {}
 
-  var base1_Property1: Int {
+  @objc var base1_Property1: Int {
     get {
       return 0
     }
     set {}
   }
 
-  var base1_Property2: Derived {
+  @objc var base1_Property2: Derived {
     get {
       return Derived()
     }
diff --git a/test/IDE/complete_multiple_files.swift b/test/IDE/complete_multiple_files.swift
index 8ee8999..d4641b7 100644
--- a/test/IDE/complete_multiple_files.swift
+++ b/test/IDE/complete_multiple_files.swift
@@ -16,9 +16,6 @@
 // T1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // T1-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // T1-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
-//
-// FIX-ME(SR-7225): We shouldn't duplicate this.
-// T1-NEXT: Decl[InstanceVar]/Super: instanceVar[#Int#]{{; name=.+$}}
 // T1-NEXT: End completions
 
 func testGenericObjectExpr() {
@@ -28,9 +25,6 @@
 // T2-NEXT: Keyword[self]/CurrNominal: self[#GenericFooStruct<Void>#]; name=self
 // T2-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // T2-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
-//
-// FIX-ME(SR-7225): We shouldn't duplicate this.
-// T2-NEXT: Decl[InstanceVar]/Super: instanceVar[#Int#]{{; name=.+$}}
 // T2-NEXT: End completions
 
 func topLevel1() {
diff --git a/test/IDE/complete_stdlib_optional.swift b/test/IDE/complete_stdlib_optional.swift
index 387b165..12252d8 100644
--- a/test/IDE/complete_stdlib_optional.swift
+++ b/test/IDE/complete_stdlib_optional.swift
@@ -1,59 +1,59 @@
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_NO_DOT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_NO_DOT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_NO_DOT_FOOSTRUCT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_NO_DOT_2 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_NO_DOT_2 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_NO_DOT_FOOSTRUCT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DOT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DOT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_DOT_FOOSTRUCT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DOT_1_SPACES > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DOT_1_SPACES > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_DOT_FOOSTRUCT_SPACES < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DOT_2 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DOT_2 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_DOT_FOOSTRUCT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_NO_DOT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_NO_DOT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=UN_OPT_NO_DOT_FOOSTRUCT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_NO_DOT_2 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_NO_DOT_2 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=UN_OPT_NO_DOT_FOOSTRUCT_RETURN < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_NO_DOT_3 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_NO_DOT_3 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=UN_OPT_NO_DOT_INT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_DOT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_DOT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=UN_OPT_DOT_FOOSTRUCT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_DOT_2 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_DOT_2 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=UN_OPT_DOT_FOOSTRUCT_RETURN < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_DOT_3 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=UN_OPT_DOT_3 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=UN_OPT_DOT_INT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_NO_DOT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_NO_DOT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OBJCCLASS_MEMBERS_NO_DOT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_NO_DOT_2 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_NO_DOT_2 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OBJCCLASS_MEMBERS_NO_DOT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_DOT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_DOT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OBJCCLASS_MEMBERS_DOT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_DOT_2 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_DOT_2 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OBJCCLASS_MEMBERS_DOT < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_FORCE_RETURN_OPTIONAL_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_DL_FORCE_RETURN_OPTIONAL_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_NO_DOT_OBJCCLASS < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_CAST_AS_RESULT_1 > %t.opt.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_CAST_AS_RESULT_1 > %t.opt.txt
 // RUN: %FileCheck %s -check-prefix=OPT_NO_DOT_OBJCCLASS < %t.opt.txt
 
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_1 | %FileCheck %s -check-prefix=OPT_TUPLE_1
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_2 | %FileCheck %s -check-prefix=OPT_TUPLE_2
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_3 | %FileCheck %s -check-prefix=OPT_TUPLE_3
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_4 | %FileCheck %s -check-prefix=OPT_TUPLE_4
-// RUN: %target-swift-ide-test -swift-version 3 -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_5 | %FileCheck %s -check-prefix=OPT_TUPLE_5
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_1 | %FileCheck %s -check-prefix=OPT_TUPLE_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_2 | %FileCheck %s -check-prefix=OPT_TUPLE_2
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_3 | %FileCheck %s -check-prefix=OPT_TUPLE_3
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_4 | %FileCheck %s -check-prefix=OPT_TUPLE_4
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -disable-objc-attr-requires-foundation-module -code-completion-token=OPT_TUPLE_5 | %FileCheck %s -check-prefix=OPT_TUPLE_5
 
 //===---
 //===--- Test code completion for stdlib Optional<T> type.
@@ -78,8 +78,8 @@
 
 @objc
 class ObjcClass {
-  var instanceVar: Int = 0
-  func instanceFunc() -> ObjcClass { return self }
+  @objc var instanceVar: Int = 0
+  @objc func instanceFunc() -> ObjcClass { return self }
 }
 
 // OPT_NO_DOT_FOOSTRUCT: Begin completions
diff --git a/test/IDE/complete_type_subscript.swift b/test/IDE/complete_type_subscript.swift
index 365087c..cfbf9bb 100644
--- a/test/IDE/complete_type_subscript.swift
+++ b/test/IDE/complete_type_subscript.swift
@@ -1,3 +1,7 @@
+protocol It {
+  associatedtype Assoc
+}
+
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PARAM_0 | %FileCheck %s -check-prefix=TOP_LEVEL_0
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RETURN_0 | %FileCheck %s -check-prefix=TOP_LEVEL_0
 
@@ -82,4 +86,35 @@
   subscript<T>(x: T) -> T.#^GEN_RETURN_5^# { return 0 }
 }
 // GEN_PARAM_5: Keyword/None:                       Type[#T.Type#];
-// GEN_PARAM_5-NOT: Keyword/CurrNominal:            self[#T#];
\ No newline at end of file
+// GEN_PARAM_5-NOT: Keyword/CurrNominal:            self[#T#];
+
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GEN_PARAM_6 | %FileCheck %s -check-prefix=GEN_PARAM_6
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GEN_RETURN_6 | %FileCheck %s -check-prefix=GEN_PARAM_6
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GEN_EXT_PARAM_6 | %FileCheck %s -check-prefix=GEN_PARAM_6
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GEN_EXT_RETURN_6 | %FileCheck %s -check-prefix=GEN_PARAM_6
+struct G6<T: It> {
+  subscript(a x: T.#^GEN_PARAM_6^#) -> Int { return 0 }
+  subscript(a x: Int) -> T.#^GEN_RETURN_6^# { return 0 }
+}
+extension G6 {
+  subscript(b x: T.#^GEN_EXT_PARAM_6^#) -> Int { return 0 }
+  subscript(b x: Int) -> T.#^GEN_EXT_RETURN_6^# { return 0 }
+}
+// GEN_PARAM_6-DAG: Decl[AssociatedType]/Super:         Assoc;
+// GEN_PARAM_6-DAG: Keyword/None:                       Type[#T.Type#];
+
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENPROTO_PARAM_1 | %FileCheck %s -check-prefix=GENPROTO_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENPROTO_RETURN_1 | %FileCheck %s -check-prefix=GENPROTO_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENPROTO_EXT_PARAM_1 | %FileCheck %s -check-prefix=GENPROTO_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENPROTO_EXT_RETURN_1 | %FileCheck %s -check-prefix=GENPROTO_1
+protocol GP1 {
+  associatedtype I: It
+  subscript(a x: I.#^GENPROTO_PARAM_1^#) -> Int
+  subscript(ax: Int) -> I.#^GENPROTO_RETURN_1^#
+}
+extension GP1 {
+  subscript(b x: I.#^GENPROTO_EXT_PARAM_1^#) -> Int { return 1 }
+  subscript(b x: Int) -> I.#^GENPROTO_EXT_RETURN_1^# { return 1 }
+}
+// GENPROTO_1-DAG: Decl[AssociatedType]/Super:         Assoc;
+// GENPROTO_1-DAG: Keyword/None:                       Type[#Self.I.Type#];
diff --git a/test/IDE/local_types.swift b/test/IDE/local_types.swift
index d4a53bf..f9c6b3f 100644
--- a/test/IDE/local_types.swift
+++ b/test/IDE/local_types.swift
@@ -1,8 +1,8 @@
 // Tests lookup and mangling of local types
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swiftc_driver -swift-version 3 -v -emit-module -module-name LocalTypes -o %t/LocalTypes.swiftmodule %s
-// RUN: %target-swift-ide-test -swift-version 3 -print-local-types -I %t -module-to-print LocalTypes -source-filename %s > %t.dump
+// RUN: %target-swiftc_driver -v -emit-module -module-name LocalTypes -o %t/LocalTypes.swiftmodule %s
+// RUN: %target-swift-ide-test -print-local-types -I %t -module-to-print LocalTypes -source-filename %s > %t.dump
 // RUN: %FileCheck %s < %t.dump
 // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t.dump
 
@@ -118,7 +118,8 @@
   return 2
 }
 
-public func singleDefaultArgument(i: Int = {
+// Cannot be public, because inlinable default arguments cannot contain local types
+func singleDefaultArgument(i: Int = {
   //CHECK-DAG: 10LocalTypes21singleDefaultArgument1iySi_tFfA_SiycfU_06SingledE6StructL_V
   struct SingleDefaultArgumentStruct {
     let sdasi: Int
diff --git a/test/IDE/merge_local_types.swift b/test/IDE/merge_local_types.swift
index 7cad7c3..c60289f 100644
--- a/test/IDE/merge_local_types.swift
+++ b/test/IDE/merge_local_types.swift
@@ -3,9 +3,9 @@
 // RUN: %empty-directory(%t)
 
 // Create separate modules and merge them together
-// RUN: %target-swiftc_driver -swift-version 3 -v -emit-module -module-name LocalTypesMerged -o %t/LocalTypesMerged.swiftmodule %s %S/local_types.swift
+// RUN: %target-swiftc_driver -v -emit-module -module-name LocalTypesMerged -o %t/LocalTypesMerged.swiftmodule %s %S/local_types.swift
 
-// RUN: %target-swift-ide-test -swift-version 3 -print-local-types -I %t -module-to-print LocalTypesMerged -source-filename %s | %FileCheck %s
+// RUN: %target-swift-ide-test -print-local-types -I %t -module-to-print LocalTypesMerged -source-filename %s | %FileCheck %s
 
 public func toMerge() {
   // CHECK-DAG: 16LocalTypesMerged7toMergeyyF16SingleFuncStructL_V
diff --git a/test/IDE/print_ast_tc_decls.swift b/test/IDE/print_ast_tc_decls.swift
index 8d031d2..3c9c4e5 100644
--- a/test/IDE/print_ast_tc_decls.swift
+++ b/test/IDE/print_ast_tc_decls.swift
@@ -529,7 +529,7 @@
 // PASS_COMMON-LABEL: {{^}}@objc class d0180_TestIBAttrs {{{$}}
 
   @IBAction func anAction(_: AnyObject) {}
-// PASS_COMMON-NEXT: {{^}}  @IBAction @objc func anAction(_: AnyObject){{$}}
+// PASS_COMMON-NEXT: {{^}}  @objc @IBAction func anAction(_: AnyObject){{$}}
 
   @IBDesignable
   class ADesignableClass {}
@@ -541,13 +541,13 @@
 // PASS_EXPLODE_PATTERN-LABEL: {{^}}@objc class d0181_TestIBAttrs {{{$}}
 
   @IBOutlet weak var anOutlet: d0181_TestIBAttrs!
-// PASS_EXPLODE_PATTERN-NEXT: {{^}}  @IBOutlet @_implicitly_unwrapped_optional @objc weak var anOutlet: @sil_weak d0181_TestIBAttrs!{{$}}
+// PASS_EXPLODE_PATTERN-NEXT: {{^}}  @objc @IBOutlet @_implicitly_unwrapped_optional weak var anOutlet: @sil_weak d0181_TestIBAttrs!{{$}}
 
   @IBInspectable var inspectableProp: Int = 0
-// PASS_EXPLODE_PATTERN-NEXT: {{^}}  @IBInspectable @objc var inspectableProp: Int{{$}}
+// PASS_EXPLODE_PATTERN-NEXT: {{^}}  @objc @IBInspectable var inspectableProp: Int{{$}}
 
   @GKInspectable var inspectableProp2: Int = 0
-// PASS_EXPLODE_PATTERN-NEXT: {{^}}  @GKInspectable @objc var inspectableProp2: Int{{$}}
+// PASS_EXPLODE_PATTERN-NEXT: {{^}}  @objc @GKInspectable var inspectableProp2: Int{{$}}
 }
 
 struct d0190_LetVarDecls {
diff --git a/test/IDE/print_module_missing.swift b/test/IDE/print_module_missing.swift
new file mode 100644
index 0000000..cf439d3
--- /dev/null
+++ b/test/IDE/print_module_missing.swift
@@ -0,0 +1,11 @@
+// Make sure we emit some kind of error message when we cannot find the module
+// to print.
+
+// RUN: not %target-swift-ide-test -print-module -print-interface -no-empty-line-between-members -module-to-print=NoSuchModule -source-filename=%s 2> %t.err
+// RUN: %FileCheck %s -check-prefix=CHECK-MISSING < %t.err
+
+// RUN: not %target-swift-ide-test -print-module -print-interface -no-empty-line-between-members -module-to-print=Swift.NoSuchSubModule -source-filename=%s 2> %t.suberr
+// RUN: %FileCheck %s -check-prefix=CHECK-MISSING-SUBMODULE < %t.suberr
+
+// CHECK-MISSING: 'NoSuchModule'
+// CHECK-MISSING-SUBMODULE: 'Swift.NoSuchSubModule'
diff --git a/test/IDE/print_usrs.swift b/test/IDE/print_usrs.swift
index da2c228..10af321 100644
--- a/test/IDE/print_usrs.swift
+++ b/test/IDE/print_usrs.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -disable-objc-attr-requires-foundation-module -enable-objc-interop %s -swift-version 3
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -enable-objc-interop -print-usrs -source-filename %s -swift-version 3 | %FileCheck %s -strict-whitespace
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -disable-objc-attr-requires-foundation-module -enable-objc-interop %s
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -enable-objc-interop -print-usrs -source-filename %s | %FileCheck %s -strict-whitespace
 
 import macros
 
@@ -165,7 +165,7 @@
 }
 
 // CHECK: [[@LINE+2]]:7 c:@M@swift_ide_test@objc(cs)ObjCClass1{{$}}
-@objc
+@objc @objcMembers
 class ObjCClass1 {
   // CHECK: [[@LINE+1]]:7 c:@M@swift_ide_test@objc(cs)ObjCClass1(py)instanceVar{{$}}
   var instanceVar: Int = 1
diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift
index 2540ce0..b68eca2 100644
--- a/test/IRGen/abitypes.swift
+++ b/test/IRGen/abitypes.swift
@@ -80,6 +80,7 @@
   // x86_64-macosx: [[SELFCAST:%.*]] = bitcast [[SELF]]* %2 to i8*
   // x86_64-macosx: [[RESULT:%.*]] = call float bitcast (void ()* @objc_msgSend to float (i8*, i8*,  <2 x float>, <2 x float>)*)(i8* [[SELFCAST]], i8* [[SEL]], <2 x float> [[FIRST_HALF]], <2 x float> [[SECOND_HALF]])
   // armv7-ios: define hidden swiftcc float @"$S8abitypes3FooC17getXFromRectSwift{{[_0-9a-zA-Z]*}}F"(float, float, float, float, [[SELF:%.*]]* swiftself) {{.*}} {
+  // armv7-ios: [[DEBUGVAR:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4
   // armv7-ios: [[COERCED:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4
   // armv7-ios: [[SEL:%.*]] = load i8*, i8** @"\01L_selector(getXFromRect:)", align 4
   // armv7-ios: [[CAST:%.*]] = bitcast [[MYRECT]]* [[COERCED]] to [4 x i32]*
diff --git a/test/IRGen/copy_value_destroy_value.sil b/test/IRGen/copy_value_destroy_value.sil
index bfdc2a9..701cbf1 100644
--- a/test/IRGen/copy_value_destroy_value.sil
+++ b/test/IRGen/copy_value_destroy_value.sil
@@ -36,10 +36,22 @@
 // CHECK: call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[VAL2]])
 // CHECK: call void @swift_release(%swift.refcounted* [[VAL1]])
 // CHECK: call void @swift_release(%swift.refcounted* [[VAL2]])
-sil @non_trivial : $@convention(thin) (Foo) -> () {
+sil @non_trivial : $@convention(thin) (@guaranteed Foo) -> () {
 bb0(%0 : $Foo):
   %1 = copy_value %0 : $Foo
   destroy_value %1 : $Foo
   %2 = tuple()
   return %2 : $()
 }
+
+// CHECK: define{{( protected)?}} swiftcc void @non_trivial_unowned(
+// CHECK: call %swift.refcounted* @swift_unownedRetainStrong(%swift.refcounted* returned %0)
+// CHECK: call void @swift_release(%swift.refcounted* %0)
+sil @non_trivial_unowned : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = ref_to_unowned %0 : $Builtin.NativeObject to $@sil_unowned Builtin.NativeObject
+  %2 = copy_unowned_value %1 : $@sil_unowned Builtin.NativeObject
+  destroy_value %2 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/IRGen/enum_resilience_objc.swift b/test/IRGen/enum_resilience_objc.swift
new file mode 100644
index 0000000..1a582d4
--- /dev/null
+++ b/test/IRGen/enum_resilience_objc.swift
@@ -0,0 +1,25 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -module-name enum_resilience -I %t -emit-ir -enable-resilience %s | %FileCheck %s -DINT=i%target-ptrsize
+// RUN: %target-swift-frontend -module-name enum_resilience -I %t -emit-ir -enable-resilience -O %s
+
+// REQUIRES: objc_interop
+
+// Because the enum is resilient we cannot pack the tag into the pointer inside of the resilient payload.
+// CHECK: %T15enum_resilience9ContainerC5Multi33_{{.*}}LLO.0 = type <{ [{{(8|4)}} x i8], [1 x i8] }>
+
+import resilient_struct
+
+public class Container {
+  private enum Multi {
+    case none
+    case some(Container)
+    case data(ResilientRef)
+  }
+  private var e: Multi
+  var i: Int
+  init() {
+    e = .none
+    i = 0
+  }
+}
diff --git a/test/IRGen/preserve_exclusivity.swift b/test/IRGen/preserve_exclusivity.swift
index 14e1a87..476c120 100644
--- a/test/IRGen/preserve_exclusivity.swift
+++ b/test/IRGen/preserve_exclusivity.swift
@@ -32,7 +32,6 @@
 // CHECK-LABEL: define {{.*}}swiftcc void @"$S20preserve_exclusivity10readAccessyyBp_xmtlF"(i8*, %swift.type*{{.*}}, %swift.type*{{.*}} %T1)
 // CHECK:   call void @swift_beginAccess
 // CHECK: ret void
-@_semantics("optimize.sil.preserve_exclusivity")
 public func readAccess<T1>(_ address: Builtin.RawPointer, _ ty1: T1.Type) {
   marker3()
   Builtin.performInstantaneousReadAccess(address, ty1);
diff --git a/test/Index/Store/Inputs/cross-file-extension-crash-other.swift b/test/Index/Store/Inputs/cross-file-extension-crash-other.swift
new file mode 100644
index 0000000..b48f4d8
--- /dev/null
+++ b/test/Index/Store/Inputs/cross-file-extension-crash-other.swift
@@ -0,0 +1,4 @@
+final class X<T> { }
+
+protocol P { }
+extension X: P { }
diff --git a/test/Index/Store/cross-file-extension-crash.swift b/test/Index/Store/cross-file-extension-crash.swift
new file mode 100644
index 0000000..3ee1848
--- /dev/null
+++ b/test/Index/Store/cross-file-extension-crash.swift
@@ -0,0 +1,9 @@
+// Ensure that we don't crash due to resolving an extension in a non-primary
+// file.
+
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -index-store-path %t/idx -o %t/file.o -typecheck -primary-file %s %S/Inputs/cross-file-extension-crash-other.swift -verify
+
+extension X {
+  func foo() { }
+}
diff --git a/test/Inputs/resilient_struct.swift b/test/Inputs/resilient_struct.swift
index 902e25e..37b52da 100644
--- a/test/Inputs/resilient_struct.swift
+++ b/test/Inputs/resilient_struct.swift
@@ -87,3 +87,7 @@
     ref = r
   }
 }
+
+public struct ResilientRef {
+  public var r: Referent
+}
diff --git a/test/Interpreter/SDK/objc_factory_method.swift b/test/Interpreter/SDK/objc_factory_method.swift
index fc45fe1..712bfe9 100644
--- a/test/Interpreter/SDK/objc_factory_method.swift
+++ b/test/Interpreter/SDK/objc_factory_method.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -module-name FactoryTest %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift -module-name FactoryTest %s -o %t/a.out
 // RUN: %target-run %t/a.out | %FileCheck %s
 // REQUIRES: executable_test
 // REQUIRES: OS=macosx
 
 import AppKit
 
-let image = NSImage(named: NSImageNameTrashEmpty)
+let image = NSImage(named: NSImage.Name.trashEmpty)
 // CHECK: TrashEmpty
 print(image!.name()!)
diff --git a/test/Interpreter/SDK/objc_mangling.swift b/test/Interpreter/SDK/objc_mangling.swift
index 0e18cdf..280b49d 100644
--- a/test/Interpreter/SDK/objc_mangling.swift
+++ b/test/Interpreter/SDK/objc_mangling.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -module-name MangleTest %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift -module-name MangleTest %s -o %t/a.out
 // RUN: %target-run %t/a.out | %FileCheck %s
 // REQUIRES: executable_test
 
@@ -21,7 +21,7 @@
 {
   // Class's name should appear unmangled.
   assert(NSStringFromClass(cls) == name)
-  assert(NSStringFromClass(object_getClass(cls)) == name)
+  assert(NSStringFromClass(object_getClass(cls)!) == name)
 
   // Look up by unmangled name should work.
   // Look up by mangled name should also work.
@@ -47,7 +47,7 @@
 
 func checkIvarName(_ cls: AnyClass, _ name: String)
 {
-  let ivarName = ivar_getName(class_getInstanceVariable(cls, name))
+  let ivarName = ivar_getName(class_getInstanceVariable(cls, name)!)
   let s = ivarName != nil ? String(cString: ivarName!) : Optional.none
   assert(name == s)
 }
diff --git a/test/Interpreter/SDK/object_literals.swift b/test/Interpreter/SDK/object_literals.swift
index 3f6d51e..27e6a89 100644
--- a/test/Interpreter/SDK/object_literals.swift
+++ b/test/Interpreter/SDK/object_literals.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
 // RUN: %empty-directory(%t/Test.app/Contents/MacOS)
 // RUN: cp -r %S/Inputs/object_literals-Resources %t/Test.app/Contents/Resources
-// RUN: %target-build-swift %s -o %t/Test.app/Contents/MacOS/main -swift-version 3
+// RUN: %target-build-swift %s -o %t/Test.app/Contents/MacOS/main
 // RUN: %target-run %t/Test.app/Contents/MacOS/main
 
 // REQUIRES: executable_test
@@ -21,7 +21,7 @@
 }
 
 LiteralsTestSuite.test("image") {
-  let image = #imageLiteral(resourceName: NSImageNameComputer)
+  let image = #imageLiteral(resourceName: NSImage.Name.computer.rawValue)
   expectTrue(image.isValid)
 }
 
diff --git a/test/Interpreter/enum.swift b/test/Interpreter/enum.swift
index 34a9e99..212e497 100644
--- a/test/Interpreter/enum.swift
+++ b/test/Interpreter/enum.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift %s -o %t/a.out
 // RUN: %target-run %t/a.out | %FileCheck %s
 // REQUIRES: executable_test
 
@@ -520,10 +520,10 @@
   presentEitherOr(EitherOr<T, U>.Right(u))
 }
 
-presentEitherOr(EitherOr<(), ()>.Left())  // CHECK-NEXT: Left(())
+presentEitherOr(EitherOr<(), ()>.Left(()))  // CHECK-NEXT: Left(())
 presentEitherOr(EitherOr<(), ()>.Middle)  // CHECK-NEXT: Middle
 presentEitherOr(EitherOr<(), ()>.Center)  // CHECK-NEXT: Center
-presentEitherOr(EitherOr<(), ()>.Right()) // CHECK-NEXT: Right(())
+presentEitherOr(EitherOr<(), ()>.Right(())) // CHECK-NEXT: Right(())
 
 // CHECK-NEXT: Left(())
 // CHECK-NEXT: Middle
@@ -542,7 +542,7 @@
 // CHECK-NEXT: Right(foo)
 presentEitherOrsOf(t: 1, u: "foo")
 
-presentEitherOr(EitherOr<(), String>.Left())       // CHECK-NEXT: Left(())
+presentEitherOr(EitherOr<(), String>.Left(()))       // CHECK-NEXT: Left(())
 presentEitherOr(EitherOr<(), String>.Middle)       // CHECK-NEXT: Middle
 presentEitherOr(EitherOr<(), String>.Center)       // CHECK-NEXT: Center
 presentEitherOr(EitherOr<(), String>.Right("foo")) // CHECK-NEXT: Right(foo)
diff --git a/test/Interpreter/enum_resilience.swift b/test/Interpreter/enum_resilience.swift
index 3db9e03..9c68d42 100644
--- a/test/Interpreter/enum_resilience.swift
+++ b/test/Interpreter/enum_resilience.swift
@@ -436,4 +436,28 @@
   expectEqual(Base.self, ResilientMultiPayloadGenericEnumFixedSize<Base>.A.getTypeParameter())
 }
 
+public class Container {
+  private enum Multi {
+    case none
+    case some(Container)
+    case other(ResilientRef)
+  }
+  private var m: Multi
+  var i: Int
+  init() {
+    m = .none
+    i = 0
+    switch self.m {
+      case .none:
+        print("success")
+      case .some(_), .other(_):
+        assert(false, "noooo!")
+    }
+  }
+}
+
+ResilientEnumTestSuite.test("ResilientPrivateEnumMember") {
+  _ = Container()
+}
+
 runAllTests()
diff --git a/test/Interpreter/imported_objc_generics.swift b/test/Interpreter/imported_objc_generics.swift
index 4b56317..bc4259a 100644
--- a/test/Interpreter/imported_objc_generics.swift
+++ b/test/Interpreter/imported_objc_generics.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
 //
 // RUN: %target-clang -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
-// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out
 // RUN: %target-run %t/a.out
 
 // REQUIRES: executable_test
@@ -111,7 +111,7 @@
   expectEqual("woof", makeContainedAnimalMakeNoise(x: petCarrier))
 }
 
-class ClassWithMethodsUsingObjCGenerics: NSObject {
+@objc @objcMembers class ClassWithMethodsUsingObjCGenerics: NSObject {
   func copyContainer(_ x: CopyingContainer<NSString>) -> CopyingContainer<NSString> {
     return x
   }
diff --git a/test/Interpreter/imported_objc_generics_extension.swift b/test/Interpreter/imported_objc_generics_extension.swift
index b3f08ee..295a05a 100644
--- a/test/Interpreter/imported_objc_generics_extension.swift
+++ b/test/Interpreter/imported_objc_generics_extension.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
 //
 // RUN: %target-clang -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
-// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out
 // RUN: %target-run %t/a.out
 
 // REQUIRES: executable_test
@@ -14,8 +14,8 @@
 
 var ImportedObjCGenericExtension = TestSuite("ImportedObjCGenericExtension")
 
-extension Container {
-  func returnSelf() -> Self {
+@objc extension Container {
+  @objc func returnSelf() -> Self {
     return self
   }
 }
diff --git a/test/Interpreter/objc_class_properties.swift b/test/Interpreter/objc_class_properties.swift
index 46e601c..23ec4f0 100644
--- a/test/Interpreter/objc_class_properties.swift
+++ b/test/Interpreter/objc_class_properties.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
 
 // RUN: %clang %target-cc-options -isysroot %sdk -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
-// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out
 // RUN: %target-run %t/a.out
 
 // REQUIRES: executable_test
diff --git a/test/Interpreter/objc_class_properties_runtime.swift b/test/Interpreter/objc_class_properties_runtime.swift
index 20ae5f0..9c3669c 100644
--- a/test/Interpreter/objc_class_properties_runtime.swift
+++ b/test/Interpreter/objc_class_properties_runtime.swift
@@ -2,7 +2,7 @@
 
 // RUN: %clang -arch x86_64 -mmacosx-version-min=10.11 -isysroot %sdk -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
 
-// RUN: %swiftc_driver -target $(echo '%target-triple' | sed -E -e 's/macosx10.(9|10).*/macosx10.11/') -sdk %sdk -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out -swift-version 3
+// RUN: %swiftc_driver -target $(echo '%target-triple' | sed -E -e 's/macosx10.(9|10).*/macosx10.11/') -sdk %sdk -I %S/Inputs/ObjCClasses/ %t/ObjCClasses.o %s -o %t/a.out
 // RUN: %t/a.out
 
 // REQUIRES: OS=macosx
@@ -76,7 +76,7 @@
   let prop = class_getProperty(object_getClass(theClass), "value")
   expectNotNil(prop)
 
-  let nameAsCString = property_getName(prop)!
+  let nameAsCString = property_getName(prop!)
   expectNotNil(nameAsCString)
   expectEqual("value", String(cString: nameAsCString))
 }
diff --git a/test/Interpreter/strong_retain_unowned_mispairing.swift b/test/Interpreter/strong_retain_unowned_mispairing.swift
new file mode 100644
index 0000000..c701adf
--- /dev/null
+++ b/test/Interpreter/strong_retain_unowned_mispairing.swift
@@ -0,0 +1,44 @@
+// RUN: %target-run-simple-opt-O-swift
+// REQUIRES: executable_test
+
+// We were crashing here due to not preserving rc identity. 
+// rdar://41328987
+
+func takeEscaping(closure: @escaping (String) -> Void) {}
+
+public class Helper {
+  weak var o: P?
+
+  @_optimize(none)
+  init(o: P) {
+    self.o = o
+  }
+}
+
+protocol P: class {}
+
+public class Binding: P {
+  private var helper: Helper?
+
+  public init() {
+    helper = Helper(o: self)
+    
+    // Listen to model changes
+    takeEscaping { [unowned self] (value: String) in
+      self.update()
+    }
+
+    takeEscaping { [unowned self] (value: String) in
+      self.update()
+    }
+  }
+
+  func update() {}
+}
+
+@_optimize(none)
+func testCrash() {
+  _ = Binding()
+}
+
+testCrash()
diff --git a/test/Misc/misc_diagnostics.swift b/test/Misc/misc_diagnostics.swift
index 2c11f75..4176dff 100644
--- a/test/Misc/misc_diagnostics.swift
+++ b/test/Misc/misc_diagnostics.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -swift-version 3
+// RUN: %target-typecheck-verify-swift
 
 // REQUIRES: objc_interop
 
@@ -135,9 +135,9 @@
 
 
 
-func tuple_splat1(_ a : Int, _ b : Int) { // expected-note {{'tuple_splat1' declared here}}
+func tuple_splat1(_ a : Int, _ b : Int) { // expected-note 2 {{'tuple_splat1' declared here}}
   let x = (1,2)
-  tuple_splat1(x)          // expected-error {{passing 2 arguments to a callee as a single tuple value has been removed in Swift 3}}
+  tuple_splat1(x)          // expected-error {{missing argument for parameter #2 in call}}
   tuple_splat1(1, 2)       // Ok.
   tuple_splat1((1, 2))     // expected-error {{missing argument for parameter #2 in call}}
 }
diff --git a/test/NameBinding/Inputs/multi-file-with-main/main.swift b/test/NameBinding/Inputs/multi-file-with-main/main.swift
index 4fb63eb..5c05f05 100644
--- a/test/NameBinding/Inputs/multi-file-with-main/main.swift
+++ b/test/NameBinding/Inputs/multi-file-with-main/main.swift
@@ -1,6 +1,6 @@
 import Swift
 
-infix operator +++ {}
+infix operator +++
 
 func +++(a: Int, b: Int) -> Int {
   return a + b
diff --git a/test/NameBinding/Inputs/reference-dependencies-helper.swift b/test/NameBinding/Inputs/reference-dependencies-helper.swift
index 640d21a..78d3a1a 100644
--- a/test/NameBinding/Inputs/reference-dependencies-helper.swift
+++ b/test/NameBinding/Inputs/reference-dependencies-helper.swift
@@ -30,8 +30,8 @@
 
 typealias OtherFileAliasForSecret = OtherFileSecretTypeWrapper.SecretType
 
-prefix operator *** {}
-prefix operator ~~~~~ {}
+prefix operator ***
+prefix operator ~~~~~
 
 prefix operator ****
 infix operator *****
diff --git a/test/NameBinding/multi-file-with-main.swift b/test/NameBinding/multi-file-with-main.swift
index 8ad0435..bf5e00f 100644
--- a/test/NameBinding/multi-file-with-main.swift
+++ b/test/NameBinding/multi-file-with-main.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -typecheck -enable-source-import -primary-file %s %S/Inputs/multi-file-with-main/main.swift -module-name=MultiFile -sdk "" -verify -swift-version 3
+// RUN: %target-swift-frontend -typecheck -enable-source-import -primary-file %s %S/Inputs/multi-file-with-main/main.swift -module-name=MultiFile -sdk "" -verify
 
 func testOperator() {
   let x: Int = 1 +++ "abc" // expected-error {{binary operator '+++' cannot be applied to operands of type 'Int' and 'String'}} expected-note {{expected an argument list of type '(Int, Int)'}}
diff --git a/test/NameBinding/name-binding.swift b/test/NameBinding/name-binding.swift
index 5a0bfbe..cd8dfa2 100644
--- a/test/NameBinding/name-binding.swift
+++ b/test/NameBinding/name-binding.swift
@@ -195,16 +195,16 @@
 //===----------------------------------------------------------------------===//
 
 func forwardReference() {
-  x = 0 // expected-error{{use of local variable 'x' before its declaration}}
-  var x: Float = 0.0 // expected-note{{'x' declared here}}
+  v = 0 // expected-error{{use of local variable 'v' before its declaration}}
+  var v: Float = 0.0 // expected-note{{'v' declared here}}
 }
 
 class ForwardReference {
   var x: Int = 0
 
   func test() {
-    x = 0 // expected-error{{use of local variable 'x' before its declaration}}
-    var x: Float = 0.0 // expected-note{{'x' declared here}}
+    x = 0
+    var x: Float = 0.0 // expected-warning{{variable 'x' was never used; consider replacing with '_' or removing it}}
   }
 }
 
diff --git a/test/NameBinding/name_lookup.swift b/test/NameBinding/name_lookup.swift
index 99324fb..720ac3f 100644
--- a/test/NameBinding/name_lookup.swift
+++ b/test/NameBinding/name_lookup.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -typo-correction-limit 100 -swift-version 3
+// RUN: %target-typecheck-verify-swift -typo-correction-limit 100
 
 class ThisBase1 {
   init() { }
@@ -525,10 +525,10 @@
 }
 
 
-// <rdar://problem/16954496> lazy properties must use "self." in their body, and can weirdly refer to class variables directly
+// <rdar://problem/31762378> lazy properties don't have to use "self." in their initializers.
 class r16954496 {
   func bar() {}
-  lazy var x: Array<() -> Void> = [bar] // expected-error {{cannot convert value of type '(r16954496) -> () -> ()' to expected element type '() -> Void'}}
+  lazy var x: Array<() -> Void> = [bar]
 }
 
 
diff --git a/test/NameBinding/reference-dependencies-dynamic-lookup.swift b/test/NameBinding/reference-dependencies-dynamic-lookup.swift
index 016bd63..80666cc 100644
--- a/test/NameBinding/reference-dependencies-dynamic-lookup.swift
+++ b/test/NameBinding/reference-dependencies-dynamic-lookup.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
 // RUN: cp %s %t/main.swift
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -primary-file %t/main.swift -emit-reference-dependencies-path - -swift-version 3 > %t.swiftdeps
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -primary-file %t/main.swift -emit-reference-dependencies-path - > %t.swiftdeps
 // RUN: %FileCheck %s < %t.swiftdeps
 // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t.swiftdeps
 
 // Check that the output is deterministic.
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -primary-file %t/main.swift -emit-reference-dependencies-path - -swift-version 3 > %t-2.swiftdeps
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -primary-file %t/main.swift -emit-reference-dependencies-path - > %t-2.swiftdeps
 // RUN: diff %t.swiftdeps %t-2.swiftdeps
 
 // REQUIRES: objc_interop
@@ -14,7 +14,7 @@
 
 // CHECK-LABEL: provides-dynamic-lookup:
 
-@objc class Base : NSObject {
+@objc @objcMembers class Base : NSObject {
   // CHECK-DAG: - "foo"
   func foo() {}
 
diff --git a/test/NameBinding/reference-dependencies.swift b/test/NameBinding/reference-dependencies.swift
index d31b845..1d1c120 100644
--- a/test/NameBinding/reference-dependencies.swift
+++ b/test/NameBinding/reference-dependencies.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
 // RUN: cp %s %t/main.swift
-// RUN: %target-swift-frontend -typecheck -primary-file %t/main.swift %S/Inputs/reference-dependencies-helper.swift -emit-reference-dependencies-path - -swift-version 3 > %t.swiftdeps
+// RUN: %target-swift-frontend -typecheck -primary-file %t/main.swift %S/Inputs/reference-dependencies-helper.swift -emit-reference-dependencies-path - > %t.swiftdeps
 // RUN: %FileCheck %s < %t.swiftdeps
 // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t.swiftdeps
 
 // Check that the output is deterministic.
-// RUN: %target-swift-frontend -typecheck -primary-file %t/main.swift %S/Inputs/reference-dependencies-helper.swift -emit-reference-dependencies-path - -swift-version 3 > %t-2.swiftdeps
+// RUN: %target-swift-frontend -typecheck -primary-file %t/main.swift %S/Inputs/reference-dependencies-helper.swift -emit-reference-dependencies-path - > %t-2.swiftdeps
 // RUN: diff %t.swiftdeps %t-2.swiftdeps
 
 // CHECK-LABEL: {{^provides-top-level:$}}
diff --git a/test/Parse/enum.swift b/test/Parse/enum.swift
index 3b201d4..dde6877 100644
--- a/test/Parse/enum.swift
+++ b/test/Parse/enum.swift
@@ -148,7 +148,7 @@
   case Ladd, Elliott, Sixteenth, Harrison
 }
 
-enum RawTypeCircularityA : RawTypeCircularityB, ExpressibleByIntegerLiteral { // expected-error {{circular enum raw types 'RawTypeCircularityA' -> 'RawTypeCircularityB' -> 'RawTypeCircularityA'}} FIXME: expected-error{{RawRepresentable}}
+enum RawTypeCircularityA : RawTypeCircularityB, ExpressibleByIntegerLiteral { // expected-error {{'RawTypeCircularityA' has a raw type that depends on itself}} FIXME: expected-error{{RawRepresentable}}
   case Morrison, Belmont, Madison, Hawthorne
 
   init(integerLiteral value: Int) {
diff --git a/test/Parse/multiline_pound_diagnostic_arg_rdar_41154797.swift b/test/Parse/multiline_pound_diagnostic_arg_rdar_41154797.swift
new file mode 100644
index 0000000..30ff25f
--- /dev/null
+++ b/test/Parse/multiline_pound_diagnostic_arg_rdar_41154797.swift
@@ -0,0 +1,4 @@
+// RUN: not %target-typecheck-verify-swift
+
+#error("""
+
diff --git a/test/Parse/operator_decl.swift b/test/Parse/operator_decl.swift
index fbcaa6b..d7dbd95 100644
--- a/test/Parse/operator_decl.swift
+++ b/test/Parse/operator_decl.swift
@@ -1,24 +1,24 @@
-// RUN: %target-typecheck-verify-swift -swift-version 3
+// RUN: %target-typecheck-verify-swift
 
-prefix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{20-23=}}
-postfix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{21-24=}}
-infix operator +++ {} // expected-warning {{operator should no longer be declared with body}} {{19-22=}}
-infix operator +++* { // expected-warning {{operator should no longer be declared with body; use a precedence group instead}} {{none}}
+prefix operator +++ {} // expected-error {{operator should no longer be declared with body}} {{20-23=}}
+postfix operator +++ {} // expected-error {{operator should no longer be declared with body}} {{21-24=}}
+infix operator +++ {} // expected-error {{operator should no longer be declared with body}} {{19-22=}}
+infix operator +++* { // expected-error {{operator should no longer be declared with body; use a precedence group instead}} {{none}}
   associativity right
 }
-infix operator +++*+ : A { } // expected-warning {{operator should no longer be declared with body}} {{25-29=}}
+infix operator +++*+ : A { } // expected-error {{operator should no longer be declared with body}} {{25-29=}}
 
 
 prefix operator +++** : A { }
 // expected-error@-1 {{only infix operators may declare a precedence}} {{23-27=}}
-// expected-warning@-2 {{operator should no longer be declared with body}} {{26-30=}}
+// expected-error@-2 {{operator should no longer be declared with body}} {{26-30=}}
 
 prefix operator ++*++ : A
 // expected-error@-1 {{only infix operators may declare a precedence}} {{23-26=}}
 
 postfix operator ++*+* : A { }
 // expected-error@-1 {{only infix operators may declare a precedence}} {{24-28=}}
-// expected-warning@-2 {{operator should no longer be declared with body}} {{27-31=}}
+// expected-error@-2 {{operator should no longer be declared with body}} {{27-31=}}
 
 postfix operator ++**+ : A
 // expected-error@-1 {{only infix operators may declare a precedence}} {{24-27=}}
@@ -28,11 +28,11 @@
 
 operator +*+++ { }
 // expected-error@-1 {{operator must be declared as 'prefix', 'postfix', or 'infix'}}
-// expected-warning@-2 {{operator should no longer be declared with body}} {{15-19=}}
+// expected-error@-2 {{operator should no longer be declared with body}} {{15-19=}}
 
 operator +*++* : A { }
 // expected-error@-1 {{operator must be declared as 'prefix', 'postfix', or 'infix'}}
-// expected-warning@-2 {{operator should no longer be declared with body}} {{19-23=}}
+// expected-error@-2 {{operator should no longer be declared with body}} {{19-23=}}
 
 prefix operator // expected-error {{expected operator name in operator declaration}}
 
diff --git a/test/PrintAsObjC/Inputs/comments-expected-output.h b/test/PrintAsObjC/Inputs/comments-expected-output.h
index b369a95..5049884 100644
--- a/test/PrintAsObjC/Inputs/comments-expected-output.h
+++ b/test/PrintAsObjC/Inputs/comments-expected-output.h
@@ -1,6 +1,5 @@
 SWIFT_CLASS("_TtC8comments4A000")
 @interface A000
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -30,7 +29,6 @@
 /// <h1>LEVEL ONE</h1>
 /// <h2>LEVEL TWO</h2>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -39,7 +37,6 @@
 /// And now for a URL.
 /// <a href="http://developer.apple.com/swift/">http://developer.apple.com/swift/</a>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -55,7 +52,6 @@
 ///
 /// </blockquote>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -75,7 +71,6 @@
 /// Aaa.
 /// Bbb.
 - (void)f3;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -83,7 +78,6 @@
 @interface ClosingComments
 /// Some comment. */
 - (void)closingComment;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -152,7 +146,6 @@
 /// \a combine error: Nothing.
 ///
 - (void)closureParameterOutlineOutlineWithA:(NSInteger)a combine:(SWIFT_NOESCAPE NSInteger (^ _Nonnull)(NSInteger, NSInteger))combine;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -166,7 +159,6 @@
 ///
 /// \endcode
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -175,7 +167,6 @@
 /// Aaa <em>bbb</em> ccc.
 /// Aaa <em>bbb</em> ccc.
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -191,7 +182,6 @@
 - (void)f3;
 /// Aaa.
 - (void)f4;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -204,7 +194,6 @@
 /// throws:
 /// An error if <code>x == 0</code>
 - (void)f1:(NSInteger)x;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -214,7 +203,6 @@
 /// <hr/>
 /// The end.
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -222,7 +210,6 @@
 @interface ImplicitNameLink
 /// <a href="https://www.apple.com/">Apple</a>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -250,7 +237,6 @@
 ///
 /// \endcode
 - (void)f2;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -258,7 +244,6 @@
 @interface InlineCode
 /// Aaa <code>bbb</code> ccc.
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -266,7 +251,6 @@
 @interface InlineLink
 /// Aaa <a href="/path/to/something">bbb</a> ccc.
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -276,7 +260,6 @@
 /// Brief after softbreak.
 /// Some paragraph text.
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -292,7 +275,6 @@
 ///   </li>
 /// </ol>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -338,7 +320,6 @@
 /// Eee.
 /// Fff.
 - (void)f4;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -351,7 +332,6 @@
 /// \param z A number
 ///
 - (void)f0:(NSInteger)x y:(NSInteger)y z:(NSInteger)z;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -372,13 +352,11 @@
 /// \param z A number
 ///
 - (void)f0:(NSInteger)x y:(NSInteger)y z:(NSInteger)z;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
 SWIFT_CLASS("_TtC8comments13ReferenceLink")
 @interface ReferenceLink
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -388,7 +366,6 @@
 /// returns:
 /// A number
 - (NSInteger)f0 SWIFT_WARN_UNUSED_RESULT;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -397,7 +374,6 @@
 /// \param x A number
 ///
 - (void)f0:(NSInteger)x y:(NSInteger)y;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -410,7 +386,6 @@
 /// <h5>LEVEL FIVE</h5>
 /// <h5>LEVEL SIX</h5>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -419,7 +394,6 @@
 /// Aaa <em>bbb</em> ccc.
 /// Aaa <em>bbb</em> ccc.
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 
@@ -448,7 +422,6 @@
 ///   </li>
 /// </ul>
 - (void)f0;
-- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 @end
 
 #if __has_attribute(external_source_symbol)
diff --git a/test/PrintAsObjC/accessibility.swift b/test/PrintAsObjC/accessibility.swift
index fc217f2..d69c757 100644
--- a/test/PrintAsObjC/accessibility.swift
+++ b/test/PrintAsObjC/accessibility.swift
@@ -1,21 +1,21 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -parse-as-library %s -typecheck -emit-objc-header-path %t/accessibility.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend -parse-as-library %s -typecheck -emit-objc-header-path %t/accessibility.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PUBLIC %s < %t/accessibility.h
 // RUN: %check-in-clang %t/accessibility.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -emit-objc-header-path %t/accessibility-internal.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -typecheck -emit-objc-header-path %t/accessibility-internal.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-INTERNAL %s < %t/accessibility-internal.h
 // RUN: %check-in-clang %t/accessibility-internal.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -typecheck -import-objc-header %S/../Inputs/empty.h -emit-objc-header-path %t/accessibility-imported-header.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -typecheck -import-objc-header %S/../Inputs/empty.h -emit-objc-header-path %t/accessibility-imported-header.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-INTERNAL %s < %t/accessibility-imported-header.h
 // RUN: %check-in-clang %t/accessibility-imported-header.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -typecheck -DMAIN -emit-objc-header-path %t/accessibility-main.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -typecheck -DMAIN -emit-objc-header-path %t/accessibility-main.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-INTERNAL %s < %t/accessibility-main.h
 // RUN: %check-in-clang %t/accessibility-main.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -typecheck -application-extension -emit-objc-header-path %t/accessibility-appext.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -typecheck -application-extension -emit-objc-header-path %t/accessibility-appext.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-INTERNAL %s < %t/accessibility-appext.h
 // RUN: %check-in-clang %t/accessibility-appext.h
 
@@ -24,16 +24,16 @@
 // CHECK-LABEL: @interface A_Public{{$}}
 // CHECK-INTERNAL-NEXT: init
 // CHECK-NEXT: @end
-@objc public class A_Public {}
+@objc @objcMembers public class A_Public {}
 
 // CHECK-PUBLIC-NOT: B_Internal
 // CHECK-INTERNAL-LABEL: @interface B_Internal{{$}}
 // CHECK-INTERNAL-NEXT: init
 // CHECK-INTERNAL-NEXT: @end
-@objc internal class B_Internal {}
+@objc @objcMembers internal class B_Internal {}
 
 // CHECK-NOT: C_Private
-@objc private class C_Private {}
+@objc @objcMembers private class C_Private {}
 
 
 #if MAIN
diff --git a/test/PrintAsObjC/availability.swift b/test/PrintAsObjC/availability.swift
index 485bb04..33b11d0 100644
--- a/test/PrintAsObjC/availability.swift
+++ b/test/PrintAsObjC/availability.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/availability.swiftmodule -typecheck -emit-objc-header-path %t/availability.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/availability.swiftmodule -typecheck -emit-objc-header-path %t/availability.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/availability.h
 // RUN: %check-in-clang %t/availability.h
 
@@ -153,7 +153,7 @@
     @available(macOS 10.10, *)
     @objc init(x _: Int) {}
 
-    var simpleProperty: Int {
+    @objc var simpleProperty: Int {
 	get {
 		return 100
 	    }
@@ -193,7 +193,7 @@
 
 
   @available(macOS, deprecated: 10.10)
-  var propertyDeprecatedInsideExtension: Int {
+  @objc var propertyDeprecatedInsideExtension: Int {
 	  get {
 		  return 0
 	  }
@@ -208,7 +208,7 @@
 
 
 @available(macOS 999, *)
-@objc class WholeClassAvailability {
+@objc @objcMembers class WholeClassAvailability {
   func wholeClassAvailability(_: WholeProtoAvailability) {}
 }
 
diff --git a/test/PrintAsObjC/blocks.swift b/test/PrintAsObjC/blocks.swift
index c2d4fec..0a8a0c8 100644
--- a/test/PrintAsObjC/blocks.swift
+++ b/test/PrintAsObjC/blocks.swift
@@ -1,8 +1,8 @@
 // Please keep this file in alphabetical order!
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/blocks.swiftmodule -typecheck -emit-objc-header-path %t/blocks.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/blocks.swiftmodule -typecheck -emit-objc-header-path %t/blocks.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/blocks.h
 // RUN: %check-in-clang %t/blocks.h
 
@@ -135,6 +135,9 @@
   
   // CHECK-NEXT: @property (nonatomic, getter=class, setter=setClass:) NSInteger (* _Nonnull class_)(NSInteger);
   @objc var `class`: @convention(c) (_ function: Int) -> Int = { $0 }
+  
+  // CHECK-NEXT: init
+  @objc init() {}
 }
-// CHECK-NEXT: init
+
 // CHECK-NEXT: @end
diff --git a/test/PrintAsObjC/circularity.swift b/test/PrintAsObjC/circularity.swift
index 6c8f54f..f0d50a2 100644
--- a/test/PrintAsObjC/circularity.swift
+++ b/test/PrintAsObjC/circularity.swift
@@ -5,13 +5,13 @@
 // RUN: %empty-directory(%t)
 
 // FIXME: BEGIN -enable-source-import hackaround
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift -swift-version 3
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
 // FIXME: END -enable-source-import hackaround
 
-// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/Inputs/circularity.h -emit-module -o %t %s -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/Inputs/circularity.h -parse-as-library %t/circularity.swiftmodule -typecheck -emit-objc-header-path %t/circularity.h -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/Inputs/circularity.h -emit-module -o %t %s
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/Inputs/circularity.h -parse-as-library %t/circularity.swiftmodule -typecheck -emit-objc-header-path %t/circularity.h
 
 // RUN: %FileCheck %s < %t/circularity.h
 
@@ -23,18 +23,18 @@
 // CHECK-LABEL: @interface A1 : ProtoImpl
 class A1: ProtoImpl {
   // CHECK: // 'test(_:)' below
-  func test(_: NeedsProto<A2>) {}
+  @objc func test(_: NeedsProto<A2>) {}
 } // CHECK: @end
 // CHECK-LABEL: @interface A2 : ProtoImpl
 class A2: ProtoImpl {
   // CHECK: - (void)test:
-  func test(_: NeedsProto<A1>) {}
+  @objc func test(_: NeedsProto<A1>) {}
 } // CHECK: @end
 
 // CHECK-LABEL: @interface B1 : ProtoImpl
 class B1: ProtoImpl {
   // CHECK: // 'test(_:)' below
-  func test(_: NeedsProto<B2>) {}
+  @objc func test(_: NeedsProto<B2>) {}
 } // CHECK: @end
 // CHECK-LABEL: @interface B2 : ProtoImpl
 class B2: ProtoImpl {
@@ -43,7 +43,7 @@
 // CHECK-LABEL: @interface C1 : ProtoImpl
 class C1: ProtoImpl {
   // CHECK: // 'test(_:)' below
-  func test(_: NeedsProto<C2>) {}
+  @objc func test(_: NeedsProto<C2>) {}
 } // CHECK: @end
 // CHECK-LABEL: @protocol C2 <Proto>
 @objc protocol C2: Proto {
@@ -52,7 +52,7 @@
 // CHECK-LABEL: @interface D1 : ProtoImpl
 class D1: ProtoImpl {
   // CHECK: // 'test(_:)' below
-  func test(_: NeedsProto<D2>) {}
+  @objc func test(_: NeedsProto<D2>) {}
 } // CHECK: @end
 // CHECK-LABEL: @protocol D2 <Proto>
 @objc protocol D2: Proto {
@@ -70,7 +70,7 @@
 } // CHECK: @end
 // Moved ahead.
 class D4: ProtoImpl {
-  func test(_: NeedsProto<D3>) {}
+  @objc func test(_: NeedsProto<D3>) {}
 }
 
 // CHECK-LABEL: @interface E2 : ProtoImpl
@@ -91,7 +91,7 @@
 // CHECK-LABEL: @interface F1 (SWIFT_EXTENSION(circularity))
 extension F1 {
   // CHECK: - (void)test:
-  func test(_: NeedsProto<F2>) {}
+  @objc func test(_: NeedsProto<F2>) {}
 } // CHECK: @end
 // Moved ahead.
 class F2: ProtoImpl {}
@@ -104,7 +104,7 @@
 // CHECK-LABEL: @interface G1 (SWIFT_EXTENSION(circularity))
 extension G1 {
   // CHECK: - (void)test:
-  func test(_: NeedsProto<G2>) {}
+  @objc func test(_: NeedsProto<G2>) {}
 } // CHECK: @end
 // Moved ahead.
 @objc protocol G2: Proto {}
@@ -112,56 +112,56 @@
 // CHECK-LABEL: @interface H1 : ProtoImpl
 class H1: ProtoImpl {
   // CHECK: 'test(_:)' below
-  func test(_: NeedsProto<H2>) {}
+  @objc func test(_: NeedsProto<H2>) {}
   // CHECK: 'anotherTest(_:)' below
-  func anotherTest(_: NeedsProto<H3>) {}
+  @objc func anotherTest(_: NeedsProto<H3>) {}
 } // CHECK: @end
 // CHECK-LABEL: @interface H2 : ProtoImpl
 class H2: ProtoImpl {
   // CHECK: // 'test(_:)' below
-  func test(_: NeedsProto<H3>) {}
+  @objc func test(_: NeedsProto<H3>) {}
   // CHECK: - (void)anotherTest:
-  func anotherTest(_: NeedsProto<H1>) {}
+  @objc func anotherTest(_: NeedsProto<H1>) {}
 } // CHECK: @end
 // CHECK-LABEL: @interface H3 : ProtoImpl
 class H3: ProtoImpl {
   // CHECK: - (void)test:
-  func test(_: NeedsProto<H1>) {}
+  @objc func test(_: NeedsProto<H1>) {}
   // CHECK: - (void)anotherTest:
-  func anotherTest(_: NeedsProto<H2>) {}
+  @objc func anotherTest(_: NeedsProto<H2>) {}
 } // CHECK: @end
 
 // CHECK-LABEL: @interface I1 : Parent
 class I1 : Parent {
   // CHECK: // 'test(_:)' below
-  func test(_: NeedsParent<I2>) {}
+  @objc func test(_: NeedsParent<I2>) {}
 } // CHECK: @end
 // CHECK-LABEL: @interface I2 : Parent
 class I2 : Parent {
   // CHECK: - (void)test:
-  func test(_: NeedsParent<I1>) {}
+  @objc func test(_: NeedsParent<I1>) {}
 } // CHECK: @end
 
 // CHECK-LABEL: @interface J1 : Parent
 class J1 : Parent {
   // CHECK: - (void)test:
-  func test(_: Unconstrained<J2>) {}
+  @objc func test(_: Unconstrained<J2>) {}
 } // CHECK: @end
 // CHECK-LABEL: @interface J2 : Parent
 class J2 : Parent {
   // CHECK: - (void)test:
-  func test(_: Unconstrained<J1>) {}
+  @objc func test(_: Unconstrained<J1>) {}
 } // CHECK: @end
 
 // CHECK-LABEL: @protocol K1 <Proto>
 @objc protocol K1 : Proto {
   // CHECK: - (void)test:
-  func test(_: Unconstrained<K2>)
+  @objc func test(_: Unconstrained<K2>)
 } // CHECK: @end
 // CHECK-LABEL: @protocol K2 <Proto>
 @objc protocol K2 : Proto {
   // CHECK: - (void)test:
-  func test(_: Unconstrained<K1>)
+  @objc func test(_: Unconstrained<K1>)
 } // CHECK: @end
 
 
diff --git a/test/PrintAsObjC/classes.swift b/test/PrintAsObjC/classes.swift
index 886c0e6..c65dd0e 100644
--- a/test/PrintAsObjC/classes.swift
+++ b/test/PrintAsObjC/classes.swift
@@ -5,15 +5,15 @@
 // RUN: %empty-directory(%t)
 
 // FIXME: BEGIN -enable-source-import hackaround
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/AppKit.swift -swift-version 3
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/AppKit.swift
 // FIXME: END -enable-source-import hackaround
 
 
-// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -I %S/Inputs/custom-modules -o %t %s -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -parse-as-library %t/classes.swiftmodule -typecheck -I %S/Inputs/custom-modules -emit-objc-header-path %t/classes.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -I %S/Inputs/custom-modules -o %t %s -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -parse-as-library %t/classes.swiftmodule -typecheck -I %S/Inputs/custom-modules -emit-objc-header-path %t/classes.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/classes.h
 // RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/classes.h
 // RUN: %check-in-clang -I %S/Inputs/custom-modules/ %t/classes.h
@@ -42,7 +42,7 @@
 // CHECK-LABEL: @interface A1{{$}}
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class A1 {}
+@objc @objcMembers class A1 {}
 
 // CHECK-LABEL: @interface B1 : A1
 // CHECK-NEXT: init
@@ -54,7 +54,7 @@
 // CHECK-NEXT: - (NSSet * _Nonnull)setBridge:(NSSet * _Nonnull)x SWIFT_WARN_UNUSED_RESULT;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class BridgedTypes {
+@objc @objcMembers class BridgedTypes {
   @objc func dictBridge(_ x: Dictionary<NSObject, AnyObject>) -> Dictionary<NSObject, AnyObject> {
     return x
   }
@@ -71,7 +71,8 @@
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
 @objc(CustomName)
-class ClassWithCustomName {
+@objcMembers
+ class ClassWithCustomName {
   @objc func forwardCustomName(_: ClassWithCustomName2) {}
 }
   
@@ -80,6 +81,7 @@
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
 @objc(CustomName2)
+@objcMembers
 class ClassWithCustomName2 {}
   
 // CHECK-LABEL: SWIFT_CLASS_NAMED("ClassWithCustomNameSub")
@@ -96,7 +98,7 @@
 // CHECK-NEXT: - (BOOL)isKindOfClass:(Class _Nonnull)aClass SWIFT_WARN_UNUSED_RESULT;
 // CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
 // CHECK-NEXT: @end
-@objc class ClassWithNSObjectProtocol : NSObjectProtocol {
+@objc @objcMembers class ClassWithNSObjectProtocol : NSObjectProtocol {
   @objc var description: String { return "me" }
   @objc(conformsToProtocol:)
   func conforms(to _: Protocol) -> Bool { return false }
@@ -290,6 +292,8 @@
   @objc func initializeEvenMoreThings() {}
 
   @objc(newWithFoo:) class func make(foo: Int) -> Methods { return Methods() }
+
+  @objc init() {}
 }
 
 typealias AliasForNSRect = NSRect
@@ -310,7 +314,7 @@
 // CHECK-NEXT: - (NSURL * _Nullable)returnsURL SWIFT_WARN_UNUSED_RESULT;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class MethodsWithImports {
+@objc @objcMembers class MethodsWithImports {
   @objc func getOrigin(_ r: NSRect) -> NSPoint { return r.origin }
   @objc func getOriginX(_ r: AliasForNSRect) -> CGFloat { return r.origin.x }
   @objc func getOriginY(_ r: CGRect) -> CGFloat { return r.origin.y }
@@ -340,7 +344,7 @@
 // CHECK-NEXT: - (void)testBridgingOptionality:(NSInteger const * _Nullable)a b:(NSInteger * _Null_unspecified)b c:(Methods * _Nullable * _Nullable)c;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class MethodsWithPointers {
+@objc @objcMembers class MethodsWithPointers {
   @objc func test(_ a: UnsafeMutablePointer<Int>) -> UnsafeMutablePointer<AnyObject> {
     return UnsafeMutablePointer(bitPattern: -1)!
   }
@@ -368,7 +372,7 @@
 // CHECK-NEXT: - (void)test:(Class <MyProtocolMetaOnly> _Nullable)x;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class MyProtocolMetaCheck {
+@objc @objcMembers class MyProtocolMetaCheck {
   @objc func test(_ x: MyProtocolMetaOnly.Type?) {}
 }
 // CHECK-LABEL: @protocol MyProtocolMetaOnly
@@ -378,21 +382,21 @@
 // CHECK-LABEL: @interface Nested
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class Nested {
+@objc @objcMembers class Nested {
   // CHECK-LABEL: @interface Inner
   // CHECK-NEXT: init
   // CHECK-NEXT: @end
-  @objc class Inner {
+  @objc @objcMembers class Inner {
     // CHECK-LABEL: @interface DeeperIn
     // CHECK-NEXT: init
     // CHECK-NEXT: @end
-    @objc class DeeperIn {}
+    @objc @objcMembers class DeeperIn {}
   }
 
   // CHECK-LABEL: @interface AnotherInner : A1
   // CHECK-NEXT: init
   // CHECK-NEXT: @end
-  @objc class AnotherInner : A1 {}
+  @objc @objcMembers class AnotherInner : A1 {}
 
   // NEGATIVE-NOT: NonObjCInner
   class NonObjCInner {}
@@ -407,13 +411,13 @@
 // CHECK-NEXT: @property (nonatomic, strong) Inner3 * _Nullable ref3;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class NestedMembers {
+@objc @objcMembers class NestedMembers {
   // NEGATIVE-NOT: @class NestedMembers;
   // CHECK-LABEL: @interface Inner2
   // CHECK-NEXT: @property (nonatomic, strong) NestedMembers * _Nullable ref;
   // CHECK-NEXT: init
   // CHECK-NEXT: @end
-  @objc class Inner2 {
+  @objc @objcMembers class Inner2 {
     @objc var ref: NestedMembers?
   }
 
@@ -424,7 +428,7 @@
   // CHECK-NEXT: @property (nonatomic, strong) NestedMembers * _Nullable ref;
   // CHECK-NEXT: init
   // CHECK-NEXT: @end
-  @objc class Inner3 {
+  @objc @objcMembers class Inner3 {
     @objc var ref: NestedMembers?
   }
 }
@@ -432,11 +436,11 @@
 // CHECK-LABEL: @interface NestedSuperclass
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class NestedSuperclass {
+@objc @objcMembers class NestedSuperclass {
   // CHECK-LABEL: @interface Subclass : NestedSuperclass
   // CHECK-NEXT: init
   // CHECK-NEXT: @end
-  @objc class Subclass : NestedSuperclass {}
+  @objc @objcMembers class Subclass : NestedSuperclass {}
 }
 
 // CHECK-LABEL: @interface NewBanned
@@ -444,7 +448,7 @@
 // CHECK-NEXT: - (nonnull instancetype)init SWIFT_UNAVAILABLE;
 // CHECK-NEXT: + (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable");
 // CHECK-NEXT: @end
-@objc class NewBanned : NSObject {
+@objc @objcMembers class NewBanned : NSObject {
   init(arbitraryArgument: Int) { super.init() }
 }
 
@@ -452,7 +456,7 @@
 // CHECK-NEXT: - (nonnull instancetype)initWithDifferentArbitraryArgument:(NSInteger)differentArbitraryArgument OBJC_DESIGNATED_INITIALIZER;
 // CHECK-NEXT: - (nonnull instancetype)initWithArbitraryArgument:(NSInteger)arbitraryArgument SWIFT_UNAVAILABLE;
 // CHECK-NEXT: @end
-@objc class NewBannedStill : NewBanned {
+@objc @objcMembers class NewBannedStill : NewBanned {
   init(differentArbitraryArgument: Int) { super.init(arbitraryArgument: 0) }
 }
 
@@ -461,7 +465,7 @@
 // CHECK-NEXT: + (nonnull instancetype)new;
 // CHECK-NEXT: - (nonnull instancetype)initWithArbitraryArgument:(NSInteger)arbitraryArgument SWIFT_UNAVAILABLE;
 // CHECK-NEXT: @end
-@objc class NewUnbanned : NewBanned {
+@objc @objcMembers class NewUnbanned : NewBanned {
   init() { super.init(arbitraryArgument: 0) }
 }
 
@@ -470,7 +474,7 @@
 // CHECK-NEXT: + (nonnull instancetype)new;
 // CHECK-NEXT: - (nonnull instancetype)initWithDifferentArbitraryArgument:(NSInteger)differentArbitraryArgument SWIFT_UNAVAILABLE;
 // CHECK-NEXT: @end
-@objc class NewUnbannedDouble : NewBannedStill {
+@objc @objcMembers class NewUnbannedDouble : NewBannedStill {
   init() { super.init(differentArbitraryArgument: 0) }
 }
 
@@ -664,6 +668,8 @@
   }
 
   @objc var customValueTypeProp: URL?
+
+  @objc init() {}
 }
 
 // CHECK-LABEL: @interface PropertiesOverridden
@@ -690,7 +696,7 @@
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
 @objc class ReversedOrder1 : ReversedOrder2 {}
-@objc class ReversedOrder2 {}
+@objc @objcMembers class ReversedOrder2 {}
 
 
 // CHECK-LABEL: @interface Subscripts1
@@ -698,7 +704,7 @@
 // CHECK-NEXT: - (Subscripts1 * _Nonnull)objectForKeyedSubscript:(Subscripts1 * _Nonnull)o SWIFT_WARN_UNUSED_RESULT;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class Subscripts1 {
+@objc @objcMembers class Subscripts1 {
   @objc subscript (i: Int) -> Subscripts1 {
     return self
   }
@@ -716,7 +722,7 @@
 // CHECK-NEXT: @property (nonatomic, copy) NSArray<NSString *> * _Nonnull cardPaths;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class Subscripts2 {
+@objc @objcMembers class Subscripts2 {
   @objc subscript (i: Int16) -> Subscripts2 {
     get {
       return self
@@ -743,7 +749,7 @@
 // CHECK-NEXT: - (Subscripts3 * _Nonnull)objectAtIndexedSubscript:(unsigned long)_ SWIFT_WARN_UNUSED_RESULT;
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class Subscripts3 {
+@objc @objcMembers class Subscripts3 {
   @objc subscript (_: CUnsignedLong) -> Subscripts3 {
     return self
   }
diff --git a/test/PrintAsObjC/comments.swift b/test/PrintAsObjC/comments.swift
index dd84918..62ce7fa 100644
--- a/test/PrintAsObjC/comments.swift
+++ b/test/PrintAsObjC/comments.swift
@@ -1,8 +1,8 @@
 // Please keep this file in alphabetical order!
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -module-name comments %S/../Inputs/comment_to_something_conversion.swift -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/comments.swiftmodule -typecheck -emit-objc-header-path %t/comments.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-module -emit-module-path %t/comments.swiftmodule -emit-module-doc -emit-module-doc-path %t/comments.swiftdoc -module-name comments %S/../Inputs/comment_to_something_conversion.swift -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/comments.swiftmodule -typecheck -emit-objc-header-path %t/comments.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: awk '/A000/,0' %t/comments.h > %t/comments.h-cleaned
 // RUN: diff -u %t/comments.h-cleaned %S/Inputs/comments-expected-output.h
 // RUN: %check-in-clang -Wno-documentation %t/comments.h
diff --git a/test/PrintAsObjC/extensions.swift b/test/PrintAsObjC/extensions.swift
index 029f5b2..60e1142 100644
--- a/test/PrintAsObjC/extensions.swift
+++ b/test/PrintAsObjC/extensions.swift
@@ -1,8 +1,8 @@
 // Please keep this file in alphabetical order!
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/extensions.swiftmodule -typecheck -emit-objc-header-path %t/extensions.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/extensions.swiftmodule -typecheck -emit-objc-header-path %t/extensions.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/extensions.h
 // RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/extensions.h
 // RUN: %check-in-clang %t/extensions.h
@@ -18,7 +18,7 @@
 // CHECK-LABEL: @interface A1{{$}}
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class A1 {}
+@objc @objcMembers class A1 {}
 
 // NEGATIVE-NOT: @interface A1 (SWIFT_EXTENSION(extensions))
 extension A1 {}
@@ -32,12 +32,12 @@
 extension A2 {
   @objc var some: Int { return 1 }
 }
-@objc class A2 {}
+@objc @objcMembers class A2 {}
 
 // CHECK-LABEL: @interface A3{{$}}
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class A3 {}
+@objc @objcMembers class A3 {}
 
 // CHECK-LABEL: @interface A3 (SWIFT_EXTENSION(extensions))
 // CHECK-DAG: @interface A3 (SWIFT_EXTENSION(extensions))
@@ -55,7 +55,7 @@
 // CHECK-LABEL: @interface A4{{$}}
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class A4 {}
+@objc @objcMembers class A4 {}
 
 // CHECK-LABEL: @interface A4 (SWIFT_EXTENSION(extensions))
 // CHECK-NEXT: @end
@@ -63,13 +63,13 @@
   // CHECK-LABEL: @interface Inner
   // CHECK-NEXT: init
   // CHECK-NEXT: @end
-  @objc class Inner {}
+  @objc @objcMembers class Inner {}
 }
 
 // CHECK-LABEL: @interface A5{{$}}
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class A5 {}
+@objc @objcMembers class A5 {}
 
 // NEGATIVE-NOT: @interface A5 (SWIFT_EXTENSION(extensions))
 extension A5 {
@@ -80,6 +80,7 @@
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
 @objc(CustomName)
+@objcMembers
 class ClassWithCustomName {
 }
 
diff --git a/test/PrintAsObjC/generic-ancestry.swift b/test/PrintAsObjC/generic-ancestry.swift
index 220d849..d731bde 100644
--- a/test/PrintAsObjC/generic-ancestry.swift
+++ b/test/PrintAsObjC/generic-ancestry.swift
@@ -1,8 +1,8 @@
 // Please keep this file in alphabetical order!
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -module-name generic -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/generic.swiftmodule -typecheck -emit-objc-header-path %t/generic.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -module-name generic -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/generic.swiftmodule -typecheck -emit-objc-header-path %t/generic.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/generic.h
 // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t/generic.h
 // RUN: %check-in-clang %t/generic.h
@@ -14,7 +14,7 @@
 // CHECK-LABEL: @interface ConcreteClass
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class ConcreteClass {}
+@objc @objcMembers class ConcreteClass {}
 
 // CHECK-NOT: @interface GenericSubclass
 // NEGATIVE-NOT: @interface GenericSubclass
@@ -30,7 +30,7 @@
 // CHECK-NOT: rocky
 // NEGATIVE-NOT: rocky
 // CHECK-NEXT: @end
-@objc class TopMoviesOfAllTime {
+@objc @objcMembers class TopMoviesOfAllTime {
   func rambo(c: ConcreteClass) {}
   func rocky(c: NonGenericSubclass) {}
 }
diff --git a/test/PrintAsObjC/imported-block-typedefs.swift b/test/PrintAsObjC/imported-block-typedefs.swift
index c67ef8a..c3740ac 100644
--- a/test/PrintAsObjC/imported-block-typedefs.swift
+++ b/test/PrintAsObjC/imported-block-typedefs.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -import-objc-header %S/Inputs/imported-block-typedefs.h -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/imported-block-typedefs.swiftmodule -typecheck -emit-objc-header-path %t/imported-block-typedefs-output.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -import-objc-header %S/Inputs/imported-block-typedefs.h -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/imported-block-typedefs.swiftmodule -typecheck -emit-objc-header-path %t/imported-block-typedefs-output.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/imported-block-typedefs-output.h
 // RUN: %check-in-clang %t/imported-block-typedefs-output.h -include %S/Inputs/imported-block-typedefs.h
 
@@ -74,5 +74,4 @@
   @objc func resultHasEscapingParam5() -> (@escaping BlockReturningBlockWithNoescapeParam) -> () { fatalError() }
 
 }
-// CHECK-NEXT: init
 // CHECK-NEXT: @end
diff --git a/test/PrintAsObjC/imports.swift b/test/PrintAsObjC/imports.swift
index 5eed477..f09c219 100644
--- a/test/PrintAsObjC/imports.swift
+++ b/test/PrintAsObjC/imports.swift
@@ -1,8 +1,8 @@
 // Please keep this file in alphabetical order!
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules/ -F %S/Inputs/ -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules/ -F %S/Inputs/ -parse-as-library %t/imports.swiftmodule -typecheck -emit-objc-header-path %t/imports.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules/ -F %S/Inputs/ -emit-module -o %t %s -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules/ -F %S/Inputs/ -parse-as-library %t/imports.swiftmodule -typecheck -emit-objc-header-path %t/imports.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/imports.h
 // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t/imports.h
 // RUN: %check-in-clang %t/imports.h -I %S/Inputs/custom-modules/ -F %S/Inputs/
@@ -41,19 +41,19 @@
 import MostlyPrivate2_Private
 
 @objc class Test {
-  let word: DWORD = 0
-  let number: TimeInterval = 0.0
+  @objc let word: DWORD = 0
+  @objc let number: TimeInterval = 0.0
 
-  let baseI: BaseI = 0
-  let baseII: BaseII = 0
-  let baseIE: BaseIE = 0
-  let baseE: BaseE = 0
-  let baseEI: BaseEI = 0
-  let baseEE: BaseEE = 0
+  @objc let baseI: BaseI = 0
+  @objc let baseII: BaseII = 0
+  @objc let baseIE: BaseIE = 0
+  @objc let baseE: BaseE = 0
+  @objc let baseEI: BaseEI = 0
+  @objc let baseEE: BaseEE = 0
 
   // Deliberately use the private type before the public type.
-  let mp1priv: MP1PrivateType = 0
-  let mp1pub: MP1PublicType = 0
+  @objc let mp1priv: MP1PrivateType = 0
+  @objc let mp1pub: MP1PublicType = 0
 
-  let mp2priv: MP2PrivateType = 0
+  @objc let mp2priv: MP2PrivateType = 0
 }
diff --git a/test/PrintAsObjC/local-types.swift b/test/PrintAsObjC/local-types.swift
index cab9ca8..2719282 100644
--- a/test/PrintAsObjC/local-types.swift
+++ b/test/PrintAsObjC/local-types.swift
@@ -1,8 +1,8 @@
 // Please keep this file in alphabetical order!
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -module-name local -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/local.swiftmodule -typecheck -emit-objc-header-path %t/local.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t %s -module-name local -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %t/local.swiftmodule -typecheck -emit-objc-header-path %t/local.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/local.h
 // RUN: %check-in-clang %t/local.h
 
@@ -13,7 +13,7 @@
 // CHECK-LABEL: @interface AFullyDefinedClass
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class AFullyDefinedClass {}
+@objc @objcMembers class AFullyDefinedClass {}
 
 class ANonObjCClass {}
 
@@ -65,6 +65,8 @@
 
   @objc var j: ZForwardClass3 { return ZForwardClass3() }
   @objc var k: ZForwardClass4.Type { return ZForwardClass4.self }
+
+  @objc init() {}
 }
 
 // CHECK-NOT: @class ZForwardClass1;
@@ -78,6 +80,7 @@
 @objc class UseForwardAgain {
   @objc func a(_ a: ZForwardClass1) {}
   @objc func b(_ b: ZForwardProtocol1) {}
+  @objc init() {}
 }
 
 typealias ZForwardAlias = ZForwardAliasClass
@@ -91,6 +94,7 @@
 // CHECK-NEXT: @end
 @objc class ZForwardClass1 {
   @objc func circular(_ a: UseForward) {}
+  @objc init() {}
 }
 @objc class ZForwardClass2 {}
 @objc class ZForwardClass3 {}
diff --git a/test/PrintAsObjC/mixed-framework-fwd.swift b/test/PrintAsObjC/mixed-framework-fwd.swift
index 3cdc7f4..862b5c3 100644
--- a/test/PrintAsObjC/mixed-framework-fwd.swift
+++ b/test/PrintAsObjC/mixed-framework-fwd.swift
@@ -1,17 +1,17 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/ -module-name Mixed -import-underlying-module %s -typecheck -emit-objc-header-path %t/mixed.h -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/ -module-name Mixed -import-underlying-module %s -typecheck -emit-objc-header-path %t/mixed.h
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=NO-IMPORT %s < %t/mixed.h
 // RUN: %check-in-clang -F %S/Inputs/ %t/mixed.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -module-name Mixed -import-objc-header %S/Inputs/Mixed.framework/Headers/Mixed.h %s -typecheck -emit-objc-header-path %t/mixed-header.h -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -module-name Mixed -import-objc-header %S/Inputs/Mixed.framework/Headers/Mixed.h %s -typecheck -emit-objc-header-path %t/mixed-header.h
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=NO-IMPORT %s < %t/mixed-header.h
 // RUN: %check-in-clang -include %S/Inputs/Mixed.framework/Headers/Mixed.h %t/mixed-header.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/ -module-name Mixed -import-underlying-module %s -typecheck -emit-objc-header-path %t/mixed-proto.h -DREQUIRE -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/ -module-name Mixed -import-underlying-module %s -typecheck -emit-objc-header-path %t/mixed-proto.h -DREQUIRE
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=FRAMEWORK %s < %t/mixed-proto.h
 // RUN: %check-in-clang -F %S/Inputs/ %t/mixed-proto.h
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -module-name Mixed -import-objc-header %S/Inputs/Mixed.framework/Headers/Mixed.h %s -typecheck -emit-objc-header-path %t/mixed-header-proto.h -DREQUIRE -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -module-name Mixed -import-objc-header %S/Inputs/Mixed.framework/Headers/Mixed.h %s -typecheck -emit-objc-header-path %t/mixed-header-proto.h -DREQUIRE
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=HEADER %s < %t/mixed-header-proto.h
 // RUN: %check-in-clang -include %S/Inputs/Mixed.framework/Headers/Mixed.h %t/mixed-header-proto.h
 
@@ -32,7 +32,7 @@
 import Foundation
 
 public class Dummy: NSNumber {
-  public func getProto() -> CustomProto? {
+  @objc public func getProto() -> CustomProto? {
     return nil
   }
 }
diff --git a/test/PrintAsObjC/protocols.swift b/test/PrintAsObjC/protocols.swift
index 1315581..d68e671 100644
--- a/test/PrintAsObjC/protocols.swift
+++ b/test/PrintAsObjC/protocols.swift
@@ -3,13 +3,13 @@
 // RUN: %empty-directory(%t)
 
 // FIXME: BEGIN -enable-source-import hackaround
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift -swift-version 3
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift -swift-version 3
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
 // FIXME: END -enable-source-import hackaround
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -I %t -emit-module -o %t %s -disable-objc-attr-requires-foundation-module -swift-version 3
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -I %t -parse-as-library %t/protocols.swiftmodule -typecheck -emit-objc-header-path %t/protocols.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module -swift-version 3
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -I %t -emit-module -o %t %s -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -I %t -parse-as-library %t/protocols.swiftmodule -typecheck -emit-objc-header-path %t/protocols.h -import-objc-header %S/../Inputs/empty.h -disable-objc-attr-requires-foundation-module
 // RUN: %FileCheck %s < %t/protocols.h
 // RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/protocols.h
 // RUN: %check-in-clang %t/protocols.h
@@ -129,12 +129,12 @@
 // CHECK-LABEL: @interface PrivateProtoAdopter{{$}}
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class PrivateProtoAdopter : PrivateProto {}
+@objc @objcMembers class PrivateProtoAdopter : PrivateProto {}
 
 // CHECK-LABEL: @interface PrivateProtoAdopter2 <A>
 // CHECK-NEXT: init
 // CHECK-NEXT: @end
-@objc class PrivateProtoAdopter2 : PrivateProto, A {}
+@objc @objcMembers class PrivateProtoAdopter2 : PrivateProto, A {}
 
 // CHECK-LABEL: @protocol Properties
 // CHECK-NEXT: @property (nonatomic, readonly) NSInteger a;
@@ -165,7 +165,7 @@
   @objc func references(someClassAndZZZ: ReferencesSomeClass2 & ZZZ)
 }
 
-@objc class ReferencesSomeClass2 {}
+@objc @objcMembers class ReferencesSomeClass2 {}
 
 
 // CHECK-LABEL: @protocol ReversedOrder2{{$}}
diff --git a/test/Prototypes/UnicodeDecoders.swift b/test/Prototypes/UnicodeDecoders.swift
index 2b2f92c..2bcd504 100644
--- a/test/Prototypes/UnicodeDecoders.swift
+++ b/test/Prototypes/UnicodeDecoders.swift
@@ -9,7 +9,7 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
-// RUN: %target-build-swift %s -swift-version 3 -g -Onone -o %t
+// RUN: %target-build-swift %s -g -Onone -o %t
 // RUN: %target-run %t
 // REQUIRES: executable_test
 
diff --git a/test/Reflection/capture_descriptors.sil b/test/Reflection/capture_descriptors.sil
index 4bb334c..967c563 100644
--- a/test/Reflection/capture_descriptors.sil
+++ b/test/Reflection/capture_descriptors.sil
@@ -208,11 +208,11 @@
   return %12 : $()
 }
 
-sil @pseudogeneric_caller : $@convention(thin) @pseudogeneric <A : AnyObject, B : AnyObject, C : AnyObject> (@owned A, @owned B) -> @owned @pseudogeneric @callee_guaranteed () -> () {
+sil @pseudogeneric_caller : $@convention(thin) @pseudogeneric <A : AnyObject, B : AnyObject, C : AnyObject> (@owned A, @owned B) -> @owned @callee_guaranteed () -> () {
 bb0(%a: $A, %b: $B):
   %f = function_ref @pseudogeneric_callee : $@convention(thin) @pseudogeneric <T : AnyObject, U : AnyObject> (@owned T, @owned U) -> ()
   %c = partial_apply [callee_guaranteed] %f<A, B>(%a, %b) : $@convention(thin) @pseudogeneric <A : AnyObject, B : AnyObject> (@owned A, @owned B) -> ()
-  return %c : $@pseudogeneric @callee_guaranteed () -> ()
+  return %c : $@callee_guaranteed () -> ()
 }
 
 // CHECK:      - Capture types:
diff --git a/test/Runtime/Inputs/synthesized_decl_uniqueness.swift b/test/Runtime/Inputs/synthesized_decl_uniqueness.swift
new file mode 100644
index 0000000..5157acc
--- /dev/null
+++ b/test/Runtime/Inputs/synthesized_decl_uniqueness.swift
@@ -0,0 +1,9 @@
+import CoreLocation
+
+public func getCLError() -> Any.Type {
+  return CLError.self
+}
+
+public func getCLErrorCode() -> Any.Type {
+  return CLError.Code.self
+}
diff --git a/test/Runtime/demangleToMetadataObjC.swift b/test/Runtime/demangleToMetadataObjC.swift
index 2712138..2b5b920 100644
--- a/test/Runtime/demangleToMetadataObjC.swift
+++ b/test/Runtime/demangleToMetadataObjC.swift
@@ -5,6 +5,7 @@
 import StdlibUnittest
 import Foundation
 import CoreFoundation
+import CoreLocation
 
 let DemangleToMetadataTests = TestSuite("DemangleToMetadataObjC")
 
@@ -74,5 +75,15 @@
   expectNil(_typeByMangledName("4main3CG4CyAA1DCAA1DCG"))
 }
 
+DemangleToMetadataTests.test("synthesized declarations") {
+  expectEqual(CLError.self, _typeByMangledName("SC7CLErrorLeV")!)
+  expectNil(_typeByMangledName("SC7CLErrorV"))
+  expectEqual(CLError.Code.self, _typeByMangledName("So7CLErrorV")!)
+
+  let error = NSError(domain: NSCocoaErrorDomain, code: 0)
+  let reflectionString = String(reflecting: CLError(_nsError: error))
+  expectTrue(reflectionString.hasPrefix("__C_Synthesized.related decl 'e' for CLError(_nsError:"))
+}
+
 runAllTests()
 
diff --git a/test/Runtime/synthesized_decl_uniqueness.swift b/test/Runtime/synthesized_decl_uniqueness.swift
new file mode 100644
index 0000000..e47aea0
--- /dev/null
+++ b/test/Runtime/synthesized_decl_uniqueness.swift
@@ -0,0 +1,21 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -parse-as-library -force-single-frontend-invocation %S/Inputs/synthesized_decl_uniqueness.swift -emit-object -o %t/A.o -module-name A -emit-module-path %t/A.swiftmodule
+// RUN: %target-build-swift -parse-as-library -force-single-frontend-invocation %S/Inputs/synthesized_decl_uniqueness.swift -emit-object -o %t/B.o -module-name B -emit-module-path %t/B.swiftmodule
+// RUN: %target-build-swift -I %t %s %t/A.o %t/B.o -o %t/a.out
+// RUN: %target-run %t/a.out
+
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+import StdlibUnittest
+import A
+import B
+
+var tests = TestSuite("metadata identity for synthesized types")
+
+tests.test("synthesized type identity across modules") {
+  expectEqual(A.getCLError(), B.getCLError())
+  expectEqual(A.getCLErrorCode(), B.getCLErrorCode())
+}
+
+runAllTests()
diff --git a/test/SIL/Parser/generic_signature_with_depth.swift b/test/SIL/Parser/generic_signature_with_depth.swift
index aa21b32..9aad7e0 100644
--- a/test/SIL/Parser/generic_signature_with_depth.swift
+++ b/test/SIL/Parser/generic_signature_with_depth.swift
@@ -1,5 +1,5 @@
 
-// RUN: %target-swift-frontend -module-name generic_signature_with_depth %s -emit-silgen -swift-version 3 | %target-sil-opt | %FileCheck %s
+// RUN: %target-swift-frontend -module-name generic_signature_with_depth %s -emit-silgen | %target-sil-opt | %FileCheck %s
 
 protocol mmGeneratorType {
   associatedtype Element
@@ -15,8 +15,7 @@
 protocol mmExt : mmCollectionType {
  mutating func extend<
      S : mmSequenceType
-     where S.Generator.Element == Self.Generator.Element
- > (_ seq: S)
+ > (_ seq: S) where S.Generator.Element == Self.Generator.Element
 }
 
 // CHECK-LABEL:  @$S28generic_signature_with_depth4testyxx_q_tAA5mmExtRzAaCR_9Generator_7ElementQY_AD_AERTzr0_lF : $@convention(thin) <EC1, EC2 where EC1 : mmExt, EC2 : mmExt, EC1.Generator.Element == EC2.Generator.Element> (@in_guaranteed EC1, @in_guaranteed EC2) -> @out EC1 {
@@ -26,9 +25,8 @@
 func test<
    EC1 : mmExt,
    EC2 : mmExt
-   where EC1.Generator.Element == EC2.Generator.Element
 >
-(_ lhs: EC1, _ rhs: EC2) -> EC1 {
+(_ lhs: EC1, _ rhs: EC2) -> EC1 where EC1.Generator.Element == EC2.Generator.Element {
  var lhs = lhs
  lhs.extend(rhs)
  return lhs
diff --git a/test/SIL/Parser/global_decl.sil b/test/SIL/Parser/global_decl.sil
new file mode 100644
index 0000000..b8e957c
--- /dev/null
+++ b/test/SIL/Parser/global_decl.sil
@@ -0,0 +1,54 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s
+
+// Check that sil_globals and their corresponding decls are
+// parsed. There is no direct way to verify that the declarations are
+// properly associated with the sil_globals, so just make sure it succeeds.
+//
+// FIXME: Add support for name collisions across private/fileprivate globals.
+
+sil_stage canonical
+
+import Builtin
+import Swift
+import SwiftShims
+
+struct S {
+  init()
+}
+
+class C {
+  init()
+  deinit
+}
+
+enum E {
+  case a
+  @_implements(Equatable, ==(_:_:)) static func __derived_enum_equals(_ a: E, _ b: E) -> Bool
+  var hashValue: Int { get }
+  func hash(into hasher: inout Hasher)
+}
+
+private var global1: S
+
+fileprivate var global2: C
+
+var global3: E
+
+public var global4: Int
+
+weak var global5: @sil_weak C?
+
+// CHECK: sil_global private @$S11global_decl7global133_EB6670D548223EDC99AF0D8F02575BC4LLAA1SVvp : $S
+sil_global private @$S11global_decl7global133_EB6670D548223EDC99AF0D8F02575BC4LLAA1SVvp : $S
+
+// CHECK: sil_global private @$S11global_decl7global233_EB6670D548223EDC99AF0D8F02575BC4LLAA1CCvp : $C
+sil_global private @$S11global_decl7global233_EB6670D548223EDC99AF0D8F02575BC4LLAA1CCvp : $C
+
+// CHECK: sil_global hidden @$S11global_decl7global3AA1EOvp : $E
+sil_global hidden @$S11global_decl7global3AA1EOvp : $E
+
+// CHECK: sil_global @$S11global_decl7global4Sivp : $Int
+sil_global @$S11global_decl7global4Sivp : $Int
+
+// CHECK: sil_global hidden @$S11global_decl7global5AA1CCSgXwvp : $@sil_weak Optional<C>
+sil_global hidden @$S11global_decl7global5AA1CCSgXwvp : $@sil_weak Optional<C>
diff --git a/test/SIL/Parser/question_mark.swift b/test/SIL/Parser/question_mark.swift
index f8f579d..4a0b5b0 100644
--- a/test/SIL/Parser/question_mark.swift
+++ b/test/SIL/Parser/question_mark.swift
@@ -1,9 +1,6 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3 | %target-sil-opt
+// RUN: %target-swift-frontend %s -emit-silgen | %target-sil-opt
 
-infix operator ?? {
-  associativity right
-  precedence 110
-}
+infix operator ??
 
 struct A<V, E> {
 }
diff --git a/test/SIL/Parser/self.swift b/test/SIL/Parser/self.swift
index f4980b5..3220445 100644
--- a/test/SIL/Parser/self.swift
+++ b/test/SIL/Parser/self.swift
@@ -1,8 +1,8 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3 | %target-sil-opt
+// RUN: %target-swift-frontend %s -emit-silgen | %target-sil-opt
 
 import Swift
 protocol P {
   func join<
-    S : Sequence where S.Iterator.Element == Self
-  >(elements: S) -> Self
+    S : Sequence
+  >(elements: S) -> Self where S.Iterator.Element == Self
 }
diff --git a/test/SIL/Parser/where.swift b/test/SIL/Parser/where.swift
index 27f7146..509af41 100644
--- a/test/SIL/Parser/where.swift
+++ b/test/SIL/Parser/where.swift
@@ -1,9 +1,9 @@
-// RUN: %target-swift-frontend %s -emit-silgen -swift-version 3 | %target-sil-opt
+// RUN: %target-swift-frontend %s -emit-silgen | %target-sil-opt
 
 import Swift
 protocol P {
   associatedtype CodeUnit
   mutating func decode<
-    G : IteratorProtocol where G.Element == CodeUnit
-  >(next: inout G) -> Int
+    G : IteratorProtocol
+  >(next: inout G) -> Int where G.Element == CodeUnit
 }
diff --git a/test/SIL/Serialization/Inputs/def_generic_marker.swift b/test/SIL/Serialization/Inputs/def_generic_marker.swift
index e5c03d7..be5b1d4 100644
--- a/test/SIL/Serialization/Inputs/def_generic_marker.swift
+++ b/test/SIL/Serialization/Inputs/def_generic_marker.swift
@@ -9,16 +9,16 @@
 public protocol mmCollectionType : mmSequenceType {
   mutating func extend<
     S : mmSequenceType
-    where S.Generator.Element == Self.Generator.Element
-  > (_ seq: S)
+  > (_ seq: S) where S.Generator.Element == Self.Generator.Element
 }
 
 @inlinable
 public func test<
   EC1 : mmCollectionType,
   EC2 : mmCollectionType
+> (_ lhs: EC1, _ rhs: EC2) -> EC1
   where EC1.Generator.Element == EC2.Generator.Element
-> (_ lhs: EC1, _ rhs: EC2) -> EC1 {
+{
   var lhs = lhs
   lhs.extend(rhs)
   return lhs
diff --git a/test/SIL/Serialization/Recovery/Inputs/bad-modules/Types.h b/test/SIL/Serialization/Recovery/Inputs/bad-modules/Types.h
new file mode 100644
index 0000000..a735ae9
--- /dev/null
+++ b/test/SIL/Serialization/Recovery/Inputs/bad-modules/Types.h
@@ -0,0 +1,3 @@
+// struct SoonToBeMissing {
+//   int value;
+// };
diff --git a/test/SIL/Serialization/Recovery/Inputs/bad-modules/module.modulemap b/test/SIL/Serialization/Recovery/Inputs/bad-modules/module.modulemap
new file mode 100644
index 0000000..b811768
--- /dev/null
+++ b/test/SIL/Serialization/Recovery/Inputs/bad-modules/module.modulemap
@@ -0,0 +1 @@
+module Types { header "Types.h" }
diff --git a/test/SIL/Serialization/Recovery/Inputs/good-modules/Types.h b/test/SIL/Serialization/Recovery/Inputs/good-modules/Types.h
new file mode 100644
index 0000000..4b49807
--- /dev/null
+++ b/test/SIL/Serialization/Recovery/Inputs/good-modules/Types.h
@@ -0,0 +1,3 @@
+struct SoonToBeMissing {
+  int value;
+};
diff --git a/test/SIL/Serialization/Recovery/Inputs/good-modules/module.modulemap b/test/SIL/Serialization/Recovery/Inputs/good-modules/module.modulemap
new file mode 100644
index 0000000..b811768
--- /dev/null
+++ b/test/SIL/Serialization/Recovery/Inputs/good-modules/module.modulemap
@@ -0,0 +1 @@
+module Types { header "Types.h" }
diff --git a/test/SIL/Serialization/Recovery/function.sil b/test/SIL/Serialization/Recovery/function.sil
new file mode 100644
index 0000000..311c1b9
--- /dev/null
+++ b/test/SIL/Serialization/Recovery/function.sil
@@ -0,0 +1,26 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -parse-sil %s -emit-sib -o %t/Library.sib -module-name Library -I %S/Inputs/good-modules -parse-stdlib
+// RUN: %target-sil-opt %t/Library.sib -I %S/Inputs/good-modules | %FileCheck %s
+// RUN: %target-sil-opt %t/Library.sib -I %S/Inputs/bad-modules | %FileCheck -check-prefix=CHECK-RECOVERY %s
+// RUN: %target-sil-opt %t/Library.sib -I %S/Inputs/bad-modules | %FileCheck -check-prefix=CHECK-RECOVERY-NEGATIVE %s
+
+// CHECK-LABEL: sil_stage raw
+// CHECK-RECOVERY-LABEL: sil_stage raw
+
+sil_stage raw
+import Types
+
+// CHECK-LABEL: sil @missingParam : $@convention(thin) (SoonToBeMissing) -> () {
+// CHECK-RECOVERY-NEGATIVE-NOT: sil @missingParam
+sil @missingParam : $@convention(thin) (SoonToBeMissing) -> () {
+entry(%arg: $SoonToBeMissing):
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @missingResult : $@convention(thin) () -> SoonToBeMissing {
+// CHECK-RECOVERY-NEGATIVE-NOT: sil @missingResult
+sil @missingResult : $@convention(thin) () -> (SoonToBeMissing) {
+entry:
+  unreachable
+}
diff --git a/test/SIL/Serialization/deserialize_generic_marker.sil b/test/SIL/Serialization/deserialize_generic_marker.sil
index ddd352f..766b322 100644
--- a/test/SIL/Serialization/deserialize_generic_marker.sil
+++ b/test/SIL/Serialization/deserialize_generic_marker.sil
@@ -1,6 +1,6 @@
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_generic_marker.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_generic_marker.swift
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -performance-linker -I %t %s | %FileCheck %s
 
 // Make sure that SILFunctionType with GenericSignature can match up with
diff --git a/test/SILGen/Inputs/objc_block_to_func_to_block.h b/test/SILGen/Inputs/objc_block_to_func_to_block.h
new file mode 100644
index 0000000..b005c74
--- /dev/null
+++ b/test/SILGen/Inputs/objc_block_to_func_to_block.h
@@ -0,0 +1,7 @@
+@import Foundation;
+
+@interface Foo<A>: NSObject
+
+- (void)blockInception:(void (^ _Nonnull)(void (^ _Nonnull)(void (^ _Nonnull)(Foo<A> * _Nonnull))))b;
+
+@end
diff --git a/test/SILGen/objc_block_to_func_to_block.swift b/test/SILGen/objc_block_to_func_to_block.swift
new file mode 100644
index 0000000..f75bee0
--- /dev/null
+++ b/test/SILGen/objc_block_to_func_to_block.swift
@@ -0,0 +1,8 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -import-objc-header %S/Inputs/objc_block_to_func_to_block.h -emit-silgen -verify %s
+// REQUIRES: objc_interop
+
+import Foundation
+
+func bar<A>(x: Foo<A>) {
+  x.blockInception { f in f { _ = $0 } }
+}
diff --git a/test/SILOptimizer/accessed_storage_analysis.sil b/test/SILOptimizer/accessed_storage_analysis.sil
index b844e0a..68ec16d 100644
--- a/test/SILOptimizer/accessed_storage_analysis.sil
+++ b/test/SILOptimizer/accessed_storage_analysis.sil
@@ -129,45 +129,207 @@
   return %6 : $Int
 }
 
-sil_global @int_global : $Int
+public var defined_global: Int64
 
-// CHECK-LABEL: @readIdentifiedGlobal
-// CHECK: [read] Global // int_global
-// CHECK: sil_global @int_global : $Int
-sil @readIdentifiedGlobal : $@convention(thin) () -> Int {
+// defined_global definition and initializer.
+//
+// A global defined in the current module must have a Swift declaration.
+// The variable name is derived from the mangled SIL name.
+sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+
+sil_global private @globalinit_33_45D320C25F1882286C6F155330EA3839_token0 : $Builtin.Word
+
+sil private @globalinit_33_45D320C25F1882286C6F155330EA3839_func0 : $@convention(c) () -> () {
 bb0:
-  %1 = global_addr @int_global : $*Int
-  %2 = begin_access [read] [dynamic] %1 : $*Int
-  %3 = load %2 : $*Int
-  end_access %2 : $*Int
-  return %3 : $Int
+  alloc_global @$S25accessed_storage_analysis14defined_globalSivp
+  %1 = global_addr @$S25accessed_storage_analysis14defined_globalSivp : $*Int64
+  %2 = integer_literal $Builtin.Int64, 0
+  %3 = struct $Int64 (%2 : $Builtin.Int64)
+  store %3 to %1 : $*Int64
+  %5 = tuple ()
+  return %5 : $()
 }
 
-// CHECK-LABEL: @writeIdentifiedGlobal
-// CHECK: [modify] Global // int_global
-// CHECK: sil_global @int_global : $Int
-sil @writeIdentifiedGlobal : $@convention(thin) (Int) -> () {
-bb0(%0 : $Int):
-  %1 = global_addr @int_global : $*Int
-  %2 = begin_access [modify] [dynamic] %1 : $*Int
-  store %0 to %2 : $*Int
-  end_access %2 : $*Int
+// defined_global.unsafeMutableAddressor
+sil hidden [global_init] @$S25accessed_storage_analysis14defined_globalSivau : $@convention(thin) () -> Builtin.RawPointer {
+bb0:
+  %0 = global_addr @globalinit_33_45D320C25F1882286C6F155330EA3839_token0 : $*Builtin.Word
+  %1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
+  %2 = function_ref @globalinit_33_45D320C25F1882286C6F155330EA3839_func0 : $@convention(c) () -> ()
+  %3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
+  %4 = global_addr @$S25accessed_storage_analysis14defined_globalSivp : $*Int64
+  %5 = address_to_pointer %4 : $*Int64 to $Builtin.RawPointer
+  return %5 : $Builtin.RawPointer
+}
+
+// CHECK-LABEL: @readIdentifiedDefinedGlobal
+// CHECK: [read] Global // defined_global
+// CHECK: sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+sil @readIdentifiedDefinedGlobal : $@convention(thin) () -> Int64 {
+bb0:
+  %1 = global_addr @$S25accessed_storage_analysis14defined_globalSivp : $*Int64
+  %2 = begin_access [read] [dynamic] %1 : $*Int64
+  %3 = load %2 : $*Int64
+  end_access %2 : $*Int64
+  return %3 : $Int64
+}
+
+// CHECK-LABEL: @writeIdentifiedDefinedGlobal
+// CHECK: [modify] Global // defined_global
+// CHECK: sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+sil @writeIdentifiedDefinedGlobal : $@convention(thin) (Int64) -> () {
+bb0(%0 : $Int64):
+  %1 = global_addr @$S25accessed_storage_analysis14defined_globalSivp : $*Int64
+  %2 = begin_access [modify] [dynamic] %1 : $*Int64
+  store %0 to %2 : $*Int64
+  end_access %2 : $*Int64
   %v = tuple ()
   return %v : $()
 }
 
-// CHECK-LABEL: @readWriteIdentifiedGlobal
-// CHECK: [modify] Global // int_global
-// CHECK: sil_global @int_global : $Int
-sil @readWriteIdentifiedGlobal : $@convention(thin) (Int) -> (Int) {
-bb0(%0 : $Int):
-  %1 = function_ref @writeIdentifiedGlobal : $@convention(thin) (Int) -> ()
-  %2 = apply %1(%0) : $@convention(thin) (Int) -> ()
-  %3 = global_addr @int_global : $*Int
-  %4 = begin_access [read] [dynamic] %3 : $*Int
-  %5 = load %4 : $*Int
-  end_access %4 : $*Int
-  return %5 : $Int
+// CHECK-LABEL: @readWriteIdentifiedDefinedGlobal
+// CHECK: [modify] Global // defined_global
+// CHECK: sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+sil @readWriteIdentifiedDefinedGlobal : $@convention(thin) (Int64) -> (Int64) {
+bb0(%0 : $Int64):
+  %1 = function_ref @writeIdentifiedDefinedGlobal : $@convention(thin) (Int64) -> ()
+  %2 = apply %1(%0) : $@convention(thin) (Int64) -> ()
+  %3 = global_addr @$S25accessed_storage_analysis14defined_globalSivp : $*Int64
+  %4 = begin_access [read] [dynamic] %3 : $*Int64
+  %5 = load %4 : $*Int64
+  end_access %4 : $*Int64
+  return %5 : $Int64
+}
+
+// CHECK-LABEL: @readIdentifiedAddressedGlobal
+// CHECK: [read] Global // defined_global
+// CHECK: sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+sil @readIdentifiedAddressedGlobal : $@convention(thin) () -> Int64 {
+bb0:
+  // function_ref myGlobal.unsafeMutableAddressor
+  %0 = function_ref @$S25accessed_storage_analysis14defined_globalSivau : $@convention(thin) () -> Builtin.RawPointer
+  %1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
+  %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Int64
+  %3 = begin_access [read] [dynamic] %2 : $*Int64
+  %4 = load %3 : $*Int64
+  end_access %3 : $*Int64
+  return %4 : $Int64
+}
+
+// CHECK-LABEL: @writeIdentifiedAddressedGlobal
+// CHECK: [modify] Global // defined_global
+// CHECK: sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+sil @writeIdentifiedAddressedGlobal : $@convention(thin) (Int64) -> () {
+bb0(%0 : $Int64):
+  // function_ref myGlobal.unsafeMutableAddressor
+  %1 = function_ref @$S25accessed_storage_analysis14defined_globalSivau : $@convention(thin) () -> Builtin.RawPointer
+  %2 = apply %1() : $@convention(thin) () -> Builtin.RawPointer
+  %3 = pointer_to_address %2 : $Builtin.RawPointer to [strict] $*Int64
+  %4 = begin_access [modify] [dynamic] %3 : $*Int64
+  store %0 to %4 : $*Int64
+  end_access %4 : $*Int64
+  %v = tuple ()
+  return %v : $()
+}
+
+// CHECK-LABEL: @readWriteIdentifiedAddressedGlobal
+// CHECK: [modify] Global // defined_global
+// CHECK: sil_global @$S25accessed_storage_analysis14defined_globalSivp : $Int64
+sil @readWriteIdentifiedAddressedGlobal : $@convention(thin) (Int64) -> (Int64) {
+bb0(%0 : $Int64):
+  %1 = function_ref @writeIdentifiedAddressedGlobal : $@convention(thin) (Int64) -> ()
+  %2 = apply %1(%0) : $@convention(thin) (Int64) -> ()
+  // function_ref myGlobal.unsafeMutableAddressor
+  %3 = function_ref @$S25accessed_storage_analysis14defined_globalSivau : $@convention(thin) () -> Builtin.RawPointer
+  %4 = apply %3() : $@convention(thin) () -> Builtin.RawPointer
+  %5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Int64
+  %6 = begin_access [modify] [dynamic] %5 : $*Int64
+  %7 = load %6 : $*Int64
+  end_access %6 : $*Int64
+  return %7 : $Int64
+}
+
+public var static_global: Int64
+
+// static_global definition and static initializer.
+//
+// A global defined in the current module must have a Swift declaration.
+// The variable name is derived from the mangled SIL name.
+sil_global @$S25accessed_storage_analysis13static_globalSivp : $Int64 = {
+  %0 = integer_literal $Builtin.Int64, 0
+  %initval = struct $Int64 (%0 : $Builtin.Int64)
+}
+
+// static_global.unsafeMutableAddressor
+sil hidden [global_init] @$S25accessed_storage_analysis13static_globalSivau : $@convention(thin) () -> Builtin.RawPointer {
+bb0:
+  %0 = global_addr @$S25accessed_storage_analysis14defined_globalSivp : $*Int64
+  %1 = address_to_pointer %0 : $*Int64 to $Builtin.RawPointer
+  return %1 : $Builtin.RawPointer
+}
+
+// A sil_global such as this without a corresponding Swift declaration must be
+// defined in another module. Such a global can only be identified when accessed
+// via global_addr instruction (as happens with C imports). Any access via an
+// addessor (as with Swift imports) will be Unidentified. For the purpose of
+// access analysis, a global is considered "external" based on the availabitiy
+// of a Swift declaraion. We only consider an global to be a disjoint access
+// location if its declaration is available.
+sil_global @external_global : $Int64
+
+sil hidden_external [global_init] @globalAddressor : $@convention(thin) () -> Builtin.RawPointer
+
+// CHECK-LABEL: @readIdentifiedExternalGlobal
+// CHECK: [read] Global // external_global
+// CHECK: sil_global @external_global : $Int64
+sil @readIdentifiedExternalGlobal : $@convention(thin) () -> Int64 {
+bb0:
+  %1 = global_addr @external_global : $*Int64
+  %2 = begin_access [read] [dynamic] %1 : $*Int64
+  %3 = load %2 : $*Int64
+  end_access %2 : $*Int64
+  return %3 : $Int64
+}
+
+// CHECK-LABEL: @writeIdentifiedExternalGlobal
+// CHECK: [modify] Global // external_global
+// CHECK: sil_global @external_global : $Int64
+sil @writeIdentifiedExternalGlobal : $@convention(thin) (Int64) -> () {
+bb0(%0 : $Int64):
+  %1 = global_addr @external_global : $*Int64
+  %2 = begin_access [modify] [dynamic] %1 : $*Int64
+  store %0 to %2 : $*Int64
+  end_access %2 : $*Int64
+  %v = tuple ()
+  return %v : $()
+}
+
+// CHECK-LABEL: @readWriteIdentifiedExternalGlobal
+// CHECK: [modify] Global // external_global
+// CHECK: sil_global @external_global : $Int64
+sil @readWriteIdentifiedExternalGlobal : $@convention(thin) (Int64) -> (Int64) {
+bb0(%0 : $Int64):
+  %1 = function_ref @writeIdentifiedExternalGlobal : $@convention(thin) (Int64) -> ()
+  %2 = apply %1(%0) : $@convention(thin) (Int64) -> ()
+  %3 = global_addr @external_global : $*Int64
+  %4 = begin_access [read] [dynamic] %3 : $*Int64
+  %5 = load %4 : $*Int64
+  end_access %4 : $*Int64
+  return %5 : $Int64
+}
+
+// CHECK-LABEL: @readUnidentifiedExternalGlobal
+// CHECK-NOT: Global
+// CHECK: unidentified accesses: modify
+sil @readUnidentifiedExternalGlobal : $@convention(thin) () -> Int64 {
+bb0:
+  %0 = function_ref @globalAddressor : $@convention(thin) () -> Builtin.RawPointer
+  %1 = apply %0() : $@convention(thin) () -> Builtin.RawPointer
+  %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Int64
+  %3 = begin_access [read] [dynamic] %2 : $*Int64
+  %4 = load %3 : $*Int64
+  end_access %3 : $*Int64
+  return %4 : $Int64
 }
 
 class C {
@@ -262,42 +424,6 @@
   return %7 : $Int
 }
 
-// CHECK-LABEL: @readUnidentified
-// CHECK: unidentified accesses: read
-sil @readUnidentified : $@convention(thin) (Builtin.RawPointer) -> Int {
-bb0(%0 : $Builtin.RawPointer):
-  %1 = pointer_to_address %0 : $Builtin.RawPointer to $*Int
-  %2 = begin_access [read] [dynamic] %1 : $*Int
-  %4 = load %2 : $*Int
-  end_access %2 : $*Int
-  return %4 : $Int
-}
-
-// CHECK-LABEL: @writeUnidentified
-// CHECK: unidentified accesses: modify
-sil @writeUnidentified : $@convention(thin) (Builtin.RawPointer, Int) -> () {
-bb0(%0 : $Builtin.RawPointer, %1 : $Int):
-  %2 = pointer_to_address %0 : $Builtin.RawPointer to $*Int
-  %3 = begin_access [modify] [dynamic] %2 : $*Int
-  store %1 to %3 : $*Int
-  end_access %3 : $*Int
-  %v = tuple ()
-  return %v : $()
-}
-
-// CHECK-LABEL: @readWriteUnidentified
-// CHECK: unidentified accesses: modify
-sil @readWriteUnidentified : $@convention(thin) (Builtin.RawPointer, Int) -> Int {
-bb0(%0 : $Builtin.RawPointer, %1 : $Int):
-  %2 = function_ref @writeUnidentified : $@convention(thin) (Builtin.RawPointer, Int) -> ()
-  %3 = apply %2(%0, %1) : $@convention(thin) (Builtin.RawPointer, Int) -> ()
-  %4 = pointer_to_address %0 : $Builtin.RawPointer to $*Int
-  %5 = begin_access [read] [dynamic] %4 : $*Int
-  %6 = load %5 : $*Int
-  end_access %5 : $*Int
-  return %6 : $Int
-}
-
 enum TreeB<T> {
   case Nil
   case Leaf(T)
@@ -360,13 +486,6 @@
 // CHECK: unidentified accesses: read
 sil @readUnexpected : $@convention(thin) (@inout Int, @inout Int?, @inout Builtin.UnsafeValueBuffer) -> () {
 bb0(%inout : $*Int, %oi : $*Optional<Int>, %b : $*Builtin.UnsafeValueBuffer):
-  br bb1(%inout : $*Int)
-
-bb1(%phi : $*Int):
-  %phiAccess = begin_access [read] [dynamic] %phi : $*Int
-  %ld = load %phiAccess : $*Int
-  end_access %phiAccess : $*Int
-
   %ea = init_enum_data_addr %oi : $*Optional<Int>, #Optional.some!enumelt.1
   %eaAccess = begin_access [read] [dynamic] %ea : $*Int
   %eaload = load %eaAccess : $*Int
diff --git a/test/SILOptimizer/array_contentof_opt.swift b/test/SILOptimizer/array_contentof_opt.swift
index b03fdfb..f658589 100644
--- a/test/SILOptimizer/array_contentof_opt.swift
+++ b/test/SILOptimizer/array_contentof_opt.swift
@@ -32,7 +32,7 @@
 
 // CHECK-LABEL: sil @{{.*}}testTooManyInts
 // CHECK-NOT: apply
-// CHECK:        [[F:%[0-9]+]] = function_ref  @$SSa6append10contentsOfyqd___t7ElementQyd__Rszs8SequenceRd__lFSi_SaySiGTg5
+// CHECK:        [[F:%[0-9]+]] = function_ref  @$SSa6append10contentsOfyqd___t7ElementQyd__RszSTRd__lFSi_SaySiGTg5
 // CHECK-NOT: apply
 // CHECK:        apply [[F]]
 // CHECK-NOT: apply
diff --git a/test/SILOptimizer/definite_init_diagnostics.swift b/test/SILOptimizer/definite_init_diagnostics.swift
index dcec8c9..d80a750 100644
--- a/test/SILOptimizer/definite_init_diagnostics.swift
+++ b/test/SILOptimizer/definite_init_diagnostics.swift
@@ -1355,130 +1355,3 @@
     c2 = tmp
   }
 }
-
-// Tests for DI when optionals are defined using unchecked_take_enum_data_addr
-// <rdar://38624845>
-
-func testOptionalDoubleWrite() -> String? {
-  let sConst: String? // expected-note {{change 'let' to 'var' to make it mutable}}
-  sConst = ""
-  sConst? = "v2" // expected-error {{immutable value 'sConst' may only be initialized once}}
-  return sConst
-}
-
-func testOptionalDoubleWrite2() -> Int? {
-  let x: Int? // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = 0
-  x? = 0 // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-protocol DIOptionalTestProtocol {
-  var f: Int { get set }
-}
-
-func testOptionalDoubleWrite3(p1: DIOptionalTestProtocol) -> DIOptionalTestProtocol? {
-  let x: DIOptionalTestProtocol? // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = p1
-  x? = p1 // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-func testOptionalWrite() {
-  let x: Int? // expected-note {{constant defined here}}
-              // expected-warning@-1 {{immutable value 'x' was never used; consider removing it}}
-  x? = 0 // expected-error {{constant 'x' used before being initialized}}
-}
-
-func testOptionalWriteGenerics<T>(p: T) -> T? {
-  let x: T? // expected-note {{constant defined here}}
-            // expected-note@-1 {{change 'let' to 'var' to make it mutable}}
-  x? = p  // expected-error {{constant 'x' used before being initialized}}
-  x = p   // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-func testOptionalWriteGenerics2<T>(p: T) -> T? {
-  let x: T? // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = p
-  x? = p  // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-enum TestOptionalEnum {
-  case Cons(Int)
-  case Nil()
-}
-
-func testOptionalWithEnum(p: TestOptionalEnum) -> TestOptionalEnum? {
-  let x: TestOptionalEnum? // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = p
-  x? = p  // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-// Tests for optional chaining
-
-class DIOptionalTestClass {
-  var r: DIOptionalTestClass? = nil
-  var f: Int = 0;
-  let g: Int = 0;
-}
-
-func testOptionalChaining(p: DIOptionalTestClass?) {
-  p?.f = 2
-}
-
-func testOptionalChaining2(p: DIOptionalTestClass?) -> DIOptionalTestClass? {
-  let x: DIOptionalTestClass?
-  x = p
-  x?.f = 1
-  p?.r?.f = 2
-  return x
-}
-
-struct DIOptionalTestStruct {
-  var f: Int
-}
-
-func testOptionalChaining3() -> DIOptionalTestStruct? {
-  let x: DIOptionalTestStruct?  // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = DIOptionalTestStruct(f: 0)
-  x?.f = 2  // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-extension DIOptionalTestStruct {
-  public init?() {
-    self.f = 0
-  }
-}
-
-func testOptionalChaining4() -> DIOptionalTestStruct? {
-  let x: DIOptionalTestStruct?  // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = DIOptionalTestStruct()
-  x?.f = 2  // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-struct DIOptionalTestStructPair {
-  var pair: (Int, Int)
-}
-
-func test6() -> DIOptionalTestStructPair? {
-  let x: DIOptionalTestStructPair?  // expected-note {{change 'let' to 'var' to make it mutable}}
-  x = DIOptionalTestStructPair(pair: (0, 0))
-  x?.pair.0 = 1 // expected-error {{immutable value 'x' may only be initialized once}}
-  return x
-}
-
-func testOptionalChainingWithGenerics<T: DIOptionalTestProtocol>(p: T) -> T? {
-  let x: T? // expected-note {{constant defined here}}
-            // expected-note@-1 {{constant defined here}}
-            // expected-note@-2 {{constant defined here}}
-
-  // note that here assignment to 'f' is a call to the setter.
-  x?.f = 0  // expected-error {{constant 'x' used before being initialized}}
-            // expected-error@-1 {{constant 'x' passed by reference before being initialized}}
-  return x  // expected-error {{constant 'x' used before being initialized}}
-}
diff --git a/test/SILOptimizer/devirt_inherited_conformance.swift b/test/SILOptimizer/devirt_inherited_conformance.swift
index 918d68e..eeb5194 100644
--- a/test/SILOptimizer/devirt_inherited_conformance.swift
+++ b/test/SILOptimizer/devirt_inherited_conformance.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -O %s -emit-sil -swift-version 3 | %FileCheck %s
+// RUN: %target-swift-frontend -O %s -emit-sil | %FileCheck %s
 
 // Make sure that we can dig all the way through the class hierarchy and
 // protocol conformances.
@@ -107,14 +107,14 @@
 }
 
 // Define a custom operator to be used instead of ==
-infix operator --- { associativity left precedence 140 } 
+infix operator ---
 
 // Simple is a protocol that simply defines an operator and
 // a few methods with different number of arguments.
 public protocol Simple {
    func foo(_: Self) -> Bool
    func boo(_: Self, _: Self) -> Bool
-   func ---(_: Self, _: Self) -> Bool
+   static func ---(_: Self, _: Self) -> Bool
 }
 
 public class C: Equatable, Comparable, Simple {
diff --git a/test/SILOptimizer/eager_specialize.sil b/test/SILOptimizer/eager_specialize.sil
index 50c01a8..e9cebc6 100644
--- a/test/SILOptimizer/eager_specialize.sil
+++ b/test/SILOptimizer/eager_specialize.sil
@@ -182,7 +182,7 @@
 }
 
 // specialized divideNum<A where ...> (A, den : A) throws -> A
-// CHECK-LABEL: sil shared @$S16eager_specialize9divideNum_3denxx_xtKs13SignedIntegerRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error) {
+// CHECK-LABEL: sil shared @$S16eager_specialize9divideNum_3denxx_xtKSZRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error) {
 // CHECK: bb0(%0 : $Int, %1 : $Int):
 // CHECK: return %{{.*}}
 // CHECK: throw %{{.*}}
@@ -224,7 +224,7 @@
 // CHECK:   %{{.*}} = unchecked_addr_cast %2 : $*T to $*Int
 // CHECK:   %{{.*}} = load %{{.*}} : $*Int
 // CHECK:   // function_ref specialized divideNum<A>(_:den:)
-// CHECK:   %{{.*}} = function_ref @$S16eager_specialize9divideNum_3denxx_xtKs13SignedIntegerRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error)
+// CHECK:   %{{.*}} = function_ref @$S16eager_specialize9divideNum_3denxx_xtKSZRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error)
 // CHECK:   try_apply %{{.*}}(%{{.*}}, %{{.*}}) : $@convention(thin) (Int, Int) -> (Int, @error Error), normal bb8, error bb7
 
 // CHECK: bb7(%{{.*}} : $Error):
diff --git a/test/SILOptimizer/exclusivity_static_diagnostics.sil b/test/SILOptimizer/exclusivity_static_diagnostics.sil
index 9f4eb98..4bb8a33 100644
--- a/test/SILOptimizer/exclusivity_static_diagnostics.sil
+++ b/test/SILOptimizer/exclusivity_static_diagnostics.sil
@@ -990,3 +990,35 @@
   %v = tuple ()
   return %v : $()
 }
+
+class SomeClass {}
+
+// LLDB uses mark_uninitialized [var] in an unsupported way via an address to
+// pointer. LLDB shouldn't do this, but until it is removed and validated we
+// need a test for this.
+//
+// Check that this doesn't trigger the DiagnoseStaticExclusivity
+// assert that all accesses have a valid AccessedStorage source.
+sil @lldb_unsupported_markuninitialized_testcase : $@convention(thin) (UnsafeMutablePointer<Any>) -> () {
+bb0(%0 : $UnsafeMutablePointer<Any>):
+  %2 = struct_extract %0 : $UnsafeMutablePointer<Any>, #UnsafeMutablePointer._rawValue
+  %3 = integer_literal $Builtin.Int64, 8
+  %4 = index_raw_pointer %2 : $Builtin.RawPointer, %3 : $Builtin.Int64
+  %5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Builtin.RawPointer
+  %6 = load [trivial] %5 : $*Builtin.RawPointer
+  %7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*Error
+  %8 = mark_uninitialized [var] %7 : $*Error
+  %9 = struct_extract %0 : $UnsafeMutablePointer<Any>, #UnsafeMutablePointer._rawValue
+  %10 = integer_literal $Builtin.Int64, 0
+  %11 = index_raw_pointer %9 : $Builtin.RawPointer, %10 : $Builtin.Int64
+  %12 = pointer_to_address %11 : $Builtin.RawPointer to [strict] $*Builtin.RawPointer
+  %13 = load [trivial] %12 : $*Builtin.RawPointer
+  %14 = pointer_to_address %13 : $Builtin.RawPointer to [strict] $*@thick SomeClass.Type
+  %15 = mark_uninitialized [var] %14 : $*@thick SomeClass.Type
+  %16 = metatype $@thick SomeClass.Type
+  %17 = begin_access [modify] [unsafe] %15 : $*@thick SomeClass.Type
+  assign %16 to %17 : $*@thick SomeClass.Type
+  end_access %17 : $*@thick SomeClass.Type
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SILOptimizer/licm_exclusivity.swift b/test/SILOptimizer/licm_exclusivity.swift
new file mode 100644
index 0000000..93cbc9c
--- /dev/null
+++ b/test/SILOptimizer/licm_exclusivity.swift
@@ -0,0 +1,50 @@
+// RUN: %target-swift-frontend -O -enforce-exclusivity=checked -emit-sil -Xllvm -debug-only=sil-licm -primary-file %s 2>&1 | %FileCheck %s --check-prefix=TEST1
+// RUN: %target-swift-frontend -O -enforce-exclusivity=checked -emit-sil -Xllvm -debug-only=sil-licm  -primary-file %s 2>&1 | %FileCheck %s --check-prefix=TEST2
+// RUN: %target-swift-frontend -O -enforce-exclusivity=checked -emit-sil  -primary-file %s | %FileCheck %s --check-prefix=TESTSIL
+// REQUIRES: optimized_stdlib,asserts
+
+// TEST1-LABEL: Processing loops in {{.*}}run_ReversedArray{{.*}}
+// TEST1: Hoist and Sink pairs attempt
+// TEST1: Hoisted
+// TEST1: Successfully hosited and sank pair
+
+// TESTSIL-LABEL: sil hidden @$S16licm_exclusivity17run_ReversedArrayyySiF : $@convention(thin) (Int) -> () {
+// TESTSIL: bb
+// TESTSIL: begin_access [modify] [dynamic] [no_nested_conflict]
+// TESTSIL: br bb{{.*}}
+// TESTSIL-NEXT bb{{.*}}:
+// TESTSIL: end_access
+// TESTSIL: return
+var x = 0
+func run_ReversedArray(_ N: Int) {
+  let array = Array(repeating: 1, count: 42)
+  let reversedArray = array.reversed()
+
+  // Iterate over the underlying type
+  // ReversedRandomAccessCollection<Array<Int>>
+  for _ in 1...N {
+    for item in reversedArray {
+      x = item
+    }
+  }
+}
+
+// TEST2-LABEL: Processing loops in {{.*}}count_unicodeScalars{{.*}}
+// TEST2: Hoist and Sink pairs attempt
+// TEST2: Hoisted
+// TEST2: cloning
+// TEST2: Successfully hosited and sank pair
+
+// TESTSIL-LABEL: sil @$S16licm_exclusivity20count_unicodeScalarsyySS17UnicodeScalarViewVF : $@convention(thin) (@guaranteed String.UnicodeScalarView) -> () {
+// TESTSIL: bb0(%0 : $String.UnicodeScalarView)
+// TESTSIL-NEXT: %1 = global_addr @$S16licm_exclusivity5countSivp : $*Int
+// TESTSIL: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int
+// TESTSIL-NEXT: br bb1
+// TESTSIL: end_access
+// TESTSIL: return
+var count: Int = 0
+public func count_unicodeScalars(_ s: String.UnicodeScalarView) {
+  for _ in s {
+    count += 1
+  }
+}
diff --git a/test/SILOptimizer/licm_multiend.sil b/test/SILOptimizer/licm_multiend.sil
new file mode 100644
index 0000000..8f2d8b1
--- /dev/null
+++ b/test/SILOptimizer/licm_multiend.sil
@@ -0,0 +1,214 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -licm | %FileCheck %s
+// REQUIRES: CPU=x86_64
+// REQUIRES: OS=macosx
+
+sil_stage canonical
+
+import Builtin
+import Swift
+import SwiftShims
+
+var x: Int
+
+let reversedArray: ReversedCollection<[Int]>
+
+// x
+sil_global hidden @$S3tmp1xSivp : $Int
+
+// reversedArray
+sil_global hidden [let] @$S3tmp13reversedArrays18ReversedCollectionVySaySiGGvp : $ReversedCollection<Array<Int>>
+
+// _swiftEmptyArrayStorage
+sil_global @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage
+
+
+// CHECK-LABEL: sil hidden @multi_end_licm : $@convention(thin) () -> () {
+// CHECK: bb2:
+// CHECK: [[GLOBALVAR:%.*]] = global_addr @$S3tmp1xSivp : $*Int
+// CHECK: [[BEGINA:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]] : $*Int
+// CHECK-NEXT: br [[LOOPH:bb[0-9]+]]({{.*}} : $Builtin.Int64)
+// CHECK: [[LOOPH]]({{.*}} : $Builtin.Int64)
+// CHECK: cond_br {{.*}}, [[LOOPCOND1:bb[0-9]+]], [[LOOPCOND2:bb[0-9]+]]
+// CHECK: [[LOOPCOND1]]:
+// CHECK-NEXT: store
+// CHECK-NEXT: cond_br {{.*}}, [[LOOPEXIT1:bb[0-9]+]], [[LOOPCONT1:bb[0-9]+]]
+// CHECK: [[LOOPEXIT1]]:
+// CHECK-NEXT: end_access [[BEGINA]] : $*Int
+// CHECK-NEXT: br [[LOOPAFTEREXIT:bb[0-9]+]]
+// CHECK: [[LOOPCOND2]]:
+// CHECK-NEXT: struct $Int
+// CHECK-NEXT: store
+// CHECK-NEXT: cond_br {{.*}}, [[LOOPEXIT2:bb[0-9]+]], [[LOOPCONT1]]
+// CHECK: [[LOOPEXIT2]]:
+// CHECK-NEXT: end_access [[BEGINA]] : $*Int
+// CHECK-NEXT: br [[LOOPAFTEREXIT]]
+// CHECK: [[LOOPCONT1]]:
+// CHECK-NEXT: br [[LOOPH]]
+// CHECK: [[LOOPAFTEREXIT]]:
+// CHECK-NEXT: br [[FUNCRET:bb[0-9]+]]
+// CHECK: [[FUNCRET]]:
+// CHECK-NEXT: tuple
+// CHECK-NEXT: return
+sil hidden @multi_end_licm : $@convention(thin) () -> () {
+bb0:
+  %0 = global_addr @$S3tmp13reversedArrays18ReversedCollectionVySaySiGGvp : $*ReversedCollection<Array<Int>>
+  %1 = struct_element_addr %0 : $*ReversedCollection<Array<Int>>, #ReversedCollection._base
+  %2 = struct_element_addr %1 : $*Array<Int>, #Array._buffer
+  %3 = struct_element_addr %2 : $*_ArrayBuffer<Int>, #_ArrayBuffer._storage
+  %4 = struct_element_addr %3 : $*_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCore>, #_BridgeStorage.rawValue
+  %5 = load %4 : $*Builtin.BridgeObject
+  %6 = unchecked_ref_cast %5 : $Builtin.BridgeObject to $_ContiguousArrayStorageBase
+  %7 = ref_element_addr %6 : $_ContiguousArrayStorageBase, #_ContiguousArrayStorageBase.countAndCapacity
+  %8 = struct_element_addr %7 : $*_ArrayBody, #_ArrayBody._storage
+  %9 = struct_element_addr %8 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count
+  %10 = struct_element_addr %9 : $*Int, #Int._value
+  %11 = load %10 : $*Builtin.Int64
+  %12 = builtin "assumeNonNegative_Int64"(%11 : $Builtin.Int64) : $Builtin.Int64
+  %13 = integer_literal $Builtin.Int64, 0
+  %14 = integer_literal $Builtin.Int1, 0
+  %15 = builtin "cmp_eq_Int64"(%12 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %16 = builtin "int_expect_Int1"(%15 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
+  cond_br %16, bb1, bb2
+
+bb1:
+  br bbRet
+
+bb2:
+  %19 = global_addr @$S3tmp1xSivp : $*Int
+  %20 = integer_literal $Builtin.Int64, 1
+  %21 = integer_literal $Builtin.Int1, -1
+  %23 = ref_tail_addr %6 : $_ContiguousArrayStorageBase, $Int
+  br bb4(%12 : $Builtin.Int64)
+
+bb4(%27 : $Builtin.Int64):
+  %28 = builtin "ssub_with_overflow_Int64"(%27 : $Builtin.Int64, %20 : $Builtin.Int64, %21 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
+  %29 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 0
+  %30 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 1
+  cond_fail %30 : $Builtin.Int1
+  %32 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %33 = load %10 : $*Builtin.Int64
+  %34 = builtin "assumeNonNegative_Int64"(%33 : $Builtin.Int64) : $Builtin.Int64 
+  %35 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %34 : $Builtin.Int64) : $Builtin.Int1
+  %36 = builtin "xor_Int1"(%35 : $Builtin.Int1, %21 : $Builtin.Int1) : $Builtin.Int1
+  %37 = builtin "or_Int1"(%32 : $Builtin.Int1, %36 : $Builtin.Int1) : $Builtin.Int1
+  cond_fail %37 : $Builtin.Int1
+  %39 = builtin "truncOrBitCast_Int64_Word"(%29 : $Builtin.Int64) : $Builtin.Word
+  %40 = index_addr %23 : $*Int, %39 : $Builtin.Word
+  %41 = struct_element_addr %40 : $*Int, #Int._value
+  %42 = load %41 : $*Builtin.Int64
+  %43 = struct $Int (%42 : $Builtin.Int64)
+  debug_value %43 : $Int, let, name "item"
+  %global = begin_access [modify] [dynamic] [no_nested_conflict] %19 : $*Int
+  %46 = builtin "cmp_eq_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %47 = builtin "int_expect_Int1"(%46 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
+  cond_br %47, bbend1, bbend2
+  
+bbend1:
+  store %43 to %global : $*Int
+  end_access %global : $*Int
+  cond_br %47, bb6, bb5
+  
+bbend2:
+  %otherInt = struct $Int (%27 : $Builtin.Int64)
+  store %otherInt to %global : $*Int
+  end_access %global : $*Int
+  cond_br %47, bb6, bb5
+
+bb5:
+  br bb4(%29 : $Builtin.Int64)
+
+bb6:
+  br bbRet
+  
+bbRet:
+  %25 = tuple ()
+  return %25 : $()
+} // end sil function 'multi_end_licm'
+
+// CHECK-LABEL: sil hidden @multi_end_licm_loop_exit : $@convention(thin) () -> () {
+// CHECK: br [[LOOPH:bb[0-9]+]]({{.*}} : $Builtin.Int64)
+// CHECK: [[LOOPH]]({{.*}} : $Builtin.Int64)
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict]
+// CHECK: cond_br {{.*}}, [[LOOPCOND1:bb[0-9]+]], [[LOOPCOND2:bb[0-9]+]]
+// CHECK: [[LOOPCOND1]]
+// CHECK-NEXT: store
+// CHECK-NEXT: end_access
+// CHECK: return
+sil hidden @multi_end_licm_loop_exit : $@convention(thin) () -> () {
+bb0:
+  %0 = global_addr @$S3tmp13reversedArrays18ReversedCollectionVySaySiGGvp : $*ReversedCollection<Array<Int>>
+  %1 = struct_element_addr %0 : $*ReversedCollection<Array<Int>>, #ReversedCollection._base
+  %2 = struct_element_addr %1 : $*Array<Int>, #Array._buffer
+  %3 = struct_element_addr %2 : $*_ArrayBuffer<Int>, #_ArrayBuffer._storage
+  %4 = struct_element_addr %3 : $*_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCore>, #_BridgeStorage.rawValue
+  %5 = load %4 : $*Builtin.BridgeObject
+  %6 = unchecked_ref_cast %5 : $Builtin.BridgeObject to $_ContiguousArrayStorageBase
+  %7 = ref_element_addr %6 : $_ContiguousArrayStorageBase, #_ContiguousArrayStorageBase.countAndCapacity
+  %8 = struct_element_addr %7 : $*_ArrayBody, #_ArrayBody._storage
+  %9 = struct_element_addr %8 : $*_SwiftArrayBodyStorage, #_SwiftArrayBodyStorage.count
+  %10 = struct_element_addr %9 : $*Int, #Int._value
+  %11 = load %10 : $*Builtin.Int64
+  %12 = builtin "assumeNonNegative_Int64"(%11 : $Builtin.Int64) : $Builtin.Int64
+  %13 = integer_literal $Builtin.Int64, 0
+  %14 = integer_literal $Builtin.Int1, 0
+  %15 = builtin "cmp_eq_Int64"(%12 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %16 = builtin "int_expect_Int1"(%15 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
+  cond_br %16, bb1, bb2
+
+bb1:
+  br bbRet
+
+bb2:
+  %19 = global_addr @$S3tmp1xSivp : $*Int
+  %20 = integer_literal $Builtin.Int64, 1
+  %21 = integer_literal $Builtin.Int1, -1
+  %23 = ref_tail_addr %6 : $_ContiguousArrayStorageBase, $Int
+  br bb4(%12 : $Builtin.Int64)
+
+bb4(%27 : $Builtin.Int64):
+  %28 = builtin "ssub_with_overflow_Int64"(%27 : $Builtin.Int64, %20 : $Builtin.Int64, %21 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
+  %29 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 0
+  %30 = tuple_extract %28 : $(Builtin.Int64, Builtin.Int1), 1
+  cond_fail %30 : $Builtin.Int1
+  %32 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %33 = load %10 : $*Builtin.Int64
+  %34 = builtin "assumeNonNegative_Int64"(%33 : $Builtin.Int64) : $Builtin.Int64 
+  %35 = builtin "cmp_slt_Int64"(%29 : $Builtin.Int64, %34 : $Builtin.Int64) : $Builtin.Int1
+  %36 = builtin "xor_Int1"(%35 : $Builtin.Int1, %21 : $Builtin.Int1) : $Builtin.Int1
+  %37 = builtin "or_Int1"(%32 : $Builtin.Int1, %36 : $Builtin.Int1) : $Builtin.Int1
+  cond_fail %37 : $Builtin.Int1
+  %39 = builtin "truncOrBitCast_Int64_Word"(%29 : $Builtin.Int64) : $Builtin.Word
+  %40 = index_addr %23 : $*Int, %39 : $Builtin.Word
+  %41 = struct_element_addr %40 : $*Int, #Int._value
+  %42 = load %41 : $*Builtin.Int64
+  %43 = struct $Int (%42 : $Builtin.Int64)
+  debug_value %43 : $Int, let, name "item"
+  %global = begin_access [modify] [dynamic] [no_nested_conflict] %19 : $*Int
+  %46 = builtin "cmp_eq_Int64"(%29 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %47 = builtin "int_expect_Int1"(%46 : $Builtin.Int1, %14 : $Builtin.Int1) : $Builtin.Int1
+  cond_br %47, bbend1, bbend2
+  
+bbend1:
+  store %43 to %global : $*Int
+  end_access %global : $*Int
+  cond_br %47, bb6, bb5
+  
+bbend2:
+  %otherInt = struct $Int (%27 : $Builtin.Int64)
+  store %otherInt to %global : $*Int
+  cond_br %47, bbOut, bb5
+
+bbOut:
+  end_access %global : $*Int
+  br bb6
+
+bb5:
+  br bb4(%29 : $Builtin.Int64)
+
+bb6:
+  br bbRet
+  
+bbRet:
+  %25 = tuple ()
+  return %25 : $()
+} // end sil function 'multi_end_licm_loop_exit'
diff --git a/test/SILOptimizer/ownership_model_eliminator.sil b/test/SILOptimizer/ownership_model_eliminator.sil
index acd3d16..6b226c6 100644
--- a/test/SILOptimizer/ownership_model_eliminator.sil
+++ b/test/SILOptimizer/ownership_model_eliminator.sil
@@ -114,11 +114,12 @@
   return %9999 : $()
 }
 
+// We no longer lower copy_unowned_value. So make sure that we actually don't.
+//
 // CHECK-LABEL: sil @copy_unowned_value_test : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> () {
 // CHECK: bb0([[ARG:%.*]] : $@sil_unowned Builtin.NativeObject):
-// CHECK-NEXT: strong_retain_unowned [[ARG]] : $@sil_unowned Builtin.NativeObject
-// CHECK-NEXT: [[OWNED_ARG:%.*]] = unowned_to_ref [[ARG]] : $@sil_unowned Builtin.NativeObject to $Builtin.NativeObject
-// CHECK-NEXT: strong_release [[OWNED_ARG]] : $Builtin.NativeObject
+// CHECK-NEXT: [[STRONG:%.*]] = copy_unowned_value [[ARG]] : $@sil_unowned Builtin.NativeObject
+// CHECK-NEXT: strong_release [[STRONG]] : $Builtin.NativeObject
 // CHECK-NEXT: unowned_release [[ARG]] : $@sil_unowned Builtin.NativeObject
 // CHECK-NEXT: tuple ()
 // CHECK-NEXT: return
diff --git a/test/SILOptimizer/predictable_memopt.sil b/test/SILOptimizer/predictable_memopt.sil
index 715ab3c..4bf5838 100644
--- a/test/SILOptimizer/predictable_memopt.sil
+++ b/test/SILOptimizer/predictable_memopt.sil
@@ -881,3 +881,23 @@
   dealloc_stack %0 : $*SWithOpt
   return %4 : $SWithOpt
 }
+
+// We do not support this now, so make sure we do not do anything.
+//
+// CHECK-LABEL: sil @promote_init_enum_data_addr : $@convention(thin)
+// CHECK: alloc_stack
+// CHECK: load
+// CHECK: [[RESULT:%.*]] = load
+// CHECK: return [[RESULT]]
+// CHECK: } // end sil function 'promote_init_enum_data_addr'
+sil @promote_init_enum_data_addr : $@convention(thin) (@in Int) -> Int {
+bb0(%0 : $*Int):
+  %1 = alloc_stack $Optional<Int>
+  %2 = load %0 : $*Int
+  %3 = init_enum_data_addr %1 : $*Optional<Int>, #Optional.some!enumelt.1
+  store %2 to %3 : $*Int
+  inject_enum_addr %1 : $*Optional<Int>, #Optional.some!enumelt.1
+  %4 = load %3 : $*Int
+  dealloc_stack %1 : $*Optional<Int>
+  return %4 : $Int
+}
diff --git a/test/SILOptimizer/sil_combine_concrete_existential.sil b/test/SILOptimizer/sil_combine_concrete_existential.sil
new file mode 100644
index 0000000..38f73f7
--- /dev/null
+++ b/test/SILOptimizer/sil_combine_concrete_existential.sil
@@ -0,0 +1,372 @@
+// RUN: %target-sil-opt -enable-objc-interop -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -sil-combine | %FileCheck %s
+
+// These tests exercise the same SILCombine optimization as
+// existential_type_propagation.sil, but cover additional corner
+// cases. These are pure unit tests. They do not run the devirtualizer
+// or inliner.
+
+sil_stage canonical
+
+import Builtin
+import Swift
+import SwiftShims
+
+//===----------------------------------------------------------------------===//
+// testReturnSelf: Call to a protocol extension method with
+// an existential self that can be type-propagated.
+// SILCombine should bailout since it does not propagate
+// type substitutions on the return value.
+//
+// <rdar://40555427> [SR-7773]:
+// SILCombiner::propagateConcreteTypeOfInitExistential fails to full propagate
+// type substitutions.
+//===----------------------------------------------------------------------===//
+public protocol P : AnyObject {
+}
+
+extension P {
+  public func returnSelf() -> Self
+}
+
+final class C : P {
+  init()
+  deinit
+}
+
+public func testReturnSelf() -> P
+
+// P.returnSelf()
+sil @$S21extension_return_self1PPAAE0B4SelfxyF : $@convention(method) <Self where Self : P> (@guaranteed Self) -> @owned Self
+
+// C.__allocating_init()
+sil @$S21extension_return_self1CCACycfC : $@convention(method) (@thick C.Type) -> @owned C
+
+// public func testReturnSelf() -> P {
+//   let p: P = C()
+//   return p.returnSelf().returnSelf()
+// }
+// Neither apply responds to type propagation.
+//
+// CHECK-LABEL: sil @$S21extension_return_self14testReturnSelfAA1P_pyF : $@convention(thin) () -> @owned P {
+// CHECK: [[E1:%.*]] = init_existential_ref %{{.*}} : $C : $C, $P
+// CHECK: [[O1:%.*]] = open_existential_ref [[E1]] : $P to $@opened("{{.*}}") P
+// CHECK: [[F1:%.*]] = function_ref @$S21extension_return_self1PPAAE0B4SelfxyF : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK: [[C1:%.*]] = apply [[F1]]<@opened("{{.*}}") P>([[O1]]) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK: [[E2:%.*]] = init_existential_ref [[C1]] : $@opened("{{.*}}") P : $@opened("{{.*}}") P, $P
+// CHECK: [[O2:%.*]] = open_existential_ref [[E2]] : $P to $@opened("{{.*}}") P
+// CHECK: [[F2:%.*]] = function_ref @$S21extension_return_self1PPAAE0B4SelfxyF : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK: apply [[F2]]<@opened("{{.*}}") P>([[O2]]) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK-LABEL: } // end sil function '$S21extension_return_self14testReturnSelfAA1P_pyF'
+sil @$S21extension_return_self14testReturnSelfAA1P_pyF : $@convention(thin) () -> @owned P {
+bb0:
+  %0 = metatype $@thick C.Type
+  // function_ref C.__allocating_init()
+  %1 = function_ref @$S21extension_return_self1CCACycfC : $@convention(method) (@thick C.Type) -> @owned C
+  %2 = apply %1(%0) : $@convention(method) (@thick C.Type) -> @owned C
+  %3 = init_existential_ref %2 : $C : $C, $P
+  %5 = open_existential_ref %3 : $P to $@opened("1217498E-72AC-11E8-9816-ACDE48001122") P
+  // function_ref P.returnSelf()
+  %6 = function_ref @$S21extension_return_self1PPAAE0B4SelfxyF : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+  %7 = apply %6<@opened("1217498E-72AC-11E8-9816-ACDE48001122") P>(%5) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+  %8 = init_existential_ref %7 : $@opened("1217498E-72AC-11E8-9816-ACDE48001122") P : $@opened("1217498E-72AC-11E8-9816-ACDE48001122") P, $P
+  %9 = open_existential_ref %8 : $P to $@opened("12174BD2-72AC-11E8-9816-ACDE48001122") P
+  // function_ref P.returnSelf()
+  %10 = function_ref @$S21extension_return_self1PPAAE0B4SelfxyF : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+  %11 = apply %10<@opened("12174BD2-72AC-11E8-9816-ACDE48001122") P>(%9) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+  %12 = init_existential_ref %11 : $@opened("12174BD2-72AC-11E8-9816-ACDE48001122") P : $@opened("12174BD2-72AC-11E8-9816-ACDE48001122") P, $P
+  strong_release %9 : $@opened("12174BD2-72AC-11E8-9816-ACDE48001122") P
+  strong_release %3 : $P
+  return %12 : $P
+}
+
+//===----------------------------------------------------------------------===//
+// testWitnessReturnOptionalSelf: Call to a witness method with an existential
+// self that can be type-propagated. SILCombine should bailout since it does
+// not propagate type substitutions on the return value, and it must walk the
+// Optional type to find Self in the return type.
+//===----------------------------------------------------------------------===//
+public protocol PP : AnyObject {
+  func returnOptionalSelf() -> Self?
+}
+
+final class CC : PP {
+  init()
+  final func returnOptionalSelf() -> Self?
+  deinit
+}
+
+public func testWitnessReturnOptionalSelf() -> PP?
+
+// CC.__allocating_init()
+sil @$S28witness_return_optional_self2CCCACycfC : $@convention(method) (@thick CC.Type) -> @owned CC
+
+// public func testWitnessReturnOptionalSelf() -> PP? {
+//   let p: PP = CC()
+//   return p.returnOptionalSelf()?.returnOptionalSelf()
+// }
+//
+// Although SILCombine will not replace the self operand, it will still
+// rewrite the witness_method.
+//
+// The first witness_method is rewritten for the concrete lookup type 'CC'.
+//
+// The second witness_method is rewritten for the first opened existential type.
+// Neither apply is rewritten.
+//
+// CHECK-LABEL: sil @$S28witness_return_optional_self29testWitnessReturnOptionalSelfAA2PP_pSgyF : $@convention(thin) () -> @owned Optional<PP> {
+// CHECK: [[E1:%.*]] = init_existential_ref %{{.*}} : $CC : $CC, $PP
+// CHECK: [[O1:%.*]] = open_existential_ref [[E1]] : $PP to $@opened("{{.*}}") PP
+// CHECK: [[W1:%.*]] = witness_method $CC, #PP.returnOptionalSelf!1 : <Self where Self : PP> (Self) -> () -> @dynamic_self Self? : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+// CHECK: apply [[W1]]<@opened("{{.*}}") PP>([[O1]]) : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+// CHECK: [[E2:%.*]] = init_existential_ref %{{.*}} : $@opened("{{.*}}") PP : $@opened("{{.*}}") PP, $PP
+// CHECK: [[O2:%.*]] = open_existential_ref [[E2]] : $PP to $@opened("{{.*}}") PP
+// CHECK: [[W2:%.*]] = witness_method $@opened("{{.*}}") PP, #PP.returnOptionalSelf!1 : <Self where Self : PP> (Self) -> () -> @dynamic_self Self?, [[O1]] : $@opened("{{.*}}") PP : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+// CHECK: apply [[W2]]<@opened("{{.*}}") PP>([[O2]]) : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+// CHECK-LABEL: } // end sil function '$S28witness_return_optional_self29testWitnessReturnOptionalSelfAA2PP_pSgyF'
+sil @$S28witness_return_optional_self29testWitnessReturnOptionalSelfAA2PP_pSgyF : $@convention(thin) () -> @owned Optional<PP> {
+bb0:
+  %0 = metatype $@thick CC.Type
+  // function_ref CC.__allocating_init()
+  %1 = function_ref @$S28witness_return_optional_self2CCCACycfC : $@convention(method) (@thick CC.Type) -> @owned CC
+  %2 = apply %1(%0) : $@convention(method) (@thick CC.Type) -> @owned CC
+  %3 = init_existential_ref %2 : $CC : $CC, $PP
+  %5 = open_existential_ref %3 : $PP to $@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP
+  %6 = witness_method $@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP, #PP.returnOptionalSelf!1 : <Self where Self : PP> (Self) -> () -> @dynamic_self Self?, %5 : $@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+  %7 = apply %6<@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP>(%5) : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+  %8 = unchecked_enum_data %7 : $Optional<@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP>, #Optional.some!enumelt.1
+  %11 = init_existential_ref %8 : $@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP : $@opened("00000000-72AD-11E8-88DF-ACDE48001122") PP, $PP
+  %12 = enum $Optional<PP>, #Optional.some!enumelt.1, %11 : $PP
+  %13 = unchecked_enum_data %12 : $Optional<PP>, #Optional.some!enumelt.1
+  %18 = open_existential_ref %13 : $PP to $@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP
+  %19 = witness_method $@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP, #PP.returnOptionalSelf!1 : <Self where Self : PP> (Self) -> () -> @dynamic_self Self?, %18 : $@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+  %20 = apply %19<@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP>(%18) : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+  %21 = unchecked_enum_data %20 : $Optional<@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP>, #Optional.some!enumelt.1
+  %22 = init_existential_ref %21 : $@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP : $@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP, $PP
+  %23 = enum $Optional<PP>, #Optional.some!enumelt.1, %22 : $PP
+  strong_release %18 : $@opened("FFFFFFFF-72AD-11E8-88DF-ACDE48001122") PP
+  strong_release %3 : $PP
+  return %23 : $Optional<PP>
+}
+
+//===----------------------------------------------------------------------===//
+// testWitnessReturnOptionalIndirectSelf: Call to a witness method with an
+// existential self that can be type-propagated. SILCombine should bailout
+// since it does not propagate type substitutions on non-self arguments. It must
+// walk the Optional type to find Self in the non-self argument.
+//===----------------------------------------------------------------------===//
+protocol PPP {
+  func returnsOptionalIndirect() -> Self?
+}
+
+struct S : PPP {
+  func returnsOptionalIndirect() -> S?
+  init()
+}
+
+public func testWitnessReturnOptionalIndirectSelf()
+
+// S.init()
+sil @$S37witness_return_optional_indirect_self1SVACycfC : $@convention(method) (@thin S.Type) -> S
+
+// testWitnessReturnOptionalIndirectSelf()
+// public func testWitnessReturnOptionalIndirectSelf() {
+//   let p: PPP = S()
+//   p.returnsOptionalIndirect()?.returnsOptionalIndirect()
+// }
+//
+// Although SILCombine will not replace the self operand, it will still
+// rewrite the witness_method. The devirtualizer could then handle the first call.
+//
+// CHECK-LABEL: sil @$S37witness_return_optional_indirect_self37testWitnessReturnOptionalIndirectSelfyyF : $@convention(thin) () -> () {
+// CHECK: [[O1:%.*]] = open_existential_addr immutable_access %0 : $*PPP to $*@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP
+// CHECK: [[R1:%.*]] = alloc_stack $Optional<@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP>
+// CHECK: [[W1:%.*]] = witness_method $S, #PPP.returnsOptionalIndirect!1 : <Self where Self : PPP> (Self) -> () -> @dynamic_self Self? : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+// CHECK: apply [[W1]]<@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP>([[R1]], [[O1]]) : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+// CHECK: inject_enum_addr [[OE1:%.*]] : $*Optional<PPP>, #Optional.some!enumelt.1
+// CHECK: [[E1:%.*]] = unchecked_take_enum_data_addr [[OE1]] : $*Optional<PPP>, #Optional.some!enumelt.1
+// CHECK: [[O2:%.*]] = open_existential_addr immutable_access [[E1]] : $*PPP to $*@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP
+// CHECK: [[R2:%.*]] = alloc_stack $Optional<@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP>
+// CHECK: [[W2:%.*]] = witness_method $@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP, #PPP.returnsOptionalIndirect!1 : <Self where Self : PPP> (Self) -> () -> @dynamic_self Self?, %19 : $*@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+// CHECK: apply [[W2]]<@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP>([[R2]], [[O2]]) : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+// CHECK-LABEL: } // end sil function '$S37witness_return_optional_indirect_self37testWitnessReturnOptionalIndirectSelfyyF'
+sil @$S37witness_return_optional_indirect_self37testWitnessReturnOptionalIndirectSelfyyF : $@convention(thin) () -> () {
+bb0:
+  %0 = alloc_stack $PPP, let, name "p"
+  %1 = init_existential_addr %0 : $*PPP, $S
+  %2 = metatype $@thin S.Type
+  // function_ref S.init()
+  %3 = function_ref @$S37witness_return_optional_indirect_self1SVACycfC : $@convention(method) (@thin S.Type) -> S
+  %4 = apply %3(%2) : $@convention(method) (@thin S.Type) -> S
+  store %4 to %1 : $*S
+  %6 = alloc_stack $Optional<PPP>
+  %7 = alloc_stack $Optional<PPP>
+  %8 = open_existential_addr immutable_access %0 : $*PPP to $*@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP
+  %9 = init_enum_data_addr %7 : $*Optional<PPP>, #Optional.some!enumelt.1
+  %10 = init_existential_addr %9 : $*PPP, $@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP
+  %11 = alloc_stack $Optional<@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP>
+  %12 = witness_method $@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP, #PPP.returnsOptionalIndirect!1 : <Self where Self : PPP> (Self) -> () -> @dynamic_self Self?, %8 : $*@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+  %13 = apply %12<@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP>(%11, %8) : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+  %14 = unchecked_take_enum_data_addr %11 : $*Optional<@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP>, #Optional.some!enumelt.1
+  copy_addr [take] %14 to [initialization] %10 : $*@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP
+  inject_enum_addr %7 : $*Optional<PPP>, #Optional.some!enumelt.1
+  dealloc_stack %11 : $*Optional<@opened("83DE9694-7315-11E8-955C-ACDE48001122") PPP>
+  %28 = unchecked_take_enum_data_addr %7 : $*Optional<PPP>, #Optional.some!enumelt.1
+  %29 = open_existential_addr immutable_access %28 : $*PPP to $*@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP
+  %30 = init_enum_data_addr %6 : $*Optional<PPP>, #Optional.some!enumelt.1
+  %31 = init_existential_addr %30 : $*PPP, $@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP
+  %32 = alloc_stack $Optional<@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP>
+  %33 = witness_method $@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP, #PPP.returnsOptionalIndirect!1 : <Self where Self : PPP> (Self) -> () -> @dynamic_self Self?, %29 : $*@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+  %34 = apply %33<@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP>(%32, %29) : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+  %41 = unchecked_take_enum_data_addr %32 : $*Optional<@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP>, #Optional.some!enumelt.1
+  copy_addr [take] %41 to [initialization] %31 : $*@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP
+  inject_enum_addr %6 : $*Optional<PPP>, #Optional.some!enumelt.1
+  dealloc_stack %32 : $*Optional<@opened("83DE97CA-7315-11E8-955C-ACDE48001122") PPP>
+  destroy_addr %28 : $*PPP
+  dealloc_stack %7 : $*Optional<PPP>
+  destroy_addr %6 : $*Optional<PPP>
+  dealloc_stack %6 : $*Optional<PPP>
+  destroy_addr %0 : $*PPP
+  dealloc_stack %0 : $*PPP
+  %52 = tuple ()
+  return %52 : $()
+}
+
+
+// ===----------------------------------------------------------------------===//
+// testOptionalSelfArg: Call a protocol extension method with an
+// existential self that can be type-propagated. SILCombine should
+// bailout since it does not know how to rewrite non-self operands.
+// SILCombine would previously generate incorrect SIL because it did
+// not properly walk all types in the function signature to find
+// dependencies on the Self type.
+// ===----------------------------------------------------------------------===//
+protocol PPPP {}
+
+extension PPPP {
+  func takeOptionalSelf(_ s: Self?)
+}
+
+class CCCC : PPPP {
+  init()
+  deinit
+}
+
+sil [noinline] @takeOptionalSelf : $@convention(method) <Self where Self : PPPP> (@in_guaranteed Optional<Self>, @in_guaranteed Self) -> ()
+
+// CHECK-LABEL: sil @testOptionalSelfArg : $@convention(thin) (@guaranteed CCCC) -> () {
+// CHECK: init_existential_addr [[A:%.*]] : $*PPPP, $CCCC   // user: %4
+// CHECK: [[OE:%.*]] = open_existential_addr immutable_access [[A]] : $*PPPP to $*@opened("{{.*}}") PPPP // users: %11, %11, %8, %6
+// CHECK: [[F:%.*]] = function_ref @takeOptionalSelf : $@convention(method) <τ_0_0 where τ_0_0 : PPPP> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed τ_0_0) -> () // user: %11
+// CHECK: apply [[F]]<@opened("{{.*}}") PPPP>(%{{.*}}, [[OE]]) : $@convention(method) <τ_0_0 where τ_0_0 : PPPP> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed τ_0_0) -> () // type-defs: %5
+// CHECK-LABEL: } // end sil function 'testOptionalSelfArg'
+sil @testOptionalSelfArg : $@convention(thin) (@guaranteed CCCC) -> () {
+bb0(%0 : $CCCC):
+  strong_retain %0 : $CCCC
+
+  %pa = alloc_stack $PPPP, let, name "p"
+  %ea = init_existential_addr %pa : $*PPPP, $CCCC
+  store %0 to %ea : $*CCCC  
+  %oe = open_existential_addr immutable_access %pa : $*PPPP to $*@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP
+
+  %optional = alloc_stack $Optional<@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP>
+  %someadr = init_enum_data_addr %optional : $*Optional<@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP>, #Optional.some!enumelt.1
+  copy_addr %oe to [initialization] %someadr : $*@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP
+  inject_enum_addr %optional : $*Optional<@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP>, #Optional.some!enumelt.1
+
+  %f = function_ref @takeOptionalSelf : $@convention(method) <τ_0_0 where τ_0_0 : PPPP> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed τ_0_0) -> ()
+  %call = apply %f<@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP>(%optional, %oe) : $@convention(method) <τ_0_0 where τ_0_0 : PPPP> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed τ_0_0) -> ()
+
+  destroy_addr %optional : $*Optional<@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP>
+  dealloc_stack %optional : $*Optional<@opened("A6DDDAF6-70BD-11E8-ADF1-ACDE48001122") PPPP>
+
+  destroy_addr %pa : $*PPPP
+  dealloc_stack %pa : $*PPPP
+  %10 = tuple ()
+  return %10 : $()
+}
+
+//===----------------------------------------------------------------------===//
+// testExtensionProtocolComposition: Call to a witness method with an
+// existential self that can be type-propagated. Handle an existential with
+// multiple conformances.
+//
+// This previously crashed in SILCombiner::propagateConcreteTypeOfInitExistential
+// with assertion failed: (proto == Conformance.getRequirement()).
+// ===----------------------------------------------------------------------===//
+public protocol Q {}
+
+extension P where Self : Q {
+  public func witnessComposition() {}
+}
+  
+public class C_PQ: P & Q {}
+
+// P<>.witnessComposition()
+sil @$S32sil_combine_concrete_existential1PPA2A1QRzrlE18witnessCompositionyyF : $@convention(method) <τ_0_0 where τ_0_0 : P, τ_0_0 : Q> (@guaranteed τ_0_0) -> ()
+
+// testExtensionProtocolComposition(c:)
+// public func testExtensionProtocolComposition(c: C_PQ) {
+//   let pp: P & Q = c
+//   pp.witnessComposition()
+// }
+//
+// SILCombine substitutes the applies opened existention parameter with a concrete type <C : P & Q>
+// CHECK-LABEL: sil @$S32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF : $@convention(thin) (@guaranteed C_PQ) -> () {
+// CHECK-NOT: init_existential_ref
+// CHECK-NOT: open_existential_ref
+// function_ref P<>.witnessComposition()
+// CHECK: [[F:%.*]] = function_ref @$S32sil_combine_concrete_existential1PPA2A1QRzrlE18witnessCompositionyyF : $@convention(method) <τ_0_0 where τ_0_0 : P, τ_0_0 : Q> (@guaranteed τ_0_0) -> ()
+// CHECK: apply [[F]]<C_PQ>(%0) : $@convention(method) <τ_0_0 where τ_0_0 : P, τ_0_0 : Q> (@guaranteed τ_0_0) -> ()
+// CHECK-LABEL: } // end sil function '$S32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF'
+sil @$S32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF : $@convention(thin) (@guaranteed C_PQ) -> () {
+bb0(%0 : $C_PQ):
+  strong_retain %0 : $C_PQ
+  %3 = init_existential_ref %0 : $C_PQ : $C_PQ, $P & Q
+  %5 = open_existential_ref %3 : $P & Q to $@opened("044D530E-7327-11E8-A998-ACDE48001122") P & Q
+  // function_ref P<>.witnessComposition()
+  %6 = function_ref @$S32sil_combine_concrete_existential1PPA2A1QRzrlE18witnessCompositionyyF : $@convention(method) <τ_0_0 where τ_0_0 : P, τ_0_0 : Q> (@guaranteed τ_0_0) -> ()
+  %7 = apply %6<@opened("044D530E-7327-11E8-A998-ACDE48001122") P & Q>(%5) : $@convention(method) <τ_0_0 where τ_0_0 : P, τ_0_0 : Q> (@guaranteed τ_0_0) -> ()
+  strong_release %3 : $P & Q
+  %9 = tuple ()
+  return %9 : $()
+}
+
+// ===----------------------------------------------------------------------===//
+// testDefaultStaticMethod: Test concrete type propagation into a direct
+// apply of a default witness method.
+// ===----------------------------------------------------------------------===//
+public protocol PDefaultStatic: class {
+  static func witnessDefaultStatic()
+}
+
+extension PDefaultStatic {
+  @inline(never)
+  public static func witnessDefaultStatic() {}
+}
+
+public class CDefaultStatic : PDefaultStatic {}
+
+public func callDefaultStatic() {
+  return CDefaultStatic.witnessDefaultStatic()
+}
+
+// static P<>.witnessDefaultStatic(_:)
+sil @witnessDefaultStatic : $@convention(method) <Self where Self : PDefaultStatic> (@thick Self.Type) -> ()
+
+// CHECK-LABEL: sil @testDefaultStaticMethod : $@convention(thin) () -> () {
+// CHECK: %0 = metatype $@thick CDefaultStatic.Type
+// CHECK-NOT: init_existential_metatype
+// CHECK-NOT: open_existential_metatype
+// CHECK: [[F:%.*]] = function_ref @witnessDefaultStatic : $@convention(method) <τ_0_0 where τ_0_0 : PDefaultStatic> (@thick τ_0_0.Type) -> ()
+// CHECK: apply [[F]]<CDefaultStatic>(%0) : $@convention(method) <τ_0_0 where τ_0_0 : PDefaultStatic> (@thick τ_0_0.Type) -> ()
+// CHECK-LABEL: } // end sil function 'testDefaultStaticMethod'
+sil @testDefaultStaticMethod : $@convention(thin) () -> () {
+bb0:
+  %mt = metatype $@thick CDefaultStatic.Type
+  %em = init_existential_metatype %mt : $@thick CDefaultStatic.Type, $@thick PDefaultStatic.Type
+  %om = open_existential_metatype %em : $@thick PDefaultStatic.Type to $@thick (@opened("22222222-72AC-11E8-9816-ACDE48001122") PDefaultStatic).Type
+  %f = function_ref @witnessDefaultStatic : $@convention(method) <Self where Self : PDefaultStatic> (@thick Self.Type) -> ()
+  %call = apply %f<@opened("22222222-72AC-11E8-9816-ACDE48001122") PDefaultStatic>(%om) : $@convention(method) <Self where Self : PDefaultStatic> (@thick Self.Type) -> ()
+  %v = tuple ()
+  return %v : $()
+}
diff --git a/test/SILOptimizer/sil_combine_concrete_existential.swift b/test/SILOptimizer/sil_combine_concrete_existential.swift
new file mode 100644
index 0000000..7824574
--- /dev/null
+++ b/test/SILOptimizer/sil_combine_concrete_existential.swift
@@ -0,0 +1,126 @@
+// RUN: %target-swift-frontend -O -emit-sil -sil-verify-all -Xllvm -sil-disable-pass=function-signature-opts %s | %FileCheck %s
+
+//===----------------------------------------------------------------------===//
+// testReturnSelf: Call to a protocol extension method with
+// an existential self that can be type-propagated.
+// sil-combine should bailout since it does not propagate
+// type substitutions on the return value.
+//
+// <rdar://40555427> [SR-7773]:
+// SILCombiner::propagateConcreteTypeOfInitExistential fails to full propagate
+// type substitutions.
+//===----------------------------------------------------------------------===//
+public protocol P: class {}
+
+extension P {
+  public func returnSelf() -> Self {
+    return self
+  }
+}
+
+final class C: P {}
+// CHECK-LABEL: sil @$S32sil_combine_concrete_existential14testReturnSelfAA1P_pyF : $@convention(thin) () -> @owned P {
+// CHECK: [[E1:%.*]] = init_existential_ref %0 : $C : $C, $P
+// CHECK: [[O1:%.*]] = open_existential_ref [[E1]] : $P to $@opened("{{.*}}") P
+// CHECK: [[F1:%.*]] = function_ref @$S32sil_combine_concrete_existential1PPAAE10returnSelfxyF : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK: [[C1:%.*]] = apply [[F1]]<@opened("{{.*}}") P>([[O1]]) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK: [[E2:%.*]] = init_existential_ref [[C1]] : $@opened("{{.*}}") P : $@opened("{{.*}}") P, $P
+// CHECK: [[O2:%.*]] = open_existential_ref [[E2]] : $P to $@opened("{{.*}}") P
+// CHECK: apply [[F1]]<@opened("{{.*}}") P>([[O2]]) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed τ_0_0) -> @owned τ_0_0
+// CHECK-LABEL: } // end sil function '$S32sil_combine_concrete_existential14testReturnSelfAA1P_pyF'
+public func testReturnSelf() -> P {
+  let p: P = C()
+  return p.returnSelf().returnSelf()
+}
+
+//===----------------------------------------------------------------------===//
+// testWitnessReturnOptionalSelf: Call to a witness method with an existential
+// self that can be type-propagated. sil-combine should bailout since it does
+// not propagate type substitutions on the return value, and it must walk the
+// Optional type to find Self in the return type.
+//
+// Although sil-combine will not replace the self operand, it will still
+// rewrite the witness_method. The devirtualizer then handles the first call.
+//===----------------------------------------------------------------------===//
+public protocol PP: class {
+  func returnOptionalSelf() -> Self?
+}
+
+final class CC: PP {
+  init() {}
+  func returnOptionalSelf() -> Self? {
+    return self
+  }
+}
+
+// The first apply has been devirtualized and inlined. The second remains unspecialized.
+// CHECK-LABEL: sil @$S32sil_combine_concrete_existential29testWitnessReturnOptionalSelfAA2PP_pSgyF : $@convention(thin) () -> @owned Optional<PP> {
+// CHECK: [[E1:%.*]] = init_existential_ref %0 : $CC : $CC, $PP
+// CHECK: [[O1:%.*]] = open_existential_ref [[E1]] : $PP to $@opened("{{.*}}") PP
+// CHECK: [[E2:%.*]] = init_existential_ref %{{.*}} : $@opened("{{.*}}") PP : $@opened("{{.*}}") PP, $PP
+// CHECK: [[O2:%.*]] = open_existential_ref [[E2]] : $PP to $@opened("{{.*}}") PP
+// CHECK: [[W:%.*]] = witness_method $@opened("{{.*}}") PP, #PP.returnOptionalSelf!1 : <Self where Self : PP> (Self) -> () -> @dynamic_self Self?, [[O1]] : $@opened("{{.*}}") PP : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+// CHECK: apply [[W]]<@opened("{{.*}}") PP>([[O2]]) : $@convention(witness_method: PP) <τ_0_0 where τ_0_0 : PP> (@guaranteed τ_0_0) -> @owned Optional<τ_0_0>
+// CHECK-LABEL: } // end sil function '$S32sil_combine_concrete_existential29testWitnessReturnOptionalSelfAA2PP_pSgyF'
+public func testWitnessReturnOptionalSelf() -> PP? {
+  let p: PP = CC()
+  return p.returnOptionalSelf()?.returnOptionalSelf()
+}
+
+//===----------------------------------------------------------------------===//
+// testWitnessReturnOptionalIndirectSelf: Call to a witness method with an
+// existential self that can be type-propagated. sil-combine should bailout
+// since it does not propagate type substitutions on non-self arguments. It must
+// walk the Optional type to find Self in the non-self argument.
+//
+// Although sil-combine will not replace the self operand, it will still
+// rewrite the witness_method. The devirtualizer then handles the first call.
+//===----------------------------------------------------------------------===//
+protocol PPP {
+  func returnsOptionalIndirect() -> Self?
+}
+
+struct S: PPP {
+  func returnsOptionalIndirect() -> S? {
+    return self
+  }
+}
+
+// The first apply has been devirtualized and inlined. The second remains unspecialized.
+// CHECK-LABEL: sil @$S32sil_combine_concrete_existential37testWitnessReturnOptionalIndirectSelfyyF : $@convention(thin) () -> () {
+// CHECK: switch_enum_addr %{{.*}} : $*Optional<@opened("{{.*}}") PPP>, case #Optional.some!enumelt.1: bb{{.*}}, case #Optional.none!enumelt: bb{{.*}}
+// CHECK: [[O:%.*]] = open_existential_addr immutable_access %{{.*}} : $*PPP to $*@opened("{{.*}}") PPP
+// CHECK: [[W:%.*]] = witness_method $@opened("{{.*}}") PPP, #PPP.returnsOptionalIndirect!1 : <Self where Self : PPP> (Self) -> () -> @dynamic_self Self?, [[O]] : $*@opened("{{.*}}") PPP : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+// CHECK: apply [[W]]<@opened("{{.*}}") PPP>(%{{.*}}, [[O]]) : $@convention(witness_method: PPP) <τ_0_0 where τ_0_0 : PPP> (@in_guaranteed τ_0_0) -> @out Optional<τ_0_0>
+// CHECK-LABEL: } // end sil function '$S32sil_combine_concrete_existential37testWitnessReturnOptionalIndirectSelfyyF'
+public func testWitnessReturnOptionalIndirectSelf() {
+  let p: PPP = S()
+  p.returnsOptionalIndirect()?.returnsOptionalIndirect()
+}
+
+//===----------------------------------------------------------------------===//
+// testExtensionProtocolComposition: Call to a witness method with an
+// existential self that can be type-propagated. Handle an existential with
+// multiple conformances.
+//
+// Previously crashed with in SILCombiner::propagateConcreteTypeOfInitExistential
+// with assertion failed: (proto == Conformance.getRequirement()).
+// ===----------------------------------------------------------------------===//
+public protocol Q {}
+
+extension P where Self : Q {
+  public func witnessComposition() {}
+}
+  
+public class C_PQ: P & Q {}
+
+// testExtensionProtocolComposition(c:)
+// CHECK-LABEL: sil @$S32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF : $@convention(thin) (@guaranteed C_PQ) -> () {
+// CHECK-NOT: init_existential_ref
+// CHECK-NOT: function_ref
+// CHECK-NOT: apply
+// CHECK: } // end sil function '$S32sil_combine_concrete_existential32testExtensionProtocolComposition1cyAA4C_PQC_tF'
+public func testExtensionProtocolComposition(c: C_PQ) {
+  let pp: P & Q = c
+  pp.witnessComposition()
+}
diff --git a/test/Sema/diag_use_before_declaration.swift b/test/Sema/diag_use_before_declaration.swift
index c0fe982..2bbef02 100644
--- a/test/Sema/diag_use_before_declaration.swift
+++ b/test/Sema/diag_use_before_declaration.swift
@@ -15,8 +15,97 @@
 var foo: Int?
 
 func test() {
-  guard let bar = foo else { // expected-error {{use of local variable 'foo' before its declaration}}
+  guard let bar = foo else {
     return
   }
-  let foo = String(bar) // expected-note {{'foo' declared here}}
+  let foo = String(bar)
+}
+
+// SR-7660
+class C {
+  var variable: Int?
+  func f() {
+    guard let _ = variable else { return }
+    let variable = 1 // expected-warning {{initialization of immutable value 'variable' was never used; consider replacing with assignment to '_' or removing it}}
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Nested scope
+//===----------------------------------------------------------------------===//
+
+func nested_scope_1() {
+  do {
+    do {
+      let _ = x // expected-error {{use of local variable 'x' before its declaration}}
+      let x = 111 // expected-note {{'x' declared here}}
+    }
+    let x = 11
+  }
+  let x = 1
+}
+
+func nested_scope_2() {
+  do {
+    let x = 11
+    do {
+      let _ = x
+      let x = 111 // expected-warning {{initialization of immutable value 'x' was never used; consider replacing with assignment to '_' or removing it}}
+    }
+  }
+  let x = 1  // expected-warning {{initialization of immutable value 'x' was never used; consider replacing with assignment to '_' or removing it}}
+}
+
+func nested_scope_3() {
+  let x = 1
+  do {
+    do {
+      let _ = x
+      let x = 111 // expected-warning {{initialization of immutable value 'x' was never used; consider replacing with assignment to '_' or removing it}}
+    }
+    let x = 11 // expected-warning {{initialization of immutable value 'x' was never used; consider replacing with assignment to '_' or removing it}}
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Type scope
+//===----------------------------------------------------------------------===//
+
+class Ty {
+  var v : Int?
+
+  func fn() {
+    let _ = v
+    let v = 1 // expected-warning {{initialization of immutable value 'v' was never used; consider replacing with assignment to '_' or removing it}}
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// File scope
+//===----------------------------------------------------------------------===//
+
+let g = 0
+
+func file_scope_1() {
+  let _ = g
+  let g = 1 // expected-warning {{initialization of immutable value 'g' was never used; consider replacing with assignment to '_' or removing it}}
+}
+
+func file_scope_2() {
+  let _ = gg // expected-error {{use of local variable 'gg' before its declaration}}
+  let gg = 1 // expected-note {{'gg' declared here}}
+}
+
+//===----------------------------------------------------------------------===//
+// Module scope
+//===----------------------------------------------------------------------===//
+
+func module_scope_1() {
+  let _ = print // Legal use of func print declared in Swift Standard Library
+  let print = "something" // expected-warning {{initialization of immutable value 'print' was never used; consider replacing with assignment to '_' or removing it}}
+}
+
+func module_scope_2() {
+  let _ = another_print // expected-error {{use of local variable 'another_print' before its declaration}}
+  let another_print = "something" // expected-note {{'another_print' declared here}}
 }
diff --git a/test/Serialization/Inputs/def_func.swift b/test/Serialization/Inputs/def_func.swift
index de6fe09..8aa5791 100644
--- a/test/Serialization/Inputs/def_func.swift
+++ b/test/Serialization/Inputs/def_func.swift
@@ -30,7 +30,7 @@
   return a != b
 }
 
-public func different2<T where T : Equatable>(a: T, b: T) -> Bool {
+public func different2<T>(a: T, b: T) -> Bool where T : Equatable {
   return a != b
 }
 
@@ -45,9 +45,9 @@
 
 public func differentWrapped<
   T : Wrapped, U : Wrapped
-  where
-  T.Value == U.Value
->(a: T, b: U) -> Bool {
+>(a: T, b: U) -> Bool
+  where T.Value == U.Value
+{
   return a.getValue() != b.getValue()
 }
 
@@ -60,7 +60,7 @@
 @_silgen_name("primitive") public func primitive()
 
 public protocol EqualOperator {
-  func ==(x: Self, y: Self) -> Bool
+  static func ==(x: Self, y: Self) -> Bool
 }
 
 public func throws1() throws {}
diff --git a/test/Serialization/Inputs/def_objc.swift b/test/Serialization/Inputs/def_objc.swift
index 29c5b24..7d673a7 100644
--- a/test/Serialization/Inputs/def_objc.swift
+++ b/test/Serialization/Inputs/def_objc.swift
@@ -2,7 +2,7 @@
   func doSomething()
 }
 
-@objc public class ObjCClass {
+@objc @objcMembers public class ObjCClass {
   public dynamic class func classMethod() {}
   public dynamic func implicitlyObjC() {}
 
@@ -10,7 +10,7 @@
   @IBAction public func performAction(_: AnyObject?) {}
 }
 
-public class NonObjCClass : ObjCProto {
+@objcMembers public class NonObjCClass : ObjCProto {
   public dynamic func doSomething() {}
 
   dynamic public func objcMethod() {}
diff --git a/test/Serialization/Inputs/def_struct.swift b/test/Serialization/Inputs/def_struct.swift
index 73dbaa2..cfaaf6e 100644
--- a/test/Serialization/Inputs/def_struct.swift
+++ b/test/Serialization/Inputs/def_struct.swift
@@ -89,8 +89,8 @@
 
 public func cacheViaWrappers<
   T : HasAssociatedType, U : AnotherAssociated
-    where T.ComputableType == U.ResettableType
->(_ computable : T, _ resettable : U) {}
+>(_ computable : T, _ resettable : U)
+  where T.ComputableType == U.ResettableType {}
 
 
 // Subscripts
diff --git a/test/Serialization/Inputs/def_transparent_std.swift b/test/Serialization/Inputs/def_transparent_std.swift
index 2593af2..24a4c29 100644
--- a/test/Serialization/Inputs/def_transparent_std.swift
+++ b/test/Serialization/Inputs/def_transparent_std.swift
@@ -1,34 +1,34 @@
 public class C {}
 
-@_transparent public func foo(x x: Builtin.Int1, y: Builtin.Int1) -> Builtin.Int1 {
+@_transparent public func foo(x: Builtin.Int1, y: Builtin.Int1) -> Builtin.Int1 {
   return Builtin.cmp_eq_Int1(x, y)
 }
 
-@_transparent public func destroy_obj(x x: Builtin.RawPointer) {
-  return Builtin.destroy(Builtin.NativeObject, x)
+@_transparent public func destroy_obj(x: Builtin.RawPointer) {
+  return Builtin.destroy(Builtin.NativeObject.self, x)
 }
 
-@_transparent public func assign_tuple(x x: (Builtin.Int64, Builtin.NativeObject),
+@_transparent public func assign_tuple(x: (Builtin.Int64, Builtin.NativeObject),
                                y: Builtin.RawPointer) {
   Builtin.assign(x, y)
 }
 
-@_transparent public func class_to_native_object(c c: C) -> Builtin.NativeObject {
+@_transparent public func class_to_native_object(c: C) -> Builtin.NativeObject {
   return Builtin.castToNativeObject(c)
 }
 
-@_transparent public func class_from_native_object(p p: Builtin.NativeObject) -> C {
+@_transparent public func class_from_native_object(p: Builtin.NativeObject) -> C {
   return Builtin.castFromNativeObject(p)
 }
 
-@_transparent public func class_to_raw_pointer(c c: C) -> Builtin.RawPointer {
+@_transparent public func class_to_raw_pointer(c: C) -> Builtin.RawPointer {
   return Builtin.bridgeToRawPointer(c)
 }
 
-@_transparent public func class_from_raw_pointer(p p: Builtin.RawPointer) -> C {
+@_transparent public func class_from_raw_pointer(p: Builtin.RawPointer) -> C {
   return Builtin.bridgeFromRawPointer(p)
 }
 
-@_transparent public func gep32(p p: Builtin.RawPointer, i: Builtin.Int32) -> Builtin.RawPointer {
+@_transparent public func gep32(p: Builtin.RawPointer, i: Builtin.Int32) -> Builtin.RawPointer {
   return Builtin.gepRaw_Int32(p, i)
 }
diff --git a/test/Serialization/Inputs/has_generic_witness.swift b/test/Serialization/Inputs/has_generic_witness.swift
index ed16009..46ac25b 100644
--- a/test/Serialization/Inputs/has_generic_witness.swift
+++ b/test/Serialization/Inputs/has_generic_witness.swift
@@ -48,14 +48,14 @@
 }
 
 
-prefix operator ~~~ {}
+prefix operator ~~~
 
 public protocol _CyclicAssociated {
   associatedtype Assoc = CyclicImpl
 }
 
 public protocol CyclicAssociated : _CyclicAssociated {
-  prefix func ~~~(_: Self.Type)
+  static prefix func ~~~(_: Self.Type)
 }
 
 prefix public func ~~~ <T: _CyclicAssociated>(_: T.Type) {}
diff --git a/test/Serialization/Inputs/struct_with_operators.swift b/test/Serialization/Inputs/struct_with_operators.swift
index 1200a07..a796fdf 100644
--- a/test/Serialization/Inputs/struct_with_operators.swift
+++ b/test/Serialization/Inputs/struct_with_operators.swift
@@ -3,8 +3,8 @@
   public init() {}
 }
 
-prefix operator +++ {}
-postfix operator +++ {}
+prefix operator +++
+postfix operator +++
 
 prefix public func +++(base: inout SpecialInt) {
   base.value += 2
diff --git a/test/Serialization/class-roundtrip-module.swift b/test/Serialization/class-roundtrip-module.swift
index ebb441b..2868e07 100644
--- a/test/Serialization/class-roundtrip-module.swift
+++ b/test/Serialization/class-roundtrip-module.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -module-name def_class -o %t/stage1.swiftmodule %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop -swift-version 3
-// RUN: %target-swift-frontend -emit-module -parse-as-library -o %t/def_class.swiftmodule %t/stage1.swiftmodule -swift-version 3
-// RUN: %target-swift-frontend -emit-sil -sil-debug-serialization -I %t %S/class.swift -swift-version 3 | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -emit-module -module-name def_class -o %t/stage1.swiftmodule %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop
+// RUN: %target-swift-frontend -emit-module -parse-as-library -o %t/def_class.swiftmodule %t/stage1.swiftmodule
+// RUN: %target-swift-frontend -emit-sil -sil-debug-serialization -I %t %S/class.swift | %FileCheck %s -check-prefix=SIL
 
 // SIL-LABEL: sil public_external [transparent] [serialized] [canonical] @$SSi1poiyS2i_SitFZ : $@convention(method) (Int, Int, @thin Int.Type) -> Int
diff --git a/test/Serialization/class.swift b/test/Serialization/class.swift
index 17f230f..3f6bbb8 100644
--- a/test/Serialization/class.swift
+++ b/test/Serialization/class.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-object -emit-module -o %t %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop -swift-version 3
+// RUN: %target-swift-frontend -emit-object -emit-module -o %t %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop
 // RUN: llvm-bcanalyzer %t/def_class.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-sil -sil-debug-serialization -I %t %s -swift-version 3 | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -emit-sil -sil-debug-serialization -I %t %s | %FileCheck %s -check-prefix=SIL
 // RUN: echo "import def_class; struct A : ClassProto {}" | not %target-swift-frontend -typecheck -I %t - 2>&1 | %FileCheck %s -check-prefix=CHECK-STRUCT
 
 // CHECK-NOT: UnknownCode
@@ -48,8 +48,8 @@
 
 struct Int {}
 
-var gc = GenericCtor<Int>()
-gc.doSomething()
+var gc = GenericCtor<Int>(42)
+gc.doSomething(42)
 
 
 a = StillEmpty()
diff --git a/test/Serialization/function.swift b/test/Serialization/function.swift
index 512e022..80fb9b4 100644
--- a/test/Serialization/function.swift
+++ b/test/Serialization/function.swift
@@ -1,8 +1,8 @@
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_func.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_func.swift
 // RUN: llvm-bcanalyzer %t/def_func.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -module-name function -emit-silgen -I %t %s -swift-version 3 | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -module-name function -emit-silgen -I %t %s | %FileCheck %s -check-prefix=SIL
 
 // CHECK-NOT: FALL_BACK_TO_TRANSLATION_UNIT
 // CHECK-NOT: UnknownCode
diff --git a/test/Serialization/generic_witness.swift b/test/Serialization/generic_witness.swift
index 9f6fe51..a06b87b 100644
--- a/test/Serialization/generic_witness.swift
+++ b/test/Serialization/generic_witness.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/has_generic_witness.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/has_generic_witness.swift
 // RUN: llvm-bcanalyzer %t/has_generic_witness.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-ir -I %t %s -o /dev/null -swift-version 3
+// RUN: %target-swift-frontend -emit-ir -I %t %s -o /dev/null
 
 // We have to perform IRGen to actually check that the generic substitutions
 // are being used.
diff --git a/test/Serialization/load-wrong-name.swift b/test/Serialization/load-wrong-name.swift
index 4de8aa4..a892af4 100644
--- a/test/Serialization/load-wrong-name.swift
+++ b/test/Serialization/load-wrong-name.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_func.swift -module-name new_module -swift-version 3
-// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal -swift-version 3 2>&1 | %FileCheck %s
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_func.swift -module-name new_module
+// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s
 
 import swift // CHECK: error: {{cannot load module 'Swift' as 'swift'|no such module 'swift'}}
 import NEW_MODULE // CHECK: error: {{cannot load module 'new_module' as 'NEW_MODULE'|no such module 'NEW_MODULE'}}
diff --git a/test/Serialization/load.swift b/test/Serialization/load.swift
index c86f680..bd8a7e9 100644
--- a/test/Serialization/load.swift
+++ b/test/Serialization/load.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend %s -typecheck -verify -show-diagnostics-after-fatal -swift-version 3
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_func.swift -module-name new_module -swift-version 3
-// RUN: %target-swift-frontend %s -typecheck -I %t -swift-version 3
+// RUN: %target-swift-frontend %s -typecheck -verify -show-diagnostics-after-fatal
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_func.swift -module-name new_module
+// RUN: %target-swift-frontend %s -typecheck -I %t
 
 // These errors should happen before we've built the module to import.
 import new_module // expected-error{{no such module 'new_module'}}
diff --git a/test/Serialization/objc.swift b/test/Serialization/objc.swift
index e2d2bc8..6306e07 100644
--- a/test/Serialization/objc.swift
+++ b/test/Serialization/objc.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_objc.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_objc.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop
 // RUN: llvm-bcanalyzer %t/def_objc.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -module-name objc -emit-silgen -I %t %s -o - -swift-version 3 | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -module-name objc -emit-silgen -I %t %s -o - | %FileCheck %s -check-prefix=SIL
 
 // CHECK-NOT: UnknownCode
 
diff --git a/test/Serialization/search-paths-relative.swift b/test/Serialization/search-paths-relative.swift
index a7d7cd7..cd190cb 100644
--- a/test/Serialization/search-paths-relative.swift
+++ b/test/Serialization/search-paths-relative.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
 // RUN: %empty-directory(%t/secret)
-// RUN: %target-swift-frontend -emit-module -o %t/secret %S/Inputs/struct_with_operators.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t/secret %S/Inputs/struct_with_operators.swift
 // RUN: %empty-directory(%t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule)
-// RUN: %target-swift-frontend -emit-module -o %t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule/%target-swiftmodule-name %S/Inputs/alias.swift -module-name has_alias -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule/%target-swiftmodule-name %S/Inputs/alias.swift -module-name has_alias
 
-// RUN: cd %t/secret && %target-swiftc_driver -emit-module -o %t/has_xref.swiftmodule -I . -F ../Frameworks -parse-as-library %S/Inputs/has_xref.swift %S/../Inputs/empty.swift -Xfrontend -serialize-debugging-options -Xcc -ivfsoverlay -Xcc %S/../Inputs/unextended-module-overlay.yaml -Xcc -DDUMMY -swift-version 3
-// RUN: %target-swift-frontend %s -typecheck -I %t -swift-version 3
+// RUN: cd %t/secret && %target-swiftc_driver -emit-module -o %t/has_xref.swiftmodule -I . -F ../Frameworks -parse-as-library %S/Inputs/has_xref.swift %S/../Inputs/empty.swift -Xfrontend -serialize-debugging-options -Xcc -ivfsoverlay -Xcc %S/../Inputs/unextended-module-overlay.yaml -Xcc -DDUMMY
+// RUN: %target-swift-frontend %s -typecheck -I %t
 
 // Check the actual serialized search paths.
 // RUN: llvm-bcanalyzer -dump %t/has_xref.swiftmodule > %t/has_xref.swiftmodule.txt
diff --git a/test/Serialization/search-paths.swift b/test/Serialization/search-paths.swift
index 698379a..7fccffb 100644
--- a/test/Serialization/search-paths.swift
+++ b/test/Serialization/search-paths.swift
@@ -1,28 +1,28 @@
 // RUN: %empty-directory(%t)
 // RUN: %empty-directory(%t/secret)
-// RUN: %target-swift-frontend -emit-module -o %t/secret %S/Inputs/struct_with_operators.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t/secret %S/Inputs/struct_with_operators.swift
 // RUN: %empty-directory(%t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule)
-// RUN: %target-swift-frontend -emit-module -o %t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule/%target-swiftmodule-name %S/Inputs/alias.swift -module-name has_alias -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule/%target-swiftmodule-name %S/Inputs/alias.swift -module-name has_alias
 
-// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift -swift-version 3
-// RUN: %target-swift-frontend %s -typecheck -I %t -verify -show-diagnostics-after-fatal -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift
+// RUN: %target-swift-frontend %s -typecheck -I %t -verify -show-diagnostics-after-fatal
 
 // Try again, treating has_xref as a main file to force serialization to occur.
-// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks %S/Inputs/has_xref.swift -swift-version 3
-// RUN: %target-swift-frontend %s -typecheck -I %t -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks %S/Inputs/has_xref.swift
+// RUN: %target-swift-frontend %s -typecheck -I %t
 
-// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift -serialize-debugging-options -swift-version 3
-// RUN: %target-swift-frontend %s -typecheck -I %t -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift -serialize-debugging-options
+// RUN: %target-swift-frontend %s -typecheck -I %t
 
-// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift -application-extension -swift-version 3
-// RUN: %target-swift-frontend %s -typecheck -I %t -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift -application-extension
+// RUN: %target-swift-frontend %s -typecheck -I %t
 
 // Make sure we don't end up with duplicate search paths.
-// RUN: %target-swiftc_driver -emit-module -o %t/has_xref.swiftmodule -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift %S/../Inputs/empty.swift -Xfrontend -serialize-debugging-options -swift-version 3
+// RUN: %target-swiftc_driver -emit-module -o %t/has_xref.swiftmodule -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -parse-as-library %S/Inputs/has_xref.swift %S/../Inputs/empty.swift -Xfrontend -serialize-debugging-options
 // RUN: %target-swift-frontend %s -typecheck -I %t
 // RUN: llvm-bcanalyzer -dump %t/has_xref.swiftmodule | %FileCheck %s
 
-// RUN: %target-swift-frontend %s -emit-module -o %t/main.swiftmodule -I %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks -swift-version 3
+// RUN: %target-swift-frontend %s -emit-module -o %t/main.swiftmodule -I %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks
 // RUN: llvm-bcanalyzer -dump %t/main.swiftmodule | %FileCheck %s
 
 import has_xref // expected-error {{missing required modules: 'has_alias', 'struct_with_operators'}}
diff --git a/test/Serialization/struct.swift b/test/Serialization/struct.swift
index 19ba381..7dd3019 100644
--- a/test/Serialization/struct.swift
+++ b/test/Serialization/struct.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_struct.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_struct.swift
 // RUN: llvm-bcanalyzer %t/def_struct.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-silgen -I %t %s -o /dev/null -swift-version 3
+// RUN: %target-swift-frontend -emit-silgen -I %t %s -o /dev/null
 
 // CHECK-NOT: UnknownCode
 
@@ -41,8 +41,8 @@
 p.first = 2
 p.second = 5.0
 
-var gc = GenericCtor<Int>()
-gc.doSomething()
+var gc = GenericCtor<Int>(42)
+gc.doSomething(42)
 
 var wrappedTypeVar : ComputableWrapper<AnotherIntWrapper>.ComputableType
 wrappedTypeVar = intWrapper2
diff --git a/test/Serialization/transparent-std.swift b/test/Serialization/transparent-std.swift
index 3e4f72b..7f70f1a 100644
--- a/test/Serialization/transparent-std.swift
+++ b/test/Serialization/transparent-std.swift
@@ -1,8 +1,8 @@
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -parse-stdlib -o %t %S/Inputs/def_transparent_std.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -parse-stdlib -o %t %S/Inputs/def_transparent_std.swift
 // RUN: llvm-bcanalyzer %t/def_transparent_std.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-sil -sil-debug-serialization -parse-stdlib -I %t %s -swift-version 3 | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-sil -sil-debug-serialization -parse-stdlib -I %t %s | %FileCheck %s -check-prefix=SIL
 
 // CHECK-NOT: UnknownCode
 
diff --git a/test/Serialization/typealias.swift b/test/Serialization/typealias.swift
index 4c00867..9a4a2a5 100644
--- a/test/Serialization/typealias.swift
+++ b/test/Serialization/typealias.swift
@@ -1,8 +1,8 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -module-name alias -emit-module -o %t %S/Inputs/alias.swift -swift-version 3
-// RUN: %target-build-swift -I %t %s -module-name typealias -emit-module-path %t/typealias.swiftmodule -o %t/typealias.o -swift-version 3
+// RUN: %target-build-swift -module-name alias -emit-module -o %t %S/Inputs/alias.swift
+// RUN: %target-build-swift -I %t %s -module-name typealias -emit-module-path %t/typealias.swiftmodule -o %t/typealias.o
 // RUN: llvm-bcanalyzer %t/alias.swiftmodule | %FileCheck %s
-// RUN: %target-build-swift -I %t %s -swift-version 3 -o %t/a.out
+// RUN: %target-build-swift -I %t %s -o %t/a.out
 // RUN: %target-run %t/a.out | %FileCheck -check-prefix=OUTPUT %s
 // REQUIRES: executable_test
 
@@ -40,8 +40,8 @@
 
 // OUTPUT: -42
 
-func subtract(x: MyInt64, y: MyInt64) -> MyInt64 {
-  return x - y
+func subtract(_ t : (x: MyInt64, y: MyInt64)) -> MyInt64 {
+  return t.x - t.y
 }
 var dyadic : TwoIntFunction = subtract
 print("\(dyadic((named.b, i))) \(dyadic(both))\n", terminator: "")
diff --git a/test/Serialization/xref-multi-file.swift b/test/Serialization/xref-multi-file.swift
index e407381..d87d87a 100644
--- a/test/Serialization/xref-multi-file.swift
+++ b/test/Serialization/xref-multi-file.swift
@@ -1,9 +1,9 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/struct_with_operators.swift -swift-version 3
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/alias.swift -module-name has_alias -swift-version 3
-// RUN: %target-swift-frontend -emit-module -o %t -I %t %S/Inputs/has_xref.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/struct_with_operators.swift
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/alias.swift -module-name has_alias
+// RUN: %target-swift-frontend -emit-module -o %t -I %t %S/Inputs/has_xref.swift
 // RUN: llvm-bcanalyzer %t/has_xref.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-silgen -I %t -primary-file %s %S/Inputs/xref-multi-file-other.swift -module-name main -swift-version 3 > /dev/null
+// RUN: %target-swift-frontend -emit-silgen -I %t -primary-file %s %S/Inputs/xref-multi-file-other.swift -module-name main > /dev/null
 
 // CHECK-NOT: UnknownCode
 
diff --git a/test/Serialization/xref.swift b/test/Serialization/xref.swift
index c93cabd..213e87e 100644
--- a/test/Serialization/xref.swift
+++ b/test/Serialization/xref.swift
@@ -1,10 +1,10 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/struct_with_operators.swift -swift-version 3
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/alias.swift -module-name has_alias -swift-version 3
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/xref_distraction.swift -swift-version 3
-// RUN: %target-swift-frontend -emit-module -o %t -I %t %S/Inputs/has_xref.swift -swift-version 3
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/struct_with_operators.swift
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/alias.swift -module-name has_alias
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/xref_distraction.swift
+// RUN: %target-swift-frontend -emit-module -o %t -I %t %S/Inputs/has_xref.swift
 // RUN: llvm-bcanalyzer %t/has_xref.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-silgen -I %t %s -swift-version 3 > /dev/null
+// RUN: %target-swift-frontend -emit-silgen -I %t %s > /dev/null
 
 // CHECK-NOT: UnknownCode
 
diff --git a/test/SourceKit/Refactoring/syntactic-rename.swift b/test/SourceKit/Refactoring/syntactic-rename.swift
index 374a219..64cb273 100644
--- a/test/SourceKit/Refactoring/syntactic-rename.swift
+++ b/test/SourceKit/Refactoring/syntactic-rename.swift
@@ -126,9 +126,9 @@
 // RUN: diff -u %S/syntactic-rename/rename-memberwise.expected %t.result/rename-memberwise.expected
 // RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/rename-layer.in.json %s >> %t.result/rename-layer.expected
 // RUN: diff -u %S/syntactic-rename/rename-layer.expected %t.result/rename-layer.expected
-// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/rename-P.in.json %s -- -swift-version 3 >> %t.result/rename-P.expected
+// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/rename-P.in.json %s >> %t.result/rename-P.expected
 // RUN: diff -u %S/syntactic-rename/rename-P.expected %t.result/rename-P.expected
-// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/keywordbase.in.json %s -- -swift-version 3 >> %t.result/keywordbase.expected
+// RUN: %sourcekitd-test -req=syntactic-rename -rename-spec %S/syntactic-rename/keywordbase.in.json %s >> %t.result/keywordbase.expected
 // RUN: diff -u %S/syntactic-rename/keywordbase.expected %t.result/keywordbase.expected
 
 // RUN: %empty-directory(%t.ranges)
diff --git a/test/TBD/class.swift b/test/TBD/class.swift
index 5c1a750..d7e77cf 100644
--- a/test/TBD/class.swift
+++ b/test/TBD/class.swift
@@ -1,24 +1,29 @@
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing -O %s
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing -O %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
 
 open class OpenNothing {}
 
 open class OpenInit {
     public init() {}
-    public init(public_: Int) {}
+    public init(public_: Int, default_: Int = 0) {}
 
-    internal init(internal_: Int) {}
+    internal init(internal_: Int, default_: Int = 0) {}
 
     deinit {}
 }
 
 open class OpenMethods {
     public init() {}
-    public func publicMethod() {}
-    internal func internalMethod() {}
-    private func privateMethod() {}
+    public func publicMethod(default_: Int = 0) {}
+    internal func internalMethod(default_: Int = 0) {}
+    private func privateMethod(default_: Int = 0) {}
 }
 
 open class OpenProperties {
@@ -49,9 +54,9 @@
 }
 
 open class OpenStatics {
-    public static func publicStaticFunc() {}
-    internal static func internalStaticFunc() {}
-    private static func privateStaticFunc() {}
+    public static func publicStaticFunc(default_: Int = 0) {}
+    internal static func internalStaticFunc(default_: Int = 0) {}
+    private static func privateStaticFunc(default_: Int = 0) {}
 
     public static let publicLet: Int = 0
     internal static let internalLet: Int = 0
@@ -107,18 +112,18 @@
 
 public class PublicInit {
     public init() {}
-    public init(public_: Int) {}
+    public init(public_: Int, default_: Int = 0) {}
     
-    internal init(internal_: Int) {}
+    internal init(internal_: Int, default_: Int = 0) {}
 
     deinit {}
 }
 
 public class PublicMethods {
     public init() {}
-    public func publicMethod() {}
-    internal func internalMethod() {}
-    private func privateMethod() {}
+    public func publicMethod(default_: Int = 0) {}
+    internal func internalMethod(default_: Int = 0) {}
+    private func privateMethod(default_: Int = 0) {}
 }
 
 public class PublicProperties {
@@ -149,9 +154,9 @@
 }
 
 public class PublicStatics {
-    public static func publicStaticFunc() {}
-    internal static func internalStaticFunc() {}
-    private static func privateStaticFunc() {}
+    public static func publicStaticFunc(default_: Int = 0) {}
+    internal static func internalStaticFunc(default_: Int = 0) {}
+    private static func privateStaticFunc(default_: Int = 0) {}
 
     public static let publicLet: Int = 0
     internal static let internalLet: Int = 0
@@ -188,19 +193,19 @@
   internal var internalVarConcrete: Int = 0
   private var privateVarConcrete: Int = 0
 
-  public init<S>(t: T, u: U, v: V, _: S) {
+  public init<S>(t: T, u: U, v: V, _: S, default_: Int = 0) {
     publicVar = t
     internalVar = u
     privateVar = v
   }
 
-  public func publicGeneric<A>(_: A) {}
-  internal func internalGeneric<A>(_: A) {}
-  private func privateGeneric<A>(_: A) {}
+  public func publicGeneric<A>(_: A, default_: Int = 0) {}
+  internal func internalGeneric<A>(_: A, default_: Int = 0) {}
+  private func privateGeneric<A>(_: A, default_: Int = 0) {}
 
-  public static func publicStaticGeneric<A>(_: A) {}
-  internal static func internalStaticGeneric<A>(_: A) {}
-  private static func privateStaticGeneric<A>(_: A) {}
+  public static func publicStaticGeneric<A>(_: A, default_: Int = 0) {}
+  internal static func internalStaticGeneric<A>(_: A, default_: Int = 0) {}
+  private static func privateStaticGeneric<A>(_: A, default_: Int = 0) {}
 }
 
 
@@ -208,14 +213,14 @@
 
 internal class InternalInit {
     internal init() {}
-    internal init(internal_: Int) {}
-    private init(private_: Int) {}
+    internal init(internal_: Int, default_: Int = 0) {}
+    private init(private_: Int, default_: Int = 0) {}
 }
 
 internal class InternalMethods {
     internal init() {}
-    internal func internalMethod() {}
-    private func privateMethod() {}
+    internal func internalMethod(default_: Int = 0) {}
+    private func privateMethod(default_: Int = 0) {}
 }
 
 internal class InternalProperties {
@@ -239,8 +244,8 @@
 }
 
 internal class InternalStatics {
-    internal static func internalStaticFunc() {}
-    private static func privateStaticFunc() {}
+    internal static func internalStaticFunc(default_: Int = 0) {}
+    private static func privateStaticFunc(default_: Int = 0) {}
 
     internal static let internalLet: Int = 0
     private static let privateLet: Int = 0
@@ -268,16 +273,16 @@
   internal var internalVarConcrete: Int = 0
   private var privateVarConcrete: Int = 0
 
-  internal init<S>(t: T, u: U, v: V, _: S) {
+  internal init<S>(t: T, u: U, v: V, _: S, default_: Int = 0) {
     internalVar = u
     privateVar = v
   }
 
-  internal func internalGeneric<A>(_: A) {}
-  private func privateGeneric<A>(_: A) {}
+  internal func internalGeneric<A>(_: A, default_: Int = 0) {}
+  private func privateGeneric<A>(_: A, default_: Int = 0) {}
 
-  internal static func internalStaticGeneric<A>(_: A) {}
-  private static func privateStaticGeneric<A>(_: A) {}
+  internal static func internalStaticGeneric<A>(_: A, default_: Int = 0) {}
+  private static func privateStaticGeneric<A>(_: A, default_: Int = 0) {}
 }
 
 
@@ -285,12 +290,12 @@
 
 private class PrivateInit {
     private init() {}
-    private init(private_: Int) {}
+    private init(private_: Int, default_: Int = 0) {}
 }
 
 private class PrivateMethods {
     private init() {}
-    private func privateMethod() {}
+    private func privateMethod(default_: Int = 0) {}
 }
 
 private class PrivateProperties {
@@ -307,7 +312,7 @@
 }
 
 private class PrivateStatics {
-    private static func privateStaticFunc() {}
+    private static func privateStaticFunc(default_: Int = 0) {}
 
     private static let privateLet: Int = 0
 
@@ -326,11 +331,11 @@
 
   private var privateVarConcrete: Int = 0
 
-  private init<S>(t: T, u: U, v: V, _: S) {
+  private init<S>(t: T, u: U, v: V, _: S, default_: Int = 0) {
     privateVar = v
   }
 
-  private func privateGeneric<A>(_: A) {}
+  private func privateGeneric<A>(_: A, default_: Int = 0) {}
 
-  private static func privateStaticGeneric<A>(_: A) {}
+  private static func privateStaticGeneric<A>(_: A, default_: Int = 0) {}
 }
diff --git a/test/TBD/class_objc.swift.gyb b/test/TBD/class_objc.swift.gyb
index ecc1277..61f59df 100644
--- a/test/TBD/class_objc.swift.gyb
+++ b/test/TBD/class_objc.swift.gyb
@@ -1,15 +1,23 @@
 // RUN: %empty-directory(%t)
 // RUN: %gyb %s > %t/main.swift
 
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=missing %t/main.swift -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=missing %t/main.swift -disable-objc-attr-requires-foundation-module
 
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=missing %t/main.swift -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=missing %t/main.swift -disable-objc-attr-requires-foundation-module
+
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=missing %t/main.swift -disable-objc-attr-requires-foundation-module -O
+
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=missing %t/main.swift -disable-objc-attr-requires-foundation-module -O
 
 // With -enable-testing:
 
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module -enable-testing
 
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module -enable-testing
+
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module -enable-testing -O
+
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -import-objc-header %S/Inputs/objc_class_header.h -validate-tbd-against-ir=all %t/main.swift -disable-objc-attr-requires-foundation-module -enable-testing -O
 
 // REQUIRES: objc_interop
 
diff --git a/test/TBD/enum.swift b/test/TBD/enum.swift
index 28d49d5..c08f7a7 100644
--- a/test/TBD/enum.swift
+++ b/test/TBD/enum.swift
@@ -1,17 +1,25 @@
 // Swift 3:
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -O
 // Swift 4:
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -O
 
 // With -enable-testing:
 // Swift 3:
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
 // Swift 4:
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -swift-version 4 -enable-testing -O
 
 public protocol P {}
 
diff --git a/test/TBD/extension.swift.gyb b/test/TBD/extension.swift.gyb
index 23676d4..ac251e1 100644
--- a/test/TBD/extension.swift.gyb
+++ b/test/TBD/extension.swift.gyb
@@ -6,22 +6,30 @@
 // RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/types/ExtensionTypes.swiftmodule
 // This module is both not resilient:
 // RUN: %target-swift-frontend -emit-ir -o%t/not_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift
+// RUN: %target-swift-frontend -emit-ir -o%t/not_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -O
 // ... and resilient:
 // RUN: %target-swift-frontend -emit-ir -o%t/not_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-resilience
+// RUN: %target-swift-frontend -emit-ir -o%t/not_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-resilience -O
 // The same, but with -enable-testing:
 // RUN: %target-swift-frontend -emit-ir -o%t/not_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o%t/not_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-testing -O
 // RUN: %target-swift-frontend -emit-ir -o%t/not_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-resilience -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o%t/not_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-resilience -enable-testing -O
 
 // Other module is resilient:
 // RUN: %empty-directory(%t/types)
 // RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/types/ExtensionTypes.swiftmodule -Xfrontend -enable-resilience
 // This module is both not resilient:
 // RUN: %target-swift-frontend -emit-ir -o%t/resilient_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -O
 // ... and resilient:
 // RUN: %target-swift-frontend -emit-ir -o%t/resilient_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-resilience
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-resilience -O
 // The same but with -enable-testing:
 // RUN: %target-swift-frontend -emit-ir -o%t/resilient_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-testing -O
 // RUN: %target-swift-frontend -emit-ir -o%t/resilient_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-resilience -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-resilience -enable-testing -O
 
 
 import ExtensionTypes
diff --git a/test/TBD/function.swift b/test/TBD/function.swift
index aed48e2..fda9187 100644
--- a/test/TBD/function.swift
+++ b/test/TBD/function.swift
@@ -1,7 +1,11 @@
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s -enable-testing
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s -enable-testing -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s -enable-testing -O
 
 public func publicNoArgs() {}
 public func publicSomeArgs(_: Int, x: Int) {}
diff --git a/test/TBD/global.swift b/test/TBD/global.swift
index 0a206c4..7866677 100644
--- a/test/TBD/global.swift
+++ b/test/TBD/global.swift
@@ -1,7 +1,11 @@
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience -enable-testing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience -enable-testing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience %s -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience -enable-testing %s -O
 
 public let publicLet: Int = 0
 internal let internalLet: Int = 0
diff --git a/test/TBD/main.swift b/test/TBD/main.swift
index e62c8c0..b86b01b 100644
--- a/test/TBD/main.swift
+++ b/test/TBD/main.swift
@@ -1,3 +1,4 @@
-// RUN: %target-swift-frontend -emit-ir -o- -module-name test -validate-tbd-against-ir=all %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -module-name test -validate-tbd-against-ir=all %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -module-name test -validate-tbd-against-ir=all %s -O
 
 // Top-level code (i.e. implicit `main`) should be handled
diff --git a/test/TBD/protocol.swift b/test/TBD/protocol.swift
index a4b13e3..b7b752f 100644
--- a/test/TBD/protocol.swift
+++ b/test/TBD/protocol.swift
@@ -1,7 +1,12 @@
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
 
 public protocol Public {
     func publicMethod()
diff --git a/test/TBD/specialization.swift b/test/TBD/specialization.swift
index 54d81fa..f4e8077 100644
--- a/test/TBD/specialization.swift
+++ b/test/TBD/specialization.swift
@@ -17,6 +17,10 @@
 }
 
 open class Bar<T> {
+    public init() {
+        bar()
+    }
+
     @inline(never)
     fileprivate func bar() {}
 }
@@ -28,8 +32,14 @@
 }
 
 
+// Generic specialization, from the foo call in f
 // CHECK-LABEL: // specialized Foo.foo<A>(_:)
 // CHECK-NEXT: sil private [noinline] @$S14specialization3FooC3foo33_A6E3E43DB6679655BDF5A878ABC489A0LLyyxmlFSi_Tg5Tf4dd_n : $@convention(thin) () -> ()
 
+// Function signature specialization, from the bar call in Bar.init
+// CHECK-LABEL: // specialized Bar.bar()
+// CHECK-NEXT: sil private [noinline] @$S14specialization3BarC3bar33_A6E3E43DB6679655BDF5A878ABC489A0LLyyFTf4d_n : $@convention(thin) () -> () {
+
+// Generic specialization, from the bar call in f
 // CHECK-LABEL: // specialized Bar.bar()
 // CHECK-NEXT: sil private [noinline] @$S14specialization3BarC3bar33_A6E3E43DB6679655BDF5A878ABC489A0LLyyFSi_Tg5Tf4d_n : $@convention(thin) () -> ()
diff --git a/test/TBD/struct.swift b/test/TBD/struct.swift
index fb7415a..893f0b2 100644
--- a/test/TBD/struct.swift
+++ b/test/TBD/struct.swift
@@ -1,7 +1,11 @@
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-testing -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience -enable-testing -O
 
 public struct PublicNothing {}
 
diff --git a/test/TBD/subclass.swift.gyb b/test/TBD/subclass.swift.gyb
index 48406e3..4637400 100644
--- a/test/TBD/subclass.swift.gyb
+++ b/test/TBD/subclass.swift.gyb
@@ -2,27 +2,41 @@
 // RUN: %gyb %s > %t/main.swift
 
 // Same-module superclass, both resilient and not, and enable-testing and not:
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -DSAME_MODULE -enable-testing -O
 
 
 // Other-module superclass is not resilient:
 // RUN: %empty-directory(%t/super)
 // RUN: %target-build-swift %S/Inputs/subclass_super.swift -emit-library -emit-module -o %t/super/subclass_super.%target-dylib-extension
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
+
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing -O
 
 // Other-module superclass is resilient:
 // RUN: %empty-directory(%t/super)
 // RUN: %target-build-swift %S/Inputs/subclass_super.swift -emit-library -emit-module -o %t/super/subclass_super.%target-dylib-extension -Xfrontend -enable-resilience
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
-// RUN: %target-swift-frontend -enable-resilience -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing
+
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -O
+// RUN: %target-swift-frontend -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing -O
+// RUN: %target-swift-frontend -enable-resilience -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=missing %t/main.swift -I %t/super -enable-testing -O
 
 #if SAME_MODULE
 open class Super {
diff --git a/test/api-digester/compare-dump.swift b/test/api-digester/compare-dump.swift
index b6e5adf..3524c80 100644
--- a/test/api-digester/compare-dump.swift
+++ b/test/api-digester/compare-dump.swift
@@ -3,7 +3,7 @@
 // RUN: %empty-directory(%t.module-cache)
 // RUN: %swift -emit-module -o %t.mod/cake1.swiftmodule %S/Inputs/cake1.swift -parse-as-library -I %S/Inputs/APINotesLeft %clang-importer-sdk-nosource
 // RUN: %swift -emit-module -o %t.mod/cake2.swiftmodule %S/Inputs/cake2.swift -parse-as-library -I %S/Inputs/APINotesRight %clang-importer-sdk-nosource
-// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 3 -I %t.mod -I %S/Inputs/APINotesLeft
-// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -swift-version 3 -I %t.mod -I %S/Inputs/APINotesRight
+// RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesLeft
+// RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesRight
 // RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json > %t.result
 // RUN: diff -u %S/Outputs/Cake.txt %t.result
diff --git a/test/api-digester/dump-module.swift b/test/api-digester/dump-module.swift
index 1325c0d..4732f1c 100644
--- a/test/api-digester/dump-module.swift
+++ b/test/api-digester/dump-module.swift
@@ -2,7 +2,7 @@
 // RUN: %empty-directory(%t.sdk)
 // RUN: %empty-directory(%t.module-cache)
 // RUN: %swift -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library
-// RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod
+// RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -sdk %t.sdk -I %t.mod
 // RUN: diff -u %S/Outputs/cake.json %t.dump.json
 // RUN: %api-digester -diagnose-sdk --input-paths %t.dump.json -input-paths %S/Outputs/cake.json
 
diff --git a/test/attr/attr_noescape.swift b/test/attr/attr_noescape.swift
index 19f6088..a1444ba 100644
--- a/test/attr/attr_noescape.swift
+++ b/test/attr/attr_noescape.swift
@@ -1,13 +1,13 @@
-// RUN: %target-typecheck-verify-swift -swift-version 3
+// RUN: %target-typecheck-verify-swift
 
 @noescape var fn : () -> Int = { 4 }  // expected-error {{attribute can only be applied to types, not declarations}}
 
 func conflictingAttrs(_ fn: @noescape @escaping () -> Int) {} // expected-error {{@escaping conflicts with @noescape}}
- // expected-warning@-1{{@noescape is the default and is deprecated}} {{29-39=}}
+// expected-error@-1{{@noescape is the default and has been removed}}  {{29-39=}}
 
 func doesEscape(_ fn : @escaping () -> Int) {}
 
-func takesGenericClosure<T>(_ a : Int, _ fn : @noescape () -> T) {} // expected-warning{{@noescape is the default and is deprecated}} {{47-57=}}
+func takesGenericClosure<T>(_ a : Int, _ fn : @noescape () -> T) {} // expected-error{{@noescape is the default and has been removed}} {{47-57=}}
 
 
 var globalAny: Any = 0
@@ -189,8 +189,8 @@
 
 // Implicit conversions (in this case to @convention(block)) are ok.
 @_silgen_name("whatever") 
-func takeNoEscapeAsObjCBlock(_: @noescape @convention(block) () -> Void)  // expected-warning{{@noescape is the default and is deprecated}} {{33-43=}}
-func takeNoEscapeTest2(_ fn : @noescape () -> ()) {  // expected-warning{{@noescape is the default and is deprecated}} {{31-41=}}
+func takeNoEscapeAsObjCBlock(_: @noescape @convention(block) () -> Void)  // expected-error{{@noescape is the default and has been removed}} {{33-43=}}
+func takeNoEscapeTest2(_ fn : @noescape () -> ()) {  // expected-error{{@noescape is the default and has been removed}} {{31-41=}}
   takeNoEscapeAsObjCBlock(fn)
 }
 
@@ -204,7 +204,7 @@
 // <rdar://problem/19470858> QoI: @autoclosure implies @noescape, so you shouldn't be allowed to specify both
 func redundant(_ fn : @noescape  // expected-error @+1 {{@noescape is implied by @autoclosure and should not be redundantly specified}}
                @autoclosure () -> Int) {
- // expected-warning@-2{{@noescape is the default and is deprecated}} {{23-33=}}
+ // expected-error@-2{{@noescape is the default and has been removed}} {{23-33=}}
 }
 
 
@@ -221,7 +221,7 @@
 
 struct S : P2 {
   typealias Element = Int
-  func each(_ transform: @noescape (Int) -> ()) { // expected-warning{{@noescape is the default and is deprecated}} {{26-36=}}
+  func each(_ transform: @noescape (Int) -> ()) { // expected-error{{@noescape is the default and has been removed}} {{26-36=}}
     overloadedEach(self,  // expected-error {{cannot invoke 'overloadedEach' with an argument list of type '(S, (Int) -> (), Int)'}}
                    transform, 1)
     // expected-note @-2 {{overloads for 'overloadedEach' exist with these partially matching parameter lists: (O, @escaping (O.Element) -> (), T), (P, @escaping (P.Element) -> (), T)}}
@@ -231,16 +231,16 @@
 
 
 // rdar://19763676 - False positive in @noescape analysis triggered by parameter label
-func r19763676Callee(_ f: @noescape (_ param: Int) -> Int) {} // expected-warning{{@noescape is the default and is deprecated}} {{27-37=}}
+func r19763676Callee(_ f: @noescape (_ param: Int) -> Int) {} // expected-error{{@noescape is the default and has been removed}} {{27-37=}}
 
-func r19763676Caller(_ g: @noescape (Int) -> Int) { // expected-warning{{@noescape is the default and is deprecated}} {{27-37=}}
+func r19763676Caller(_ g: @noescape (Int) -> Int) { // expected-error{{@noescape is the default and has been removed}} {{27-37=}}
   r19763676Callee({ _ in g(1) })
 }
 
 
 // <rdar://problem/19763732> False positive in @noescape analysis triggered by default arguments
-func calleeWithDefaultParameters(_ f: @noescape () -> (), x : Int = 1) {} // expected-warning{{@noescape is the default and is deprecated}} {{39-49=}}
-func callerOfDefaultParams(_ g: @noescape () -> ()) { // expected-warning{{@noescape is the default and is deprecated}} {{33-43=}}
+func calleeWithDefaultParameters(_ f: @noescape () -> (), x : Int = 1) {} // expected-error{{@noescape is the default and has been removed}} {{39-49=}}
+func callerOfDefaultParams(_ g: @noescape () -> ()) { // expected-error{{@noescape is the default and has been removed}} {{33-43=}}
   calleeWithDefaultParameters(g)
 }
 
@@ -268,20 +268,20 @@
 
 
 /// SR-770 - Currying and `noescape`/`rethrows` don't work together anymore
-func curriedFlatMap<A, B>(_ x: [A]) -> (@noescape (A) -> [B]) -> [B] { // expected-warning{{@noescape is the default and is deprecated}} {{41-50=}}
+func curriedFlatMap<A, B>(_ x: [A]) -> (@noescape (A) -> [B]) -> [B] { // expected-error{{@noescape is the default and has been removed}} {{41-50=}}
   return { f in
     x.flatMap(f)
   }
 }
 
-func curriedFlatMap2<A, B>(_ x: [A]) -> (@noescape (A) -> [B]) -> [B] { // expected-warning{{@noescape is the default and is deprecated}} {{42-51=}}
-  return { (f : @noescape (A) -> [B]) in // expected-warning{{@noescape is the default and is deprecated}} {{17-27=}}
+func curriedFlatMap2<A, B>(_ x: [A]) -> (@noescape (A) -> [B]) -> [B] { // expected-error{{@noescape is the default and has been removed}} {{42-51=}}
+  return { (f : @noescape (A) -> [B]) in // expected-error{{@noescape is the default and has been removed}} {{17-27=}}
     x.flatMap(f)
   }
 }
 
 func bad(_ a : @escaping (Int)-> Int) -> Int { return 42 }
-func escapeNoEscapeResult(_ x: [Int]) -> (@noescape (Int) -> Int) -> Int { // expected-warning{{@noescape is the default and is deprecated}} {{43-52=}}
+func escapeNoEscapeResult(_ x: [Int]) -> (@noescape (Int) -> Int) -> Int { // expected-error{{@noescape is the default and has been removed}} {{43-52=}}
   return { f in // expected-note{{parameter 'f' is implicitly non-escaping}}
     bad(f)  // expected-error {{passing non-escaping parameter 'f' to function expecting an @escaping closure}}
   }
@@ -292,7 +292,7 @@
 //
 
 // Old syntax -- @noescape is the default, and is redundant
-typealias CompletionHandlerNE = @noescape (_ success: Bool) -> () // expected-warning{{@noescape is the default and is deprecated}} {{33-43=}}
+typealias CompletionHandlerNE = @noescape (_ success: Bool) -> () // expected-error{{@noescape is the default and has been removed}} {{33-43=}}
 
 // Explicit @escaping is not allowed here
 typealias CompletionHandlerE = @escaping (_ success: Bool) -> () // expected-error{{@escaping attribute may only be used in function parameter position}} {{32-42=}}
@@ -326,11 +326,11 @@
 
 // <rdar://problem/19997680> @noescape doesn't work on parameters of function type
 func apply<T, U>(_ f: @noescape (T) -> U, g: @noescape (@noescape (T) -> U) -> U) -> U { 
-  // expected-warning@-1{{@noescape is the default and is deprecated}} {{23-33=}}
-  // expected-warning@-2{{@noescape is the default and is deprecated}} {{46-56=}}
-  // expected-warning@-3{{@noescape is the default and is deprecated}} {{57-66=}}
+  // expected-error@-1{{@noescape is the default and has been removed}} {{23-33=}}
+  // expected-error@-2{{@noescape is the default and has been removed}} {{46-56=}}
+  // expected-error@-3{{@noescape is the default and has been removed}} {{57-66=}}
   return g(f)
-  // expected-warning@-1{{passing a non-escaping function parameter 'f' to a call to a non-escaping function parameter}}
+  // expected-error@-1{{passing a non-escaping function parameter 'f' to a call to a non-escaping function parameter}}
 }
 
 // <rdar://problem/19997577> @noescape cannot be applied to locals, leading to duplication of code
@@ -339,8 +339,8 @@
   case Function(() -> r19997577Type, () -> r19997577Type)
   case Sum(() -> r19997577Type, () -> r19997577Type)
 
-  func reduce<Result>(_ initial: Result, _ combine: @noescape (Result, r19997577Type) -> Result) -> Result { // expected-warning{{@noescape is the default and is deprecated}} {{53-63=}}
-    let binary: @noescape (r19997577Type, r19997577Type) -> Result = { combine(combine(combine(initial, self), $0), $1) } // expected-warning{{@noescape is the default and is deprecated}} {{17-27=}}
+  func reduce<Result>(_ initial: Result, _ combine: @noescape (Result, r19997577Type) -> Result) -> Result { // expected-error{{@noescape is the default and has been removed}} {{53-63=}}
+    let binary: @noescape (r19997577Type, r19997577Type) -> Result = { combine(combine(combine(initial, self), $0), $1) } // expected-error{{@noescape is the default and has been removed}} {{17-27=}}
     switch self {
     case .Unit:
       return combine(initial, self)
@@ -354,7 +354,7 @@
 
 // type attribute and decl attribute
 func noescapeD(@noescape f: @escaping () -> Bool) {} // expected-error {{attribute can only be applied to types, not declarations}}
-func noescapeT(f: @noescape () -> Bool) {} // expected-warning{{@noescape is the default and is deprecated}} {{19-29=}}
+func noescapeT(f: @noescape () -> Bool) {} // expected-error{{@noescape is the default and has been removed}} {{19-29=}}
 func noescapeG<T>(@noescape f: () -> T) {} // expected-error{{attribute can only be applied to types, not declarations}}
 
 func autoclosureD(@autoclosure f: () -> Bool) {} // expected-error {{attribute can only be applied to types, not declarations}}
@@ -362,7 +362,7 @@
 func autoclosureG<T>(@autoclosure f: () -> T) {} // expected-error{{attribute can only be applied to types, not declarations}}
 
 func noescapeD_noescapeT(@noescape f: @noescape () -> Bool) {} // expected-error {{attribute can only be applied to types, not declarations}}
- // expected-warning@-1{{@noescape is the default and is deprecated}} {{39-49=}}
+ // expected-error@-1{{@noescape is the default and has been removed}} {{39-49=}}
 
 func autoclosureD_noescapeT(@autoclosure f: @noescape () -> Bool) {} // expected-error {{attribute can only be applied to types, not declarations}}
- // expected-warning@-1{{@noescape is the default and is deprecated}} {{45-55=}}
+ // expected-error@-1{{@noescape is the default and has been removed}} {{45-55=}}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 5dd01c9..da83057 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -1655,7 +1655,7 @@
   init() {}
 
   @IBOutlet weak var goodOutlet: Class_ObjC1!
-  // CHECK-LABEL: {{^}} @IBOutlet @_implicitly_unwrapped_optional @objc weak var goodOutlet: @sil_weak Class_ObjC1!
+  // CHECK-LABEL: {{^}} @objc @IBOutlet @_implicitly_unwrapped_optional weak var goodOutlet: @sil_weak Class_ObjC1!
 
   @IBOutlet var badOutlet: PlainStruct
   // expected-error@-1 {{@IBOutlet property cannot have non-object type 'PlainStruct'}} {{3-13=}}
@@ -1672,7 +1672,7 @@
 // CHECK-LABEL: {{^}}class HasIBAction {
 class HasIBAction {
   @IBAction func goodAction(_ sender: AnyObject?) { }
-  // CHECK: {{^}}  @IBAction @objc func goodAction(_ sender: AnyObject?) {
+  // CHECK: {{^}}  @objc @IBAction func goodAction(_ sender: AnyObject?) {
 
   @IBAction func badAction(_ sender: PlainStruct?) { }
   // expected-error@-1{{argument to @IBAction method cannot have non-object type 'PlainStruct?'}}
@@ -1686,7 +1686,7 @@
 // CHECK-LABEL: {{^}}class HasIBInspectable {
 class HasIBInspectable {
   @IBInspectable var goodProperty: AnyObject?
-  // CHECK: {{^}}  @IBInspectable @objc var goodProperty: AnyObject?
+  // CHECK: {{^}}  @objc @IBInspectable var goodProperty: AnyObject?
 }
 
 //===---
@@ -1696,7 +1696,7 @@
 // CHECK-LABEL: {{^}}class HasGKInspectable {
 class HasGKInspectable {
   @GKInspectable var goodProperty: AnyObject?
-  // CHECK: {{^}}  @GKInspectable @objc var goodProperty: AnyObject?
+  // CHECK: {{^}}  @objc @GKInspectable var goodProperty: AnyObject?
 }
 
 //===---
@@ -1710,7 +1710,7 @@
 
   @NSManaged
   var goodManaged: Class_ObjC1
-  // CHECK-LABEL: {{^}}  @NSManaged @objc dynamic var goodManaged: Class_ObjC1
+  // CHECK-LABEL: {{^}}  @objc @NSManaged dynamic var goodManaged: Class_ObjC1
 
   @NSManaged
   var badManaged: PlainStruct
diff --git a/test/decl/class/circular_inheritance.swift b/test/decl/class/circular_inheritance.swift
index f75e56c..d19ac4b 100644
--- a/test/decl/class/circular_inheritance.swift
+++ b/test/decl/class/circular_inheritance.swift
@@ -8,15 +8,15 @@
 // Check that we produced superclass type requests.
 // RUN: %{python} %utils/process-stats-dir.py --evaluate 'SuperclassTypeRequest == 16' %t/stats-dir
 
-class C : B { } // expected-error{{circular class inheritance 'C' -> 'B' -> 'A' -> 'C'}}
+class C : B { } // expected-error{{'C' inherits from itself}}
 class B : A { } // expected-note{{class 'B' declared here}}
 class A : C { } // expected-note{{class 'A' declared here}}
 
-class TrivialCycle : TrivialCycle {} // expected-error{{circular class inheritance TrivialCycle}}
-protocol P : P {} // expected-error {{circular protocol inheritance P}}
+class TrivialCycle : TrivialCycle {} // expected-error{{'TrivialCycle' inherits from itself}}
+protocol P : P {} // expected-error {{protocol 'P' refines itself}}
 
 class Isomorphism : Automorphism { }
-class Automorphism : Automorphism { } // expected-error{{circular class inheritance Automorphism}}
+class Automorphism : Automorphism { } // expected-error{{'Automorphism' inherits from itself}}
 
 // FIXME: Useless error
 let _ = A() // expected-error{{'A' cannot be constructed because it has no accessible initializers}}
diff --git a/test/decl/nested/type_in_function.swift b/test/decl/nested/type_in_function.swift
index ab62acb..509dcf8 100644
--- a/test/decl/nested/type_in_function.swift
+++ b/test/decl/nested/type_in_function.swift
@@ -130,7 +130,7 @@
   // expected-error@-1 {{type 'First' cannot be nested in generic function 'genericFunction(t:)'}}
   class Second<T> : Second { }
   // expected-error@-1 {{type 'Second' cannot be nested in generic function 'genericFunction(t:)'}}
-  // expected-error@-2 2 {{circular class inheritance Second}}
+  // expected-error@-2 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 15439ee..2e7dc74 100644
--- a/test/decl/protocol/protocols.swift
+++ b/test/decl/protocol/protocols.swift
@@ -98,16 +98,15 @@
 
 // Circular protocols
 
-protocol CircleMiddle : CircleStart { func circle_middle() } // expected-error  {{circular protocol inheritance CircleMiddle}}
-// expected-error@-1{{circular protocol inheritance 'CircleMiddle' -> 'CircleStart' -> 'CircleEnd' -> 'CircleMiddle'}}
+protocol CircleMiddle : CircleStart { func circle_middle() } // expected-error 2 {{protocol 'CircleMiddle' refines itself}}
 protocol CircleStart : CircleEnd { func circle_start() }
 // expected-note@-1{{protocol 'CircleStart' declared here}}
-// expected-error@-2{{circular protocol inheritance CircleStart}}
+// expected-error@-2{{protocol 'CircleStart' refines itself}}
 protocol CircleEnd : CircleMiddle { func circle_end()} // expected-note{{protocol 'CircleEnd' declared here}}
-// expected-error@-1{{circular protocol inheritance CircleEnd}}
+// expected-error@-1{{protocol 'CircleEnd' refines itself}}
 
 protocol CircleEntry : CircleTrivial { }
-protocol CircleTrivial : CircleTrivial { } // expected-error 2{{circular protocol inheritance CircleTrivial}}
+protocol CircleTrivial : CircleTrivial { } // expected-error 2{{protocol 'CircleTrivial' refines itself}}
 
 struct Circle {
   func circle_start() {}
diff --git a/test/lit.cfg b/test/lit.cfg
index 5b8e166..21d6cb0 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -974,6 +974,18 @@
         '%s %%t/a.out &&'
         '%s %%t/a.out'
         % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
+    config.target_run_simple_opt_O_swift = (
+        '%%empty-directory(%%t) && '
+        '%s %s -O %%s -o %%t/a.out -module-name main && '
+        '%s %%t/a.out &&'
+        '%s %%t/a.out'
+        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
+    config.target_run_simple_opt_Osize_swift = (
+        '%%empty-directory(%%t) && '
+        '%s %s -Osize %%s -o %%t/a.out -module-name main && '
+        '%s %%t/a.out &&'
+        '%s %%t/a.out'
+        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
     config.target_run_simple_swift_swift3 = (
         '%%empty-directory(%%t) && '
         '%s %s %%s -o %%t/a.out -module-name main -swift-version 3 && '
@@ -1097,6 +1109,8 @@
 config.substitutions.append(('%target-run-simple-swiftgyb', config.target_run_simple_swiftgyb))
 config.substitutions.append(('%target-run-simple-swift-swift3', config.target_run_simple_swift_swift3))
 config.substitutions.append(('%target-run-simple-swift', config.target_run_simple_swift))
+config.substitutions.append(('%target-run-simple-opt-O-swift', config.target_run_simple_opt_O_swift))
+config.substitutions.append(('%target-run-simple-opt-Osize-swift', config.target_run_simple_opt_Osize_swift))
 config.substitutions.append(('%target-run-stdlib-swiftgyb-swift3', config.target_run_stdlib_swiftgyb_swift3))
 config.substitutions.append(('%target-run-stdlib-swiftgyb', config.target_run_stdlib_swiftgyb))
 config.substitutions.append(('%target-run-stdlib-swift-swift3', config.target_run_stdlib_swift_swift3))
diff --git a/test/stdlib/BinaryIntegerRequirements.swift b/test/stdlib/BinaryIntegerRequirements.swift
index 4436295..cb238bd 100644
--- a/test/stdlib/BinaryIntegerRequirements.swift
+++ b/test/stdlib/BinaryIntegerRequirements.swift
@@ -1,9 +1,6 @@
 // RUN: %target-typecheck-verify-swift -swift-version 4
 
 struct MyInt: FixedWidthInteger { // expected-error {{type 'MyInt' does not conform to protocol 'BinaryInteger'}}
-  // expected-error@-1 {{unavailable operator function '&=' was used to satisfy a requirement of protocol 'BinaryInteger'}}
-  // expected-error@-2 {{unavailable operator function '|=' was used to satisfy a requirement of protocol 'BinaryInteger'}}
-  // expected-error@-3 {{unavailable operator function '^=' was used to satisfy a requirement of protocol 'BinaryInteger'}}
   typealias IntegerLiteralType = Int
   static let isSigned = false
   init(integerLiteral value: Int) { fatalError() }
diff --git a/test/stdlib/Character.swift b/test/stdlib/Character.swift
index 1924f04..12649db 100644
--- a/test/stdlib/Character.swift
+++ b/test/stdlib/Character.swift
@@ -202,6 +202,9 @@
   // Only run it on ObjC platforms. Supported Linux versions do not have a
   // recent enough ICU for Unicode 9 support.
 #if _runtime(_ObjC)
+  // Check for Unicode 9 or later
+  guard #available(iOS 10.0, macOS 10.12, *) else { return }
+
   let flags = "🇺🇸🇨🇦🇩🇰🏳️‍🌈"
   expectEqual(4, flags.count)
   expectEqual(flags.reversed().count, flags.count)
diff --git a/test/stdlib/IndexDistanceRemoval.swift b/test/stdlib/IndexDistanceRemoval.swift
index 5c81ccf..3922d6c 100644
--- a/test/stdlib/IndexDistanceRemoval.swift
+++ b/test/stdlib/IndexDistanceRemoval.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -swift-version 4
 
 struct Int64Distance<Element>: Collection {
   let _storage: [Element]
diff --git a/test/stdlib/KeyPathObjC.swift b/test/stdlib/KeyPathObjC.swift
index 1545f56..86150a6 100644
--- a/test/stdlib/KeyPathObjC.swift
+++ b/test/stdlib/KeyPathObjC.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift %s -o %t/a.out -swift-version 3
+// RUN: %target-build-swift %s -o %t/a.out
 // RUN: %target-run %t/a.out
 // REQUIRES: executable_test
 // REQUIRES: objc_interop
@@ -21,7 +21,7 @@
   @objc subscript(x: Int) -> Foo { return self }
   @objc subscript(x: Bar) -> Foo { return self }
 
-  dynamic var dynamic: Bar { fatalError() }
+  @objc dynamic var dynamic: Bar { fatalError() }
 
   let storedLet = LifetimeTracked(0)
 }
diff --git a/test/stdlib/NSError.swift b/test/stdlib/NSError.swift
index 418a88c..917d139 100644
--- a/test/stdlib/NSError.swift
+++ b/test/stdlib/NSError.swift
@@ -6,11 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-// RUN: %target-run-simple-swift-swift3
+// RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 // REQUIRES: objc_interop
 
-// RUN: %target-build-swift %s -swift-version 3 2> %t.warnings.txt
+// RUN: %target-build-swift %s 2> %t.warnings.txt
 // RUN: %FileCheck -check-prefix=CHECK-WARNINGS %s < %t.warnings.txt
 
 import StdlibUnittest
@@ -23,8 +23,8 @@
   let error = NSError(domain: "MyDomain", code: 1, userInfo: [
       // CHECK-WARNINGS: warning: 'localizedDescriptionKey' is deprecated: renamed to 'NSLocalizedDescriptionKey'
       // CHECK-WARNINGS: note: use 'NSLocalizedDescriptionKey' instead
-        AnyHashable(ErrorUserInfoKey.localizedDescriptionKey.rawValue): "description",
-        AnyHashable(NSLocalizedFailureReasonErrorKey): "reason"
+        ErrorUserInfoKey.localizedDescriptionKey.rawValue: "description",
+        NSLocalizedFailureReasonErrorKey: "reason"
       ])
   expectEqual("description", error.userInfo[NSLocalizedDescriptionKey]! as! String)
 
@@ -32,7 +32,7 @@
 
   // TODO: Without the 'as NSObject' conversion, this produces nil.
   // We may need to forward _CustomAnyHashable through swift_newtypes.
-  expectEqual("reason", error.userInfo[ErrorUserInfoKey.localizedFailureReasonErrorKey as NSObject]! as! String)
+  expectEqual("reason", error.userInfo[ErrorUserInfoKey.localizedFailureReasonErrorKey.rawValue]! as! String)
 }
 
 tests.test("convenience") {
diff --git a/test/stdlib/RuntimeObjC.swift b/test/stdlib/RuntimeObjC.swift
index f96192a..4dee6ff 100644
--- a/test/stdlib/RuntimeObjC.swift
+++ b/test/stdlib/RuntimeObjC.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
 //
 // RUN: %target-clang %S/Inputs/Mirror/Mirror.mm -c -o %t/Mirror.mm.o -g
-// RUN: %target-build-swift -parse-stdlib -Xfrontend -disable-access-control -module-name a -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o %s -o %t.out -swift-version 3
+// RUN: %target-build-swift -parse-stdlib -Xfrontend -disable-access-control -module-name a -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o %s -o %t.out
 // RUN: %target-run %t.out
 // REQUIRES: executable_test
 // REQUIRES: objc_interop
@@ -292,13 +292,13 @@
 
 
 Runtime.test("isBridgedToObjectiveC") {
-  expectTrue(_isBridgedToObjectiveC(BridgedValueType))
-  expectTrue(_isBridgedToObjectiveC(BridgedVerbatimRefType))
+  expectTrue(_isBridgedToObjectiveC(BridgedValueType.self))
+  expectTrue(_isBridgedToObjectiveC(BridgedVerbatimRefType.self))
 }
 
 Runtime.test("isBridgedVerbatimToObjectiveC") {
-  expectFalse(_isBridgedVerbatimToObjectiveC(BridgedValueType))
-  expectTrue(_isBridgedVerbatimToObjectiveC(BridgedVerbatimRefType))
+  expectFalse(_isBridgedVerbatimToObjectiveC(BridgedValueType.self))
+  expectTrue(_isBridgedVerbatimToObjectiveC(BridgedVerbatimRefType.self))
 }
 
 //===----------------------------------------------------------------------===//
@@ -700,7 +700,7 @@
   }
 }
 
-class TestArtificialSubclass: NSObject {
+@objc @objcMembers class TestArtificialSubclass: NSObject {
   dynamic var foo = "foo"
 }
 
diff --git a/test/stdlib/StringCompatibility.swift b/test/stdlib/StringCompatibility.swift
index 22c68d1..1251d25 100644
--- a/test/stdlib/StringCompatibility.swift
+++ b/test/stdlib/StringCompatibility.swift
@@ -279,8 +279,10 @@
   var sub = s[s.startIndex ..< s.endIndex]
   var subsub = sub[s.startIndex ..< s.endIndex]
 
-  expectType(ExpectedConcreteSlice.self, &sub)
-  expectType(ExpectedConcreteSlice.self, &subsub)
+  // slicing a String in Swift 3 produces a String
+  // but slicing a Substring should still produce a Substring
+  expectType(Substring.self, &sub)
+  expectType(Substring.self, &subsub)
 }
 
 Tests.test("Substring/ClosedRange/Slice/ExpectedType/\(swift)") {
diff --git a/test/stdlib/StringDiagnostics.swift b/test/stdlib/StringDiagnostics.swift
index 81d5fa3..893cbf2 100644
--- a/test/stdlib/StringDiagnostics.swift
+++ b/test/stdlib/StringDiagnostics.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -swift-version 3
+// RUN: %target-typecheck-verify-swift
 
 // XFAIL: linux
 
@@ -52,10 +52,10 @@
 
 func testStringDeprecation(hello: String) {
   let hello2 = hello
-    .addingPercentEscapes(using: .utf8) // expected-warning{{'addingPercentEscapes(using:)' is deprecated}}
+    .addingPercentEscapes(using: .utf8) // expected-error{{'addingPercentEscapes(using:)' is unavailable}}
 
   _ = hello2?
-    .replacingPercentEscapes(using: .utf8) // expected-warning{{'replacingPercentEscapes(using:)' is deprecated}}
+    .replacingPercentEscapes(using: .utf8) // expected-error{{'replacingPercentEscapes(using:)' is unavailable}}
 }
 
 // Positive and negative tests for String collection types. Testing the complete
diff --git a/test/stdlib/TestData.swift b/test/stdlib/TestData.swift
index 9e5f266..a4cec23 100644
--- a/test/stdlib/TestData.swift
+++ b/test/stdlib/TestData.swift
@@ -10,7 +10,7 @@
 // RUN: %empty-directory(%t)
 //
 // RUN: %target-clang %S/Inputs/FoundationBridge/FoundationBridge.m -c -o %t/FoundationBridgeObjC.o -g
-// RUN: %target-build-swift %s -I %S/Inputs/FoundationBridge/ -Xlinker %t/FoundationBridgeObjC.o -o %t/TestData -swift-version 3
+// RUN: %target-build-swift %s -I %S/Inputs/FoundationBridge/ -Xlinker %t/FoundationBridgeObjC.o -o %t/TestData
 
 // RUN: %target-run %t/TestData
 // REQUIRES: executable_test
@@ -257,8 +257,7 @@
             // Mutate it
             bytes.pointee = 0x67
             expectEqual(bytes.pointee, 0x67, "First byte should be 0x67")
-            expectEqual(mutatingHello[0], 0x67, "First byte accessed via other method should still be 0x67")
-            
+
             // Verify that the first data is still correct
             expectEqual(hello[0], 0x68, "The first byte should still be 0x68")
         }
@@ -283,7 +282,6 @@
             // Mutate the second data
             bytes.pointee = 0
             expectEqual(bytes.pointee, 0, "First byte should be 0")
-            expectEqual(allOnesCopyToMutate[0], 0, "First byte accessed via other method should still be 0")
             
             // Verify that the first data is still 1
             expectEqual(allOnesData[0], 1, "The first byte should still be 1")
diff --git a/test/stdlib/TestDecimal.swift b/test/stdlib/TestDecimal.swift
index 463890e..afa3636 100644
--- a/test/stdlib/TestDecimal.swift
+++ b/test/stdlib/TestDecimal.swift
@@ -9,7 +9,7 @@
 // RUN: %empty-directory(%t)
 //
 // RUN: %target-clang %S/Inputs/FoundationBridge/FoundationBridge.m -c -o %t/FoundationBridgeObjC.o -g
-// RUN: %target-build-swift %s -I %S/Inputs/FoundationBridge/ -Xlinker %t/FoundationBridgeObjC.o -o %t/TestDecimal -swift-version 3
+// RUN: %target-build-swift %s -I %S/Inputs/FoundationBridge/ -Xlinker %t/FoundationBridgeObjC.o -o %t/TestDecimal
 
 // RUN: %target-run %t/TestDecimal > %t.txt
 // REQUIRES: executable_test
@@ -244,7 +244,7 @@
                     var failed: Bool = false
                     var count = 0
                     let SIG_FIG = 14
-                    for (a, b) in zip(answerDescription.characters, approximationDescription.characters) {
+                    for (a, b) in zip(answerDescription, approximationDescription) {
                         if a != b {
                             failed = true
                             break
@@ -299,33 +299,36 @@
         expectEqual(Decimal(1.234), abs(Decimal(1.234)))
         expectEqual(Decimal(1.234), abs(Decimal(-1.234)))
         var a = Decimal(1234)
-        expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&a, &a, 1, .plain))
-        expectEqual(Decimal(12340), a)
+        var r = a
+        expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&r, &a, 1, .plain))
+        expectEqual(Decimal(12340), r)
         a = Decimal(1234)
-        expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&a, &a, 2, .plain))
-        expectEqual(Decimal(123400), a)
-        expectEqual(.overflow, NSDecimalMultiplyByPowerOf10(&a, &a, 128, .plain))
-        expectTrue(a.isNaN)
+        expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&r, &a, 2, .plain))
+        expectEqual(Decimal(123400), r)
+        expectEqual(.overflow, NSDecimalMultiplyByPowerOf10(&r, &a, 128, .plain))
+        expectTrue(r.isNaN)
         a = Decimal(1234)
-        expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&a, &a, -2, .plain))
-        expectEqual(Decimal(12.34), a)
-        expectEqual(.underflow, NSDecimalMultiplyByPowerOf10(&a, &a, -128, .plain))
-        expectTrue(a.isNaN)
+        expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&r, &a, -2, .plain))
+        expectEqual(Decimal(12.34), r)
+        var ur = r
+        expectEqual(.underflow, NSDecimalMultiplyByPowerOf10(&ur, &r, -128, .plain))
+        expectTrue(ur.isNaN)
         a = Decimal(1234)
-        expectEqual(.noError, NSDecimalPower(&a, &a, 0, .plain))
-        expectEqual(Decimal(1), a)
+        expectEqual(.noError, NSDecimalPower(&r, &a, 0, .plain))
+        expectEqual(Decimal(1), r)
         a = Decimal(8)
-        expectEqual(.noError, NSDecimalPower(&a, &a, 2, .plain))
-        expectEqual(Decimal(64), a)
+        expectEqual(.noError, NSDecimalPower(&r, &a, 2, .plain))
+        expectEqual(Decimal(64), r)
         a = Decimal(-2)
-        expectEqual(.noError, NSDecimalPower(&a, &a, 3, .plain))
-        expectEqual(Decimal(-8), a)
+        expectEqual(.noError, NSDecimalPower(&r, &a, 3, .plain))
+        expectEqual(Decimal(-8), r)
         for i in -2...10 {
             for j in 0...5 {
                 var actual = Decimal(i)
-                expectEqual(.noError, NSDecimalPower(&actual, &actual, j, .plain))
+                var result = actual
+                expectEqual(.noError, NSDecimalPower(&result, &actual, j, .plain))
                 let expected = Decimal(pow(Double(i), Double(j)))
-                expectEqual(expected, actual, "\(actual) == \(i)^\(j)")
+                expectEqual(expected, result, "\(result) == \(i)^\(j)")
             }
         }
     }
@@ -510,8 +513,9 @@
         for testCase in testCases {
             let (expected, start, scale, mode) = testCase
             var num = Decimal(start)
-            NSDecimalRound(&num, &num, scale, mode)
-            expectEqual(Decimal(expected), num)
+            var r = num
+            NSDecimalRound(&r, &num, scale, mode)
+            expectEqual(Decimal(expected), r)
             let numnum = NSDecimalNumber(decimal:Decimal(start))
             let behavior = NSDecimalNumberHandler(roundingMode: mode, scale: Int16(scale), raiseOnExactness: false, raiseOnOverflow: true, raiseOnUnderflow: true, raiseOnDivideByZero: true)
             let result = numnum.rounding(accordingToBehavior:behavior)
diff --git a/test/stmt/switch_stmt2.swift b/test/stmt/switch_stmt2.swift
index a74cd36..49c9928 100644
--- a/test/stmt/switch_stmt2.swift
+++ b/test/stmt/switch_stmt2.swift
@@ -136,3 +136,17 @@
   }
   return x
 }
+
+// Do not crash if another switch statement follows a fallthrough.
+func fallthrough_not_last(i: Int) {
+  switch i {
+  case 1:
+    fallthrough
+    switch i {
+    case 1: break
+    default: break
+    }
+  default:
+    break
+  }
+}
diff --git a/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake b/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
index ea19c93..c030879 100644
--- a/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
+++ b/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
@@ -428,6 +428,13 @@
 
   add_dependencies(${framework_target} ${name})
 
+  # This is necessary to avoid having an rpath with an absolute build directory.
+  # Without this, such an rpath is added during build time and preserved at install time.
+  set_target_properties(${name} PROPERTIES
+                        BUILD_WITH_INSTALL_RPATH On
+                        INSTALL_RPATH "@loader_path/../lib"
+                        INSTALL_NAME_DIR "@rpath")
+
   if (SOURCEKIT_DEPLOYMENT_OS MATCHES "^macosx")
     add_custom_command(TARGET ${name} POST_BUILD
       COMMAND ${CMAKE_COMMAND} -E create_symlink "Versions/Current/XPCServices" XPCServices
diff --git a/tools/SourceKit/include/SourceKit/Core/LangSupport.h b/tools/SourceKit/include/SourceKit/Core/LangSupport.h
index 7c009cc..9bb3fcf 100644
--- a/tools/SourceKit/include/SourceKit/Core/LangSupport.h
+++ b/tools/SourceKit/include/SourceKit/Core/LangSupport.h
@@ -190,7 +190,6 @@
 
 class EditorConsumer {
   virtual void anchor();
-
 public:
   virtual ~EditorConsumer() { }
 
@@ -518,7 +517,6 @@
   codeCompleteSetCustom(ArrayRef<CustomCompletionInfo> completions) = 0;
 
   virtual void editorOpen(StringRef Name, llvm::MemoryBuffer *Buf,
-                          bool EnableSyntaxMap,
                           EditorConsumer &Consumer,
                           ArrayRef<const char *> Args) = 0;
 
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
index 23d9ba8..7a0d175 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
@@ -2027,7 +2027,6 @@
 //===----------------------------------------------------------------------===//
 
 void SwiftLangSupport::editorOpen(StringRef Name, llvm::MemoryBuffer *Buf,
-                                  bool EnableSyntaxMap,
                                   EditorConsumer &Consumer,
                                   ArrayRef<const char *> Args) {
 
@@ -2084,7 +2083,8 @@
 // EditorReplaceText
 //===----------------------------------------------------------------------===//
 
-void SwiftLangSupport::editorReplaceText(StringRef Name, llvm::MemoryBuffer *Buf,
+void SwiftLangSupport::editorReplaceText(StringRef Name,
+                                         llvm::MemoryBuffer *Buf,
                                          unsigned Offset, unsigned Length,
                                          EditorConsumer &Consumer) {
   auto EditorDoc = EditorDocuments.getByUnresolvedName(Name);
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
index b1bf255..b90d5b6 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
@@ -397,7 +397,7 @@
   void
   codeCompleteSetCustom(ArrayRef<CustomCompletionInfo> completions) override;
 
-  void editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, bool EnableSyntaxMap,
+  void editorOpen(StringRef Name, llvm::MemoryBuffer *Buf,
                   EditorConsumer &Consumer,
                   ArrayRef<const char *> Args) override;
 
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
index 740f99f..d88d0f4 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
@@ -68,6 +68,15 @@
     return StringRef(Name);
   }
 };
+
+struct SKEditorConsumerOptions {
+  bool EnableSyntaxMap = false;
+  bool EnableStructure = false;
+  bool EnableDiagnostics = false;
+  bool EnableSyntaxTree = false;
+  bool SyntacticOnly = false;
+};
+
 } // anonymous namespace
 
 #define REQUEST(NAME, CONTENT) static LazySKDUID Request##NAME(CONTENT);
@@ -151,9 +160,8 @@
 static sourcekitd_response_t codeCompleteClose(StringRef name, int64_t Offset);
 
 static sourcekitd_response_t
-editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, bool EnableSyntaxMap,
-           bool EnableStructure, bool EnableDiagnostics, bool EnableSyntaxTree,
-           bool SyntacticOnly, ArrayRef<const char *> Args);
+editorOpen(StringRef Name, llvm::MemoryBuffer *Buf,
+           SKEditorConsumerOptions Opts, ArrayRef<const char *> Args);
 
 static sourcekitd_response_t
 editorOpenInterface(StringRef Name, StringRef ModuleName,
@@ -186,9 +194,7 @@
 
 static sourcekitd_response_t
 editorReplaceText(StringRef Name, llvm::MemoryBuffer *Buf, unsigned Offset,
-                  unsigned Length, bool EnableSyntaxMap, bool EnableStructure,
-                  bool EnableDiagnostics, bool EnableSyntaxTree,
-                  bool SyntacticOnly);
+                  unsigned Length, SKEditorConsumerOptions Opts);
 
 static void
 editorApplyFormatOptions(StringRef Name, RequestDict &FmtOptions);
@@ -429,9 +435,14 @@
     Req.getInt64(KeyEnableSyntaxTree, EnableSyntaxTree, /*isOptional=*/true);
     int64_t SyntacticOnly = false;
     Req.getInt64(KeySyntacticOnly, SyntacticOnly, /*isOptional=*/true);
-    return Rec(editorOpen(*Name, InputBuf.get(), EnableSyntaxMap, EnableStructure,
-                          EnableDiagnostics, EnableSyntaxTree, SyntacticOnly,
-                          Args));
+
+    SKEditorConsumerOptions Opts;
+    Opts.EnableSyntaxMap = EnableSyntaxMap;
+    Opts.EnableStructure = EnableStructure;
+    Opts.EnableDiagnostics = EnableDiagnostics;
+    Opts.EnableSyntaxTree = EnableSyntaxTree;
+    Opts.SyntacticOnly = SyntacticOnly;
+    return Rec(editorOpen(*Name, InputBuf.get(), Opts, Args));
   }
   if (ReqUID == RequestEditorClose) {
     Optional<StringRef> Name = Req.getString(KeyName);
@@ -465,10 +476,15 @@
     Req.getInt64(KeyEnableSyntaxTree, EnableSyntaxTree, /*isOptional=*/true);
     int64_t SyntacticOnly = false;
     Req.getInt64(KeySyntacticOnly, SyntacticOnly, /*isOptional=*/true);
-    return Rec(editorReplaceText(*Name, InputBuf.get(), Offset, Length,
-                                 EnableSyntaxMap, EnableStructure,
-                                 EnableDiagnostics, EnableSyntaxTree,
-                                 SyntacticOnly));
+
+    SKEditorConsumerOptions Opts;
+    Opts.EnableSyntaxMap = EnableSyntaxMap;
+    Opts.EnableStructure = EnableStructure;
+    Opts.EnableDiagnostics = EnableDiagnostics;
+    Opts.EnableSyntaxTree = EnableSyntaxTree;
+    Opts.SyntacticOnly = SyntacticOnly;
+
+    return Rec(editorReplaceText(*Name, InputBuf.get(), Offset, Length, Opts));
   }
   if (ReqUID == RequestEditorFormatText) {
     Optional<StringRef> Name = Req.getString(KeyName);
@@ -1984,35 +2000,22 @@
   ResponseBuilder::Array Diags;
   sourcekitd_response_t Error = nullptr;
 
-  bool EnableSyntaxMap;
-  bool EnableStructure;
-  bool EnableDiagnostics;
-  bool EnableSyntaxTree;
-  bool SyntacticOnly;
+  SKEditorConsumerOptions Opts;
 
 public:
-  SKEditorConsumer(bool EnableSyntaxMap, bool EnableStructure,
-                   bool EnableDiagnostics, bool EnableSyntaxTree,
-                   bool SyntacticOnly)
-      : EnableSyntaxMap(EnableSyntaxMap), EnableStructure(EnableStructure),
-        EnableDiagnostics(EnableDiagnostics), EnableSyntaxTree(EnableSyntaxTree),
-        SyntacticOnly(SyntacticOnly) {
-
+  SKEditorConsumer(SKEditorConsumerOptions Opts) : Opts(Opts) {
     Dict = RespBuilder.getDictionary();
   }
 
-  SKEditorConsumer(ResponseReceiver RespReceiver, bool EnableSyntaxMap,
-                   bool EnableStructure, bool EnableDiagnostics,
-                   bool EnableSyntaxTree, bool SyntacticOnly)
-  : SKEditorConsumer(EnableSyntaxMap, EnableStructure,
-                     EnableDiagnostics, EnableSyntaxTree, SyntacticOnly) {
+  SKEditorConsumer(ResponseReceiver RespReceiver, SKEditorConsumerOptions Opts)
+      : SKEditorConsumer(Opts) {
     this->RespReceiver = RespReceiver;
   }
 
   sourcekitd_response_t createResponse();
 
   bool needsSemanticInfo() override {
-    return !SyntacticOnly && !isSemanticEditorDisabled();
+    return !Opts.SyntacticOnly && !isSemanticEditorDisabled();
   }
 
   void handleRequestError(const char *Description) override;
@@ -2056,7 +2059,7 @@
 
   bool handleSourceText(StringRef Text) override;
   bool handleSerializedSyntaxTree(StringRef Text) override;
-  virtual bool syntaxTreeEnabled() override;
+  bool syntaxTreeEnabled() override { return Opts.EnableSyntaxTree; }
   void finished() override {
     if (RespReceiver)
       RespReceiver(createResponse());
@@ -2066,13 +2069,11 @@
 } // end anonymous namespace
 
 static sourcekitd_response_t
-editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, bool EnableSyntaxMap,
-           bool EnableStructure, bool EnableDiagnostics, bool EnableSyntaxTree,
-           bool SyntacticOnly, ArrayRef<const char *> Args) {
-  SKEditorConsumer EditC(EnableSyntaxMap, EnableStructure,
-                         EnableDiagnostics, EnableSyntaxTree, SyntacticOnly);
+editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, SKEditorConsumerOptions Opts,
+           ArrayRef<const char *> Args) {
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
-  Lang.editorOpen(Name, Buf, EnableSyntaxMap, EditC, Args);
+  Lang.editorOpen(Name, Buf, EditC, Args);
   return EditC.createResponse();
 }
 
@@ -2081,11 +2082,10 @@
                     Optional<StringRef> Group, ArrayRef<const char *> Args,
                     bool SynthesizedExtensions,
                     Optional<StringRef> InterestedUSR) {
-  SKEditorConsumer EditC(/*EnableSyntaxMap=*/true,
-                         /*EnableStructure=*/true,
-                         /*EnableDiagnostics=*/false,
-                         /*EnableSyntaxTree=*/false,
-                         /*SyntacticOnly=*/false);
+  SKEditorConsumerOptions Opts;
+  Opts.EnableSyntaxMap = true;
+  Opts.EnableStructure = true;
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorOpenInterface(EditC, Name, ModuleName, Group, Args,
                            SynthesizedExtensions, InterestedUSR);
@@ -2099,12 +2099,10 @@
 editorOpenSwiftSourceInterface(StringRef Name, StringRef HeaderName,
                                ArrayRef<const char *> Args,
                                ResponseReceiver Rec) {
-  auto EditC = std::make_shared<SKEditorConsumer>(Rec,
-                                                  /*EnableSyntaxMap=*/true,
-                                                  /*EnableStructure=*/true,
-                                                  /*EnableDiagnostics=*/false,
-                                                  /*EnableSyntaxTree=*/false,
-                                                  /*SyntacticOnly=*/false);
+  SKEditorConsumerOptions Opts;
+  Opts.EnableSyntaxMap = true;
+  Opts.EnableStructure = true;
+  auto EditC = std::make_shared<SKEditorConsumer>(Rec, Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorOpenSwiftSourceInterface(Name, HeaderName, Args, EditC);
 }
@@ -2112,33 +2110,27 @@
 static void
 editorOpenSwiftTypeInterface(StringRef TypeUsr, ArrayRef<const char *> Args,
                              ResponseReceiver Rec) {
-  auto EditC = std::make_shared<SKEditorConsumer>(Rec,
-                                                  /*EnableSyntaxMap=*/true,
-                                                  /*EnableStructure=*/true,
-                                                  /*EnableDiagnostics=*/false,
-                                                  /*EnableSyntaxTree=*/false,
-                                                  /*SyntacticOnly=*/false);
+  SKEditorConsumerOptions Opts;
+  Opts.EnableSyntaxMap = true;
+  Opts.EnableStructure = true;
+  auto EditC = std::make_shared<SKEditorConsumer>(Rec, Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorOpenTypeInterface(*EditC, Args, TypeUsr);
 }
 
 static sourcekitd_response_t editorExtractTextFromComment(StringRef Source) {
-  SKEditorConsumer EditC(/*EnableSyntaxMap=*/false,
-                         /*EnableStructure=*/false,
-                         /*EnableDiagnostics=*/false,
-                         /*EnableSyntaxTree=*/false,
-                         /*SyntacticOnly=*/true);
+  SKEditorConsumerOptions Opts;
+  Opts.SyntacticOnly = true;
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorExtractTextFromComment(Source, EditC);
   return EditC.createResponse();
 }
 
 static sourcekitd_response_t editorConvertMarkupToXML(StringRef Source) {
-  SKEditorConsumer EditC(/*EnableSyntaxMap=*/false,
-                         /*EnableStructure=*/false,
-                         /*EnableDiagnostics=*/false,
-                         /*EnableSyntaxTree=*/false,
-                         /*SyntacticOnly=*/true);
+  SKEditorConsumerOptions Opts;
+  Opts.SyntacticOnly = true;
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorConvertMarkupToXML(Source, EditC);
   return EditC.createResponse();
@@ -2150,11 +2142,10 @@
                           bool UsingSwiftArgs,
                           bool SynthesizedExtensions,
                           StringRef swiftVersion) {
-  SKEditorConsumer EditC(/*EnableSyntaxMap=*/true,
-                         /*EnableStructure=*/true,
-                         /*EnableDiagnostics=*/false,
-                         /*EnableSyntaxTree=*/false,
-                         /*SyntacticOnly=*/false);
+  SKEditorConsumerOptions Opts;
+  Opts.EnableSyntaxMap = true;
+  Opts.EnableStructure = true;
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorOpenHeaderInterface(EditC, Name, HeaderName, Args, UsingSwiftArgs,
                                  SynthesizedExtensions, swiftVersion);
@@ -2171,11 +2162,8 @@
 
 static sourcekitd_response_t
 editorReplaceText(StringRef Name, llvm::MemoryBuffer *Buf, unsigned Offset,
-                  unsigned Length, bool EnableSyntaxMap, bool EnableStructure,
-                  bool EnableDiagnostics, bool EnableSyntaxTree,
-                  bool SyntacticOnly) {
-  SKEditorConsumer EditC(EnableSyntaxMap, EnableStructure,
-                         EnableDiagnostics, EnableSyntaxTree, SyntacticOnly);
+                  unsigned Length, SKEditorConsumerOptions Opts) {
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorReplaceText(Name, Buf, Offset, Length, EditC);
   return EditC.createResponse();
@@ -2190,8 +2178,9 @@
 
 static sourcekitd_response_t
 editorFormatText(StringRef Name, unsigned Line, unsigned Length) {
-  SKEditorConsumer EditC(false, false, false, false,
-                         /*SyntacticOnly=*/true);
+  SKEditorConsumerOptions Opts;
+  Opts.SyntacticOnly = true;
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorFormatText(Name, Line, Length, EditC);
   return EditC.createResponse();
@@ -2199,8 +2188,9 @@
 
 static sourcekitd_response_t
 editorExpandPlaceholder(StringRef Name, unsigned Offset, unsigned Length) {
-  SKEditorConsumer EditC(false, false, false, false,
-                         /*SyntacticOnly=*/true);
+  SKEditorConsumerOptions Opts;
+  Opts.SyntacticOnly = true;
+  SKEditorConsumer EditC(Opts);
   LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
   Lang.editorExpandPlaceholder(Name, Offset, Length, EditC);
   return EditC.createResponse();
@@ -2210,7 +2200,7 @@
   if (Error)
     return Error;
 
-  if (EnableSyntaxMap) {
+  if (Opts.EnableSyntaxMap) {
     Dict.setCustomBuffer(KeySyntaxMap,
         CustomBufferKind::TokenAnnotationsArray,
         SyntaxMap.createBuffer());
@@ -2220,7 +2210,7 @@
         CustomBufferKind::TokenAnnotationsArray,
         SemanticAnnotations.createBuffer());
   }
-  if (EnableStructure) {
+  if (Opts.EnableStructure) {
     Dict.setCustomBuffer(KeySubStructure, CustomBufferKind::DocStructureArray,
                          DocStructure.createBuffer());
   }
@@ -2241,7 +2231,7 @@
 
 bool SKEditorConsumer::handleSyntaxMap(unsigned Offset, unsigned Length,
                                        UIdent Kind) {
-  if (!EnableSyntaxMap)
+  if (!Opts.EnableSyntaxMap)
     return true;
 
   SyntaxMap.add(Kind, Offset, Length, /*IsSystem=*/false);
@@ -2273,7 +2263,7 @@
                                             StringRef SelectorName,
                                             ArrayRef<StringRef> InheritedTypes,
                                             ArrayRef<std::tuple<UIdent, unsigned, unsigned>> Attrs) {
-  if (EnableStructure) {
+  if (Opts.EnableStructure) {
     DocStructure.beginSubStructure(
         Offset, Length, Kind, AccessLevel, SetterAccessLevel, NameOffset,
         NameLength, BodyOffset, BodyLength, DocOffset, DocLength, DisplayName,
@@ -2283,7 +2273,7 @@
 }
 
 bool SKEditorConsumer::endDocumentSubStructure() {
-  if (EnableStructure)
+  if (Opts.EnableStructure)
     DocStructure.endSubStructure();
   return true;
 }
@@ -2291,7 +2281,7 @@
 bool SKEditorConsumer::handleDocumentSubStructureElement(UIdent Kind,
                                                          unsigned Offset,
                                                          unsigned Length) {
-  if (EnableStructure)
+  if (Opts.EnableStructure)
     DocStructure.addElement(Kind, Offset, Length);
   return true;
 }
@@ -2387,7 +2377,7 @@
 
 bool SKEditorConsumer::handleDiagnostic(const DiagnosticEntryInfo &Info,
                                         UIdent DiagStage) {
-  if (!EnableDiagnostics)
+  if (!Opts.EnableDiagnostics)
     return true;
 
   ResponseBuilder::Array &Arr = Diags;
@@ -2405,12 +2395,8 @@
   return true;
 }
 
-bool SKEditorConsumer::syntaxTreeEnabled() {
-  return EnableSyntaxTree;
-}
-
 bool SKEditorConsumer::handleSerializedSyntaxTree(StringRef Text) {
-  if (EnableSyntaxTree)
+  if (syntaxTreeEnabled())
     Dict.set(KeySerializedSyntaxTree, Text);
   return true;
 }
diff --git a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp
index dc9ef9b..1c6a60b 100644
--- a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp
+++ b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp
@@ -192,6 +192,9 @@
   llvm::cl::opt<std::string> DumpTypeFromMangled(
       "type-from-mangled", llvm::cl::desc("dump type from mangled names list"));
 
+  llvm::cl::opt<std::string> ResourceDir("resource-dir",
+      llvm::cl::desc("The directory that holds the compiler resource files"));
+
   llvm::cl::ParseCommandLineOptions(argc, argv);
   // Unregister our options so they don't interfere with the command line
   // parsing in CodeGen/BackendUtil.cpp.
@@ -254,6 +257,10 @@
   Invocation.setModuleName("lldbtest");
   Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
 
+  if (!ResourceDir.empty()) {
+    Invocation.setRuntimeResourcePath(ResourceDir);
+  }
+
   if (CI.setup(Invocation))
     return 1;
 
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index c3dba4b..d371862 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -1854,6 +1854,8 @@
     // Get the (sub)module to print.
     auto *M = getModuleByFullName(Context, ModuleToPrint);
     if (!M) {
+      llvm::errs() << "error: could not find module '" << ModuleToPrint
+                   << "'\n";
       ExitCode = 1;
       continue;
     }
@@ -1873,6 +1875,8 @@
     if (ModuleName.size() > 1) {
       M = getModuleByFullName(Context, ModuleName[0]);
       if (!M) {
+        llvm::errs() << "error: could not find module '" << ModuleName[0]
+                     << "'\n";
         ExitCode = 1;
         continue;
       }
diff --git a/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp b/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp
index 4b314a2..3477e8d 100644
--- a/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp
+++ b/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp
@@ -136,8 +136,7 @@
     auto Args = CArgs.hasValue() ? makeArgs(DocName, *CArgs)
                                  : std::vector<const char *>{};
     auto Buf = MemoryBuffer::getMemBufferCopy(Text, DocName);
-    getLang().editorOpen(DocName, Buf.get(), /*EnableSyntaxMap=*/false,
-                         Consumer, Args);
+    getLang().editorOpen(DocName, Buf.get(), Consumer, Args);
   }
 
   void replaceText(StringRef DocName, unsigned Offset, unsigned Length,
diff --git a/unittests/SourceKit/SwiftLang/EditingTest.cpp b/unittests/SourceKit/SwiftLang/EditingTest.cpp
index 0c61b0f..bc7d217 100644
--- a/unittests/SourceKit/SwiftLang/EditingTest.cpp
+++ b/unittests/SourceKit/SwiftLang/EditingTest.cpp
@@ -157,8 +157,7 @@
             EditorConsumer &Consumer) {
     auto Args = makeArgs(DocName, CArgs);
     auto Buf = MemoryBuffer::getMemBufferCopy(Text, DocName);
-    getLang().editorOpen(DocName, Buf.get(), /*EnableSyntaxMap=*/false, Consumer,
-                         Args);
+    getLang().editorOpen(DocName, Buf.get(), Consumer, Args);
   }
 
   void close(const char *DocName) {
diff --git a/utils/swift-api-dump.py b/utils/swift-api-dump.py
index 1e10b76..8355e3a 100755
--- a/utils/swift-api-dump.py
+++ b/utils/swift-api-dump.py
@@ -5,9 +5,9 @@
 # (Objective-)C APIs, any API notes added on top of those APIs, and the
 # Clang importer itself. One can execute it to dump the API of a given
 # module within a particular SDK, e.g., UIKit from the iOS SDK as seen in
-# Swift 3 compatibility mode:
+# Swift 4 compatibility mode:
 #
-#   /path/to/bin/dir/swift-api-dump.py -swift-version 3 -o output-dir \
+#   /path/to/bin/dir/swift-api-dump.py -swift-version 4 -o output-dir \
 #       -m UIKit -s iphoneos
 #
 # The "-m" argument can be omitted, in which case the script will collect
@@ -15,9 +15,9 @@
 #
 # One can supply multiple SDKs, written as a list. For example, to
 # dump the API for all frameworks across macOS, iOS, watchOS, and tvOS,
-# in Swift 4, use:
+# in Swift 4.2, use:
 #
-#  /path/to/bin/dir/swift-api-dump.py -swift-version 4 -o output-dir \
+#  /path/to/bin/dir/swift-api-dump.py -swift-version 4.2 -o output-dir \
 #      -s macosx iphoneos watchos appletvos
 #
 
@@ -102,7 +102,7 @@
     parser.add_argument('--enable-infer-import-as-member', action='store_true',
                         help='Infer when a global could be imported as a ' +
                         'member.')
-    parser.add_argument('-swift-version', type=int, metavar='N',
+    parser.add_argument('-swift-version', metavar='N',
                         help='the Swift version to use')
     parser.add_argument('-show-overlay', action='store_true',
                         help='Show overlay API in addition to Objective-C ' +
@@ -326,7 +326,7 @@
     if args.enable_infer_import_as_member:
         extra_args = extra_args + ['-enable-infer-import-as-member']
     if args.swift_version:
-        extra_args = extra_args + ['-swift-version', '%d' % args.swift_version]
+        extra_args = extra_args + ['-swift-version', '%s' % args.swift_version]
 
     # Create a .swift file we can feed into swift-ide-test
     subprocess.call(['touch', source_filename])
diff --git a/utils/swift-project-settings.el b/utils/swift-project-settings.el
index ec6ecc1..fcbeba1 100644
--- a/utils/swift-project-settings.el
+++ b/utils/swift-project-settings.el
@@ -114,7 +114,7 @@
 ;; project settings yet.  For example, Swift files may come up in
 ;; Fundamental mode, and C++ files won't use the swift style, unless
 ;; we do something.  This hack causes the file to be re-mode-ed.
-(set-auto-mode)
+(ignore-errors (set-auto-mode))
 
 (defun swift-project-comment-end ()
   "If comment-end is non-empty returns it, stripped of leading whitespace.  Returns nil otherwise"
diff --git a/validation-test/Sema/type_checker_perf/slow/rdar22770433.swift b/validation-test/Sema/type_checker_perf/fast/rdar22770433.swift
similarity index 85%
rename from validation-test/Sema/type_checker_perf/slow/rdar22770433.swift
rename to validation-test/Sema/type_checker_perf/fast/rdar22770433.swift
index cd2d914..ad4f07a 100644
--- a/validation-test/Sema/type_checker_perf/slow/rdar22770433.swift
+++ b/validation-test/Sema/type_checker_perf/fast/rdar22770433.swift
@@ -3,7 +3,6 @@
 
 func test(n: Int) -> Int {
   return n == 0 ? 0 : (0..<n).reduce(0) {
-  // expected-error@-1 {{reasonable time}}
     ($0 > 0 && $1 % 2 == 0) ? (($0 + $1) / ($1 - $0)) : $0
   }
 }
diff --git a/validation-test/Serialization/Inputs/custom-modules/module.modulemap b/validation-test/Serialization/Inputs/custom-modules/module.modulemap
new file mode 100644
index 0000000..b8ef16f
--- /dev/null
+++ b/validation-test/Serialization/Inputs/custom-modules/module.modulemap
@@ -0,0 +1 @@
+module rdar40899824Helper { header "rdar40899824Helper.h" }
diff --git a/validation-test/Serialization/Inputs/custom-modules/rdar40899824Helper.h b/validation-test/Serialization/Inputs/custom-modules/rdar40899824Helper.h
new file mode 100644
index 0000000..390ee41
--- /dev/null
+++ b/validation-test/Serialization/Inputs/custom-modules/rdar40899824Helper.h
@@ -0,0 +1,13 @@
+#ifndef BAD
+typedef struct {
+  int value;
+} SoonToBeMissing;
+#endif
+
+@interface Impl
+#ifndef BAD
+- (void)use:(SoonToBeMissing)value;
+#endif
+
+- (void)unrelated;
+@end
diff --git a/validation-test/Serialization/SR7337.swift b/validation-test/Serialization/SR7337.swift
new file mode 100644
index 0000000..b3f9c81
--- /dev/null
+++ b/validation-test/Serialization/SR7337.swift
@@ -0,0 +1,20 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-module -o %t/Lib.swiftmodule %s -DLIB
+// RUN: %target-build-swift -emit-module -o %t/main.swiftmodule -I %t %s
+
+#if LIB
+
+protocol Proto {}
+
+open class Base<T> {}
+public struct ArbitraryStruct {}
+
+extension Base: Proto where T: Proto {}
+
+#else // LIB
+
+import Lib
+
+final class ConcreteSub: Base<ArbitraryStruct> {}
+
+#endif // LIB
\ No newline at end of file
diff --git a/validation-test/Serialization/rdar40899824.swift b/validation-test/Serialization/rdar40899824.swift
new file mode 100644
index 0000000..1e793d5
--- /dev/null
+++ b/validation-test/Serialization/rdar40899824.swift
@@ -0,0 +1,38 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift %s -emit-module -o %t/Library.swiftmodule -I %S/Inputs/custom-modules -DLIBRARY -Xfrontend -enable-objc-interop -Xfrontend -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend %s -I %t -I %S/Inputs/custom-modules -enable-objc-interop -emit-ir > /dev/null
+
+// RUN: %target-swift-frontend %s -I %t -I %S/Inputs/custom-modules -enable-objc-interop -emit-ir -Xcc -DBAD > /dev/null
+// RUN: %target-swift-frontend %s -I %t -I %S/Inputs/custom-modules -enable-objc-interop -emit-ir -Xcc -DBAD -O > /dev/null
+
+#if LIBRARY
+
+import rdar40899824Helper
+
+public protocol Proto: class {
+  func use(_: SoonToBeMissing)
+  func unrelated()
+}
+
+extension Impl: Proto {}
+
+#else // LIBRARY
+
+import Library
+import rdar40899824Helper
+
+func testGeneric<T: Proto>(_ obj: T) {
+  obj.unrelated()
+}
+
+func testExistential(_ obj: Proto) {
+  obj.unrelated()
+}
+
+func test(_ proto: Proto, _ impl: Impl) {
+  impl.unrelated()
+  testGeneric(impl)
+  testExistential(impl)
+}
+
+#endif // LIBRARY
diff --git a/validation-test/stdlib/BoolDiagnostics_Dataflow.swift b/validation-test/stdlib/BoolDiagnostics_Dataflow.swift
index 29774a6..576b4d0 100644
--- a/validation-test/stdlib/BoolDiagnostics_Dataflow.swift
+++ b/validation-test/stdlib/BoolDiagnostics_Dataflow.swift
@@ -55,5 +55,5 @@
   }
 } // expected-error {{missing return in a function expected to return 'Int'}}
 
-// expected-warning@+1 {{'ExpressibleByStringInterpolation' is deprecated: it will be replaced or redesigned in Swift 4.0.  Instead of conforming to 'ExpressibleByStringInterpolation', consider adding an 'init(_:String)'}}
+// expected-warning@+1 {{'ExpressibleByStringInterpolation' is deprecated: it will be replaced or redesigned in Swift 5.0.  Instead of conforming to 'ExpressibleByStringInterpolation', consider adding an 'init(_:String)'}}
 typealias X = ExpressibleByStringInterpolation
diff --git a/validation-test/stdlib/CollectionCompatibility.swift b/validation-test/stdlib/CollectionCompatibility.swift
index 4040c41..4049393 100644
--- a/validation-test/stdlib/CollectionCompatibility.swift
+++ b/validation-test/stdlib/CollectionCompatibility.swift
@@ -24,7 +24,7 @@
 }
 
 //===--- MyBidiCollection -------------------------------------------------===//
-/// A simple collection that attempts to use an Int16 IndexDistance
+/// A simple collection that doesn't declare an IndexDistance
 struct MyBidiCollection<Element>: BidirectionalCollection {
   var _elements: [Element]
   
@@ -45,12 +45,12 @@
 
 CollectionDistance.test("Int16/distance") {
   let c = MyCollection<Int>(_elements: [1,2,3])
-  let d: Int16 = c.distance(from: c.startIndex, to: c.endIndex)
+  var d: Int16 = c.distance(from: c.startIndex, to: c.endIndex)
   expectEqual(3, d)
+  expectType(MyCollection<Int>.IndexDistance.self, &d)
   // without type context, you now get an Int
   var i = c.distance(from: c.startIndex, to: c.endIndex)
   expectType(Int.self, &i)
-  expectType(MyCollection<Int>.IndexDistance.self, &i)
 }
 
 CollectionDistance.test("Int16/advance") {
@@ -76,12 +76,10 @@
 
 CollectionDistance.test("Int64/distance") {
   let c = MyBidiCollection<Int>(_elements: [1,2,3])
-  let d: Int16 = c.distance(from: c.startIndex, to: c.endIndex)
+  var d = c.distance(from: c.startIndex, to: c.endIndex)
   expectEqual(3, d)
-  // without type context, you now get an Int
-  var i = c.distance(from: c.startIndex, to: c.endIndex)
-  expectType(Int.self, &i)
-  expectType(MyCollection<Int>.IndexDistance.self, &i)
+  expectType(Int.self, &d)
+  expectType(MyBidiCollection<Int>.IndexDistance.self, &d)
 }
 
 CollectionDistance.test("Int64/advance") {
@@ -106,4 +104,15 @@
   checkBidirectionalCollection(c, [1,2,3])
 }
 
+extension Collection where Index == Int, IndexDistance == Int {
+  var myCount: Int {
+    return distance(from: startIndex, to: endIndex)
+  }
+}
+
+CollectionDistance.test("IndexDistance/constraint") {
+  let n = [1,2,3].myCount
+  expectEqual(3, n)
+}
+
 runAllTests()
diff --git a/validation-test/stdlib/CollectionDiagnostics.swift b/validation-test/stdlib/CollectionDiagnostics.swift
index f1158bc..78cee40 100644
--- a/validation-test/stdlib/CollectionDiagnostics.swift
+++ b/validation-test/stdlib/CollectionDiagnostics.swift
@@ -48,7 +48,8 @@
   array.sorted { $0 < $1 } // expected-warning {{result of call to 'sorted(by:)' is unused}}
 }
 
-// expected-warning@+1 {{'Indexable' is deprecated: it will be removed in Swift 4.0.  Please use 'Collection' instead}}
+// expected-warning@+2 {{'Indexable' is deprecated: it will be removed in Swift 5.0.  Please use 'Collection' instead}}
+// expected-note@+1 {{use 'Collection' instead}}
 struct GoodIndexable : Indexable { 
   func index(after i: Int) -> Int { return i + 1 }
   var startIndex: Int { return 0 }
@@ -59,7 +60,8 @@
 }
 
 
-// expected-warning@+1 {{'Indexable' is deprecated: it will be removed in Swift 4.0.  Please use 'Collection' instead}}
+// expected-warning@+2 {{'Indexable' is deprecated: it will be removed in Swift 5.0.  Please use 'Collection' instead}}
+// expected-note@+1 {{use 'Collection' instead}}
 struct AnotherGoodIndexable1 : Indexable {
   func index(after i: Int) -> Int { return i + 1 }
   var startIndex: Int { return 0 }
@@ -68,8 +70,9 @@
   subscript(pos: Int) -> Int { return 0 }
 }
 
-// expected-warning@+2 {{'Indexable' is deprecated: it will be removed in Swift 4.0.  Please use 'Collection' instead}}
-// expected-error@+1 {{type 'BadIndexable2' does not conform to protocol 'Collection'}}
+// expected-warning@+3 {{'Indexable' is deprecated: it will be removed in Swift 5.0.  Please use 'Collection' instead}}
+// expected-error@+2 {{type 'BadIndexable2' does not conform to protocol 'Collection'}}
+// expected-note@+1 {{use 'Collection' instead}}
 struct BadIndexable2 : Indexable {
   var startIndex: Int { return 0 }
   var endIndex: Int { return 0 }
@@ -79,7 +82,8 @@
   // Missing index(after:) -> Int
 }
 
-// expected-warning@+1 {{'BidirectionalIndexable' is deprecated: it will be removed in Swift 4.0.  Please use 'BidirectionalCollection' instead}}
+// expected-warning@+2 {{'BidirectionalIndexable' is deprecated: it will be removed in Swift 5.0.  Please use 'BidirectionalCollection' instead}}
+// expected-note@+1 {{use 'BidirectionalCollection' instead}}
 struct GoodBidirectionalIndexable1 : BidirectionalIndexable {
   var startIndex: Int { return 0 }
   var endIndex: Int { return 0 }
@@ -92,7 +96,8 @@
 
 // We'd like to see: {{type 'BadBidirectionalIndexable' does not conform to protocol 'BidirectionalIndexable'}}
 // But the compiler doesn't generate that error.
-// expected-warning@+1 {{'BidirectionalIndexable' is deprecated: it will be removed in Swift 4.0.  Please use 'BidirectionalCollection' instead}}
+// expected-warning@+2 {{'BidirectionalIndexable' is deprecated: it will be removed in Swift 5.0.  Please use 'BidirectionalCollection' instead}}
+// expected-note@+1 {{use 'BidirectionalCollection' instead}}
 struct BadBidirectionalIndexable : BidirectionalIndexable {
   var startIndex: Int { return 0 }
   var endIndex: Int { return 0 }