Merge pull request #21487 from rintaro/parse-collection-rdar45221238

[Parse] Eliminate backtracking in collection expression parsing
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8166b35..859499f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -907,7 +907,7 @@
     message(SEND_ERROR "libdispatch requires a newer clang compiler (${CMAKE_C_COMPILER_VERSION} < 3.9)")
   endif()
 
-  if(SWIFT_HOST_VARIANT_SDK STREQUAL Windows)
+  if(SWIFT_HOST_VARIANT_SDK STREQUAL WINDOWS)
     set(SOURCEKIT_LIBDISPATCH_RUNTIME_DIR bin)
   else()
     set(SOURCEKIT_LIBDISPATCH_RUNTIME_DIR lib)
diff --git a/benchmark/scripts/Benchmark_Driver b/benchmark/scripts/Benchmark_Driver
index 6df7916..230e180 100755
--- a/benchmark/scripts/Benchmark_Driver
+++ b/benchmark/scripts/Benchmark_Driver
@@ -330,11 +330,15 @@
         super(BenchmarkDoctor, self).__init__()
         self.driver = driver or BenchmarkDriver(args)
         self.results = {}
-        self.console_handler = logging.StreamHandler(sys.stdout)
-        self.console_handler.setLevel(logging.DEBUG if args.verbose else
-                                      logging.INFO)
-        self.console_handler.setFormatter(
-            LoggingReportFormatter(use_color=sys.stdout.isatty()))
+
+        if hasattr(args, 'markdown') and args.markdown:
+            self.console_handler = MarkdownReportHandler(sys.stdout)
+        else:
+            self.console_handler = logging.StreamHandler(sys.stdout)
+            self.console_handler.setFormatter(
+                LoggingReportFormatter(use_color=sys.stdout.isatty()))
+            self.console_handler.setLevel(logging.DEBUG if args.verbose else
+                                          logging.INFO)
         self.log.addHandler(self.console_handler)
         self.log.debug('Checking tests: %s', ', '.join(self.driver.tests))
         self.requirements = [
@@ -350,6 +354,7 @@
         """Close log handlers on exit."""
         for handler in list(self.log.handlers):
             handler.close()
+        self.log.removeHandler(self.console_handler)
 
     benchmark_naming_convention_re = re.compile(r'[A-Z][a-zA-Z0-9\-.!?]+')
     camel_humps_re = re.compile(r'[a-z][A-Z]')
@@ -703,9 +708,13 @@
         'check',
         help='',
         parents=[shared_benchmarks_parser])
-    check_parser.add_argument(
+    check_group = check_parser.add_mutually_exclusive_group()
+    check_group.add_argument(
         '-v', '--verbose', action='store_true',
-        help='show more details during benchmark analysis',)
+        help='show more details during benchmark analysis')
+    check_group.add_argument(
+        '-md', '--markdown', action='store_true',
+        help='format report as Markdown table')
     check_parser.set_defaults(func=BenchmarkDoctor.run_check)
 
     compare_parser = subparsers.add_parser(
diff --git a/benchmark/scripts/test_Benchmark_Driver.py b/benchmark/scripts/test_Benchmark_Driver.py
index f0194ce..5ecf76f 100644
--- a/benchmark/scripts/test_Benchmark_Driver.py
+++ b/benchmark/scripts/test_Benchmark_Driver.py
@@ -120,6 +120,20 @@
         self.assertTrue(parse_args(['check', '-v']).verbose)
         self.assertTrue(parse_args(['check', '--verbose']).verbose)
 
+    def test_check_supports_mardown_output(self):
+        self.assertFalse(parse_args(['check']).markdown)
+        self.assertTrue(parse_args(['check', '-md']).markdown)
+        self.assertTrue(parse_args(['check', '--markdown']).markdown)
+
+    def test_check_flags_are_mutually_exclusive(self):
+        with captured_output() as (out, err):
+            self.assertRaises(SystemExit,
+                              parse_args, ['check', '-md', '-v'])
+        self.assert_contains(
+            ['error:', 'argument -v/--verbose: ' +
+             'not allowed with argument -md/--markdown'],
+            err.getvalue())
+
 
 class ArgsStub(object):
     def __init__(self):
@@ -497,7 +511,7 @@
 
     def setUp(self):
         super(TestBenchmarkDoctor, self).setUp()
-        self.args = Stub(verbose=False)
+        self.args = Stub(verbose=False, markdown=False)
         self._doctor_log_handler.reset()
         self.logs = self._doctor_log_handler.messages
 
@@ -516,8 +530,9 @@
     def test_supports_verbose_output(self):
         driver = BenchmarkDriverMock(tests=['B1', 'B2'])
         driver.verbose = True
+        self.args.verbose = True
         with captured_output() as (out, _):
-            BenchmarkDoctor(Stub(verbose=True), driver)
+            BenchmarkDoctor(self.args, driver)
         self.assert_contains(['Checking tests: B1, B2'], out.getvalue())
 
     def test_uses_report_formatter(self):
@@ -528,6 +543,14 @@
         self.assertTrue(isinstance(console_handler.formatter,
                                    LoggingReportFormatter))
 
+    def test_uses_optional_markdown_report_formatter(self):
+        self.args.markdown = True
+        with captured_output() as (_, _):
+            doc = BenchmarkDoctor(self.args, BenchmarkDriverMock(tests=['B1']))
+        self.assertTrue(doc)
+        console_handler = logging.getLogger('BenchmarkDoctor').handlers[1]
+        self.assertTrue(isinstance(console_handler, MarkdownReportHandler))
+
     def test_measure_10_independent_1s_benchmark_series(self):
         """Measurement strategy takes 5 i2 and 5 i1 series.
 
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index a9165aa..18f844d 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -1433,11 +1433,13 @@
     INSTALL_IN_COMPONENT "dev"
     )
 
-  swift_install_in_component(dev
-    TARGETS ${name}
-    ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
-    LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
-    RUNTIME DESTINATION bin)
+  if(NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+    swift_install_in_component(dev
+      TARGETS ${name}
+      ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+      LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+      RUNTIME DESTINATION bin)
+  endif()
 
   swift_is_installing_component(dev is_installing)
   if(NOT is_installing)
@@ -2015,10 +2017,19 @@
             WORLD_READ)
       endif()
 
-      swift_install_in_component("${SWIFTLIB_INSTALL_IN_COMPONENT}"
-          FILES "${UNIVERSAL_LIBRARY_NAME}"
-          DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${resource_dir}/${resource_dir_sdk_subdir}"
+      if(sdk STREQUAL WINDOWS AND CMAKE_SYSTEM_NAME STREQUAL Windows)
+        swift_install_in_component("${SWIFTLIB_INSTALL_IN_COMPONENT}"
+          TARGETS ${name}-windows-${SWIFT_PRIMARY_VARIANT_ARCH}
+          RUNTIME DESTINATION "bin"
+          LIBRARY DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${resource_dir}/${resource_dir_sdk_subdir}/${SWIFT_PRIMARY_VARIANT_ARCH}"
+          ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${resource_dir}/${resource_dir_sdk_subdir}/${SWIFT_PRIMARY_VARIANT_ARCH}"
           PERMISSIONS ${file_permissions})
+      else()
+        swift_install_in_component("${SWIFTLIB_INSTALL_IN_COMPONENT}"
+            FILES "${UNIVERSAL_LIBRARY_NAME}"
+            DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${resource_dir}/${resource_dir_sdk_subdir}"
+            PERMISSIONS ${file_permissions})
+      endif()
       if(sdk STREQUAL WINDOWS)
         foreach(arch ${SWIFT_SDK_WINDOWS_ARCHITECTURES})
           if(TARGET ${name}-windows-${arch}_IMPLIB)
@@ -2319,31 +2330,28 @@
 endmacro()
 
 function(add_swift_host_tool executable)
-  set(ADDSWIFTHOSTTOOL_multiple_parameter_options
-        SWIFT_COMPONENT)
+  set(options)
+  set(single_parameter_options SWIFT_COMPONENT)
+  set(multiple_parameter_options)
 
-  cmake_parse_arguments(
-      ADDSWIFTHOSTTOOL # prefix
-      "" # options
-      "" # single-value args
-      "${ADDSWIFTHOSTTOOL_multiple_parameter_options}" # multi-value args
-      ${ARGN})
+  cmake_parse_arguments(ASHT
+    "${options}"
+    "${single_parameter_options}"
+    "${multiple_parameter_options}"
+    ${ARGN})
 
-  precondition(ADDSWIFTHOSTTOOL_SWIFT_COMPONENT
+  precondition(ASHT_SWIFT_COMPONENT
                MESSAGE "Swift Component is required to add a host tool")
 
   # Create the executable rule.
-  add_swift_executable(
-    ${executable} 
-    ${ADDSWIFTHOSTTOOL_UNPARSED_ARGUMENTS}
-  )
+  add_swift_executable(${executable}
+    ${ASHT_UNPARSED_ARGUMENTS})
 
-  swift_install_in_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
+  swift_install_in_component(${ASHT_SWIFT_COMPONENT}
     TARGETS ${executable}
     RUNTIME DESTINATION bin)
 
-  swift_is_installing_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
-    is_installing)
+  swift_is_installing_component(${ASHT_SWIFT_COMPONENT} is_installing)
 
   if(NOT is_installing)
     set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${executable})
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index abf7917..132ad6e 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -7,6 +7,8 @@
   precondition_translate_flag(${product}_PATH_TO_LLVM_SOURCE PATH_TO_LLVM_SOURCE)
   precondition_translate_flag(${product}_PATH_TO_LLVM_BUILD PATH_TO_LLVM_BUILD)
 
+  file(TO_CMAKE_PATH "${PATH_TO_LLVM_BUILD}" PATH_TO_LLVM_BUILD)
+
   set(SWIFT_LLVM_CMAKE_PATHS
       "${PATH_TO_LLVM_BUILD}/share/llvm/cmake"
       "${PATH_TO_LLVM_BUILD}/lib/cmake/llvm")
@@ -139,6 +141,9 @@
   set(PATH_TO_CLANG_SOURCE "${${product}_PATH_TO_CLANG_SOURCE}")
   set(PATH_TO_CLANG_BUILD "${${product}_PATH_TO_CLANG_BUILD}")
 
+  file(TO_CMAKE_PATH "${PATH_TO_CLANG_SOURCE}" PATH_TO_CLANG_SOURCE)
+  file(TO_CMAKE_PATH "${PATH_TO_CLANG_BUILD}" PATH_TO_CLANG_BUILD)
+
   # Add all Clang CMake paths to our cmake module path.
   set(SWIFT_CLANG_CMAKE_PATHS
     "${PATH_TO_CLANG_BUILD}/share/clang/cmake"
@@ -188,12 +193,17 @@
     ABSOLUTE)
   get_filename_component(CMARK_LIBRARY_DIR "${${product}_CMARK_LIBRARY_DIR}"
     ABSOLUTE)
+
   set(CMARK_MAIN_INCLUDE_DIR "${CMARK_MAIN_SRC_DIR}/src")
   set(CMARK_BUILD_INCLUDE_DIR "${PATH_TO_CMARK_BUILD}/src")
+
+  file(TO_CMAKE_PATH "${CMARK_MAIN_INCLUDE_DIR}" CMARK_MAIN_INCLUDE_DIR)
+  file(TO_CMAKE_PATH "${CMARK_BUILD_INCLUDE_DIR}" CMARK_BUILD_INCLUDE_DIR)
+
   include_directories("${CMARK_MAIN_INCLUDE_DIR}"
                       "${CMARK_BUILD_INCLUDE_DIR}")
 
-  include(${${product}_PATH_TO_CMARK_BUILD}/src/CMarkExports.cmake)
+  include(${PATH_TO_CMARK_BUILD}/src/CMarkExports.cmake)
   add_definitions(-DCMARK_STATIC_DEFINE)
 endmacro()
 
diff --git a/docs/ByteTree.md b/docs/ByteTree.md
index 175c633..0ac4b87 100644
--- a/docs/ByteTree.md
+++ b/docs/ByteTree.md
@@ -13,20 +13,20 @@
 
 ## Serialization of objects
 
-An object consists of its size, measured in the number of fields and represented as a `uint_32t` in little endian order, followed by the direct concatenation of its fields. Because each field is again prefixed with its size, no delimites are necessary in between the fields.
+An object consists of its size, measured in the number of fields and represented as a `uint_32t` in little endian order, followed by the direct concatenation of its fields. Because each field is again prefixed with its size, no delimits are necessary in between the fields.
 
-To distinguish scalars and objects, the size of objects has its most-siginificant bit set to 1. It must be ignored to retrieve the number of fields in the object.
+To distinguish scalars and objects, the size of objects has its most-significant bit set to 1. It must be ignored to retrieve the number of fields in the object.
 
 Arrays are modelled as objects whose fields are all of the same type and whose length is variadic (and is indicated by the object's size).
 
 ## Versioning
 
-The ByteTree format is prepended by a 4-byte protocol version number that describes the version of the object tree that was serialized. Its exact semantics are up to each specific application, but it is encouraged to interpret it as a two-comentent number where the first component, consisting of the three most significant bytes, is incremented for breaking changes and the last byte is incremented for backwards-compatible changes.
+The ByteTree format is prepended by a 4-byte protocol version number that describes the version of the object tree that was serialized. Its exact semantics are up to each specific application, but it is encouraged to interpret it as a two-component number where the first component, consisting of the three most significant bytes, is incremented for breaking changes and the last byte is incremented for backwards-compatible changes.
 
-## Forward compatilibity
+## Forward compatibility
 
 Fields may be added to the end of objects in a backwards compatible manner (older deserialisers will still be able to deserialise the format). It does so by skipping over all fields that are not read during deserialisation. Newer versions of the deserialiser can detect if recently added fields are not present in the serialised data by inspecting the `numFields` property passed during deserialisation.
 
 ## Serialization safety
 
-Since all fields in objects are accessed by their index, issues quickly arise if a new field is accidentally added at the beginning of an object. To prevent issues like this, the ByteTree serialiser and deserialiser requires the explicit specification of each field's index within the object. These indicies are never serialised. Their sole purpose is to check that all fields are read in the correct order in assertion builds.
+Since all fields in objects are accessed by their index, issues quickly arise if a new field is accidentally added at the beginning of an object. To prevent issues like this, the ByteTree serialiser and deserialiser requires the explicit specification of each field's index within the object. These indices are never serialised. Their sole purpose is to check that all fields are read in the correct order in assertion builds.
diff --git a/docs/CompilerPerformance.md b/docs/CompilerPerformance.md
index a7b794d..bbf5e12 100644
--- a/docs/CompilerPerformance.md
+++ b/docs/CompilerPerformance.md
@@ -695,7 +695,7 @@
 
 This option also provides _some_ high-level counters that are "always available"
 regardless of whether you're using an assert or release build, though assert
-builds still get _more_ counters (all of those available thorugh
+builds still get _more_ counters (all of those available through
 `-print-stats`). If you are using a new-enough compiler, `-stats-output-dir`
 often simplifies analysis, since its output is machine-readable and aggregates
 all the jobs in a multi-job compilation, and there's a post-processing script
@@ -1322,7 +1322,7 @@
 
   - Add Open Source projects to the
     [source-compatibility testsuite](https://swift.org/source-compatibility/).
-    Apple's internal CI infastructure is now tracking selected non-assert-build
+    Apple's internal CI infrastructure is now tracking selected non-assert-build
     `UnifiedStatsReporter` counters on those projects, and the team is far
     more likely to catch a regression if it's shown by a project in the testsuite.
 
diff --git a/docs/Random.md b/docs/Random.md
index 98905f87..9603756 100644
--- a/docs/Random.md
+++ b/docs/Random.md
@@ -13,4 +13,4 @@
 - Linux, FreeBSD, and other UNIX-like platforms use `getrandom(2)` when available;
 otherwise, they read from `/dev/urandom`.
 - Fuchsia platforms use `getentropy(3)`.
-- Windows paltforms use `BCryptGenRandom`.
+- Windows platforms use `BCryptGenRandom`.
diff --git a/docs/SIL.rst b/docs/SIL.rst
index f396156..0531d6f 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -984,6 +984,7 @@
   sil-linkage ::= 'private'
   sil-linkage ::= 'public_external'
   sil-linkage ::= 'hidden_external'
+  sil-linkage ::= 'non_abi'
 
 A linkage specifier controls the situations in which two objects in
 different SIL modules are *linked*, i.e. treated as the same object.
@@ -1048,6 +1049,25 @@
 If an object has any uses, then it must be linked to a definition
 with non-external linkage.
 
+Public non-ABI linkage
+``````````````````````
+
+The `non_abi` linkage is a special linkage used for definitions which
+only exist in serialized SIL, and do not define visible symbols in the
+object file.
+
+A definition with `non_abi` linkage behaves like it has `shared` linkage,
+except that it must be serialized in the SIL module even if not referenced
+from anywhere else in the module. For example, this means it is considered
+a root for dead function elimination.
+
+When a `non_abi` definition is deserialized, it will have `shared_external`
+linkage.
+
+There is no `non_abi_external` linkage. Instead, when referencing a
+`non_abi` declaration that is defined in a different translation unit from
+the same Swift module, you must use `hidden_external` linkage.
+
 Summary
 ```````
 
@@ -4750,7 +4770,7 @@
 lifetime of its operand was not guaranteed by SILGen and a mandatory pass must
 be run to ensure the lifetime of ``%opd``` for the conversion's uses.
 
-A ``convert_escape_to_noescape [escaped]`` indiciates that the result was
+A ``convert_escape_to_noescape [escaped]`` indicates that the result was
 passed to a function (materializeForSet) which escapes the closure in a way not
 expressed by the convert's users. The mandatory pass must ensure the lifetime
 in a conservative way.
diff --git a/docs/SILProgrammersManual.md b/docs/SILProgrammersManual.md
index 9b7a58c..de119be 100644
--- a/docs/SILProgrammersManual.md
+++ b/docs/SILProgrammersManual.md
@@ -172,7 +172,7 @@
 ## SILAnalysis and the PassManager
 
 TBD: describe the mechanism by which passes invalidate and update the
-PassManager and its avaiable analyses.
+PassManager and its available analyses.
 
 ## High Level SIL Optimizations
 
diff --git a/docs/Testing.md b/docs/Testing.md
index 7cc1e6e..0de1d60 100644
--- a/docs/Testing.md
+++ b/docs/Testing.md
@@ -56,23 +56,23 @@
 configured to use your local build directory. For example:
 
 ```
-    % ${LLVM_SOURCE_ROOT}/utils/lit/lit.py -sv ${SWIFT_BUILD_DIR}/test-iphonesimulator-i386/Parse/
+    % ${LLVM_SOURCE_ROOT}/utils/lit/lit.py -sv ${SWIFT_BUILD_DIR}/test-macosx-x86_64/Parse/
 ```
 
-This runs the tests in the 'test/Parse/' directory targeting the 32-bit iOS
-Simulator. The ``-sv`` options give you a nice progress bar and only show you
+This runs the tests in the 'test/Parse/' directory targeting 64-bit macOS. 
+The ``-sv`` options give you a nice progress bar and only show you
 output from the tests that fail.
 
 One downside of using this form is that you're appending relative paths from
 the source directory to the test directory in your build directory. (That is,
 there may not actually be a directory named 'Parse' in
-'test-iphonesimulator-i386/'; the invocation works because there is one in the
+'test-macosx-x86_64/'; the invocation works because there is one in the
 source 'test/' directory.) There is a more verbose form that specifies the
 testing configuration explicitly, which then allows you to test files
 regardless of location.
 
 ```
-    % ${LLVM_SOURCE_ROOT}/utils/lit/lit.py -sv --param swift_site_config=${SWIFT_BUILD_DIR}/test-iphonesimulator-i386/lit.site.cfg ${SWIFT_SOURCE_ROOT}/test/Parse/
+    % ${LLVM_SOURCE_ROOT}/utils/lit/lit.py -sv --param swift_site_config=${SWIFT_BUILD_DIR}/test-macosx-x86_64/lit.site.cfg ${SWIFT_SOURCE_ROOT}/test/Parse/
 ```
 
 For more complicated configuration, copy the invocation from one of the build
diff --git a/docs/Windows.md b/docs/Windows.md
index fc521cf..0519c33 100644
--- a/docs/Windows.md
+++ b/docs/Windows.md
@@ -19,7 +19,7 @@
 `clang-cl` is recommended over MSVC for building Swift on Windows.
 Although it is possible to build the compiler and the standard library with
 MSVC to use those built products to compile a Swift program, it won't be
-possible to run the binary without seperately obtaining the Swift runtime. On
+possible to run the binary without separately obtaining the Swift runtime. On
 the other hand, `clang-cl` is able to build the runtime, which makes it
 possible to build and run all the components required for Swift natively on
 Windows.
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 762e690..0bbaa56 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -30,6 +30,7 @@
   installation.
 
 ### 2. Clone the repositories
+1. Configure git to work with Unix file endings
 1. Create a folder to contain all the Swift repositories
 1. Clone `apple/swift-cmark` into a folder named `cmark`
 1. Clone `apple/swift-clang` into a folder named `clang`
@@ -37,29 +38,46 @@
 1. Clone `apple/swift-compiler-rt` into a folder named `compiler-rt`
 1. Clone `apple/swift` into a folder named `swift`
 1. Clone `apple/swift-corelibs-libdispatch` into a folder named `swift-corelibs-libdispatch`
+1. Clone `apple/swift-corelibs-foundation` into a folder name `swift-corelibs-foundation`
+
 - Currently, other repositories in the Swift project have not been tested and
   may not be supported.
 
+If your sources live else where, you can create a substitution for this:
+
+```cmd
+subst S: <path to sources>
+```
+
+```cmd
+git config --global core.autocrlf input
+S:
+git clone https://github.com/apple/swift-cmark cmark
+git clone https://github.com/apple/swift-clang clang
+git clone https://github.com/apple/swift-llvm llvm
+git clone https://github.com/apple/swift-compiler-rt compiler-rt
+git clone https://github.com/apple/swift
+git clone https://github.com/apple/swift-corelibs-libdispatch
+git clone https://github.com/apple/swift-corelibs-foundation
+```
+
 ### 3. Acquire ICU
 1. Download ICU from [ICU Project](http://site.icu-project.org) for Windows x64 and extract the binaries.
 1. Add the `bin64` folder to your `Path` environment variable.
 
 ### 4. Get ready
-- From within a **developer** command prompt (not PowerShell nor cmd, but [the
-  Visual Studio Developer Command
-  Prompt](https://msdn.microsoft.com/en-us/library/f35ctcxw.aspx)), execute the
-  following command if you have an x64 PC.
+- From within a **developer** command prompt (not PowerShell nor cmd, but the [Visual Studio Developer Command Prompt](https://msdn.microsoft.com/en-us/library/f35ctcxw.aspx)), execute the following command if you have an x64 PC.
+
 ```cmd
 VsDevCmd -arch=amd64
 ```
-If instead you're compiling for a 32-bit Windows target, adapt the `arch`
-argument to `x86` and run
+
+If instead you're compiling for a 32-bit Windows target, adapt the `arch` argument to `x86` and run
+
 ```cmd
 VsDevCmd -arch=x86
 ```
 
-- We will use the assumption that the sources are on the `S` drive.  Replace it with the path to the checkout.  Make sure to use forward slashes (`/`) instead of backslashes (`\`) as the path separators. `clang` breaks with backslashed paths.
-
 - 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 
@@ -70,23 +88,25 @@
   `${UniversalCRTSdkDir}/Include/${UCRTVersion}/ucrt` as `module.modulemap`, copying `visualc.modulemap` located at `swift/stdlib/public/Platform/visualc.modulemap` into `${VCToolsInstallDir}/include` as `module.modulemap`, and copying `winsdk.modulemap` located at `swift/stdlib/public/Platform/winsdk.modulemap` into `${UniversalCRTSdkDir}/Include/${UCRTVersion}/um` and setup the `visualc.apinotes` located at `swift/stdlib/public/Platform/visualc.apinotes` into `${VCToolsInstallDir}/include` as `visualc.apinotes`
 
 ```cmd
-cd %UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt
-mklink module.modulemap S:\swift\stdlib\public\Platform\ucrt.modulemap
-cd %VCToolsInstallDir%\include
-mklink module.modulemap S:\swift\stdlib\public\Platform\visualc.modulemap
-mklink visualc.apinotes S:\swift\stdlib\public\Platform\visualc.apinotes
-cd %UniversalCRTSdkDir\Include\%UCRTVersion%\um
-mklink module.modulemap S:\swift\stdlib\public\Platform\winsdk.modulemap
+mklink %UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap S:\swift\stdlib\public\Platform\ucrt.modulemap
+mklink %VCToolsInstallDir%\include\module.modulemap S:\swift\stdlib\public\Platform\visualc.modulemap
+mklink %VCToolsInstallDir%\include\visualc.apinotes S:\swift\stdlib\public\Platform\visualc.apinotes
+mklink %UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap S:\swift\stdlib\public\Platform\winsdk.modulemap
 ```
 
 ### 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 S:/build/Ninja-DebugAssert/cmark-windows-amd64"
-pushd S:/build/Ninja-DebugAssert/cmark-windows-amd64" "S:/%swift_source_dir%/cmark"
+mkdir S:\build\Ninja-DebugAssert\cmark-windows-amd64"
+pushd S:\build\Ninja-DebugAssert\cmark-windows-amd64" "S:\cmark"
+cmake -G Ninja^
+  -DCMAKE_BUILD_TYPE=Debug^
+  -DCMAKE_C_COMPILER=cl^
+  -DCMAKE_CXX_COMPIELR=cl^
+  S:\cmark
 popd
-cmake --build "S:/build/Ninja-DebugAssert/cmark-windows-amd64/"
+cmake --build "S:\build\Ninja-DebugAssert\cmark-windows-amd64"
 ```
 
 ### 6. Build LLVM/Clang
@@ -95,20 +115,23 @@
   type (e.g. `Debug`, `Release`, `RelWithDebInfoAssert`) for LLVM/Clang matches the
   build type for Swift.
 ```cmd
-mkdir "S:/build/Ninja-DebugAssert/llvm-windows-amd64"
-pushd "S:/build/Ninja-DebugAssert/llvm-windows-amd64"
+mkdir "S:\build\Ninja-DebugAssert\llvm-windows-amd64"
+pushd "S:\build\Ninja-DebugAssert\llvm-windows-amd64"
 cmake -G "Ninja"^
- -DLLVM_ENABLE_ASSERTIONS=TRUE^
  -DCMAKE_BUILD_TYPE=Debug^
+ -DCMAKE_C_COMPILER=cl^
+ -DCMAKE_CXX_COMPILER=cl^
+ -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc^
+ -DLLVM_ENABLE_ASSERTIONS=TRUE^
  -DLLVM_ENABLE_PROJECTS=clang^
  -DLLVM_TARGETS_TO_BUILD=X86^
- -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc^
- "S:/llvm"
+ "S:\llvm"
 popd
-cmake --build "S:/build/Ninja-DebugAssert/llvm-windows-amd64"
+cmake --build "S:\build\Ninja-DebugAssert\llvm-windows-amd64"
 ```
 
-- If you intend to build any libraries, update your path to include the LLVM tools.
+- Update your path to include the LLVM tools.
+
 ```cmd
 set PATH=%PATH%;S:\build\Ninja-DebugAssert\llvm-windows-amd64\bin
 ```
@@ -119,31 +142,31 @@
 - You may need to adjust the `SWIFT_WINDOWS_LIB_DIRECTORY` parameter depending on
   your target platform or Windows SDK version.
 ```cmd
-mkdir "S:/build/Ninja-DebugAssert/swift-windows-amd64"
-pushd "S:/build/Ninja-DebugAssert/swift-windows-amd64"
+mkdir "S:\build\Ninja-DebugAssert\swift-windows-amd64"
+pushd "S:\build\inja-DebugAssert\swift-windows-amd64"
 cmake -G "Ninja"^
  -DCMAKE_BUILD_TYPE=Debug^
- -DCMAKE_C_COMPILER="S:/build/Ninja-DebugAssert/llvm-windows-amd64/clang-cl.exe"^
- -DCMAKE_CXX_COMPILER="S:/build/Ninja-DebugAssert/llvm-windows-amd64/clang-cl.exe"^
- -DSWIFT_PATH_TO_CMARK_SOURCE="S:/cmark"^
+ -DCMAKE_C_COMPILER=clang-cl^
+ -DCMAKE_CXX_COMPILER=clang-cl^
+ -DSWIFT_PATH_TO_CMARK_SOURCE="S:\cmark"^
  -DCMAKE_CXX_FLAGS="-Wno-c++98-compat -Wno-c++98-compat-pedantic"^
  -DCMAKE_EXE_LINKER_FLAGS:STRING="/INCREMENTAL:NO"^
  -DCMAKE_SHARED_LINKER_FLAGS="/INCREMENTAL:NO"^
  -DSWIFT_INCLUDE_DOCS=NO^
- -DSWIFT_PATH_TO_LLVM_SOURCE="S:/llvm"^
- -DSWIFT_PATH_TO_CLANG_SOURCE="S:/clang"^
- -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE="S:/swift-corelibs-libdispatch"^
- -DSWIFT_PATH_TO_LLVM_BUILD="S:/build/Ninja-DebugAssert/llvm-windows-amd64"^
- -DSWIFT_PATH_TO_CLANG_BUILD="S:/build/Ninja-DebugAssert/llvm-windows-amd64"^
- -DSWIFT_PATH_TO_CMARK_BUILD="S:/build/Ninja-DebugAssert/cmark-windows-amd64"^
- -DSWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE="S:/icu/include"^
- -DSWIFT_WINDOWS_x86_64_ICU_UC="S:/icu/lib64/icuuc.lib"^
- -DSWIFT_WINDOWS_x86_64_ICU_I18N_INCLUDE="S:/icu/include"^
- -DSWIFT_WINDOWS_x86_64_ICU_I18N="S:/icu/lib64/icuin.lib"^
- -DCMAKE_INSTALL_PREFIX="C:/Program Files (x86)/Swift"^
- "S:/swift"
+ -DSWIFT_PATH_TO_LLVM_SOURCE="S:\llvm"^
+ -DSWIFT_PATH_TO_CLANG_SOURCE="S:\clang"^
+ -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE="S:\swift-corelibs-libdispatch"^
+ -DSWIFT_PATH_TO_LLVM_BUILD="S:\build\Ninja-DebugAssert\llvm-windows-amd64"^
+ -DSWIFT_PATH_TO_CLANG_BUILD="S:\build\Ninja-DebugAssert\llvm-windows-amd64"^
+ -DSWIFT_PATH_TO_CMARK_BUILD="S:\build\Ninja-DebugAssert\cmark-windows-amd64"^
+ -DSWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE="S:\icu\include"^
+ -DSWIFT_WINDOWS_x86_64_ICU_UC="S:\icu\lib64\icuuc.lib"^
+ -DSWIFT_WINDOWS_x86_64_ICU_I18N_INCLUDE="S:\icu\include"^
+ -DSWIFT_WINDOWS_x86_64_ICU_I18N="S:\icu\lib64\icuin.lib"^
+ -DCMAKE_INSTALL_PREFIX="C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr"^
+ "S:\swift"
 popd
-cmake --build "S:/build/Ninja-DebugAssert/swift-windows-amd64"
+cmake --build "S:\build\Ninja-DebugAssert\swift-windows-amd64"
 ```
 
 - To create a Visual Studio project, you'll need to change the generator and,
@@ -154,9 +177,7 @@
   a file.
 
 ```cmd
-cmake -G "Visual Studio 2017" "%swift_source_dir%/swift"^
- -DCMAKE_GENERATOR_PLATFORM="x64"^
- ...
+cmake -G "Visual Studio 2017" "S:\swift" -DCMAKE_GENERATOR_PLATFORM="x64"^ ...
 ```
 
 ### 8. Build lldb
@@ -186,8 +207,9 @@
 
   1. coreutils
   2. diffutils
-  3. grep
-  4. sed
+  3. file
+  4. grep
+  5. sed
   
 ```cmd
 ninja -C "S:/build/Ninja-DebugAssert/swift-windows-amd64" check-swift
@@ -235,14 +257,13 @@
 ### 12. Install Swift on Windows
 
 - Run ninja install:
+
 ```cmd 
 ninja -C "S:/build/Ninja-DebugAssert/swift-windows-amd64" install
 ```
-- 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.
+
+- Add the Swift on Windows binaries path (`C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr\bin`)  to the `PATH` environment variable.
 
 ## MSVC
 
-To use `cl` instead, just remove the `-DCMAKE_C_COMPILER` and `-DCMAKE_CXX_COMPILER` parameters to the `cmake` invocations.
+To use `cl` instead, just replace the `-DCMAKE_C_COMPILER` and `-DCMAKE_CXX_COMPILER` parameters to the `cmake` invocations.
diff --git a/include/swift/AST/AccessScope.h b/include/swift/AST/AccessScope.h
index b8a200f..a8e1444 100644
--- a/include/swift/AST/AccessScope.h
+++ b/include/swift/AST/AccessScope.h
@@ -47,6 +47,7 @@
   bool isPublic() const { return !Value.getPointer(); }
   bool isPrivate() const { return Value.getInt(); }
   bool isFileScope() const;
+  bool isInternal() const;
 
   /// Returns true if this is a child scope of the specified other access scope.
   ///
diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def
index f88c975..4b0c973 100644
--- a/include/swift/AST/Builtins.def
+++ b/include/swift/AST/Builtins.def
@@ -423,9 +423,29 @@
 BUILTIN_MISC_OPERATION(Alignof, "alignof", "n", Special)
 
 /// AllocRaw has type (Int, Int) -> Builtin.RawPointer
+///
+/// Parameters: object size, object alignment.
+///
+/// This alignment is not a mask; the compiler decrements by one to provide
+/// a mask to the runtime.
+///
+/// If alignment == 0, then the runtime will use "aligned" allocation,
+/// and the memory will be aligned to _swift_MinAllocationAlignment.
 BUILTIN_MISC_OPERATION(AllocRaw, "allocRaw", "", Special)
 
 /// DeallocRaw has type (Builtin.RawPointer, Int, Int) -> ()
+///
+/// Parameters: object address, object size, object alignment.
+///
+/// This alignment is not a mask; the compiler decrements by one to provide
+/// a mask to the runtime.
+///
+/// If alignment == 0, then the runtime will use the "aligned" deallocation
+/// path, which assumes that "aligned" allocation was used.
+///
+/// Note that the alignment value provided to `deallocRaw` must be identical to
+/// the alignment value provided to `allocRaw` when the memory at this address
+/// was allocated.
 BUILTIN_MISC_OPERATION(DeallocRaw, "deallocRaw", "", Special)
 
 /// Fence has type () -> ().
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 1467616..b256ab6 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3886,6 +3886,10 @@
      "replaced function %0 could not be found", (DeclName))
 ERROR(dynamic_replacement_accessor_not_found, none,
       "replaced accessor for %0 could not be found", (DeclName))
+ERROR(dynamic_replacement_accessor_ambiguous, none,
+      "replaced accessor for %0 occurs in multiple places", (DeclName))
+NOTE(dynamic_replacement_accessor_ambiguous_candidate, none,
+      "candidate accessor found in module %0", (DeclName))
 ERROR(dynamic_replacement_function_of_type_not_found, none,
       "replaced function %0 of type %1 could not be found", (DeclName, Type))
 NOTE(dynamic_replacement_found_function_of_type, none,
@@ -4099,6 +4103,9 @@
       "but %0 is %select{private|fileprivate|internal|%error|%error}1",
       (DeclBaseName, AccessLevel))
 
+ERROR(inlinable_resilient_deinit,
+      none, "deinitializer can only be '@inlinable' if the class is '@_fixed_layout'", ())
+
 //------------------------------------------------------------------------------
 // MARK: @_specialize diagnostics
 //------------------------------------------------------------------------------
diff --git a/include/swift/AST/SwiftNameTranslation.h b/include/swift/AST/SwiftNameTranslation.h
index fa9836a..1f07c28 100644
--- a/include/swift/AST/SwiftNameTranslation.h
+++ b/include/swift/AST/SwiftNameTranslation.h
@@ -18,6 +18,7 @@
 
 namespace swift {
   class ValueDecl;
+  class EnumDecl;
   class EnumElementDecl;
 
 namespace objc_translation {
@@ -29,6 +30,8 @@
   StringRef getNameForObjC(const ValueDecl *VD,
                            CustomNamesOnly_t customNamesOnly = Normal);
 
+  std::string getErrorDomainStringForObjC(const EnumDecl *ED);
+
   /// Print the ObjC name of an enum element decl to OS, also allowing the client
   /// to specify a preferred name other than the decl's original name.
   ///
diff --git a/include/swift/Basic/Dwarf.h b/include/swift/Basic/Dwarf.h
index baac035..16e0612 100644
--- a/include/swift/Basic/Dwarf.h
+++ b/include/swift/Basic/Dwarf.h
@@ -27,6 +27,7 @@
   static const char MachOASTSectionName[] = "__ast";
   static const char ELFASTSectionName[] = ".swift_ast";
   static const char COFFASTSectionName[] = "swiftast";
+  static const char WasmASTSectionName[] = ".swift_ast";
 } // end namespace swift
 
 #endif // SWIFT_BASIC_DWARF_H
diff --git a/include/swift/Basic/type_traits.h b/include/swift/Basic/type_traits.h
index 31f9763..5b4aecd 100644
--- a/include/swift/Basic/type_traits.h
+++ b/include/swift/Basic/type_traits.h
@@ -30,7 +30,7 @@
 /// is not intended to be specialized.
 template<typename T>
 struct IsTriviallyCopyable {
-#if _LIBCPP_VERSION || SWIFT_COMPILER_IS_MSVC
+#if defined(_LIBCPP_VERSION) || SWIFT_COMPILER_IS_MSVC
   // libc++ and MSVC implement is_trivially_copyable.
   static const bool value = std::is_trivially_copyable<T>::value;
 #elif __has_feature(is_trivially_copyable) || __GNUC__ >= 5
@@ -42,7 +42,7 @@
 
 template<typename T>
 struct IsTriviallyConstructible {
-#if _LIBCPP_VERSION || SWIFT_COMPILER_IS_MSVC
+#if defined(_LIBCPP_VERSION) || SWIFT_COMPILER_IS_MSVC
   // libc++ and MSVC implement is_trivially_constructible.
   static const bool value = std::is_trivially_constructible<T>::value;
 #elif __has_feature(has_trivial_constructor) || __GNUC__ >= 5
@@ -54,7 +54,7 @@
 
 template<typename T>
 struct IsTriviallyDestructible {
-#if _LIBCPP_VERSION || SWIFT_COMPILER_IS_MSVC
+#if defined(_LIBCPP_VERSION) || SWIFT_COMPILER_IS_MSVC
   // libc++ and MSVC implement is_trivially_destructible.
   static const bool value = std::is_trivially_destructible<T>::value;
 #elif __has_feature(has_trivial_destructor) || __GNUC__ >= 5
diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h
index 55ed17d..0005bf7 100644
--- a/include/swift/Demangling/TypeDecoder.h
+++ b/include/swift/Demangling/TypeDecoder.h
@@ -163,9 +163,15 @@
     case NodeKind::BoundGenericClass:
     {
 #if SWIFT_OBJC_INTEROP
-      if (Node->getNumChildren() == 2)
-        if (auto mangledName = getObjCClassOrProtocolName(Node->getChild(0)))
+      if (Node->getNumChildren() >= 2) {
+        auto ChildNode = Node->getChild(0);
+        if (ChildNode->getKind() == NodeKind::Type &&
+            ChildNode->getNumChildren() > 0)
+          ChildNode = ChildNode->getChild(0);
+
+        if (auto mangledName = getObjCClassOrProtocolName(ChildNode))
           return Builder.createObjCClassType(mangledName->str());
+      }
 #endif
       LLVM_FALLTHROUGH;
     }
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index f36f2df..f51e6c9 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -1043,7 +1043,11 @@
   llvm::GlobalValue::DLLStorageClassTypes DLLStorage;
 
   static const IRLinkage InternalLinkOnceODR;
+  static const IRLinkage InternalWeakODR;
   static const IRLinkage Internal;
+
+  static const IRLinkage ExternalImport;
+  static const IRLinkage ExternalExport;
 };
 
 class ApplyIRLinkage {
@@ -1051,23 +1055,23 @@
 public:
   ApplyIRLinkage(IRLinkage IRL) : IRL(IRL) {}
   void to(llvm::GlobalValue *GV) const {
+    llvm::Module *M = GV->getParent();
+    const llvm::Triple Triple(M->getTargetTriple());
+
     GV->setLinkage(IRL.Linkage);
     GV->setVisibility(IRL.Visibility);
-    GV->setDLLStorageClass(IRL.DLLStorage);
+    if (Triple.isOSBinFormatCOFF() && !Triple.isOSCygMing())
+      GV->setDLLStorageClass(IRL.DLLStorage);
+
+    // TODO: BFD and gold do not handle COMDATs properly
+    if (Triple.isOSBinFormatELF())
+      return;
 
     if (IRL.Linkage == llvm::GlobalValue::LinkOnceODRLinkage ||
-        IRL.Linkage == llvm::GlobalValue::WeakODRLinkage) {
-      llvm::Module *M = GV->getParent();
-      const llvm::Triple Triple(M->getTargetTriple());
-
-      // TODO: BFD and gold do not handle COMDATs properly
-      if (Triple.isOSBinFormatELF())
-        return;
-
+        IRL.Linkage == llvm::GlobalValue::WeakODRLinkage)
       if (Triple.supportsCOMDAT())
         if (llvm::GlobalObject *GO = dyn_cast<llvm::GlobalObject>(GV))
           GO->setComdat(M->getOrInsertComdat(GV->getName()));
-    }
   }
 };
 
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 8ee68cf..298f835 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -677,7 +677,7 @@
            !hasOwnership() && "Unqualified inst in qualified function");
     assert((Qualifier == LoadOwnershipQualifier::Unqualified) ||
            hasOwnership() && "Qualified inst in unqualified function");
-    assert(LV->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(LV->getType()));
     return insert(new (getModule())
                       LoadInst(getSILDebugLocation(Loc), LV, Qualifier));
   }
@@ -696,13 +696,13 @@
   /// non-address values.
   SILValue emitLoadValueOperation(SILLocation Loc, SILValue LV,
                                   LoadOwnershipQualifier Qualifier) {
-    assert(LV->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(LV->getType()));
     const auto &lowering = getTypeLowering(LV->getType());
     return lowering.emitLoad(*this, Loc, LV, Qualifier);
   }
 
   LoadBorrowInst *createLoadBorrow(SILLocation Loc, SILValue LV) {
-    assert(LV->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(LV->getType()));
     return insert(new (getModule())
                       LoadBorrowInst(getSILDebugLocation(Loc), LV));
   }
@@ -927,10 +927,10 @@
 
   ConvertEscapeToNoEscapeInst *
   createConvertEscapeToNoEscape(SILLocation Loc, SILValue Op, SILType Ty,
-                                bool isEscapedByUser, bool lifetimeGuaranteed) {
+                                bool lifetimeGuaranteed) {
     return insert(ConvertEscapeToNoEscapeInst::create(
         getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes,
-        isEscapedByUser, lifetimeGuaranteed));
+        lifetimeGuaranteed));
   }
 
   ThinFunctionToPointerInst *
@@ -1069,7 +1069,7 @@
   }
 
   DestroyValueInst *createDestroyValue(SILLocation Loc, SILValue operand) {
-    assert(operand->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(operand->getType()));
     return insert(new (getModule())
                       DestroyValueInst(getSILDebugLocation(Loc), operand));
   }
@@ -1100,7 +1100,7 @@
   RetainValueInst *createRetainValue(SILLocation Loc, SILValue operand,
                                      Atomicity atomicity) {
     assert(!hasOwnership());
-    assert(operand->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(operand->getType()));
     return insert(new (getModule()) RetainValueInst(getSILDebugLocation(Loc),
                                                       operand, atomicity));
   }
@@ -1115,7 +1115,7 @@
   ReleaseValueInst *createReleaseValue(SILLocation Loc, SILValue operand,
                                        Atomicity atomicity) {
     assert(!hasOwnership());
-    assert(operand->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(operand->getType()));
     return insert(new (getModule()) ReleaseValueInst(getSILDebugLocation(Loc),
                                                        operand, atomicity));
   }
@@ -1132,7 +1132,7 @@
                                                        SILValue operand,
                                                        Atomicity atomicity) {
     assert(hasOwnership());
-    assert(operand->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(operand->getType()));
     return insert(new (getModule()) UnmanagedRetainValueInst(
         getSILDebugLocation(Loc), operand, atomicity));
   }
@@ -1141,7 +1141,7 @@
                                                          SILValue operand,
                                                          Atomicity atomicity) {
     assert(hasOwnership());
-    assert(operand->getType().isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(operand->getType()));
     return insert(new (getModule()) UnmanagedReleaseValueInst(
         getSILDebugLocation(Loc), operand, atomicity));
   }
@@ -1177,14 +1177,14 @@
 
   StructInst *createStruct(SILLocation Loc, SILType Ty,
                            ArrayRef<SILValue> Elements) {
-    assert(Ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(Ty));
     return insert(StructInst::create(getSILDebugLocation(Loc), Ty, Elements,
                                      getModule(), hasOwnership()));
   }
 
   TupleInst *createTuple(SILLocation Loc, SILType Ty,
                          ArrayRef<SILValue> Elements) {
-    assert(Ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(Ty));
     return insert(TupleInst::create(getSILDebugLocation(Loc), Ty, Elements,
                                     getModule(), hasOwnership()));
   }
@@ -1193,21 +1193,21 @@
 
   EnumInst *createEnum(SILLocation Loc, SILValue Operand,
                        EnumElementDecl *Element, SILType Ty) {
-    assert(Ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(Ty));
     return insert(new (getModule()) EnumInst(getSILDebugLocation(Loc),
                                                Operand, Element, Ty));
   }
 
   /// Inject a loadable value into the corresponding optional type.
   EnumInst *createOptionalSome(SILLocation Loc, SILValue operand, SILType ty) {
-    assert(ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(ty));
     auto someDecl = getModule().getASTContext().getOptionalSomeDecl();
     return createEnum(Loc, operand, someDecl, ty);
   }
 
   /// Create the nil value of a loadable optional type.
   EnumInst *createOptionalNone(SILLocation Loc, SILType ty) {
-    assert(ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(ty));
     auto noneDecl = getModule().getASTContext().getOptionalNoneDecl();
     return createEnum(Loc, nullptr, noneDecl, ty);
   }
@@ -1224,7 +1224,7 @@
                                                  SILValue Operand,
                                                  EnumElementDecl *Element,
                                                  SILType Ty) {
-    assert(Ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(Ty));
     return insert(new (getModule()) UncheckedEnumDataInst(
         getSILDebugLocation(Loc), Operand, Element, Ty));
   }
@@ -1264,7 +1264,7 @@
                    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
                    Optional<ArrayRef<ProfileCounter>> CaseCounts = None,
                    ProfileCounter DefaultCount = ProfileCounter()) {
-    assert(Ty.isLoadableOrOpaque(getModule()));
+    assert(isLoadableOrOpaque(Ty));
     return insert(SelectEnumInst::create(
         getSILDebugLocation(Loc), Operand, Ty, DefaultValue, CaseValues,
         getModule(), CaseCounts, DefaultCount, hasOwnership()));
@@ -2125,6 +2125,15 @@
 #endif
   }
 
+  bool isLoadableOrOpaque(SILType Ty) {
+    if (!F) {
+      // We are inserting into the static initializer of a SILGlobalVariable.
+      // All types used there are loadable by definition.
+      return true;
+    }
+    return Ty.isLoadableOrOpaque(F);
+  }
+
   void appendOperandTypeName(SILType OpdTy, llvm::SmallString<16> &Name) {
     if (auto BuiltinIntTy =
             dyn_cast<BuiltinIntegerType>(OpdTy.getASTType())) {
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 12186cd..47f2e6c 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -1267,8 +1267,7 @@
   recordClonedInstruction(
       Inst, getBuilder().createConvertEscapeToNoEscape(
                 getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
-                getOpType(Inst->getType()), Inst->isEscapedByUser(),
-                Inst->isLifetimeGuaranteed()));
+                getOpType(Inst->getType()), Inst->isLifetimeGuaranteed()));
 }
 
 template<typename ImplClass>
diff --git a/include/swift/SIL/SILConstants.h b/include/swift/SIL/SILConstants.h
index a6c9a29..6fc7913 100644
--- a/include/swift/SIL/SILConstants.h
+++ b/include/swift/SIL/SILConstants.h
@@ -268,6 +268,9 @@
   SymbolicValueMemoryObject *
   getAddressValue(SmallVectorImpl<unsigned> &accessPath) const;
 
+  /// Return just the memory object for an address value.
+  SymbolicValueMemoryObject *getAddressValueMemoryObject() const;
+
   //===--------------------------------------------------------------------===//
   // Helpers
 
@@ -312,6 +315,24 @@
   static SymbolicValueMemoryObject *create(Type type, SymbolicValue value,
                                            ASTContext &astContext);
 
+  /// Given that this memory object contains an aggregate value like
+  /// {{1, 2}, 3}, and given an access path like [0,1], return the indexed
+  /// element, e.g. "2" in this case.
+  ///
+  /// Returns uninit memory if the access path points at or into uninit memory.
+  ///
+  /// Precondition: The access path must be valid for this memory object's type.
+  SymbolicValue getIndexedElement(ArrayRef<unsigned> accessPath);
+
+  /// Given that this memory object contains an aggregate value like
+  /// {{1, 2}, 3}, given an access path like [0,1], and given a new element like
+  /// "4", set the indexed element to the specified scalar, producing {{1, 4},
+  /// 3} in this case.
+  ///
+  /// Precondition: The access path must be valid for this memory object's type.
+  void setIndexedElement(ArrayRef<unsigned> accessPath,
+                         SymbolicValue newElement, ASTContext &astCtx);
+
 private:
   const Type type;
   SymbolicValue value;
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 483ecc8..baf8e12 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -326,7 +326,7 @@
   /// Update this instruction's SILDebugScope. This function should
   /// never be called directly. Use SILBuilder, SILBuilderWithScope or
   /// SILClonerWithScope instead.
-  void setDebugScope(SILBuilder &B, const SILDebugScope *DS);
+  void setDebugScope(const SILDebugScope *DS);
 
   /// Total number of created and deleted SILInstructions.
   /// It is used only for collecting the compiler statistics.
@@ -4037,18 +4037,14 @@
   friend SILBuilder;
 
   bool lifetimeGuaranteed;
-  bool isEscaped; // Even if we can analyze this
-                        // instruction the user might have
-                        // escaped it.
 
   ConvertEscapeToNoEscapeInst(SILDebugLocation DebugLoc, SILValue Operand,
                               ArrayRef<SILValue> TypeDependentOperands,
-                              SILType Ty, bool isEscapedByUser,
+                              SILType Ty,
                               bool isLifetimeGuaranteed)
       : UnaryInstructionWithTypeDependentOperandsBase(
             DebugLoc, Operand, TypeDependentOperands, Ty),
-        lifetimeGuaranteed(isLifetimeGuaranteed),
-        isEscaped(isEscapedByUser) {
+        lifetimeGuaranteed(isLifetimeGuaranteed) {
     assert(!Operand->getType().castTo<SILFunctionType>()->isNoEscape());
     assert(Ty.castTo<SILFunctionType>()->isNoEscape());
   }
@@ -4056,17 +4052,11 @@
   static ConvertEscapeToNoEscapeInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
          SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
-         bool isEscapedByUser, bool lifetimeGuaranteed);
+         bool lifetimeGuaranteed);
 public:
   bool isLifetimeGuaranteed() const {
     return lifetimeGuaranteed;
   }
-
-  bool isEscapedByUser() const {
-    return isEscaped;
-  }
-
-  void setEscapedByUser(bool isEscaped = true) { this->isEscaped = isEscaped; }
 };
 
 /// ThinFunctionToPointerInst - Convert a thin function pointer to a
diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h
index edba967..38ab5d9 100644
--- a/include/swift/SIL/SILModule.h
+++ b/include/swift/SIL/SILModule.h
@@ -316,8 +316,10 @@
   mutable Lowering::TypeConverter Types;
 
   /// Look up the TypeLowering for a SILType.
-  const Lowering::TypeLowering &getTypeLowering(SILType t) {
-    return Types.getTypeLowering(t);
+  const Lowering::TypeLowering &
+  getTypeLowering(SILType t, ResilienceExpansion expansion =
+                               ResilienceExpansion::Minimal) {
+    return Types.getTypeLowering(t, expansion);
   }
 
   /// Invalidate cached entries in SIL Loader.
diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h
index 284579d..2ac0c12 100644
--- a/include/swift/SIL/SILType.h
+++ b/include/swift/SIL/SILType.h
@@ -257,14 +257,35 @@
   bool isLoadable(SILModule &M) const {
     return !isAddressOnly(M);
   }
+
+  /// Like isLoadable(SILModule), but specific to a function.
+  ///
+  /// This takes the resilience expansion of the function into account. If the
+  /// type is not loadable in general (because it's resilient), it still might
+  /// be loadable inside a resilient function in the module.
+  /// In other words: isLoadable(SILModule) is the conservative default, whereas
+  /// isLoadable(SILFunction) might give a more optimistic result.
+  bool isLoadable(SILFunction *inFunction) const {
+    return !isAddressOnly(inFunction);
+  }
+
   /// True if either:
   /// 1) The type, or the referenced type of an address type, is loadable.
   /// 2) The SIL Module conventions uses lowered addresses
   bool isLoadableOrOpaque(SILModule &M) const;
+
+  /// Like isLoadableOrOpaque(SILModule), but takes the resilience expansion of
+  /// \p inFunction into account (see isLoadable(SILFunction)).
+  bool isLoadableOrOpaque(SILFunction *inFunction) const;
+
   /// True if the type, or the referenced type of an address type, is
   /// address-only. This is the opposite of isLoadable.
   bool isAddressOnly(SILModule &M) const;
 
+  /// Like isAddressOnly(SILModule), but takes the resilience expansion of
+  /// \p inFunction into account (see isLoadable(SILFunction)).
+  bool isAddressOnly(SILFunction *inFunction) const;
+
   /// True if the type, or the referenced type of an address type, is trivial.
   bool isTrivial(SILModule &M) const;
 
diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h
index 759243d..295ec0b 100644
--- a/include/swift/SIL/TypeLowering.h
+++ b/include/swift/SIL/TypeLowering.h
@@ -148,6 +148,12 @@
   IsReferenceCounted = true
 };
 
+/// Is this type address only because it's resilient?
+enum IsResilient_t : bool {
+  IsNotResilient = false,
+  IsResilient = true
+};
+
 /// Extended type information used by SIL.
 class TypeLowering {
 public:
@@ -157,6 +163,7 @@
       NonTrivialFlag     = 1 << 0,
       NonFixedABIFlag    = 1 << 1,
       AddressOnlyFlag    = 1 << 2,
+      ResilientFlag      = 1 << 3,
     };
 
     uint8_t Flags;
@@ -167,17 +174,23 @@
 
     constexpr RecursiveProperties(IsTrivial_t isTrivial,
                                   IsFixedABI_t isFixedABI,
-                                  IsAddressOnly_t isAddressOnly)
+                                  IsAddressOnly_t isAddressOnly,
+                                  IsResilient_t isResilient = IsNotResilient)
       : Flags((isTrivial ? 0U : NonTrivialFlag) | 
               (isAddressOnly ? AddressOnlyFlag : 0U) |
-              (isFixedABI ? 0U : NonFixedABIFlag)) {}
+              (isFixedABI ? 0U : NonFixedABIFlag) |
+              (isResilient ? ResilientFlag : 0U)) {}
 
     static constexpr RecursiveProperties forReference() {
-      return {IsNotTrivial, IsFixedABI, IsNotAddressOnly};
+      return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient };
     }
 
     static constexpr RecursiveProperties forOpaque() {
-      return {IsNotTrivial, IsNotFixedABI, IsAddressOnly};
+      return {IsNotTrivial, IsNotFixedABI, IsAddressOnly, IsNotResilient};
+    }
+
+    static constexpr RecursiveProperties forResilient() {
+      return {IsNotTrivial, IsNotFixedABI, IsAddressOnly, IsResilient};
     }
 
     void addSubobject(RecursiveProperties other) {
@@ -193,6 +206,9 @@
     IsAddressOnly_t isAddressOnly() const {
       return IsAddressOnly_t((Flags & AddressOnlyFlag) != 0);
     }
+    IsResilient_t isResilient() const {
+      return IsResilient_t((Flags & ResilientFlag) != 0);
+    }
 
     void setNonTrivial() { Flags |= NonTrivialFlag; }
     void setNonFixedABI() { Flags |= NonFixedABIFlag; }
@@ -206,7 +222,16 @@
   RecursiveProperties Properties;
   unsigned ReferenceCounted : 1;
 
-protected:  
+public:
+  /// The resilience expansion for this type lowering.
+  /// If the type is not resilient at all, this is always Minimal.
+  ResilienceExpansion forExpansion = ResilienceExpansion::Minimal;
+
+  /// A single linked list of lowerings for different resilience expansions.
+  /// The first lowering is always for ResilientExpansion::Minimal.
+  mutable const TypeLowering *nextExpansion = nullptr;
+
+protected:
   TypeLowering(SILType type, RecursiveProperties properties,
                IsReferenceCounted_t isRefCounted)
     : LoweredType(type), Properties(properties),
@@ -277,6 +302,10 @@
     return LoweredType.isAddress();
   }
 
+  bool isResilient() const {
+    return Properties.isResilient();
+  }
+
   /// Return the semantic type.
   ///
   /// The semantic type is what a type pretends to be during
@@ -670,7 +699,8 @@
   Optional<CanType> BridgedType##Ty;
 #include "swift/SIL/BridgedTypes.def"
 
-  const TypeLowering &getTypeLoweringForLoweredType(TypeKey key);
+  const TypeLowering &
+  getTypeLoweringForLoweredType(TypeKey key, ResilienceExpansion forExpansion);
   const TypeLowering &getTypeLoweringForUncachedLoweredType(TypeKey key);
 
 public:
@@ -746,7 +776,9 @@
   /// Returns the SIL TypeLowering for an already lowered SILType. If the
   /// SILType is an address, returns the TypeLowering for the pointed-to
   /// type.
-  const TypeLowering &getTypeLowering(SILType t);
+  const TypeLowering &
+  getTypeLowering(SILType t, ResilienceExpansion forExpansion =
+                               ResilienceExpansion::Minimal);
 
   // Returns the lowered SIL type for a Swift type.
   SILType getLoweredType(Type t) {
diff --git a/include/swift/SILOptimizer/Utils/CastOptimizer.h b/include/swift/SILOptimizer/Utils/CastOptimizer.h
index c8d37ad..6384dd5 100644
--- a/include/swift/SILOptimizer/Utils/CastOptimizer.h
+++ b/include/swift/SILOptimizer/Utils/CastOptimizer.h
@@ -129,6 +129,10 @@
                                        SILValue Dest, CanType Source,
                                        CanType Target, SILBasicBlock *SuccessBB,
                                        SILBasicBlock *FailureBB);
+
+  SILInstruction *
+  optimizeMetatypeConversion(ConversionInst *MCI,
+                             MetatypeRepresentation Representation);
 };
 
 } // namespace swift
diff --git a/include/swift/SILOptimizer/Utils/Existential.h b/include/swift/SILOptimizer/Utils/Existential.h
index fa0f3c6..39cb1be 100644
--- a/include/swift/SILOptimizer/Utils/Existential.h
+++ b/include/swift/SILOptimizer/Utils/Existential.h
@@ -21,33 +21,35 @@
 
 namespace swift {
 
-/// Find InitExistential from global_addr and copy_addr.
-SILValue findInitExistentialFromGlobalAddrAndCopyAddr(GlobalAddrInst *GAI,
-                                                      CopyAddrInst *CAI);
-
-/// Find InitExistential from global_addr and an apply argument.
-SILValue findInitExistentialFromGlobalAddrAndApply(GlobalAddrInst *GAI,
-                                                   ApplySite Apply, int ArgIdx);
-
-/// Returns the address of an object with which the stack location \p ASI is
-/// initialized. This is either a init_existential_addr or the destination of a
-/// copy_addr. Returns a null value if the address does not dominate the
-/// alloc_stack user \p ASIUser.
-/// If the value is copied from another stack location, \p isCopied is set to
-/// true.
-SILValue getAddressOfStackInit(SILValue allocStackAddr, SILInstruction *ASIUser,
-                               bool &isCopied);
-
-/// Find the init_existential, which could be used to determine a concrete
-/// type of the value used by \p openedUse.
-/// If the value is copied from another stack location, \p isCopied is set to
-/// true.
+/// Record information about an opened archetype.
 ///
-/// FIXME: replace all uses of this with ConcreteExistentialInfo.
-SILInstruction *findInitExistential(Operand &openedUse,
-                                    ArchetypeType *&OpenedArchetype,
-                                    SILValue &OpenedArchetypeDef,
-                                    bool &isCopied);
+/// This is used to determine whether a generic call argument originates from
+/// an opened existential. For example:
+/// %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
+///
+/// When successfull, ConcreteExistentialInfo can be used to determine the
+/// concrete type of the opened existential.
+struct OpenedArchetypeInfo {
+  ArchetypeType *OpenedArchetype = nullptr;
+  // The opened value.
+  SingleValueInstruction *OpenedArchetypeValue;
+  // The existential value.
+  SILValue ExistentialValue;
+  // True if the openedValue is copied from another stack location
+  bool isOpenedValueCopied = false;
+
+  // Construct a valid instance if the given use originates from a recognizable
+  // OpenedArchetype instruction.
+  OpenedArchetypeInfo(Operand &use);
+
+  bool isValid() const {
+    assert(!OpenedArchetype || (OpenedArchetypeValue && ExistentialValue));
+    return OpenedArchetype;
+  }
+};
 
 /// 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
@@ -60,20 +62,16 @@
 ///   : $@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 concrete type of self from the init_existential. `$C` above.
   CanType ConcreteType;
+  // The concrete value used to initialize the opened existential.
+  // `%c` in the above comment.
+  SILValue ConcreteValue;
+  // True if the ConcreteValue is copied from another stack location
+  bool isConcreteValueCopied = false;
   // When ConcreteType is itself an opened existential, record the type
   // definition. May be nullptr for a valid AppliedConcreteType.
   SingleValueInstruction *ConcreteTypeDef = nullptr;
@@ -82,31 +80,20 @@
   // 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);
+  // Search for a recognized pattern in which the given existential value is
+  // initialized to a concrete type. Constructs a valid ConcreteExistentialInfo
+  // object if successfull.
+  ConcreteExistentialInfo(SILValue existential, SILInstruction *user);
 
   // This constructor initializes a ConcreteExistentialInfo based on already
-  // known ConcreteType and ProtocolDecl pair. It determines the
-  // OpenedArchetypeDef for the ArgOperand that will be used by unchecked_cast
-  // instructions to cast OpenedArchetypeDef to ConcreteType.
-  ConcreteExistentialInfo(Operand &ArgOperand, CanType ConcreteType,
-                          ProtocolDecl *Protocol);
+  // known ConcreteType and ProtocolDecl pair.
+  ConcreteExistentialInfo(SILValue existential, SILInstruction *user,
+                          CanType ConcreteType, ProtocolDecl *Protocol);
 
   /// For scenerios where ConcreteExistentialInfo is created using a known
-  /// ConcreteType and ProtocolDecl, both of InitExistential
-  /// and ConcreteValue can be null. So there is no need for explicit check for
-  /// not null for them instead we assert on (!InitExistential ||
-  /// ConcreteValue). 
-  bool isValid() const {
-    assert(!InitExistential || ConcreteValue);
-    return OpenedArchetype && OpenedArchetypeDef && ConcreteType &&
-           !ExistentialSubs.empty();
-  }
+  /// ConcreteType and ProtocolDecl, the ConcreteValue can be null.
+  bool isValid() const { return ConcreteType && !ExistentialSubs.empty(); }
 
   // Do a conformance lookup on ConcreteType with the given requirement, P. If P
   // is satisfiable based on the existential's conformance, return the new
@@ -116,6 +103,35 @@
     CanType selfTy = P->getSelfInterfaceType()->getCanonicalType();
     return ExistentialSubs.lookupConformance(selfTy, P);
   }
+
+private:
+  void initializeSubstitutionMap(
+      ArrayRef<ProtocolConformanceRef> ExistentialConformances, SILModule *M);
+
+  void initializeConcreteTypeDef(SILInstruction *typeConversionInst);
+};
+
+// Convenience for tracking both the OpenedArchetypeInfo and
+// ConcreteExistentialInfo from the same SILValue.
+struct ConcreteOpenedExistentialInfo {
+  OpenedArchetypeInfo OAI;
+  // If CEI has a value, it must be valid.
+  Optional<ConcreteExistentialInfo> CEI;
+
+  ConcreteOpenedExistentialInfo(Operand &use);
+
+  // Provide a whole module type-inferred ConcreteType to fall back on if the
+  // concrete type cannot be determined from data flow.
+  ConcreteOpenedExistentialInfo(Operand &use, CanType concreteType,
+                                ProtocolDecl *protocol);
+
+  bool isValid() const {
+    if (!CEI)
+      return false;
+
+    assert(CEI->isValid());
+    return true;
+  }
 };
 
 } // end namespace swift
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 8177807..b28ed6c 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -889,8 +889,8 @@
 
     if (auto vd = dyn_cast<VarDecl>(D)) {
       // Don't print @_hasInitialValue if we're printing an initializer
-      // expression.
-      if (vd->isInitExposedToClients())
+      // expression or if the storage is resilient.
+      if (vd->isInitExposedToClients() || vd->isResilient())
         Options.ExcludeAttrList.push_back(DAK_HasInitialValue);
 
       if (!Options.PrintForSIL) {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index d30d070c..014d870 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -5101,6 +5101,14 @@
     auto existing = DefaultValueAndFlags.getPointer()->StringRepresentation;
     if (!existing.empty())
       return existing;
+
+    if (!getDefaultValue()) {
+      // TypeChecker::checkDefaultArguments() nulls out the default value
+      // if it fails to type check it. This only seems to happen with an
+      // invalid/incomplete parameter list that contains a parameter with an
+      // unresolved default value.
+      return "<<empty>>";
+    }
     return extractInlinableText(getASTContext().SourceMgr, getDefaultValue(),
                                 scratch);
   }
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index a19869c..4694e95 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -839,6 +839,11 @@
   return DC && isa<FileUnit>(DC);
 }
 
+bool AccessScope::isInternal() const {
+  auto DC = getDeclContext();
+  return DC && isa<ModuleDecl>(DC);
+}
+
 AccessLevel AccessScope::accessLevelForDiagnostics() const {
   if (isPublic())
     return AccessLevel::Public;
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index af11060..e1d1723 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -4799,8 +4799,12 @@
   auto T1 = OrigT1->getRepresentative();
   auto T2 = OrigT2->getRepresentative();
 
-  // Pick representative based on the canonical ordering of the type parameters.
-  if (compareDependentTypes(depType2, depType1) < 0) {
+  // Decide which potential archetype is to be considered the representative.
+  // We prefer potential archetypes with lower nesting depths, because it
+  // prevents us from unnecessarily building deeply nested potential archetypes.
+  unsigned nestingDepth1 = T1->getNestingDepth();
+  unsigned nestingDepth2 = T2->getNestingDepth();
+  if (nestingDepth2 < nestingDepth1) {
     std::swap(T1, T2);
     std::swap(OrigT1, OrigT2);
     std::swap(equivClass, equivClass2);
@@ -6831,6 +6835,14 @@
           auto locA = (*a)->constraint.source->getLoc();
           auto locB = (*b)->constraint.source->getLoc();
 
+          // Put invalid locations after valid ones.
+          if (locA.isInvalid() || locB.isInvalid()) {
+            if (locA.isInvalid() != locB.isInvalid())
+              return locA.isInvalid() ? 1 : -1;
+
+            return 0;
+          }
+
           auto bufferA = sourceMgr.findBufferContainingLoc(locA);
           auto bufferB = sourceMgr.findBufferContainingLoc(locB);
 
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index 2336176..525d5f8 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -352,19 +352,17 @@
       return None;
     };
 
+  // Check whether the superclass conforms.
+  if (auto superclass = genericSig->getSuperclassBound(type)) {
+    LookUpConformanceInSignature lookup(*getGenericSignature());
+    if (auto conformance = lookup(type->getCanonicalType(), superclass, proto))
+      return conformance;
+  }
+
   // If the type doesn't conform to this protocol, the result isn't formed
   // from these requirements.
-  if (!genericSig->conformsToProtocol(type, proto)) {
-    // Check whether the superclass conforms.
-    if (auto superclass = genericSig->getSuperclassBound(type)) {
-      return LookUpConformanceInSignature(*getGenericSignature())(
-                                                 type->getCanonicalType(),
-                                                 superclass,
-                                                 proto);
-    }
-
+  if (!genericSig->conformsToProtocol(type, proto))
     return None;
-  }
 
   auto accessPath =
     genericSig->getConformanceAccessPath(type, proto);
diff --git a/lib/AST/SwiftNameTranslation.cpp b/lib/AST/SwiftNameTranslation.cpp
index b7661c1..f928669 100644
--- a/lib/AST/SwiftNameTranslation.cpp
+++ b/lib/AST/SwiftNameTranslation.cpp
@@ -16,6 +16,7 @@
 
 #include "swift/AST/SwiftNameTranslation.h"
 #include "swift/AST/ASTContext.h"
+#include "swift/AST/Module.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/LazyResolver.h"
 #include "swift/Basic/StringExtras.h"
@@ -51,6 +52,34 @@
   return VD->getBaseName().getIdentifier().str();
 }
 
+std::string swift::objc_translation::
+getErrorDomainStringForObjC(const EnumDecl *ED) {
+  // Should have already been diagnosed as diag::objc_enum_generic.
+  assert(!ED->isGenericContext() && "Trying to bridge generic enum error to Obj-C");
+
+  // Clang decls have custom domains, but we shouldn't see them here anyway.
+  assert(!ED->getClangDecl() && "clang decls shouldn't be re-exported");
+
+  SmallVector<const NominalTypeDecl *, 4> outerTypes;
+  for (const NominalTypeDecl * D = ED;
+       D != nullptr;
+       D = D->getDeclContext()->getSelfNominalTypeDecl()) {
+    // We don't currently PrintAsObjC any types whose parents are private or
+    // fileprivate.
+    assert(D->getFormalAccess() >= AccessLevel::Internal &&
+            "We don't currently append private discriminators");
+    outerTypes.push_back(D);
+  }
+
+  std::string buffer = ED->getParentModule()->getNameStr();
+  for (auto D : reversed(outerTypes)) {
+    buffer += ".";
+    buffer += D->getNameStr();
+  }
+
+  return buffer;
+}
+
 bool swift::objc_translation::
 printSwiftEnumElemNameInObjC(const EnumElementDecl *EL, llvm::raw_ostream &OS,
                              Identifier PreferredName) {
diff --git a/lib/Basic/UUID.cpp b/lib/Basic/UUID.cpp
index f17aab4..ad90e55 100644
--- a/lib/Basic/UUID.cpp
+++ b/lib/Basic/UUID.cpp
@@ -23,6 +23,7 @@
 #define NOMINMAX
 #include <objbase.h>
 #include <string>
+#include <algorithm>
 #else
 #include <uuid/uuid.h>
 #endif
@@ -94,6 +95,7 @@
 
   char* signedStr = reinterpret_cast<char*>(str);
   memcpy(out.data(), signedStr, StringBufferSize);
+  std::transform(std::begin(out), std::end(out), std::begin(out), toupper);
 #else
   uuid_unparse_upper(Value, out.data());
 #endif
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 15b0b7f..67ae131 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -2055,9 +2055,10 @@
         var->setSection(".data");
         break;
       case llvm::Triple::ELF:
+      case llvm::Triple::Wasm:
         var->setSection(".data");
         break;
-      default:
+      case llvm::Triple::UnknownObjectFormat:
         llvm_unreachable("Don't know how to emit private global constants for "
                          "the selected object format.");
       }
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 55f852e..c3cbe27 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -901,7 +901,7 @@
   case llvm::Triple::COFF:
     return ("." + Section.substr(2) + "$B").str();
   case llvm::Triple::Wasm:
-    error(SourceLoc(), "wasm is not a supported object file format");
+    return Section.substr(2).str();
   }
 
   llvm_unreachable("unexpected object file format");
@@ -932,7 +932,6 @@
   case llvm::Triple::COFF:
     return;
   case llvm::Triple::Wasm:
-    error(SourceLoc(), "wasm is not a supported object file format");
     return;
   }
 
@@ -1211,18 +1210,19 @@
 static std::string getDynamicReplacementSection(IRGenModule &IGM) {
   std::string sectionName;
   switch (IGM.TargetInfo.OutputObjectFormat) {
+  case llvm::Triple::UnknownObjectFormat:
+    llvm_unreachable("Don't know how to emit field records table for "
+                     "the selected object format.");
   case llvm::Triple::MachO:
     sectionName = "__TEXT, __swift5_replace, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     sectionName = "swift5_replace";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5repl$B";
     break;
-  default:
-    llvm_unreachable("Don't know how to emit field records table for "
-                     "the selected object format.");
   }
   return sectionName;
 }
@@ -1410,9 +1410,8 @@
 
     if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden)
       alias->setVisibility(llvm::GlobalValue::HiddenVisibility);
-
-    if (useDllStorage())
-      alias->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+    else
+      ApplyIRLinkage(IRLinkage::ExternalExport).to(alias);
   }
 }
 
@@ -2674,18 +2673,19 @@
 
   StringRef sectionName;
   switch (TargetInfo.OutputObjectFormat) {
+  case llvm::Triple::UnknownObjectFormat:
+    llvm_unreachable("Don't know how to emit protocols for "
+                     "the selected object format.");
   case llvm::Triple::MachO:
     sectionName = "__TEXT, __swift5_protos, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     sectionName = "swift5_protocols";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5prt$B";
     break;
-  default:
-    llvm_unreachable("Don't know how to emit protocols for "
-                     "the selected object format.");
   }
 
   var->setSection(sectionName);
@@ -2733,18 +2733,19 @@
 
   StringRef sectionName;
   switch (TargetInfo.OutputObjectFormat) {
+  case llvm::Triple::UnknownObjectFormat:
+    llvm_unreachable("Don't know how to emit protocol conformances for "
+                     "the selected object format.");
   case llvm::Triple::MachO:
     sectionName = "__TEXT, __swift5_proto, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     sectionName = "swift5_protocol_conformances";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5prtc$B";
     break;
-  default:
-    llvm_unreachable("Don't know how to emit protocol conformances for "
-                     "the selected object format.");
   }
 
   var->setSection(sectionName);
@@ -2764,12 +2765,13 @@
     sectionName = "__TEXT, __swift5_types, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     sectionName = "swift5_type_metadata";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5tymd$B";
     break;
-  default:
+  case llvm::Triple::UnknownObjectFormat:
     llvm_unreachable("Don't know how to emit type metadata table for "
                      "the selected object format.");
   }
@@ -2831,12 +2833,13 @@
     sectionName = "__TEXT, __swift5_fieldmd, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     sectionName = "swift5_fieldmd";
     break;
   case llvm::Triple::COFF:
     sectionName = ".swift5_fieldmd";
     break;
-  default:
+  case llvm::Triple::UnknownObjectFormat:
     llvm_unreachable("Don't know how to emit field records table for "
                      "the selected object format.");
   }
diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp
index 0f882d2..0a5244c 100644
--- a/lib/IRGen/GenFunc.cpp
+++ b/lib/IRGen/GenFunc.cpp
@@ -77,6 +77,7 @@
 #include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/SubstitutionMap.h"
 #include "swift/AST/Types.h"
+#include "swift/IRGen/Linking.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/CodeGen/CodeGenABITypes.h"
 #include "llvm/IR/Constants.h"
@@ -1621,9 +1622,8 @@
   auto NSConcreteStackBlock =
       IGF.IGM.getModule()->getOrInsertGlobal("_NSConcreteStackBlock",
                                              IGF.IGM.ObjCClassStructTy);
-  if (IGF.IGM.useDllStorage())
-    cast<llvm::GlobalVariable>(NSConcreteStackBlock)
-        ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+  ApplyIRLinkage(IRLinkage::ExternalImport)
+      .to(cast<llvm::GlobalVariable>(NSConcreteStackBlock));
 
   //
   // Set the flags.
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index de2c749..851528c 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -837,6 +837,15 @@
     // ObjC-ness and resilience of the class hierarchy, there might be a few
     // different ways we need to go about this.
     if (loweredBaseTy.getClassOrBoundGenericClass()) {
+
+      // Use the property's class type to determine the field access.
+      auto propertyBaseDecl = property->getDeclContext()->getSelfClassDecl();
+      auto currentBaseTy =
+          loweredBaseTy.getASTType()->getSuperclassForDecl(propertyBaseDecl);
+      assert(currentBaseTy->getClassOrBoundGenericClass() == propertyBaseDecl);
+      loweredBaseTy =
+          IGM.getLoweredType(AbstractionPattern::getOpaque(), currentBaseTy);
+
       switch (getClassFieldAccess(IGM, loweredBaseTy, property)) {
       case FieldAccess::ConstantDirect: {
         // Known constant fixed offset.
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index b24f2d6..f82861a 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -119,7 +119,7 @@
     var->setSection(".rdata");
     break;
   case llvm::Triple::Wasm:
-    llvm_unreachable("web assembly object format is not supported.");
+    var->setSection(".rodata");
     break;
   }
 }
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index 8f50f60..d1761ea 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -230,10 +230,7 @@
                                       llvm::GlobalValue::LinkOnceODRLinkage,
                                       nullptr,
                                       symbolName);
-  ApplyIRLinkage({llvm::GlobalValue::LinkOnceODRLinkage,
-                  llvm::GlobalValue::HiddenVisibility,
-                  llvm::GlobalValue::DefaultStorageClass})
-      .to(var);
+  ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(var);
   var->setAlignment(2);
   setTrueConstGlobal(var);
   var->setSection(getReflectionTypeRefSectionName());
@@ -869,6 +866,7 @@
     OS << ".sw5" << FourCC << "$B";
     break;
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     OS << "swift5_" << LongName;
     break;
   case llvm::Triple::MachO:
@@ -876,9 +874,6 @@
            "Mach-O section name length must be <= 16 characters");
     OS << "__TEXT,__swift5_" << LongName << ", regular, no_dead_strip";
     break;
-  case llvm::Triple::Wasm:
-    llvm_unreachable("web assembly object format is not supported.");
-    break;
   }
   return OS.str();
 }
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index e7f67eb..4e83b4b 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -1160,7 +1160,7 @@
     Section = std::string(MachOASTSegmentName) + "," + MachOASTSectionName;
     break;
   case llvm::Triple::Wasm:
-    llvm_unreachable("web assembly object format is not supported.");
+    Section = WasmASTSectionName;
     break;
   }
   ASTSym->setSection(Section);
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 6d18685..10016fc 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -659,8 +659,8 @@
       return NAME;                                                             \
     NAME = Module.getOrInsertGlobal(SYM, FullTypeMetadataStructTy);            \
     if (useDllStorage() && !isStandardLibrary())                               \
-      cast<llvm::GlobalVariable>(NAME)->setDLLStorageClass(                    \
-          llvm::GlobalValue::DLLImportStorageClass);                           \
+      ApplyIRLinkage(IRLinkage::ExternalImport)                                \
+          .to(cast<llvm::GlobalVariable>(NAME));                               \
     return NAME;                                                               \
   }
 
@@ -681,9 +681,8 @@
     // struct objc_cache _objc_empty_cache;
     ObjCEmptyCachePtr = Module.getOrInsertGlobal("_objc_empty_cache",
                                                  OpaquePtrTy->getElementType());
-    if (useDllStorage())
-      cast<llvm::GlobalVariable>(ObjCEmptyCachePtr)
-          ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    ApplyIRLinkage(IRLinkage::ExternalImport)
+        .to(cast<llvm::GlobalVariable>(ObjCEmptyCachePtr));
   } else {
     // FIXME: Remove even the null value per rdar://problem/18801263
     ObjCEmptyCachePtr = llvm::ConstantPointerNull::get(OpaquePtrTy);
@@ -714,9 +713,8 @@
   assert(TargetInfo.hasISAMasking());
   if (!ObjCISAMaskPtr) {
     ObjCISAMaskPtr = Module.getOrInsertGlobal("swift_isaMask", IntPtrTy);
-    if (useDllStorage())
-      cast<llvm::GlobalVariable>(ObjCISAMaskPtr)
-          ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    ApplyIRLinkage(IRLinkage::ExternalImport)
+        .to(cast<llvm::GlobalVariable>(ObjCISAMaskPtr));
   }
   return Address(ObjCISAMaskPtr, getPointerAlignment());
 }
@@ -960,9 +958,8 @@
     encodeForceLoadSymbolName(buf, linkLib.getName());
     auto ForceImportThunk =
         Module.getOrInsertFunction(buf, llvm::FunctionType::get(VoidTy, false));
-    if (useDllStorage())
-      cast<llvm::GlobalValue>(ForceImportThunk)
-          ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    ApplyIRLinkage(IRLinkage::ExternalImport)
+        .to(cast<llvm::GlobalValue>(ForceImportThunk));
 
     buf += "_$";
     appendEncodedName(buf, IRGen.Opts.ModuleName);
@@ -970,9 +967,9 @@
     if (!Module.getGlobalVariable(buf.str())) {
       auto ref = new llvm::GlobalVariable(Module, ForceImportThunk->getType(),
                                           /*isConstant=*/true,
-                                          llvm::GlobalValue::WeakAnyLinkage,
+                                          llvm::GlobalValue::WeakODRLinkage,
                                           ForceImportThunk, buf.str());
-      ref->setVisibility(llvm::GlobalValue::HiddenVisibility);
+      ApplyIRLinkage(IRLinkage::InternalWeakODR).to(ref);
       auto casted = llvm::ConstantExpr::getBitCast(ref, Int8PtrTy);
       LLVMUsed.push_back(casted);
     }
@@ -1049,6 +1046,7 @@
 
   } else {
     assert((TargetInfo.OutputObjectFormat == llvm::Triple::ELF ||
+            TargetInfo.OutputObjectFormat == llvm::Triple::Wasm ||
             Triple.isOSCygMing()) &&
            "expected ELF output format or COFF format for Cygwin/MinGW");
 
@@ -1083,9 +1081,7 @@
         llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
                                llvm::GlobalValue::ExternalLinkage, buf,
                                &Module);
-    if (useDllStorage())
-      ForceImportThunk
-          ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+    ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk);
 
     auto BB = llvm::BasicBlock::Create(getLLVMContext(), "", ForceImportThunk);
     llvm::IRBuilder<> IRB(BB);
diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp
index 5a0e83f..fe620cc 100644
--- a/lib/IRGen/Linking.cpp
+++ b/lib/IRGen/Linking.cpp
@@ -37,12 +37,30 @@
   llvm::GlobalValue::DefaultStorageClass,
 };
 
+const IRLinkage IRLinkage::InternalWeakODR = {
+  llvm::GlobalValue::WeakODRLinkage,
+  llvm::GlobalValue::HiddenVisibility,
+  llvm::GlobalValue::DefaultStorageClass,
+};
+
 const IRLinkage IRLinkage::Internal = {
   llvm::GlobalValue::InternalLinkage,
   llvm::GlobalValue::DefaultVisibility,
   llvm::GlobalValue::DefaultStorageClass,
 };
 
+const IRLinkage IRLinkage::ExternalImport = {
+  llvm::GlobalValue::ExternalLinkage,
+  llvm::GlobalValue::DefaultVisibility,
+  llvm::GlobalValue::DLLImportStorageClass,
+};
+
+const IRLinkage IRLinkage::ExternalExport = {
+  llvm::GlobalValue::ExternalLinkage,
+  llvm::GlobalValue::DefaultVisibility,
+  llvm::GlobalValue::DLLExportStorageClass,
+};
+
 bool swift::irgen::useDllStorage(const llvm::Triple &triple) {
   return triple.isOSBinFormatCOFF() && !triple.isOSCygMing();
 }
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index aa639e3..c62fbbf 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -2632,7 +2632,7 @@
       auto instr = cast<ConvertEscapeToNoEscapeInst>(convInstr);
       newInstr = convBuilder.createConvertEscapeToNoEscape(
           instr->getLoc(), instr->getOperand(), newType,
-          instr->isEscapedByUser(), instr->isLifetimeGuaranteed());
+          instr->isLifetimeGuaranteed());
       break;
     }
     case SILInstructionKind::MarkDependenceInst: {
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index ec19035..4524c57 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -248,10 +248,7 @@
                                       nullptr,
                                       symbolName);
 
-  ApplyIRLinkage({llvm::GlobalValue::LinkOnceODRLinkage,
-    llvm::GlobalValue::HiddenVisibility,
-    llvm::GlobalValue::DefaultStorageClass})
-  .to(var);
+  ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(var);
   if (alignment)
     var->setAlignment(alignment);
   setTrueConstGlobal(var);
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index fdf84e6..324ad1a 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -219,10 +219,13 @@
     if (!SyntaxContext->isEnabled())
       return;
     MetatypeTypeSyntaxBuilder Builder(Context.getSyntaxArena());
+    auto TypeOrProtocol = SyntaxContext->popToken();
+    auto Period = SyntaxContext->popToken();
+    auto BaseType = SyntaxContext->popIf<TypeSyntax>().getValue();
     Builder
-      .useTypeOrProtocol(SyntaxContext->popToken())
-      .usePeriod(SyntaxContext->popToken())
-      .useBaseType(SyntaxContext->popIf<TypeSyntax>().getValue());
+      .useTypeOrProtocol(TypeOrProtocol)
+      .usePeriod(Period)
+      .useBaseType(BaseType);
     SyntaxContext->addSyntax(Builder.build());
   };
   
@@ -433,10 +436,13 @@
       auto InputNode = SyntaxContext->popIf<TypeSyntax>().getValue();
       if (auto TupleTypeNode = InputNode.getAs<TupleTypeSyntax>()) {
         // Decompose TupleTypeSyntax and repack into FunctionType.
+        auto LeftParen = TupleTypeNode->getLeftParen();
+        auto Arguments = TupleTypeNode->getElements();
+        auto RightParen = TupleTypeNode->getRightParen();
         Builder
-          .useLeftParen(TupleTypeNode->getLeftParen())
-          .useArguments(TupleTypeNode->getElements())
-          .useRightParen(TupleTypeNode->getRightParen());
+          .useLeftParen(LeftParen)
+          .useArguments(Arguments)
+          .useRightParen(RightParen);
       } else {
         Builder.addTupleTypeElement(SyntaxFactory::makeTupleTypeElement(
             InputNode, /*TrailingComma=*/None, Context.getSyntaxArena()));
@@ -705,9 +711,11 @@
 
     if (SyntaxContext->isEnabled() && Status.isSuccess()) {
       CompositionTypeElementSyntaxBuilder Builder(Context.getSyntaxArena());
+      auto Ampersand = SyntaxContext->popToken();
+      auto Type = SyntaxContext->popIf<TypeSyntax>().getValue();
       Builder
-        .useAmpersand(SyntaxContext->popToken())
-        .useType(SyntaxContext->popIf<TypeSyntax>().getValue());
+        .useAmpersand(Ampersand)
+        .useType(Type);
       SyntaxContext->addSyntax(Builder.build());
     }
 
@@ -1114,12 +1122,17 @@
         DictionaryTypeRepr(firstTy.get(), secondTy.get(), colonLoc, brackets);
     if (SyntaxContext->isEnabled()) {
       DictionaryTypeSyntaxBuilder Builder(Context.getSyntaxArena());
+      auto RightSquareBracket = SyntaxContext->popToken();
+      auto ValueType = SyntaxContext->popIf<TypeSyntax>().getValue();
+      auto Colon = SyntaxContext->popToken();
+      auto KeyType = SyntaxContext->popIf<TypeSyntax>().getValue();
+      auto LeftSquareBracket = SyntaxContext->popToken();
       Builder
-        .useRightSquareBracket(SyntaxContext->popToken())
-        .useValueType(SyntaxContext->popIf<TypeSyntax>().getValue())
-        .useColon(SyntaxContext->popToken())
-        .useKeyType(SyntaxContext->popIf<TypeSyntax>().getValue())
-        .useLeftSquareBracket(SyntaxContext->popToken());
+        .useRightSquareBracket(RightSquareBracket)
+        .useValueType(ValueType)
+        .useColon(Colon)
+        .useKeyType(KeyType)
+        .useLeftSquareBracket(LeftSquareBracket);
       SyntaxNode.emplace(Builder.build());
     }
   } else {
@@ -1127,10 +1140,13 @@
     TyR = new (Context) ArrayTypeRepr(firstTy.get(), brackets);
     if (SyntaxContext->isEnabled()) {
       ArrayTypeSyntaxBuilder Builder(Context.getSyntaxArena());
+      auto RightSquareBracket = SyntaxContext->popToken();
+      auto ElementType = SyntaxContext->popIf<TypeSyntax>().getValue();
+      auto LeftSquareBracket = SyntaxContext->popToken();
       Builder
-        .useRightSquareBracket(SyntaxContext->popToken())
-        .useElementType(SyntaxContext->popIf<TypeSyntax>().getValue())
-        .useLeftSquareBracket(SyntaxContext->popToken());
+        .useRightSquareBracket(RightSquareBracket)
+        .useElementType(ElementType)
+        .useLeftSquareBracket(LeftSquareBracket);
       SyntaxNode.emplace(Builder.build());
     }
   }
@@ -1212,9 +1228,11 @@
   if (SyntaxContext->isEnabled()) {
     ImplicitlyUnwrappedOptionalTypeSyntaxBuilder Builder(
         Context.getSyntaxArena());
+    auto ExclamationMark = SyntaxContext->popToken();
+    auto WrappedType = SyntaxContext->popIf<TypeSyntax>().getValue();
     Builder
-      .useExclamationMark(SyntaxContext->popToken())
-      .useWrappedType(SyntaxContext->popIf<TypeSyntax>().getValue());
+      .useExclamationMark(ExclamationMark)
+      .useWrappedType(WrappedType);
     SyntaxNode.emplace(Builder.build());
   }
   return makeSyntaxResult(SyntaxNode, TyR);
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 43fe6b2..97a3e7a 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -1399,21 +1399,24 @@
         ParseState = 1;
       } else if (!ParseState &&
                  (accessorKind = getAccessorKind(Id.str())).hasValue()) {
-        auto storageDecl = dyn_cast<AbstractStorageDecl>(VD);
-        auto accessor = (storageDecl
-                           ? storageDecl->getAccessor(*accessorKind)
-                           : nullptr);
-        if (!accessor) {
+        // Drill down to the corresponding accessor for each declaration,
+        // compacting away decls that lack it.
+        size_t destI = 0;
+        for (size_t srcI = 0, e = values.size(); srcI != e; ++srcI) {
+          if (auto storage = dyn_cast<AbstractStorageDecl>(values[srcI]))
+            if (auto accessor = storage->getAccessor(*accessorKind))
+              values[destI++] = accessor;
+        }
+        values.resize(destI);
+
+        // Complain if none of the decls had a corresponding accessor.
+        if (destI == 0) {
           P.diagnose(IdLoc, diag::referenced_value_no_accessor, 0);
           return true;
         }
+
         Kind = SILDeclRef::Kind::Func;
-        VD = accessor;
-        // Update values for this accessor kind.
-        for (unsigned I = 0, E = values.size(); I < E; I++)
-          if (auto otherDecl = dyn_cast<AbstractStorageDecl>(values[I]))
-            if (auto otherAccessor = otherDecl->getAccessor(*accessorKind))
-              values[I] = otherAccessor;
+        VD = values[0];
         ParseState = 1;
       } else if (!ParseState && Id.str() == "allocator") {
         Kind = SILDeclRef::Kind::Allocator;
@@ -3117,20 +3120,15 @@
     Identifier ToToken;
     SourceLoc ToLoc;
     bool not_guaranteed = false;
-    bool escaped = false;
     bool without_actually_escaping = false;
     if (Opcode == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
       StringRef attrName;
       if (parseSILOptional(attrName, *this)) {
-        if (attrName.equals("escaped"))
-          escaped = true;
-        else if (attrName.equals("not_guaranteed"))
+        if (attrName.equals("not_guaranteed"))
           not_guaranteed = true;
         else
           return true;
       }
-      if (parseSILOptional(escaped, *this, "escaped"))
-        return true;
     }
     if (parseTypedValueRef(Val, B)
         || parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
@@ -3175,8 +3173,8 @@
           B.createConvertFunction(InstLoc, Val, Ty, without_actually_escaping);
       break;
     case SILInstructionKind::ConvertEscapeToNoEscapeInst:
-      ResultVal = B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, escaped,
-                                                  !not_guaranteed);
+      ResultVal =
+          B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, !not_guaranteed);
       break;
     case SILInstructionKind::AddressToPointerInst:
       ResultVal = B.createAddressToPointer(InstLoc, Val, Ty);
diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp
index 0a2e514..85434fe 100644
--- a/lib/PrintAsObjC/PrintAsObjC.cpp
+++ b/lib/PrintAsObjC/PrintAsObjC.cpp
@@ -2511,7 +2511,7 @@
       });
       if (!hasDomainCase) {
         os << "static NSString * _Nonnull const " << getNameForObjC(ED)
-           << "Domain = @\"" << M.getName() << "." << ED->getName() << "\";\n";
+           << "Domain = @\"" << getErrorDomainStringForObjC(ED) << "\";\n";
       }
     }
 
diff --git a/lib/SIL/SILBasicBlock.cpp b/lib/SIL/SILBasicBlock.cpp
index 035866c..59dbe08 100644
--- a/lib/SIL/SILBasicBlock.cpp
+++ b/lib/SIL/SILBasicBlock.cpp
@@ -260,8 +260,7 @@
   assert(I->getParent() != this && "Must move from different basic block");
   InstList.splice(To, I->getParent()->InstList, I);
   ScopeCloner ScopeCloner(*Parent);
-  SILBuilder B(*Parent);
-  I->setDebugScope(B, ScopeCloner.getOrCreateClonedScope(I->getDebugScope()));
+  I->setDebugScope(ScopeCloner.getOrCreateClonedScope(I->getDebugScope()));
 }
 
 void
@@ -277,14 +276,12 @@
     return;
 
   ScopeCloner ScopeCloner(*Parent);
-  SILBuilder B(*Parent);
 
   // If splicing blocks not in the same function, update the parent pointers.
   for (; First != Last; ++First) {
     First->Parent = Parent;
     for (auto &II : *First)
-      II.setDebugScope(B,
-                       ScopeCloner.getOrCreateClonedScope(II.getDebugScope()));
+      II.setDebugScope(ScopeCloner.getOrCreateClonedScope(II.getDebugScope()));
   }
 }
 
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index b4b68d7..b0db398 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -120,7 +120,7 @@
 // Create the appropriate cast instruction based on result type.
 SingleValueInstruction *
 SILBuilder::createUncheckedBitCast(SILLocation Loc, SILValue Op, SILType Ty) {
-  assert(Ty.isLoadableOrOpaque(getModule()));
+  assert(isLoadableOrOpaque(Ty));
   if (Ty.isTrivial(getModule()))
     return insert(UncheckedTrivialBitCastInst::create(
         getSILDebugLocation(Loc), Op, Ty, getFunction(), C.OpenedArchetypes));
@@ -552,7 +552,7 @@
 
 DebugValueInst *SILBuilder::createDebugValue(SILLocation Loc, SILValue src,
                                              SILDebugVariable Var) {
-  assert(src->getType().isLoadableOrOpaque(getModule()));
+  assert(isLoadableOrOpaque(src->getType()));
   // Debug location overrides cannot apply to debug value instructions.
   DebugLocOverrideRAII LocOverride{*this, None};
   return insert(
diff --git a/lib/SIL/SILConstants.cpp b/lib/SIL/SILConstants.cpp
index 2666f45..94ea0dc 100644
--- a/lib/SIL/SILConstants.cpp
+++ b/lib/SIL/SILConstants.cpp
@@ -404,6 +404,14 @@
   return dav->memoryObject;
 }
 
+/// Return just the memory object for an address value.
+SymbolicValueMemoryObject *SymbolicValue::getAddressValueMemoryObject() const {
+  if (representationKind == RK_DirectAddress)
+    return value.directAddress;
+  assert(representationKind == RK_DerivedAddress);
+  return value.derivedAddress->memoryObject;
+}
+
 //===----------------------------------------------------------------------===//
 // Higher level code
 //===----------------------------------------------------------------------===//
@@ -521,3 +529,124 @@
     emittedFirstNote = true;
   }
 }
+
+/// Returns the element of `aggregate` specified by the access path.
+///
+/// This is a helper for `SymbolicValueMemoryObject::getIndexedElement`. See
+/// there for more detailed documentation.
+static SymbolicValue getIndexedElement(SymbolicValue aggregate,
+                                       ArrayRef<unsigned> accessPath,
+                                       Type type) {
+  // We're done if we've run out of access path.
+  if (accessPath.empty())
+    return aggregate;
+
+  // Everything inside uninit memory is uninit memory.
+  if (aggregate.getKind() == SymbolicValue::UninitMemory)
+    return SymbolicValue::getUninitMemory();
+
+  assert(aggregate.getKind() == SymbolicValue::Aggregate &&
+         "the accessPath is invalid for this type");
+
+  unsigned elementNo = accessPath.front();
+
+  SymbolicValue elt = aggregate.getAggregateValue()[elementNo];
+  Type eltType;
+  if (auto *decl = type->getStructOrBoundGenericStruct()) {
+    auto it = decl->getStoredProperties().begin();
+    std::advance(it, elementNo);
+    eltType = (*it)->getType();
+  } else if (auto tuple = type->getAs<TupleType>()) {
+    assert(elementNo < tuple->getNumElements() && "invalid index");
+    eltType = tuple->getElement(elementNo).getType();
+  } else {
+    llvm_unreachable("the accessPath is invalid for this type");
+  }
+
+  return getIndexedElement(elt, accessPath.drop_front(), eltType);
+}
+
+/// Given that this memory object contains an aggregate value like
+/// {{1, 2}, 3}, and given an access path like [0,1], return the indexed
+/// element, e.g. "2" in this case.
+///
+/// Returns uninit memory if the access path points at or into uninit memory.
+///
+/// Precondition: The access path must be valid for this memory object's type.
+SymbolicValue
+SymbolicValueMemoryObject::getIndexedElement(ArrayRef<unsigned> accessPath) {
+  return ::getIndexedElement(value, accessPath, type);
+}
+
+/// Returns `aggregate` with the element specified by the access path set to
+/// `newElement`.
+///
+/// This is a helper for `SymbolicValueMemoryObject::setIndexedElement`. See
+/// there for more detailed documentation.
+static SymbolicValue setIndexedElement(SymbolicValue aggregate,
+                                       ArrayRef<unsigned> accessPath,
+                                       SymbolicValue newElement, Type type,
+                                       ASTContext &astCtx) {
+  // We're done if we've run out of access path.
+  if (accessPath.empty())
+    return newElement;
+
+  // If we have an uninit memory, then scalarize it into an aggregate to
+  // continue.  This happens when memory objects are initialized piecewise.
+  if (aggregate.getKind() == SymbolicValue::UninitMemory) {
+    unsigned numMembers;
+    // We need to have either a struct or a tuple type.
+    if (auto *decl = type->getStructOrBoundGenericStruct()) {
+      numMembers = std::distance(decl->getStoredProperties().begin(),
+                                 decl->getStoredProperties().end());
+    } else if (auto tuple = type->getAs<TupleType>()) {
+      numMembers = tuple->getNumElements();
+    } else {
+      llvm_unreachable("the accessPath is invalid for this type");
+    }
+
+    SmallVector<SymbolicValue, 4> newElts(numMembers,
+                                          SymbolicValue::getUninitMemory());
+    aggregate = SymbolicValue::getAggregate(newElts, astCtx);
+  }
+
+  assert(aggregate.getKind() == SymbolicValue::Aggregate &&
+         "the accessPath is invalid for this type");
+
+  unsigned elementNo = accessPath.front();
+
+  ArrayRef<SymbolicValue> oldElts = aggregate.getAggregateValue();
+  Type eltType;
+  if (auto *decl = type->getStructOrBoundGenericStruct()) {
+    auto it = decl->getStoredProperties().begin();
+    std::advance(it, elementNo);
+    eltType = (*it)->getType();
+  } else if (auto tuple = type->getAs<TupleType>()) {
+    assert(elementNo < tuple->getNumElements() && "invalid index");
+    eltType = tuple->getElement(elementNo).getType();
+  } else {
+    llvm_unreachable("the accessPath is invalid for this type");
+  }
+
+  // Update the indexed element of the aggregate.
+  SmallVector<SymbolicValue, 4> newElts(oldElts.begin(), oldElts.end());
+  newElts[elementNo] = setIndexedElement(newElts[elementNo],
+                                         accessPath.drop_front(), newElement,
+                                         eltType, astCtx);
+
+  aggregate = SymbolicValue::getAggregate(newElts, astCtx);
+
+  return aggregate;
+}
+
+/// Given that this memory object contains an aggregate value like
+/// {{1, 2}, 3}, given an access path like [0,1], and given a new element like
+/// "4", set the indexed element to the specified scalar, producing {{1, 4},
+/// 3} in this case.
+///
+/// Precondition: The access path must be valid for this memory object's type.
+void SymbolicValueMemoryObject::setIndexedElement(
+    ArrayRef<unsigned> accessPath, SymbolicValue newElement,
+    ASTContext &astCtx) {
+  value = ::setIndexedElement(value, accessPath, newElement, type, astCtx);
+}
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index e612eae..6b3983c 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -444,6 +444,11 @@
 
 /// True if the function should have its body serialized.
 IsSerialized_t SILDeclRef::isSerialized() const {
+  // Native-to-foreign thunks are only referenced from the Objective-C
+  // method table.
+  if (isForeign)
+    return IsNotSerialized;
+
   DeclContext *dc;
   if (auto closure = getAbstractClosureExpr())
     dc = closure->getLocalContext();
diff --git a/lib/SIL/SILFunction.cpp b/lib/SIL/SILFunction.cpp
index 067d0b1..d1db70d 100644
--- a/lib/SIL/SILFunction.cpp
+++ b/lib/SIL/SILFunction.cpp
@@ -477,10 +477,16 @@
   if (hasValidLinkageForFragileInline())
     return true;
 
-  // If the containing module has been serialized
-  if (getModule().isSerialized()) {
+  // If the containing module has been serialized already, we no longer
+  // enforce any invariants.
+  if (getModule().isSerialized())
     return true;
-  }
+
+  // If the function has a subclass scope that limits its visibility outside
+  // the module despite its linkage, we cannot reference it.
+  if (getClassSubclassScope() == SubclassScope::Resilient &&
+      isAvailableExternally())
+    return false;
 
   // Otherwise, only public functions can be referenced.
   return hasPublicVisibility(getLinkage());
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 5d14830..c652c9e 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -865,15 +865,17 @@
                          .getReferenceStorageReferentType();
 
   auto storage = accessor->getStorage();
-  auto valueType = storage->getValueInterfaceType()
-                          ->getReferenceStorageReferent();
+  auto valueType = storage->getValueInterfaceType();
   if (reqtSubs) {
     valueType = valueType.subst(*reqtSubs);
   }
 
+  auto canValueType = valueType->getCanonicalType(
+    accessor->getGenericSignature());
+
   // 'modify' yields an inout of the target type.
   if (accessor->getAccessorKind() == AccessorKind::Modify) {
-    auto loweredValueTy = M.Types.getLoweredType(origType, valueType);
+    auto loweredValueTy = M.Types.getLoweredType(origType, canValueType);
     yields.push_back(SILYieldInfo(loweredValueTy.getASTType(),
                                   ParameterConvention::Indirect_Inout));
     return;
@@ -882,8 +884,7 @@
   // 'read' yields a borrowed value of the target type, destructuring
   // tuples as necessary.
   assert(accessor->getAccessorKind() == AccessorKind::Read);
-  destructureYieldsForReadAccessor(M, origType, valueType->getCanonicalType(),
-                                   yields);
+  destructureYieldsForReadAccessor(M, origType, canValueType, yields);
 }
 
 /// Create the appropriate SIL function type for the given formal type
diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp
index 243745f..bfac323 100644
--- a/lib/SIL/SILInstruction.cpp
+++ b/lib/SIL/SILInstruction.cpp
@@ -41,7 +41,7 @@
   return Location.getScope();
 }
 
-void SILInstruction::setDebugScope(SILBuilder &B, const SILDebugScope *DS) {
+void SILInstruction::setDebugScope(const SILDebugScope *DS) {
   if (getDebugScope() && getDebugScope()->InlinedCallSite)
     assert(DS->InlinedCallSite && "throwing away inlined scope info");
 
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index fa3045d..28ab291 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -1993,8 +1993,7 @@
 
 ConvertEscapeToNoEscapeInst *ConvertEscapeToNoEscapeInst::create(
     SILDebugLocation DebugLoc, SILValue Operand, SILType Ty, SILFunction &F,
-    SILOpenedArchetypesState &OpenedArchetypes, bool isEscapedByUser,
-    bool isLifetimeGuaranteed) {
+    SILOpenedArchetypesState &OpenedArchetypes, bool isLifetimeGuaranteed) {
   SILModule &Mod = F.getModule();
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
@@ -2002,9 +2001,8 @@
   unsigned size =
     totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
   void *Buffer = Mod.allocateInst(size, alignof(ConvertEscapeToNoEscapeInst));
-  auto *CFI = ::new (Buffer)
-      ConvertEscapeToNoEscapeInst(DebugLoc, Operand, TypeDependentOperands, Ty,
-                                  isEscapedByUser, isLifetimeGuaranteed);
+  auto *CFI = ::new (Buffer) ConvertEscapeToNoEscapeInst(
+      DebugLoc, Operand, TypeDependentOperands, Ty, isLifetimeGuaranteed);
   // If we do not have lowered SIL, make sure that are not performing
   // ABI-incompatible conversions.
   //
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 2b53424..f52085e 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -1414,7 +1414,6 @@
   }
   void visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *CI) {
     *this << (CI->isLifetimeGuaranteed() ? "" : "[not_guaranteed] ")
-          << (CI->isEscapedByUser() ? "[escaped] " : "")
           << getIDAndType(CI->getOperand()) << " to " << CI->getType();
   }
   void visitThinFunctionToPointerInst(ThinFunctionToPointerInst *CI) {
diff --git a/lib/SIL/SILType.cpp b/lib/SIL/SILType.cpp
index 0031d5c..79d4ae5 100644
--- a/lib/SIL/SILType.cpp
+++ b/lib/SIL/SILType.cpp
@@ -175,6 +175,12 @@
   return isLoadable(M) || !SILModuleConventions(M).useLoweredAddresses();
 }
 
+bool SILType::isLoadableOrOpaque(SILFunction *inFunction) const {
+  SILModule &M = inFunction->getModule();
+  return isLoadable(inFunction) ||
+         !SILModuleConventions(M).useLoweredAddresses();
+}
+
 /// True if the type, or the referenced type of an address type, is
 /// address-only. For example, it could be a resilient struct or something of
 /// unknown size.
@@ -182,6 +188,11 @@
   return M.getTypeLowering(*this).isAddressOnly();
 }
 
+bool SILType::isAddressOnly(SILFunction *inFunction) const {
+  return inFunction->getModule().getTypeLowering(*this,
+                        inFunction->getResilienceExpansion()).isAddressOnly();
+}
+
 SILType SILType::substGenericArgs(SILModule &M,
                                   SubstitutionMap SubMap) const {
   auto fnTy = castTo<SILFunctionType>();
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 6798e44..9a8da28 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -119,6 +119,7 @@
 
 /// Verify invariants on a key path component.
 void verifyKeyPathComponent(SILModule &M,
+                            ResilienceExpansion expansion,
                             llvm::function_ref<void(bool, StringRef)> require,
                             CanType &baseTy,
                             CanType leafTy,
@@ -211,6 +212,12 @@
   switch (auto kind = component.getKind()) {
   case KeyPathPatternComponent::Kind::StoredProperty: {
     auto property = component.getStoredPropertyDecl();
+    if (expansion == ResilienceExpansion::Minimal) {
+      require(property->getEffectiveAccess() >= AccessLevel::Public,
+              "Key path in serialized function cannot reference non-public "
+              "property");
+    }
+
     auto fieldTy = baseTy->getTypeOfMember(M.getSwiftModule(), property)
                          ->getReferenceStorageReferent()
                          ->getCanonicalType();
@@ -218,6 +225,8 @@
             "property decl should be a member of the base with the same type "
             "as the component");
     require(property->hasStorage(), "property must be stored");
+    require(!property->isResilient(M.getSwiftModule(), expansion),
+            "cannot access storage of resilient property");
     auto propertyTy = loweredBaseTy.getFieldType(property, M);
     require(propertyTy.getObjectType()
               == loweredComponentTy.getObjectType(),
@@ -247,6 +256,12 @@
     // Getter should be <Sig...> @convention(thin) (@in_guaranteed Base) -> @out Result
     {
       auto getter = component.getComputedPropertyGetter();
+      if (expansion == ResilienceExpansion::Minimal) {
+        require(getter->hasValidLinkageForFragileRef(),
+                "Key path in serialized function should not reference "
+                "less visible getters");
+      }
+
       auto substGetterType = getter->getLoweredFunctionType()
         ->substGenericArgs(M, patternSubs);
       require(substGetterType->getRepresentation() ==
@@ -286,6 +301,12 @@
       // <Sig...> @convention(thin) (@in_guaranteed Result, @in Base) -> ()
       
       auto setter = component.getComputedPropertySetter();
+      if (expansion == ResilienceExpansion::Minimal) {
+        require(setter->hasValidLinkageForFragileRef(),
+                "Key path in serialized function should not reference "
+                "less visible setters");
+      }
+
       auto substSetterType = setter->getLoweredFunctionType()
         ->substGenericArgs(M, patternSubs);
       
@@ -1456,8 +1477,13 @@
   }
 
   void checkAllocGlobalInst(AllocGlobalInst *AGI) {
+    SILGlobalVariable *RefG = AGI->getReferencedGlobal();
+    if (auto *VD = RefG->getDecl()) {
+      require(!VD->isResilient(F.getModule().getSwiftModule(),
+                               F.getResilienceExpansion()),
+              "cannot access storage of resilient global");
+    }
     if (F.isSerialized()) {
-      SILGlobalVariable *RefG = AGI->getReferencedGlobal();
       require(RefG->isSerialized()
                 || hasPublicVisibility(RefG->getLinkage()),
               "alloc_global inside fragile function cannot "
@@ -1469,6 +1495,11 @@
     SILGlobalVariable *RefG = GAI->getReferencedGlobal();
     require(GAI->getType().getObjectType() == RefG->getLoweredType(),
             "global_addr/value must be the type of the variable it references");
+    if (auto *VD = RefG->getDecl()) {
+      require(!VD->isResilient(F.getModule().getSwiftModule(),
+                               F.getResilienceExpansion()),
+              "cannot access storage of resilient global");
+    }
     if (F.isSerialized()) {
       require(RefG->isSerialized()
               || hasPublicVisibility(RefG->getLinkage()),
@@ -1503,7 +1534,7 @@
   void checkLoadInst(LoadInst *LI) {
     require(LI->getType().isObject(), "Result of load must be an object");
     require(!fnConv.useLoweredAddresses()
-                || LI->getType().isLoadable(LI->getModule()),
+                || LI->getType().isLoadable(LI->getFunction()),
             "Load must have a loadable type");
     require(LI->getOperand()->getType().isAddress(),
             "Load operand must be an address");
@@ -1542,7 +1573,7 @@
         "Inst with qualified ownership in a function that is not qualified");
     require(LBI->getType().isObject(), "Result of load must be an object");
     require(!fnConv.useLoweredAddresses()
-            || LBI->getType().isLoadable(LBI->getModule()),
+            || LBI->getType().isLoadable(LBI->getFunction()),
             "Load must have a loadable type");
     require(LBI->getOperand()->getType().isAddress(),
             "Load operand must be an address");
@@ -1660,7 +1691,7 @@
     require(SI->getSrc()->getType().isObject(),
             "Can't store from an address source");
     require(!fnConv.useLoweredAddresses()
-                || SI->getSrc()->getType().isLoadable(SI->getModule()),
+                || SI->getSrc()->getType().isLoadable(SI->getFunction()),
             "Can't store a non loadable type");
     require(SI->getDest()->getType().isAddress(),
             "Must store to an address dest");
@@ -2041,6 +2072,9 @@
     require(!structDecl->hasUnreferenceableStorage(),
             "Cannot build a struct with unreferenceable storage from elements "
             "using StructInst");
+    require(!structDecl->isResilient(F.getModule().getSwiftModule(),
+                                     F.getResilienceExpansion()),
+            "cannot access storage of resilient struct");
     require(SI->getType().isObject(),
             "StructInst must produce an object");
 
@@ -2232,8 +2266,14 @@
   void checkDeallocRefInst(DeallocRefInst *DI) {
     require(DI->getOperand()->getType().isObject(),
             "Operand of dealloc_ref must be object");
-    require(DI->getOperand()->getType().getClassOrBoundGenericClass(),
-            "Operand of dealloc_ref must be of class type");
+    auto *cd = DI->getOperand()->getType().getClassOrBoundGenericClass();
+    require(cd, "Operand of dealloc_ref must be of class type");
+
+    if (!DI->canAllocOnStack()) {
+      require(!cd->isResilient(F.getModule().getSwiftModule(),
+                              F.getResilienceExpansion()),
+              "cannot directly deallocate resilient class");
+    }
   }
   void checkDeallocPartialRefInst(DeallocPartialRefInst *DPRI) {
     require(DPRI->getInstance()->getType().isObject(),
@@ -2247,6 +2287,9 @@
         ->getInstanceType()->getClassOrBoundGenericClass();
     require(class2,
             "Second operand of dealloc_partial_ref must be a class metatype");
+    require(!class2->isResilient(F.getModule().getSwiftModule(),
+                                 F.getResilienceExpansion()),
+            "cannot directly deallocate resilient class");
     while (class1 != class2) {
       class1 = class1->getSuperclassDecl();
       require(class1, "First operand not superclass of second instance type");
@@ -2343,6 +2386,9 @@
             "result of struct_extract cannot be address");
     StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
     require(sd, "must struct_extract from struct");
+    require(!sd->isResilient(F.getModule().getSwiftModule(),
+                             F.getResilienceExpansion()),
+            "cannot access storage of resilient struct");
     require(!EI->getField()->isStatic(),
             "cannot get address of static property with struct_element_addr");
     require(EI->getField()->hasStorage(),
@@ -2384,6 +2430,9 @@
             "must derive struct_element_addr from address");
     StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
     require(sd, "struct_element_addr operand must be struct address");
+    require(!sd->isResilient(F.getModule().getSwiftModule(),
+                             F.getResilienceExpansion()),
+            "cannot access storage of resilient struct");
     require(EI->getType().isAddress(),
             "result of struct_element_addr must be address");
     require(!EI->getField()->isStatic(),
@@ -2413,6 +2462,9 @@
     SILType operandTy = EI->getOperand()->getType();
     ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
     require(cd, "ref_element_addr operand must be a class instance");
+    require(!cd->isResilient(F.getModule().getSwiftModule(),
+                             F.getResilienceExpansion()),
+            "cannot access storage of resilient class");
 
     require(EI->getField()->getDeclContext() == cd,
             "ref_element_addr field must be a member of the class");
@@ -2433,8 +2485,21 @@
     SILType operandTy = RTAI->getOperand()->getType();
     ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
     require(cd, "ref_tail_addr operand must be a class instance");
+    require(!cd->isResilient(F.getModule().getSwiftModule(),
+                             F.getResilienceExpansion()),
+            "cannot access storage of resilient class");
+    require(cd, "ref_tail_addr operand must be a class instance");
   }
-  
+
+  void checkDestructureStructInst(DestructureStructInst *DSI) {
+    SILType operandTy = DSI->getOperand()->getType();
+    StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
+    require(sd, "must struct_extract from struct");
+    require(!sd->isResilient(F.getModule().getSwiftModule(),
+                             F.getResilienceExpansion()),
+            "cannot access storage of resilient struct");
+  }
+
   SILType getMethodSelfType(CanSILFunctionType ft) {
     return fnConv.getSILType(ft->getParameters().back());
   }
@@ -3618,9 +3683,6 @@
     // '[not_guaranteed]' or '[escaped]' attributes.
     if (!SkipConvertEscapeToNoescapeAttributes &&
         F.getModule().getStage() != SILStage::Raw) {
-      require(!ICI->isEscapedByUser(),
-              "convert_escape_to_noescape [escaped] not "
-              "allowed after mandatory passes");
       require(ICI->isLifetimeGuaranteed(),
               "convert_escape_to_noescape [not_guaranteed] not "
               "allowed after mandatory passes");
@@ -3867,8 +3929,6 @@
 
     // Find the set of enum elements for the type so we can verify
     // exhaustiveness.
-    // FIXME: We also need to consider if the enum is resilient, in which case
-    // we're never guaranteed to be exhaustive.
     llvm::DenseSet<EnumElementDecl*> unswitchedElts;
     uDecl->getAllElements(unswitchedElts);
 
@@ -3954,8 +4014,6 @@
 
     // Find the set of enum elements for the type so we can verify
     // exhaustiveness.
-    // FIXME: We also need to consider if the enum is resilient, in which case
-    // we're never guaranteed to be exhaustive.
     llvm::DenseSet<EnumElementDecl*> unswitchedElts;
     uDecl->getAllElements(unswitchedElts);
 
@@ -3979,9 +4037,12 @@
     }
 
     // If the switch is non-exhaustive, we require a default.
-    require(unswitchedElts.empty() || SOI->hasDefault(),
-            "nonexhaustive switch_enum_addr must have a default "
-            "destination");
+    bool isExhaustive =
+        uDecl->isEffectivelyExhaustive(F.getModule().getSwiftModule(),
+                                       F.getResilienceExpansion());
+    require((isExhaustive && unswitchedElts.empty()) || SOI->hasDefault(),
+            "nonexhaustive switch_enum_addr must have a default destination");
+
     if (SOI->hasDefault())
       require(SOI->getDefaultBB()->args_empty(),
               "switch_enum_addr default destination must take "
@@ -4242,7 +4303,7 @@
           break;
         }
       
-        verifyKeyPathComponent(F.getModule(),
+        verifyKeyPathComponent(F.getModule(), F.getResilienceExpansion(),
           [&](bool reqt, StringRef message) { _require(reqt, message); },
           baseTy,
           leafTy,
@@ -4879,15 +4940,16 @@
 
   if (auto &component = getComponent()) {
     verifyKeyPathComponent(const_cast<SILModule&>(M),
-      require,
-      baseTy,
-      leafTy,
-      *component,
-      {},
-      canSig,
-      subs,
-      /*property descriptor*/true,
-      hasIndices);
+                           ResilienceExpansion::Maximal,
+                           require,
+                           baseTy,
+                           leafTy,
+                           *component,
+                           {},
+                           canSig,
+                           subs,
+                           /*property descriptor*/true,
+                           hasIndices);
     // verifyKeyPathComponent updates baseTy to be the projected type of the
     // component, which should be the same as the type of the declared storage
     require(baseTy == leafTy,
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index 72fe4b2..e93ab8c 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -1139,7 +1139,7 @@
   /// Build the appropriate TypeLowering subclass for the given type,
   /// which is assumed to already have been lowered.
   class LowerType
-    : public TypeClassifierBase<LowerType, const TypeLowering *>
+    : public TypeClassifierBase<LowerType, TypeLowering *>
   {
     TypeConverter &TC;
     IsDependent_t Dependent;
@@ -1149,18 +1149,18 @@
       : TypeClassifierBase(TC.M, Sig, Expansion),
         TC(TC), Dependent(Dependent) {}
 
-    const TypeLowering *
+    TypeLowering *
     handleTrivial(CanType type) {
       auto silType = SILType::getPrimitiveObjectType(type);
       return new (TC, Dependent) TrivialTypeLowering(silType);
     }
 
-    const TypeLowering *handleReference(CanType type) {
+    TypeLowering *handleReference(CanType type) {
       auto silType = SILType::getPrimitiveObjectType(type);
       return new (TC, Dependent) ReferenceTypeLowering(silType);
     }
 
-    const TypeLowering *handleAddressOnly(CanType type, 
+    TypeLowering *handleAddressOnly(CanType type,
                                           RecursiveProperties properties) {
       if (SILModuleConventions(M).useLoweredAddresses()) {
         auto silType = SILType::getPrimitiveAddressType(type);
@@ -1171,20 +1171,20 @@
     }
 
 #define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
-    const TypeLowering * \
+    TypeLowering * \
     visitLoadable##Name##StorageType(Can##Name##StorageType type) { \
       return new (TC, Dependent) Loadable##Name##TypeLowering( \
                                   SILType::getPrimitiveObjectType(type)); \
     }
 #include "swift/AST/ReferenceStorage.def"
 
-    const TypeLowering *
+    TypeLowering *
     visitBuiltinUnsafeValueBufferType(CanBuiltinUnsafeValueBufferType type) {
       auto silType = SILType::getPrimitiveAddressType(type);
       return new (TC, Dependent) UnsafeValueBufferTypeLowering(silType);
     }
 
-    const TypeLowering *visitTupleType(CanTupleType tupleType) {
+    TypeLowering *visitTupleType(CanTupleType tupleType) {
       RecursiveProperties properties;
       for (auto eltType : tupleType.getElementTypes()) {
         auto &lowering = TC.getTypeLowering(eltType);
@@ -1195,13 +1195,13 @@
                                                                     properties);
     }
 
-    const TypeLowering *visitAnyStructType(CanType structType, StructDecl *D) {
+    TypeLowering *visitAnyStructType(CanType structType, StructDecl *D) {
 
       // For now, if the type does not have a fixed layout in all resilience
       // domains, we will treat it as address-only in SIL.
       if (D->isResilient(M.getSwiftModule(), Expansion))
         return handleAddressOnly(structType,
-                                 RecursiveProperties::forOpaque());
+                                 RecursiveProperties::forResilient());
 
       // Classify the type according to its stored properties.
       RecursiveProperties properties;
@@ -1216,11 +1216,11 @@
                                                                     properties);
     }
         
-    const TypeLowering *visitAnyEnumType(CanType enumType, EnumDecl *D) {
+    TypeLowering *visitAnyEnumType(CanType enumType, EnumDecl *D) {
       // For now, if the type does not have a fixed layout in all resilience
       // domains, we will treat it as address-only in SIL.
       if (D->isResilient(M.getSwiftModule(), Expansion))
-        return handleAddressOnly(enumType, RecursiveProperties::forOpaque());
+        return handleAddressOnly(enumType, RecursiveProperties::forResilient());
 
       // If the whole enum is indirect, we lower it as if all payload
       // cases were indirect. This means a fixed-layout indirect enum
@@ -1257,7 +1257,7 @@
     }
 
     template <class LoadableLoweringClass>
-    const TypeLowering *handleAggregateByProperties(CanType type,
+    TypeLowering *handleAggregateByProperties(CanType type,
                                                     RecursiveProperties props) {
       if (props.isAddressOnly()) {
         return handleAddressOnly(type, props);
@@ -1451,7 +1451,8 @@
     AbstractionPattern(getCurGenericContext(), loweredSubstType);
   auto loweredKey = getTypeKey(origTypeForCaching, loweredSubstType);
 
-  auto &lowering = getTypeLoweringForLoweredType(loweredKey);
+  auto &lowering = getTypeLoweringForLoweredType(loweredKey,
+                                                 ResilienceExpansion::Minimal);
   insert(key, &lowering);
   return lowering;
 }
@@ -1565,16 +1566,18 @@
   return substType;
 }
 
-const TypeLowering &TypeConverter::getTypeLowering(SILType type) {
+const TypeLowering &
+TypeConverter::getTypeLowering(SILType type, ResilienceExpansion forExpansion) {
   auto loweredType = type.getASTType();
   auto key = getTypeKey(AbstractionPattern(getCurGenericContext(), loweredType),
                         loweredType);
 
-  return getTypeLoweringForLoweredType(key);
+  return getTypeLoweringForLoweredType(key, forExpansion);
 }
 
 const TypeLowering &
-TypeConverter::getTypeLoweringForLoweredType(TypeKey key) {
+TypeConverter::getTypeLoweringForLoweredType(TypeKey key,
+                                             ResilienceExpansion forExpansion) {
   auto type = key.SubstType;
   assert(type->isLegalSILType() && "type is not lowered!");
   (void)type;
@@ -1582,10 +1585,39 @@
   // Re-using uncurry level 0 is reasonable because our uncurrying
   // transforms are idempotent at this level.  This means we don't
   // need a ton of redundant entries in the map.
-  if (auto existing = find(key))
-    return *existing;
+  const TypeLowering *lowering = find(key);
+  if (!lowering) {
+    lowering = &getTypeLoweringForUncachedLoweredType(key);
+  }
+  assert(lowering->forExpansion == ResilienceExpansion::Minimal &&
+         "the first lowering in the list must be for minimal expansion");
 
-  return getTypeLoweringForUncachedLoweredType(key);
+  if (key.isDependent() || !lowering->isResilient()) {
+    // Don't try to refine the lowering for other resilience expansions if
+    // we don't expect to get a different lowering anyway.
+    return *lowering;
+  }
+
+  // Search for a matching lowering in the linked list of lowerings.
+  while (true) {
+    if (lowering->forExpansion == forExpansion)
+      return *lowering;
+    if (lowering->nextExpansion) {
+      // Continue searching.
+      lowering = lowering->nextExpansion;
+      continue;
+    }
+
+    // Create a new lowering for the resilience expansion.
+    TypeLowering *theInfo = LowerType(*this,
+                              CanGenericSignature(),
+                              forExpansion,
+                              key.isDependent()).visit(key.SubstType);
+
+    lowering->nextExpansion = theInfo;
+    theInfo->forExpansion = forExpansion;
+    return *theInfo;
+  }
 }
 
 /// Do type-lowering for a lowered type which is not already in the cache,
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 4aa6800..2ff32b8 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -973,7 +973,7 @@
   // Handle the escaping to noescape conversion.
   assert(loweredFuncTy->isNoEscape());
   return B.createConvertEscapeToNoEscape(
-      loc, thunkedFn, SILType::getPrimitiveObjectType(loweredFuncTy), false);
+      loc, thunkedFn, SILType::getPrimitiveObjectType(loweredFuncTy));
 }
 
 static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index 8bc97e8..ffe70ba 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -218,8 +218,7 @@
 }
 
 ManagedValue SILGenBuilder::createConvertEscapeToNoEscape(
-    SILLocation loc, ManagedValue fn, SILType resultTy,
-    bool isEscapedByUser) {
+    SILLocation loc, ManagedValue fn, SILType resultTy) {
 
   auto fnType = fn.getType().castTo<SILFunctionType>();
   auto resultFnType = resultTy.castTo<SILFunctionType>();
@@ -234,8 +233,8 @@
   (void)fnType;
   (void)resultFnType;
   SILValue fnValue = fn.getValue();
-  SILValue result = createConvertEscapeToNoEscape(
-      loc, fnValue, resultTy, isEscapedByUser, false);
+  SILValue result =
+      createConvertEscapeToNoEscape(loc, fnValue, resultTy, false);
   return ManagedValue::forTrivialObjectRValue(result);
 }
 
diff --git a/lib/SILGen/SILGenBuilder.h b/lib/SILGen/SILGenBuilder.h
index a3920ae..1809bd0 100644
--- a/lib/SILGen/SILGenBuilder.h
+++ b/lib/SILGen/SILGenBuilder.h
@@ -379,8 +379,7 @@
   using SILBuilder::createConvertEscapeToNoEscape;
   ManagedValue
   createConvertEscapeToNoEscape(SILLocation loc, ManagedValue fn,
-                                SILType resultTy,
-                                bool isEscapedByUser);
+                                SILType resultTy);
 
   using SILBuilder::createStore;
   /// Forward \p value into \p address.
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 6cf3f42..5427725 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -3181,7 +3181,7 @@
   // Handle the escaping to noescape conversion.
   assert(expectedType->isNoEscape());
   return SGF.B.createConvertEscapeToNoEscape(
-      loc, thunkedFn, SILType::getPrimitiveObjectType(expectedType), false);
+      loc, thunkedFn, SILType::getPrimitiveObjectType(expectedType));
 }
 
 static CanSILFunctionType buildWithoutActuallyEscapingThunkType(
@@ -3355,7 +3355,7 @@
   } else if (newFnType != expectedFnType) {
     // Escaping to noescape conversion.
     SILType resTy = SILType::getPrimitiveObjectType(expectedFnType);
-    fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy, false);
+    fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy);
   }
 
   return fn;
diff --git a/lib/SILOptimizer/Analysis/ProtocolConformanceAnalysis.cpp b/lib/SILOptimizer/Analysis/ProtocolConformanceAnalysis.cpp
index b16d47d..859e5af 100644
--- a/lib/SILOptimizer/Analysis/ProtocolConformanceAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ProtocolConformanceAnalysis.cpp
@@ -17,6 +17,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/SILInstruction.h"
 #include "swift/SIL/SILModule.h"
 #include "swift/SIL/SILValue.h"
@@ -34,6 +35,7 @@
       : ProtocolConformanceCache(ProtocolConformanceCache) {}
 
   bool walkToDeclPre(Decl *D) override {
+    /// (1) Walk over all NominalTypeDecls to determine conformances.
     if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
       auto Protocols = NTD->getAllProtocols();
       for (auto &Protocol : Protocols) {
@@ -42,6 +44,20 @@
         }
       }
     }
+    /// (2) Walk over all ExtensionDecls to determine conformances.
+    if (auto *e = dyn_cast<ExtensionDecl>(D)) {
+      auto *ntd = e->getExtendedNominal();
+      if (!isa<ProtocolDecl>(ntd)) {
+        for (auto *conformance : e->getLocalConformances()) {
+          if (isa<NormalProtocolConformance>(conformance)) {
+            auto *proto = conformance->getProtocol();
+            if (proto->getEffectiveAccess() <= AccessLevel::Internal) {
+              ProtocolConformanceCache[proto].push_back(ntd);
+            }
+          }
+        }
+      }
+    }
     return true;
   }
 };
diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp
index d497b69..d587871 100644
--- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp
+++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialSpecializer.cpp
@@ -38,12 +38,12 @@
   /// Determine if the current function is a target for existential
   /// specialization of args.
   bool canSpecializeExistentialArgsInFunction(
-      ApplySite &Apply,
+      FullApplySite &Apply,
       llvm::SmallDenseMap<int, ExistentialTransformArgumentDescriptor>
           &ExistentialArgDescriptor);
 
   /// Can Callee be specialized?
-  bool canSpecializeCalleeFunction(ApplySite &Apply);
+  bool canSpecializeCalleeFunction(FullApplySite &Apply);
 
   /// Specialize existential args in function F.
   void specializeExistentialArgsInAppliesWithinFunction(SILFunction &F);
@@ -70,82 +70,6 @@
 };
 } // namespace
 
-/// Find concrete type from init_existential_refs/addrs.
-static bool findConcreteTypeFromInitExistential(SILValue Arg,
-                                                CanType &ConcreteType) {
-  if (auto *IER = dyn_cast<InitExistentialRefInst>(Arg)) {
-    ConcreteType = IER->getFormalConcreteType();
-    return true;
-  } else if (auto *IE = dyn_cast<InitExistentialAddrInst>(Arg)) {
-    ConcreteType = IE->getFormalConcreteType();
-    return true;
-  }
-  return false;
-}
-
-/// Find the concrete type of the existential argument. Wrapper
-/// for findInitExistential in Local.h/cpp. In future, this code
-/// can move to Local.h/cpp.
-static bool findConcreteType(ApplySite AI, int ArgIdx, CanType &ConcreteType) {
-  bool isCopied = false;
-  auto Arg = AI.getArgument(ArgIdx);
-
-  /// Ignore any unconditional cast instructions. Is it Safe? Do we need to
-  /// also add UnconditionalCheckedCastAddrInst? TODO.
-  if (auto *Instance = dyn_cast<UnconditionalCheckedCastInst>(Arg)) {
-    Arg = Instance->getOperand();
-  }
-
-  /// Return init_existential if the Arg is global_addr.
-  if (auto *GAI = dyn_cast<GlobalAddrInst>(Arg)) {
-    SILValue InitExistential =
-        findInitExistentialFromGlobalAddrAndApply(GAI, AI, ArgIdx);
-    /// If the Arg is already init_existential, return the concrete type.
-    if (InitExistential &&
-        findConcreteTypeFromInitExistential(InitExistential, ConcreteType)) {
-      return true;
-    }
-  }
-
-  /// Handle AllocStack instruction separately.
-  if (auto *Instance = dyn_cast<AllocStackInst>(Arg)) {
-    if (SILValue Src =
-            getAddressOfStackInit(Instance, AI.getInstruction(), isCopied)) {
-      Arg = Src;
-    }
-  }
-
-  /// If the Arg is already init_existential after getAddressofStackInit
-  /// call, return the concrete type.
-  if (findConcreteTypeFromInitExistential(Arg, ConcreteType)) {
-    return true;
-  }
-
-  /// Call findInitExistential and determine the init_existential.
-  ArchetypeType *OpenedArchetype = nullptr;
-  SILValue OpenedArchetypeDef;
-  auto FAS = FullApplySite::isa(AI.getInstruction());
-  if (!FAS)
-    return false;
-  SILInstruction *InitExistential =
-      findInitExistential(FAS.getArgumentOperands()[ArgIdx], OpenedArchetype,
-                          OpenedArchetypeDef, isCopied);
-  if (!InitExistential) {
-    LLVM_DEBUG(llvm::dbgs() << "ExistentialSpecializer Pass: Bail! Due to "
-                               "findInitExistential\n";);
-    return false;
-  }
-
-  /// Return the concrete type from init_existential returned from
-  /// findInitExistential.
-  if (auto *SingleVal = InitExistential->castToSingleValueInstruction()) {
-    if (findConcreteTypeFromInitExistential(SingleVal, ConcreteType)) {
-      return true;
-    }
-  }
-  return false;
-}
-
 /// Check if the argument Arg is used in a destroy_use instruction.
 static void
 findIfCalleeUsesArgInDestroyUse(SILValue Arg,
@@ -162,17 +86,21 @@
 /// Check if any apply argument meets the criteria for existential
 /// specialization.
 bool ExistentialSpecializer::canSpecializeExistentialArgsInFunction(
-    ApplySite &Apply,
+    FullApplySite &Apply,
     llvm::SmallDenseMap<int, ExistentialTransformArgumentDescriptor>
         &ExistentialArgDescriptor) {
   auto *F = Apply.getReferencedFunction();
-  auto Args = F->begin()->getFunctionArguments();
+  auto CalleeArgs = F->begin()->getFunctionArguments();
   bool returnFlag = false;
 
-  /// Analyze the argument for protocol conformance.
-  for (unsigned Idx = 0, Num = Args.size(); Idx < Num; ++Idx) {
-    auto Arg = Args[Idx];
-    auto ArgType = Arg->getType();
+  /// Analyze the argument for protocol conformance.  Iterator over the callee's
+  /// function arguments.  The same SIL argument index is used for both caller
+  /// and callee side arguments.
+  auto origCalleeConv = Apply.getOrigCalleeConv();
+  assert(Apply.getCalleeArgIndexOfFirstAppliedArg() == 0);
+  for (unsigned Idx = 0, Num = CalleeArgs.size(); Idx < Num; ++Idx) {
+    auto CalleeArg = CalleeArgs[Idx];
+    auto ArgType = CalleeArg->getType();
     auto SwiftArgType = ArgType.getASTType();
 
     /// Checking for AnyObject and Any is added to ensure that we do not blow up
@@ -184,18 +112,21 @@
       continue;
 
     auto ExistentialRepr =
-        Arg->getType().getPreferredExistentialRepresentation(F->getModule());
+        CalleeArg->getType().getPreferredExistentialRepresentation(
+            F->getModule());
     if (ExistentialRepr != ExistentialRepresentation::Opaque &&
           ExistentialRepr != ExistentialRepresentation::Class)
       continue;
 
     /// Find the concrete type.
-    CanType ConcreteType;
-    if (!findConcreteType(Apply, Idx, ConcreteType)) {
+    Operand &ArgOper = Apply.getArgumentRef(Idx);
+    CanType ConcreteType =
+        ConcreteExistentialInfo(ArgOper.get(), ArgOper.getUser()).ConcreteType;
+    if (!ConcreteType) {
       LLVM_DEBUG(
           llvm::dbgs()
-              << "ExistentialSpecializer Pass: Bail! Due to findConcreteType "
-                 "for callee:"
+              << "ExistentialSpecializer Pass: Bail! cannot find ConcreteType "
+                 "for call argument to:"
               << F->getName() << " in caller:"
               << Apply.getInstruction()->getParent()->getParent()->getName()
               << "\n";);
@@ -205,15 +136,15 @@
     /// Determine attributes of the existential addr arguments such as
     /// destroy_use, immutable_access. 
     ExistentialTransformArgumentDescriptor ETAD;
-    ETAD.AccessType =
-        Apply.getOrigCalleeType()->getParameters()[Idx].isIndirectMutating() ||
-                Apply.getOrigCalleeType()->getParameters()[Idx].isConsumed()
-            ? OpenedExistentialAccess::Mutable
-            : OpenedExistentialAccess::Immutable;
+    auto paramInfo = origCalleeConv.getParamInfoForSILArg(Idx);
+    ETAD.AccessType = (paramInfo.isIndirectMutating() || paramInfo.isConsumed())
+                          ? OpenedExistentialAccess::Mutable
+                          : OpenedExistentialAccess::Immutable;
     ETAD.DestroyAddrUse = false;
-    if ((Args[Idx]->getType().getPreferredExistentialRepresentation(
-            F->getModule())) != ExistentialRepresentation::Class)
-      findIfCalleeUsesArgInDestroyUse(Arg, ETAD);
+    if ((CalleeArgs[Idx]->getType().getPreferredExistentialRepresentation(
+            F->getModule()))
+        != ExistentialRepresentation::Class)
+      findIfCalleeUsesArgInDestroyUse(CalleeArg, ETAD);
 
     /// Save the attributes
     ExistentialArgDescriptor[Idx] = ETAD;
@@ -226,12 +157,7 @@
 }
 
 /// Determine if this callee function can be specialized or not.
-bool ExistentialSpecializer::canSpecializeCalleeFunction(ApplySite &Apply) {
-
-  /// Do not handle partial applies.
-  if (isa<PartialApplyInst>(Apply.getInstruction())) {
-    return false;
-  }
+bool ExistentialSpecializer::canSpecializeCalleeFunction(FullApplySite &Apply) {
 
   /// Determine the caller of the apply.
   auto *Callee = Apply.getReferencedFunction();
@@ -285,7 +211,7 @@
       auto *I = &*It;
 
       /// Is it an apply site?
-      ApplySite Apply = ApplySite::isa(I);
+      FullApplySite Apply = FullApplySite::isa(I);
       if (!Apply)
         continue;
 
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index c1e3fb7..678b263 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -708,7 +708,7 @@
   calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder,
                                       NeedsRelease);
   return Builder.createConvertEscapeToNoEscape(
-      CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), false, true);
+      CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), true);
 }
 
 /// Populate the body of the cloned closure, modifying instructions as
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index ebc0d6f..62479ac 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -137,6 +137,9 @@
   /// can be statically initialized.
   void optimizeInitializer(SILFunction *AddrF, GlobalInitCalls &Calls);
 
+  /// Perform peephole optimizations on the initializer list.
+  void peepholeInitializer(SILFunction *InitFunc);
+
   /// Optimize access to the global variable, which is known to have a constant
   /// value. Replace all loads from the global address by invocations of a
   /// getter that returns the value of this variable.
@@ -253,12 +256,14 @@
   if (auto *F = M.lookUpFunction(getterNameTmp))
     return F;
 
-  auto Linkage = (varDecl->getEffectiveAccess() >= AccessLevel::Public
-                  ? SILLinkage::PublicNonABI
-                  : SILLinkage::Private);
-  auto Serialized = (varDecl->getEffectiveAccess() >= AccessLevel::Public
-                     ? IsSerialized
-                     : IsNotSerialized);
+  auto Linkage = SILLinkage::Private;
+  auto Serialized = IsNotSerialized;
+
+  if (varDecl->getEffectiveAccess() >= AccessLevel::Public &&
+      !varDecl->isResilient()) {
+    Linkage = SILLinkage::PublicNonABI;
+    Serialized = IsSerialized;
+  }
 
   auto refType = M.Types.getLoweredType(varDecl->getInterfaceType());
 
@@ -690,7 +695,17 @@
       auto *PTAI = dyn_cast<PointerToAddressInst>(Use->getUser());
       assert(PTAI && "All uses should be pointer_to_address");
       for (auto PTAIUse : PTAI->getUses()) {
-        replaceLoadSequence(PTAIUse->getUser(), NewAI, B);
+        SILInstruction *Load = PTAIUse->getUser();
+        if (auto *CA = dyn_cast<CopyAddrInst>(Load)) {
+          // The result of the initializer is stored to another location.
+          SILBuilder B(CA);
+          B.createStore(CA->getLoc(), NewAI, CA->getDest(),
+                        StoreOwnershipQualifier::Unqualified);
+          CA->eraseFromParent();
+        } else {
+          // The result of the initializer is used as a value.
+          replaceLoadSequence(Load, NewAI, B);
+        }
       }
     }
 
@@ -721,6 +736,8 @@
       InitializerCount[InitF] > 1)
     return;
 
+  peepholeInitializer(InitF);
+
   // If the globalinit_func is trivial, continue; otherwise bail.
   SingleValueInstruction *InitVal;
   SILGlobalVariable *SILG = getVariableOfStaticInitializer(InitF, InitVal);
@@ -743,6 +760,58 @@
   HasChanged = true;
 }
 
+void SILGlobalOpt::peepholeInitializer(SILFunction *InitFunc) {
+  if (InitFunc->size() != 1)
+    return;
+  SILBasicBlock *BB = &InitFunc->front();
+
+  for (auto &I : *BB) {
+    if (auto *SI = dyn_cast<StoreInst>(&I)) {
+
+      // If struct S has a single field, replace
+      //   %a = struct_element_addr %s : $*S
+      //   store %x to %a
+      // with
+      //   %y = struct $S (%x)
+      //   store %y to %s
+      //
+      // This pattern occurs with resilient static properties, like
+      // struct ResilientStruct {
+      //   var singleField: Int
+      //   public static let x = ResilientStruct(singleField: 27)
+      // }
+      //
+      // TODO: handle structs with multiple fields.
+      SILValue Addr = SI->getDest();
+      auto *SEA = dyn_cast<StructElementAddrInst>(Addr);
+      if (!SEA)
+        continue;
+
+      if (SEA->getOperand()->getType().isAddressOnly(InitFunc))
+        continue;
+
+      StructDecl *Decl = SEA->getStructDecl();
+      auto beginProp = Decl->getStoredProperties().begin();
+      if (std::next(beginProp) != Decl->getStoredProperties().end())
+        continue;
+
+      assert(*beginProp == SEA->getField());
+
+      SILBuilder B(SI);
+      SILValue StructAddr = SEA->getOperand();
+      StructInst *Struct = B.createStruct(SEA->getLoc(),
+                                          StructAddr->getType().getObjectType(),
+                                          { SI->getSrc() });
+      SI->setOperand(StoreInst::Src, Struct);
+      SI->setOperand(StoreInst::Dest, StructAddr);
+      if (SEA->use_empty()) {
+        SEA->eraseFromParent();
+      }
+      HasChanged = true;
+    }
+  }
+}
+
 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/Mandatory/CMakeLists.txt b/lib/SILOptimizer/Mandatory/CMakeLists.txt
index 88dd651..e5a153c 100644
--- a/lib/SILOptimizer/Mandatory/CMakeLists.txt
+++ b/lib/SILOptimizer/Mandatory/CMakeLists.txt
@@ -4,7 +4,7 @@
   AddressLowering.cpp
   ConstantPropagation.cpp
   DefiniteInitialization.cpp
-  DIMemoryUseCollectorOwnership.cpp
+  DIMemoryUseCollector.cpp
   DataflowDiagnostics.cpp
   DiagnoseInfiniteRecursion.cpp
   DiagnoseStaticExclusivity.cpp
diff --git a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
index 8076ad3..f00f8ec 100644
--- a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
+++ b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
@@ -98,7 +98,7 @@
 
   SILBuilderWithScope B(Cvt);
   auto NewCvt = B.createConvertEscapeToNoEscape(
-      Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
+      Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
   Cvt->replaceAllUsesWith(NewCvt);
   Cvt->eraseFromParent();
   Cvt = NewCvt;
@@ -189,11 +189,6 @@
 static bool tryExtendLifetimeToLastUse(
     ConvertEscapeToNoEscapeInst *Cvt,
     llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized) {
-  // Don't optimize converts that might have been escaped by the function call
-  // (materializeForSet 'escapes' its arguments into the writeback buffer).
-  if (Cvt->isEscapedByUser())
-    return false;
-
   // If there is a single user that is an apply this is simple: extend the
   // lifetime of the operand until after the apply.
   auto SingleUser = lookThroughRebastractionUsers(Cvt, Memoized);
@@ -215,7 +210,7 @@
     {
       SILBuilderWithScope B(Cvt);
       auto NewCvt = B.createConvertEscapeToNoEscape(
-          Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
+          Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
       Cvt->replaceAllUsesWith(NewCvt);
       Cvt->eraseFromParent();
       Cvt = NewCvt;
@@ -264,11 +259,6 @@
 ///   diamonds. And a destroy of %closure at the last destroy of
 ///   %convertOptionalBlock.
 static bool trySwitchEnumPeephole(ConvertEscapeToNoEscapeInst *Cvt) {
-  // Don't optimize converts that might have been escaped by the function call
-  // (materializeForSet 'escapes' its arguments into the writeback buffer).
-  if (Cvt->isEscapedByUser())
-    return false;
-
   auto *blockArg = dyn_cast<SILArgument>(Cvt->getOperand());
   if (!blockArg)
     return false;
@@ -314,7 +304,7 @@
   {
     SILBuilderWithScope B(Cvt);
     auto NewCvt = B.createConvertEscapeToNoEscape(
-        Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
+        Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
     Cvt->replaceAllUsesWith(NewCvt);
     Cvt->eraseFromParent();
   }
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
similarity index 99%
rename from lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
rename to lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
index 76f805a..eb609a0 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
@@ -1,8 +1,8 @@
-//===--- DIMemoryUseCollectorOwnership.cpp - Memory use analysis for DI ---===//
+//===--- DIMemoryUseCollector.cpp -----------------------------------------===//
 //
 // 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
@@ -11,7 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "definite-init"
-#include "DIMemoryUseCollectorOwnership.h"
+#include "DIMemoryUseCollector.h"
 #include "swift/AST/Expr.h"
 #include "swift/SIL/ApplySite.h"
 #include "swift/SIL/InstructionUtils.h"
@@ -21,10 +21,6 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
 
-#ifdef SWIFT_SILOPTIMIZER_MANDATORY_DIMEMORYUSECOLLECTOR_H
-#error "Included non ownership header?!"
-#endif
-
 using namespace swift;
 using namespace ownership;
 
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
similarity index 96%
rename from lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h
rename to lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
index f3feab4..c780a42 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
@@ -1,8 +1,8 @@
-//===--- DIMemoryUseCollectorOwnership.h - Mem. use info for DI -*- C++ -*-===//
+//===--- DIMemoryUseCollector.h -------------------------------------------===//
 //
 // 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
@@ -17,8 +17,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_DIMEMORYUSECOLLECTOROWNERSHIP_H
-#define SWIFT_SILOPTIMIZER_PASSMANAGER_DIMEMORYUSECOLLECTOROWNERSHIP_H
+#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_DIMEMORYUSECOLLECTOR_H
+#define SWIFT_SILOPTIMIZER_PASSMANAGER_DIMEMORYUSECOLLECTOR_H
 
 #include "swift/Basic/LLVM.h"
 #include "swift/SIL/SILInstruction.h"
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index e72172d..b16e2e1 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -11,7 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "definite-init"
-#include "DIMemoryUseCollectorOwnership.h"
+#include "DIMemoryUseCollector.h"
 #include "MandatoryOptUtils.h"
 #include "swift/AST/DiagnosticEngine.h"
 #include "swift/AST/DiagnosticsSIL.h"
@@ -33,10 +33,6 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 
-#ifdef SWIFT_SILOPTIMIZER_PASSMANAGER_DIMEMORYUSECOLLECTOR_H
-#error "Included non ownership header?!"
-#endif
-
 using namespace swift;
 using namespace ownership;
 
@@ -929,12 +925,13 @@
       // a diagnostic.
       if (!shouldEmitError(Use.Inst))
         continue;
-      
+
       std::string PropertyName;
       auto *VD = TheMemory.getPathStringToElement(i, PropertyName);
       diagnose(Module, Use.Inst->getLoc(),
-               diag::immutable_property_already_initialized, PropertyName);
-      
+               diag::immutable_property_already_initialized,
+               StringRef(PropertyName));
+
       if (auto *Var = dyn_cast<VarDecl>(VD)) {
         if (Var->getParentInitializer())
           diagnose(Module, SILLocation(VD),
@@ -1089,7 +1086,7 @@
 
     std::string PropertyName;
     auto VD = TheMemory.getPathStringToElement(i, PropertyName);
-    
+
     // Try to produce a specific error message about the inout use.  If this is
     // a call to a method or a mutating property access, indicate that.
     // Otherwise, we produce a generic error.
@@ -1154,15 +1151,15 @@
                  : diag::using_mutating_accessor_on_immutable_value,
                accessor->getStorage()->getBaseName(),
                isa<SubscriptDecl>(accessor->getStorage()),
-               PropertyName);
+               StringRef(PropertyName));
     } else if (FD && FD->isOperator()) {
       diagnose(Module, Use.Inst->getLoc(),
                diag::mutating_method_called_on_immutable_value,
-               FD->getName(), /*operator*/ 1, PropertyName);
+               FD->getName(), /*operator*/ 1, StringRef(PropertyName));
     } else if (FD && isSelfParameter) {
       diagnose(Module, Use.Inst->getLoc(),
                diag::mutating_method_called_on_immutable_value,
-               FD->getName(), /*method*/ 0, PropertyName);
+               FD->getName(), /*method*/ 0, StringRef(PropertyName));
     } else if (isAssignment) {
       diagnose(Module, Use.Inst->getLoc(),
                diag::assignment_to_immutable_value, StringRef(PropertyName));
@@ -2821,7 +2818,7 @@
 //                           Top Level Driver
 //===----------------------------------------------------------------------===//
 
-static bool processMemoryObject(MarkUninitializedInst *I) {
+static void processMemoryObject(MarkUninitializedInst *I) {
   LLVM_DEBUG(llvm::dbgs() << "*** Definite Init looking at: " << *I << "\n");
   DIMemoryObjectInfo MemInfo(I);
 
@@ -2833,7 +2830,6 @@
                            /*TreatAddressToPointerAsInout*/ true);
 
   LifetimeChecker(MemInfo, UseInfo).doIt();
-  return true;
 }
 
 /// Check that all memory objects that require initialization before use are
@@ -2849,11 +2845,14 @@
       SILInstruction *Inst = &*I;
 
       auto *MUI = dyn_cast<MarkUninitializedInst>(Inst);
-      if (!MUI || !processMemoryObject(MUI)) {
+      if (!MUI) {
         ++I;
         continue;
       }
 
+      // Then process the memory object.
+      processMemoryObject(MUI);
+
       // Move off of the MUI only after we have processed memory objects. The
       // lifetime checker may rewrite instructions, so it is important to not
       // move onto the next element until after it runs.
diff --git a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
index 189508f..8677c8f 100644
--- a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
+++ b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
@@ -20,157 +20,30 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
 
-#ifdef SWIFT_SILOPTIMIZER_PASSMANAGER_PMOMEMORYUSECOLLECTOROWNERSHIP_H
-#error "Included ownership header?!"
-#endif
-
 using namespace swift;
 
 //===----------------------------------------------------------------------===//
-//                  PMOMemoryObjectInfo Implementation
+//                     PMOMemoryObjectInfo Implementation
 //===----------------------------------------------------------------------===//
 
-static unsigned getElementCountRec(SILModule &Module, SILType T) {
-  // If this is a tuple, it is always recursively flattened.
-  if (CanTupleType TT = T.getAs<TupleType>()) {
-    unsigned NumElements = 0;
-    for (unsigned i = 0, e = TT->getNumElements(); i < e; i++)
-      NumElements += getElementCountRec(Module, T.getTupleElementType(i));
-    return NumElements;
-  }
+PMOMemoryObjectInfo::PMOMemoryObjectInfo(AllocationInst *allocation)
+    : MemoryInst(allocation) {
+  auto &module = MemoryInst->getModule();
 
-  // Otherwise, it is a single element.
-  return 1;
-}
-
-PMOMemoryObjectInfo::PMOMemoryObjectInfo(SingleValueInstruction *MI) {
-  auto &Module = MI->getModule();
-
-  MemoryInst = MI;
   // Compute the type of the memory object.
-  if (auto *ABI = dyn_cast<AllocBoxInst>(MemoryInst)) {
-    assert(ABI->getBoxType()->getLayout()->getFields().size() == 1 &&
+  if (auto *abi = dyn_cast<AllocBoxInst>(MemoryInst)) {
+    assert(abi->getBoxType()->getLayout()->getFields().size() == 1 &&
            "analyzing multi-field boxes not implemented");
-    MemorySILType = ABI->getBoxType()->getFieldType(Module, 0);
-  } else if (auto *ASI = dyn_cast<AllocStackInst>(MemoryInst)) {
-    MemorySILType = ASI->getElementType();
+    MemorySILType = abi->getBoxType()->getFieldType(module, 0);
   } else {
-    llvm_unreachable(
-        "Predictable Mem Opts should only be analyzing alloc_box/alloc_stack");
+    MemorySILType = cast<AllocStackInst>(MemoryInst)->getElementType();
   }
-
-  // Break down the initializer.
-  NumElements = getElementCountRec(Module, MemorySILType);
 }
 
 SILInstruction *PMOMemoryObjectInfo::getFunctionEntryPoint() const {
   return &*getFunction().begin()->begin();
 }
 
-/// Given a symbolic element number, return the type of the element.
-static SILType getElementTypeRec(SILModule &Module, SILType T, unsigned EltNo) {
-  // If this is a tuple type, walk into it.
-  if (CanTupleType TT = T.getAs<TupleType>()) {
-    for (unsigned i = 0, e = TT->getNumElements(); i < e; i++) {
-      auto FieldType = T.getTupleElementType(i);
-      unsigned NumFieldElements = getElementCountRec(Module, FieldType);
-      if (EltNo < NumFieldElements)
-        return getElementTypeRec(Module, FieldType, EltNo);
-      EltNo -= NumFieldElements;
-    }
-    // This can only happen if we look at a symbolic element number of an empty
-    // tuple.
-    llvm::report_fatal_error("invalid element number");
-  }
-
-  // Otherwise, it is a leaf element.
-  assert(EltNo == 0);
-  return T;
-}
-
-/// getElementTypeRec - Return the swift type of the specified element.
-SILType PMOMemoryObjectInfo::getElementType(unsigned EltNo) const {
-  auto &Module = MemoryInst->getModule();
-  return getElementTypeRec(Module, MemorySILType, EltNo);
-}
-
-/// Push the symbolic path name to the specified element number onto the
-/// specified std::string.
-static void getPathStringToElementRec(SILModule &Module, SILType T,
-                                      unsigned EltNo, std::string &Result) {
-  if (CanTupleType TT = T.getAs<TupleType>()) {
-    unsigned FieldNo = 0;
-    for (unsigned i = 0, e = TT->getNumElements(); i < e; i++) {
-      auto Field = TT->getElement(i);
-      SILType FieldTy = T.getTupleElementType(i);
-      unsigned NumFieldElements = getElementCountRec(Module, FieldTy);
-
-      if (EltNo < NumFieldElements) {
-        Result += '.';
-        if (Field.hasName())
-          Result += Field.getName().str();
-        else
-          Result += llvm::utostr(FieldNo);
-        return getPathStringToElementRec(Module, FieldTy, EltNo, Result);
-      }
-
-      EltNo -= NumFieldElements;
-
-      ++FieldNo;
-    }
-    llvm_unreachable("Element number is out of range for this type!");
-  }
-
-  // Otherwise, there are no subelements.
-  assert(EltNo == 0 && "Element count problem");
-}
-
-ValueDecl *
-PMOMemoryObjectInfo::getPathStringToElement(unsigned Element,
-                                            std::string &Result) const {
-  auto &Module = MemoryInst->getModule();
-
-  if (auto *VD = dyn_cast_or_null<ValueDecl>(getLoc().getAsASTNode<Decl>()))
-    Result = VD->getBaseName().userFacingName();
-  else
-    Result = "<unknown>";
-
-  // Get the path through a tuple, if relevant.
-  getPathStringToElementRec(Module, MemorySILType, Element, Result);
-
-  // Otherwise, we can't.
-  return nullptr;
-}
-
-/// If the specified value is a 'let' property in an initializer, return true.
-bool PMOMemoryObjectInfo::isElementLetProperty(unsigned Element) const {
-  // If we aren't representing 'self' in a non-delegating initializer, then we
-  // can't have 'let' properties.
-  return IsLet;
-}
-
-//===----------------------------------------------------------------------===//
-//                        PMOMemoryUse Implementation
-//===----------------------------------------------------------------------===//
-
-/// onlyTouchesTrivialElements - Return true if all of the accessed elements
-/// have trivial type.
-bool PMOMemoryUse::onlyTouchesTrivialElements(
-    const PMOMemoryObjectInfo &MI) const {
-  auto &Module = Inst->getModule();
-
-  for (unsigned i = FirstElement, e = i + NumElements; i != e; ++i) {
-    // Skip 'super.init' bit
-    if (i == MI.getNumMemoryElements())
-      return false;
-
-    auto EltTy = MI.getElementType(i);
-    if (!EltTy.isTrivial(Module))
-      return false;
-  }
-  return true;
-}
-
 //===----------------------------------------------------------------------===//
 //                          Scalarization Logic
 //===----------------------------------------------------------------------===//
@@ -220,6 +93,7 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
+
 class ElementUseCollector {
   SILModule &Module;
   const PMOMemoryObjectInfo &TheMemory;
@@ -243,125 +117,74 @@
   LLVM_NODISCARD bool collectFrom();
 
 private:
-  LLVM_NODISCARD bool collectUses(SILValue Pointer, unsigned BaseEltNo);
+  LLVM_NODISCARD bool collectUses(SILValue Pointer);
   LLVM_NODISCARD bool collectContainerUses(AllocBoxInst *ABI);
-  void addElementUses(unsigned BaseEltNo, SILType UseTy, SILInstruction *User,
-                      PMOUseKind Kind);
-  LLVM_NODISCARD bool collectTupleElementUses(TupleElementAddrInst *TEAI,
-                                              unsigned BaseEltNo);
-  LLVM_NODISCARD bool collectStructElementUses(StructElementAddrInst *SEAI,
-                                               unsigned BaseEltNo);
 };
 } // end anonymous namespace
 
 bool ElementUseCollector::collectFrom() {
-  bool shouldOptimize = false;
-
-  if (auto *ABI = TheMemory.getContainer()) {
-    shouldOptimize = collectContainerUses(ABI);
-  } else {
-    shouldOptimize = collectUses(TheMemory.getAddress(), 0);
+  if (auto *abi = TheMemory.getContainer()) {
+    return collectContainerUses(abi);
   }
 
-  if (!shouldOptimize)
-    return false;
+  return collectUses(TheMemory.getAddress());
+}
 
-  // Collect information about the retain count result as well.
-  for (auto UI : TheMemory.MemoryInst->getUses()) {
-    auto *User = UI->getUser();
+bool ElementUseCollector::collectContainerUses(AllocBoxInst *abi) {
+  for (auto *ui : abi->getUses()) {
+    auto *user = ui->getUser();
 
-    // If this is a release or dealloc_stack, then remember it as such.
-    if (isa<StrongReleaseInst>(User) || isa<DeallocStackInst>(User) ||
-        isa<DeallocBoxInst>(User)) {
-      Releases.push_back(User);
+    // dealloc_box deallocated a box containing uninitialized memory. This can
+    // not effect any value stored into the box.
+    if (isa<DeallocBoxInst>(user))
+      continue;
+
+    // Retaining the box doesn't effect the value inside the box.
+    if (isa<StrongRetainInst>(user) || isa<RetainValueInst>(user))
+      continue;
+
+    // Since we are trying to promote loads/stores, any releases of the box are
+    // not considered uses of the underlying value due to:
+    //
+    // 1. If this is not the last release of the box, then the underlying value
+    // is not effected implying we do not add this value.
+    //
+    // 2. If this is the last release of the box, then the box's destruction
+    // will result in a release of the underlying value. If there are any
+    // loads/stores after this point, the behavior would be undefined so we can
+    // ignore this possibility.
+    //
+    // That being said, if we want to eliminate the box completely we need to
+    // know where the releases are so that we can release the value that would
+    // have been at +1 in the box at that time. So we add these to the Releases
+    // array.
+    //
+    // FIXME: Since we do not support promoting strong_release or release_value
+    // today this will cause the underlying allocation to never be
+    // eliminated. That should be implemented and fixed.
+    if (isa<StrongReleaseInst>(user) || isa<ReleaseValueInst>(user)) {
+      Releases.push_back(user);
+      continue;
     }
-  }
 
-  return true;
-}
-
-/// addElementUses - An operation (e.g. load, store, inout use, etc) on a value
-/// acts on all of the aggregate elements in that value.  For example, a load
-/// of $*(Int,Int) is a use of both Int elements of the tuple.  This is a helper
-/// to keep the Uses data structure up to date for aggregate uses.
-void ElementUseCollector::addElementUses(unsigned BaseEltNo, SILType UseTy,
-                                         SILInstruction *User,
-                                         PMOUseKind Kind) {
-  // 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)
-    NumElements = getElementCountRec(Module, UseTy);
-
-  Uses.push_back(PMOMemoryUse(User, Kind, BaseEltNo, NumElements));
-}
-
-/// Given a tuple_element_addr or struct_element_addr, compute the new
-/// BaseEltNo implicit in the selected member, and recursively add uses of
-/// the instruction.
-bool ElementUseCollector::collectTupleElementUses(TupleElementAddrInst *TEAI,
-                                                  unsigned BaseEltNo) {
-
-  // 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)
-    return collectUses(TEAI, BaseEltNo);
-
-  // tuple_element_addr P, 42 indexes into the current tuple element.
-  // Recursively process its uses with the adjusted element number.
-  unsigned FieldNo = TEAI->getFieldNo();
-  auto T = TEAI->getOperand()->getType();
-  if (T.is<TupleType>()) {
-    for (unsigned i = 0; i != FieldNo; ++i) {
-      SILType EltTy = T.getTupleElementType(i);
-      BaseEltNo += getElementCountRec(Module, EltTy);
-    }
-  }
-
-  return collectUses(TEAI, BaseEltNo);
-}
-
-bool ElementUseCollector::collectStructElementUses(StructElementAddrInst *SEAI,
-                                                   unsigned BaseEltNo) {
-  // Generally, we set the "InStructSubElement" flag and recursively process
-  // the uses so that we know that we're looking at something within the
-  // current element.
-  llvm::SaveAndRestore<bool> X(InStructSubElement, true);
-  return collectUses(SEAI, BaseEltNo);
-}
-
-bool ElementUseCollector::collectContainerUses(AllocBoxInst *ABI) {
-  for (Operand *UI : ABI->getUses()) {
-    auto *User = UI->getUser();
-
-    // Deallocations and retain/release don't affect the value directly.
-    if (isa<DeallocBoxInst>(User))
-      continue;
-    if (isa<StrongRetainInst>(User))
-      continue;
-    if (isa<StrongReleaseInst>(User))
-      continue;
-
-    if (auto project = dyn_cast<ProjectBoxInst>(User)) {
-      if (!collectUses(project, project->getFieldIndex()))
+    if (auto *p = dyn_cast<ProjectBoxInst>(user)) {
+      if (!collectUses(p))
         return false;
       continue;
     }
 
-    // Other uses of the container are considered escapes of the values.
-    for (unsigned field :
-         indices(ABI->getBoxType()->getLayout()->getFields())) {
-      addElementUses(field,
-                     ABI->getBoxType()->getFieldType(ABI->getModule(), field),
-                     User, PMOUseKind::Escape);
-    }
+    // Other uses of the container are considered escapes of the underlying
+    // value.
+    //
+    // This will cause the dataflow to stop propagating any information at the
+    // use block.
+    Uses.emplace_back(user, PMOUseKind::Escape);
   }
 
   return true;
 }
 
-bool ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
+bool ElementUseCollector::collectUses(SILValue Pointer) {
   assert(Pointer->getType().isAddress() &&
          "Walked through the pointer to the value?");
   SILType PointeeType = Pointer->getType().getObjectType();
@@ -376,22 +199,26 @@
     auto *User = UI->getUser();
 
     // struct_element_addr P, #field indexes into the current element.
-    if (auto *SEAI = dyn_cast<StructElementAddrInst>(User)) {
-      if (!collectStructElementUses(SEAI, BaseEltNo))
+    if (auto *seai = dyn_cast<StructElementAddrInst>(User)) {
+      // Generally, we set the "InStructSubElement" flag and recursively process
+      // the uses so that we know that we're looking at something within the
+      // current element.
+      llvm::SaveAndRestore<bool> X(InStructSubElement, true);
+      if (!collectUses(seai))
         return false;
       continue;
     }
 
     // Instructions that compute a subelement are handled by a helper.
-    if (auto *TEAI = dyn_cast<TupleElementAddrInst>(User)) {
-      if (!collectTupleElementUses(TEAI, BaseEltNo))
+    if (auto *teai = dyn_cast<TupleElementAddrInst>(User)) {
+      if (!collectUses(teai))
         return false;
       continue;
     }
 
     // Look through begin_access.
-    if (auto I = dyn_cast<BeginAccessInst>(User)) {
-      if (!collectUses(I, BaseEltNo))
+    if (auto *bai = dyn_cast<BeginAccessInst>(User)) {
+      if (!collectUses(bai))
         return false;
       continue;
     }
@@ -406,15 +233,15 @@
       if (PointeeType.is<TupleType>())
         UsesToScalarize.push_back(User);
       else
-        addElementUses(BaseEltNo, PointeeType, User, PMOUseKind::Load);
+        Uses.emplace_back(User, PMOUseKind::Load);
       continue;
     }
 
-#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
-    if (isa<Load##Name##Inst>(User)) { \
-      Uses.push_back(PMOMemoryUse(User, PMOUseKind::Load, BaseEltNo, 1)); \
-      continue; \
-    }
+#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...)             \
+  if (isa<Load##Name##Inst>(User)) {                                           \
+    Uses.emplace_back(User, PMOUseKind::Load);                                 \
+    continue;                                                                  \
+  }
 #include "swift/AST/ReferenceStorage.def"
 
     // Stores *to* the allocation are writes.
@@ -434,24 +261,24 @@
       else
         Kind = PMOUseKind::Initialization;
 
-      addElementUses(BaseEltNo, PointeeType, User, Kind);
+      Uses.emplace_back(User, Kind);
       continue;
     }
 
-#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
-    if (auto *SI = dyn_cast<Store##Name##Inst>(User)) { \
-      if (UI->getOperandNumber() == 1) { \
-        PMOUseKind Kind; \
-        if (InStructSubElement) \
-          Kind = PMOUseKind::PartialStore; \
-        else if (SI->isInitializationOfDest()) \
-          Kind = PMOUseKind::Initialization; \
-        else \
-          Kind = PMOUseKind::Assign; \
-        Uses.push_back(PMOMemoryUse(User, Kind, BaseEltNo, 1)); \
-        continue; \
-      } \
-    }
+#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...)             \
+  if (auto *SI = dyn_cast<Store##Name##Inst>(User)) {                          \
+    if (UI->getOperandNumber() == 1) {                                         \
+      PMOUseKind Kind;                                                         \
+      if (InStructSubElement)                                                  \
+        Kind = PMOUseKind::PartialStore;                                       \
+      else if (SI->isInitializationOfDest())                                   \
+        Kind = PMOUseKind::Initialization;                                     \
+      else                                                                     \
+        Kind = PMOUseKind::Assign;                                             \
+      Uses.emplace_back(User, Kind);                                           \
+      continue;                                                                \
+    }                                                                          \
+  }
 #include "swift/AST/ReferenceStorage.def"
 
     if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
@@ -476,7 +303,7 @@
       else
         Kind = PMOUseKind::Assign;
 
-      addElementUses(BaseEltNo, PointeeType, User, Kind);
+      Uses.emplace_back(User, Kind);
       continue;
     }
 
@@ -501,8 +328,7 @@
         if (InStructSubElement) {
           return false;
         }
-        addElementUses(BaseEltNo, PointeeType, User,
-                       PMOUseKind::Initialization);
+        Uses.emplace_back(User, PMOUseKind::Initialization);
         continue;
 
         // Otherwise, adjust the argument index.
@@ -523,7 +349,7 @@
       case ParameterConvention::Indirect_In:
       case ParameterConvention::Indirect_In_Constant:
       case ParameterConvention::Indirect_In_Guaranteed:
-        addElementUses(BaseEltNo, PointeeType, User, PMOUseKind::IndirectIn);
+        Uses.emplace_back(User, PMOUseKind::IndirectIn);
         continue;
 
       // If this is an @inout parameter, it is like both a load and store.
@@ -533,7 +359,7 @@
         // mutating method, we model that as an escape of self.  If an
         // individual sub-member is passed as inout, then we model that as an
         // inout use.
-        addElementUses(BaseEltNo, PointeeType, User, PMOUseKind::InOutUse);
+        Uses.emplace_back(User, PMOUseKind::InOutUse);
         continue;
       }
       }
@@ -546,15 +372,14 @@
       if (InStructSubElement) {
         return false;
       }
-      Uses.push_back(
-          PMOMemoryUse(User, PMOUseKind::Initialization, BaseEltNo, 1));
+      Uses.emplace_back(User, PMOUseKind::Initialization);
       continue;
     }
 
     // open_existential_addr is a use of the protocol value,
     // so it is modeled as a load.
     if (isa<OpenExistentialAddrInst>(User)) {
-      Uses.push_back(PMOMemoryUse(User, PMOUseKind::Load, BaseEltNo, 1));
+      Uses.emplace_back(User, PMOUseKind::Load);
       // TODO: Is it safe to ignore all uses of the open_existential_addr?
       continue;
     }
@@ -575,7 +400,7 @@
       continue;
 
     // Otherwise, the use is something complicated, it escapes.
-    addElementUses(BaseEltNo, PointeeType, User, PMOUseKind::Escape);
+    Uses.emplace_back(User, PMOUseKind::Escape);
   }
 
   // Now that we've walked all of the immediate uses, scalarize any operations
@@ -640,9 +465,8 @@
     // Now that we've scalarized some stuff, recurse down into the newly created
     // element address computations to recursively process it.  This can cause
     // further scalarization.
-    if (llvm::any_of(ElementAddrs, [&](SILValue V) {
-          return !collectTupleElementUses(cast<TupleElementAddrInst>(V),
-                                          BaseEltNo);
+    if (llvm::any_of(ElementAddrs, [&](SILValue v) {
+          return !collectUses(cast<TupleElementAddrInst>(v));
         })) {
       return false;
     }
diff --git a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h
index 456b188..348590d 100644
--- a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h
+++ b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h
@@ -70,24 +70,15 @@
 /// not super.init() has been called or not.
 class PMOMemoryObjectInfo {
 public:
-  /// This is the instruction that represents the memory.  It is either an
-  /// allocation (alloc_box, alloc_stack) or a mark_uninitialized.
-  SingleValueInstruction *MemoryInst;
+  /// This is the instruction that represents the memory. It is either an
+  /// alloc_box or alloc_stack.
+  AllocationInst *MemoryInst;
 
   /// This is the base type of the memory allocation.
   SILType MemorySILType;
 
-  /// True if the memory object being analyzed represents a 'let', which is
-  /// initialize-only (reassignments are not allowed).
-  bool IsLet = false;
-
-  /// This is the count of elements being analyzed.  For memory objects that are
-  /// tuples, this is the flattened element count.  For 'self' members in init
-  /// methods, this is the local field count (+1 for derive classes).
-  unsigned NumElements;
-
 public:
-  PMOMemoryObjectInfo(SingleValueInstruction *MemoryInst);
+  PMOMemoryObjectInfo(AllocationInst *MemoryInst);
 
   SILLocation getLoc() const { return MemoryInst->getLoc(); }
   SILFunction &getFunction() const { return *MemoryInst->getFunction(); }
@@ -107,24 +98,6 @@
   AllocBoxInst *getContainer() const {
     return dyn_cast<AllocBoxInst>(MemoryInst);
   }
-
-  /// getNumMemoryElements - Return the number of elements, without the extra
-  /// "super.init" tracker in initializers of derived classes.
-  unsigned getNumMemoryElements() const {
-    return NumElements - unsigned(false);
-  }
-
-  /// getElementType - Return the swift type of the specified element.
-  SILType getElementType(unsigned EltNo) const;
-
-  /// Push the symbolic path name to the specified element number onto the
-  /// specified std::string.  If the actual decl (or a subelement thereof) can
-  /// be determined, return it.  Otherwise, return null.
-  ValueDecl *getPathStringToElement(unsigned Element,
-                                    std::string &Result) const;
-
-  /// If the specified value is a 'let' property in an initializer, return true.
-  bool isElementLetProperty(unsigned Element) const;
 };
 
 enum PMOUseKind {
@@ -155,13 +128,6 @@
   /// This instruction is a general escape of the value, e.g. a call to a
   /// closure that captures it.
   Escape,
-
-  /// This instruction is a call to 'super.init' in a 'self' initializer of a
-  /// derived class.
-  SuperInit,
-
-  /// This instruction is a call to 'self.init' in a delegating initializer.
-  SelfInit
 };
 
 /// This struct represents a single classified access to the memory object
@@ -173,36 +139,13 @@
   /// This is what kind of access it is, load, store, escape, etc.
   PMOUseKind Kind;
 
-  /// For memory objects of (potentially recursive) tuple type, this keeps
-  /// track of which tuple elements are affected.
-  unsigned short FirstElement, NumElements;
-
-  PMOMemoryUse(SILInstruction *Inst, PMOUseKind Kind, unsigned FE, unsigned NE)
-      : Inst(Inst), Kind(Kind), FirstElement(FE), NumElements(NE) {
-    assert(FE == FirstElement && NumElements == NE &&
-           "more than 64K elements not supported yet");
-  }
+  PMOMemoryUse(SILInstruction *Inst, PMOUseKind Kind)
+      : Inst(Inst), Kind(Kind) {}
 
   PMOMemoryUse() : Inst(nullptr) {}
 
   bool isInvalid() const { return Inst == nullptr; }
   bool isValid() const { return Inst != nullptr; }
-
-  bool usesElement(unsigned i) const {
-    return i >= FirstElement &&
-           i < static_cast<unsigned>(FirstElement + NumElements);
-  }
-
-  /// onlyTouchesTrivialElements - Return true if all of the accessed elements
-  /// have trivial type.
-  bool onlyTouchesTrivialElements(const PMOMemoryObjectInfo &MemoryInfo) const;
-
-  /// getElementBitmask - Return a bitmask with the touched tuple elements
-  /// set.
-  APInt getElementBitmask(unsigned NumMemoryTupleElements) const {
-    return APInt::getBitsSet(NumMemoryTupleElements, FirstElement,
-                             FirstElement + NumElements);
-  }
 };
 
 /// collectPMOElementUsesFrom - Analyze all uses of the specified allocation
diff --git a/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
index 52da9f5..a5f41f6 100644
--- a/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
+++ b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
@@ -516,8 +516,7 @@
   if (!Val) {
     auto *Load =
         B.createLoad(Loc, Address, LoadOwnershipQualifier::Unqualified);
-    Uses.push_back(PMOMemoryUse(Load, PMOUseKind::Load, FirstElt,
-                                getNumSubElements(Load->getType(), M)));
+    Uses.emplace_back(Load, PMOUseKind::Load);
     return Load;
   }
 
@@ -1250,9 +1249,6 @@
     if (U.Inst == nullptr) continue;
 
     switch (U.Kind) {
-    case PMOUseKind::SelfInit:
-    case PMOUseKind::SuperInit:
-      llvm_unreachable("Can't happen on allocations");
     case PMOUseKind::Assign:
     case PMOUseKind::PartialStore:
     case PMOUseKind::InitOrAssign:
@@ -1276,35 +1272,50 @@
     }
   }
 
-  // If the memory object has non-trivial type, then removing the deallocation
-  // will drop any releases.  Check that there is nothing preventing removal.
+  // If our memory is trivially typed, we can just remove it without needing to
+  // consider if the stored value needs to be destroyed. So at this point,
+  // delete the memory!
+  if (MemoryType.isTrivial(Module)) {
+    LLVM_DEBUG(llvm::dbgs() << "*** Removing autogenerated trivial allocation: "
+                            << *TheMemory);
+
+    // If it is safe to remove, do it.  Recursively remove all instructions
+    // hanging off the allocation instruction, then return success.  Let the
+    // caller remove the allocation itself to avoid iterator invalidation.
+    eraseUsesOfInstruction(TheMemory);
+
+    return true;
+  }
+
+  // Otherwise removing the deallocation will drop any releases.  Check that
+  // there is nothing preventing removal.
   llvm::SmallVector<unsigned, 8> DestroyAddrIndices;
   llvm::SmallVector<AvailableValue, 32> AvailableValueList;
   llvm::SmallVector<unsigned, 8> AvailableValueStartOffsets;
 
-  if (!MemoryType.isTrivial(Module)) {
-    for (auto P : llvm::enumerate(Releases)) {
-      auto *R = P.value();
-      if (R == nullptr || isa<DeallocStackInst>(R) || isa<DeallocBoxInst>(R))
-        continue;
+  for (auto P : llvm::enumerate(Releases)) {
+    auto *R = P.value();
+    if (R == nullptr)
+      continue;
 
-      // We stash all of the destroy_addr that we see.
-      if (auto *DAI = dyn_cast<DestroyAddrInst>(R)) {
-        AvailableValueStartOffsets.push_back(AvailableValueList.size());
-        // Make sure we can actually promote this destroy addr. If we can not,
-        // then we must bail. In order to not gather available values twice, we
-        // gather the available values here that we will use to promote the
-        // values.
-        if (!canPromoteDestroyAddr(DAI, AvailableValueList))
-          return false;
-        DestroyAddrIndices.push_back(P.index());
-        continue;
-      }
-
-      LLVM_DEBUG(llvm::dbgs() << "*** Failed to remove autogenerated alloc: "
-                 "kept alive by release: " << *R);
-      return false;
+    // We stash all of the destroy_addr that we see.
+    if (auto *DAI = dyn_cast<DestroyAddrInst>(R)) {
+      AvailableValueStartOffsets.push_back(AvailableValueList.size());
+      // Make sure we can actually promote this destroy addr. If we can not,
+      // then we must bail. In order to not gather available values twice, we
+      // gather the available values here that we will use to promote the
+      // values.
+      if (!canPromoteDestroyAddr(DAI, AvailableValueList))
+        return false;
+      DestroyAddrIndices.push_back(P.index());
+      continue;
     }
+
+    LLVM_DEBUG(llvm::dbgs()
+               << "*** Failed to remove autogenerated non-trivial alloc: "
+                  "kept alive by release: "
+               << *R);
+    return false;
   }
 
   // If we reached this point, we can promote all of our destroy_addr.
@@ -1327,7 +1338,7 @@
     Releases[DestroyAddrIndex] = nullptr;
   }
 
-  LLVM_DEBUG(llvm::dbgs() << "*** Removing autogenerated alloc_stack: "
+  LLVM_DEBUG(llvm::dbgs() << "*** Removing autogenerated non-trivial alloc: "
                           << *TheMemory);
 
   // If it is safe to remove, do it.  Recursively remove all instructions
diff --git a/lib/SILOptimizer/SILCombiner/SILCombiner.h b/lib/SILOptimizer/SILCombiner/SILCombiner.h
index 34ba6e6..0d46a02 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombiner.h
+++ b/lib/SILOptimizer/SILCombiner/SILCombiner.h
@@ -296,26 +296,27 @@
   FullApplySite rewriteApplyCallee(FullApplySite apply, SILValue callee);
 
   // Build concrete existential information using findInitExistential.
-  Optional<ConcreteExistentialInfo>
-  buildConcreteExistentialInfo(Operand &ArgOperand);
+  Optional<ConcreteOpenedExistentialInfo>
+  buildConcreteOpenedExistentialInfo(Operand &ArgOperand);
 
   // Build concrete existential information using SoleConformingType.
-  Optional<ConcreteExistentialInfo>
-  buildConcreteExistentialInfoFromSoleConformingType(Operand &ArgOperand);
+  Optional<ConcreteOpenedExistentialInfo>
+  buildConcreteOpenedExistentialInfoFromSoleConformingType(Operand &ArgOperand);
 
   // Common utility function to build concrete existential information for all
   // arguments of an apply instruction.
-  void buildConcreteExistentialInfos(
+  void buildConcreteOpenedExistentialInfos(
       FullApplySite Apply,
-      llvm::SmallDenseMap<unsigned, ConcreteExistentialInfo> &CEIs,
+      llvm::SmallDenseMap<unsigned, ConcreteOpenedExistentialInfo> &COEIs,
       SILBuilderContext &BuilderCtx,
       SILOpenedArchetypesTracker &OpenedArchetypesTracker);
 
-  bool canReplaceArg(FullApplySite Apply, const ConcreteExistentialInfo &CEI,
-                     unsigned ArgIdx);
+  bool canReplaceArg(FullApplySite Apply, const OpenedArchetypeInfo &OAI,
+                     const ConcreteExistentialInfo &CEI, unsigned ArgIdx);
+
   SILInstruction *createApplyWithConcreteType(
       FullApplySite Apply,
-      const llvm::SmallDenseMap<unsigned, ConcreteExistentialInfo> &CEIs,
+      const llvm::SmallDenseMap<unsigned, ConcreteOpenedExistentialInfo> &COEIs,
       SILBuilderContext &BuilderCtx);
 
   // Common utility function to replace the WitnessMethodInst using a
@@ -328,6 +329,7 @@
   SILInstruction *
   propagateConcreteTypeOfInitExistential(FullApplySite Apply,
                                          WitnessMethodInst *WMI);
+
   SILInstruction *propagateConcreteTypeOfInitExistential(FullApplySite Apply);
 
   /// Propagate concrete types from ProtocolConformanceAnalysis.
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 55e15ad..83e7f47 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -615,13 +615,11 @@
     eraseInstFromFunction(*WMI);
 }
 
-//  This function determines concrete type of existential self argument using
-//  ProtocolConformanceAnalysis. The concrete type of self can be a class,
-//  struct, or an enum. It replaces the witness_method instruction
-//  with one that has a concrete type, allowing other optimizations to
-//  devirtualize it later.
-Optional<ConcreteExistentialInfo>
-SILCombiner::buildConcreteExistentialInfoFromSoleConformingType(
+// This function determines concrete type of an opened existential argument
+// using ProtocolConformanceAnalysis. The concrete type of the argument can be a
+// class, struct, or an enum.
+Optional<ConcreteOpenedExistentialInfo>
+SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
     Operand &ArgOperand) {
   SILInstruction *AI = ArgOperand.getUser();
   SILModule &M = AI->getModule();
@@ -637,6 +635,9 @@
   if (FAS && (WMI = dyn_cast<WitnessMethodInst>(FAS.getCallee())) &&
       (FAS.getSelfArgumentOperand().get()  == ArgOperand.get())) {
     // If the witness method mutates self, we cannot replace self.
+    //
+    // FIXME: Remove this out-dated check for mutating self. canReplaceCopiedArg
+    // is supposed to handle this case.
     if (FAS.getOrigCalleeType()->getSelfParameter().isIndirectMutating())
       return None;
     PD = WMI->getLookupProtocol();
@@ -669,53 +670,67 @@
   auto ElementType = NTD->getDeclaredType();
   auto ConcreteType = ElementType->getCanonicalType();
 
-  /// Determine OpenedArchetypeDef and SubstituionMap.
-  ConcreteExistentialInfo SoleCEI(ArgOperand, ConcreteType, PD);
-  if (!SoleCEI.isValid())
+  // Determine OpenedArchetypeDef and SubstituionMap.
+  ConcreteOpenedExistentialInfo COAI(ArgOperand, ConcreteType, PD);
+  if (!COAI.CEI)
     return None;
 
-  /// Determine the CEI.ConcreteValue.
-  if (!SoleCEI.InitExistential) {
-    // Create SIL type for the concrete type.
-    SILType ConcreteSILType = M.Types.getLoweredType(ConcreteType);
+  const OpenedArchetypeInfo &OAI = COAI.OAI;
+  ConcreteExistentialInfo &SoleCEI = *COAI.CEI;
+  assert(SoleCEI.isValid());
 
-    // Prepare the code by adding UncheckedCast instructions that cast opened
-    // existentials to concrete types. Set the ConcreteValue of CEI.
-    if (auto *OER =
-            dyn_cast<OpenExistentialRefInst>(SoleCEI.OpenedArchetypeDef)) {
-      auto *URCI =
-          Builder.createUncheckedRefCast(OER->getLoc(), OER, ConcreteSILType);
-      SoleCEI.ConcreteValue = URCI;
-    } else if (auto *OEA = dyn_cast<OpenExistentialAddrInst>(
-                   SoleCEI.OpenedArchetypeDef)) {
-      auto *UACI = Builder.createUncheckedAddrCast(
-          OEA->getLoc(), OEA, ConcreteSILType.getAddressType());
-      SoleCEI.ConcreteValue = UACI;
-    } else {
-      return None;
-    }
+  if (SoleCEI.ConcreteValue)
+    return COAI;
+
+  // Create SIL type for the concrete type.
+  SILType concreteSILType = M.Types.getLoweredType(ConcreteType);
+
+  // Prepare the code by adding UncheckedCast instructions that cast opened
+  // existentials to concrete types. Set the ConcreteValue of CEI.
+  if (auto *OER = dyn_cast<OpenExistentialRefInst>(OAI.OpenedArchetypeValue)) {
+    SoleCEI.ConcreteValue =
+        Builder.createUncheckedRefCast(OER->getLoc(), OER, concreteSILType);
+    return COAI;
   }
-  return SoleCEI;
+  if (auto *OEA = dyn_cast<OpenExistentialAddrInst>(OAI.OpenedArchetypeValue)) {
+    // Bail if ConcreteSILType is not the same SILType as the type stored in the
+    // existential after maximal reabstraction.
+    auto abstractionPattern = Lowering::AbstractionPattern::getOpaque();
+    auto abstractTy = M.Types.getLoweredType(abstractionPattern, ConcreteType);
+    if (abstractTy != concreteSILType)
+       return None;
+
+    SoleCEI.ConcreteValue =
+      Builder.createUncheckedAddrCast(
+        OEA->getLoc(), OEA, concreteSILType.getAddressType());
+    return COAI;
+  }
+  // Bail if OpenArchetypeInfo recognizes any additional opened archetype
+  // producers. This shouldn't be hit currently because metatypes don't
+  // conform to protocols.
+  return None;
 }
+
 // This function builds a ConcreteExistentialInfo by first following the data
 // flow chain from the ArgOperand. Otherwise, we check if the operand is of
 // protocol type that conforms to a single concrete type.
-Optional<ConcreteExistentialInfo>
-SILCombiner::buildConcreteExistentialInfo(Operand &ArgOperand) {
-  // Build a ConcreteExistentialInfo usfollowing the data flow chain of the
-  // ArgOperand until the init_existential.
-  ConcreteExistentialInfo CEI(ArgOperand);
-  if (CEI.isValid())
-    return CEI;
+Optional<ConcreteOpenedExistentialInfo>
+SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
+  // Build a ConcreteOpenedExistentialInfo following the data flow chain of the
+  // ArgOperand through the open_existential backward to an init_existential.
+  ConcreteOpenedExistentialInfo COEI(ArgOperand);
+  if (COEI.CEI)
+    return COEI;
+
   // Use SoleConformingType information.
-  return buildConcreteExistentialInfoFromSoleConformingType(ArgOperand);
+  return buildConcreteOpenedExistentialInfoFromSoleConformingType(ArgOperand);
 }
 
 // Build ConcreteExistentialInfo for every existential argument of an Apply
 // instruction including Self.
-void SILCombiner::buildConcreteExistentialInfos(
+void SILCombiner::buildConcreteOpenedExistentialInfos(
     FullApplySite Apply,
-    llvm::SmallDenseMap<unsigned, ConcreteExistentialInfo> &CEIs,
+    llvm::SmallDenseMap<unsigned, ConcreteOpenedExistentialInfo> &COEIs,
     SILBuilderContext &BuilderCtx,
     SILOpenedArchetypesTracker &OpenedArchetypesTracker) {
   for (unsigned ArgIdx = 0; ArgIdx < Apply.getNumArguments(); ArgIdx++) {
@@ -723,17 +738,18 @@
     if (!ArgASTType->hasArchetype())
       continue;
 
-    auto OptionalCEI =
-        buildConcreteExistentialInfo(Apply.getArgumentOperands()[ArgIdx]);
-    if (!OptionalCEI.hasValue())
+    auto OptionalCOEI =
+        buildConcreteOpenedExistentialInfo(Apply.getArgumentOperands()[ArgIdx]);
+    if (!OptionalCOEI.hasValue())
       continue;
-    auto CEI = OptionalCEI.getValue();
-    assert(CEI.isValid());
-    CEIs.try_emplace(ArgIdx, CEI);
+    auto COEI = OptionalCOEI.getValue();
+    assert(COEI.isValid());
+    COEIs.try_emplace(ArgIdx, COEI);
 
+    ConcreteExistentialInfo &CEI = *COEI.CEI;
     if (CEI.ConcreteType->isOpenedExistential()) {
       // Temporarily record this opened existential def in this local
-      // BuilderContext before rewriting the witness method.
+      // BuilderContext before rewriting any uses of the ConcreteType.
       OpenedArchetypesTracker.addOpenedArchetypeDef(
           cast<ArchetypeType>(CEI.ConcreteType), CEI.ConcreteTypeDef);
     }
@@ -744,9 +760,13 @@
 /// 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 canReplaceCopiedArg(FullApplySite Apply,
-                                 SILInstruction *InitExistential,
-                                 DominanceAnalysis *DA, unsigned ArgIdx) {
+static bool canReplaceCopiedArg(FullApplySite Apply, SILValue Arg,
+                                DominanceAnalysis *DA, unsigned ArgIdx) {
+  auto *IEA = dyn_cast<InitExistentialAddrInst>(Arg);
+  // Only init_existential_addr may be copied.
+  if (!IEA)
+    return false;
+
   // If the witness method mutates Arg, we cannot replace Arg with
   // the source of a copy. Otherwise the call would modify another value than
   // the original argument.
@@ -756,9 +776,7 @@
 
   auto *DT = DA->get(Apply.getFunction());
   auto *AI = Apply.getInstruction();
-  // Only init_existential_addr may be copied.
-  SILValue existentialAddr =
-      cast<InitExistentialAddrInst>(InitExistential)->getOperand();
+  SILValue existentialAddr = IEA->getOperand();
 
   // If we peeked through an InitEnumDataAddr or some such, then don't assume we
   // can reuse the copied value. It's likely destroyed by
@@ -809,6 +827,7 @@
 // can be replaced with a concrete type. Concrete type info is passed as CEI
 // argument.
 bool SILCombiner::canReplaceArg(FullApplySite Apply,
+                                const OpenedArchetypeInfo &OAI,
                                 const ConcreteExistentialInfo &CEI,
                                 unsigned ArgIdx) {
 
@@ -818,7 +837,7 @@
   // references to OpenedArchetype will be substituted. So walk to type to
   // find all possible references, such as returning Optional<Arg>.
   if (Apply.getType().getASTType().findIf(
-          [&CEI](Type t) -> bool { return t->isEqual(CEI.OpenedArchetype); })) {
+          [&OAI](Type t) -> bool { return t->isEqual(OAI.OpenedArchetype); })) {
     return false;
   }
   // Bail out if any other arguments or indirect result that refer to the
@@ -837,17 +856,17 @@
     if (Idx == ArgIdx)
       continue;
     if (Apply.getArgument(Idx)->getType().getASTType().findIf(
-            [&CEI](Type t) -> bool {
-              return t->isEqual(CEI.OpenedArchetype);
+            [&OAI](Type t) -> bool {
+              return t->isEqual(OAI.OpenedArchetype);
             })) {
       return false;
     }
   }
   // The apply can only be rewritten in terms of the concrete value if it is
   // legal to pass that value as the Arg argument.
-  if (CEI.isCopied &&
-      (!CEI.InitExistential ||
-       !canReplaceCopiedArg(Apply, CEI.InitExistential, DA, ArgIdx))) {
+  if (CEI.isConcreteValueCopied
+      && (!CEI.ConcreteValue
+          || !canReplaceCopiedArg(Apply, CEI.ConcreteValue, DA, ArgIdx))) {
     return false;
   }
   // It is safe to replace Arg.
@@ -879,7 +898,7 @@
 /// SSA uses in those cases. Currently we bail out on methods that return Self.
 SILInstruction *SILCombiner::createApplyWithConcreteType(
     FullApplySite Apply,
-    const llvm::SmallDenseMap<unsigned, ConcreteExistentialInfo> &CEIs,
+    const llvm::SmallDenseMap<unsigned, ConcreteOpenedExistentialInfo> &COAIs,
     SILBuilderContext &BuilderCtx) {
 
   // Ensure that the callee is polymorphic.
@@ -897,15 +916,18 @@
   }
   // Transform the parameter arguments.
   for (unsigned EndIdx = Apply.getNumArguments(); ArgIdx < EndIdx; ++ArgIdx) {
-    auto ArgIt = CEIs.find(ArgIdx);
-    if (ArgIt == CEIs.end()) {
+    auto ArgIt = COAIs.find(ArgIdx);
+    if (ArgIt == COAIs.end()) {
       // Use the old argument if it does not have a valid concrete existential.
       NewArgs.push_back(Apply.getArgument(ArgIdx));
       continue;
     }
-    auto &CEI = ArgIt->second;
+    const OpenedArchetypeInfo &OAI = ArgIt->second.OAI;
+    const ConcreteExistentialInfo &CEI = *ArgIt->second.CEI;
+    assert(CEI.isValid());
+
     // Check for Arg's concrete type propagation legality.
-    if (!canReplaceArg(Apply, CEI, ArgIdx)) {
+    if (!canReplaceArg(Apply, OAI, CEI, ArgIdx)) {
       NewArgs.push_back(Apply.getArgument(ArgIdx));
       continue;
     }
@@ -917,13 +939,13 @@
     // replaced with a concrete type.
     NewCallSubs = NewCallSubs.subst(
         [&](SubstitutableType *type) -> Type {
-          if (type == CEI.OpenedArchetype)
+          if (type == OAI.OpenedArchetype)
             return CEI.ConcreteType;
           return type;
         },
         [&](CanType origTy, Type substTy,
             ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> {
-          if (origTy->isEqual(CEI.OpenedArchetype)) {
+          if (origTy->isEqual(OAI.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
@@ -981,25 +1003,33 @@
   // Try to derive the concrete type and the related conformance of self and
   // other existential arguments by searching either for a preceding
   // init_existential or looking up sole conforming type.
+  //
+  // buildConcreteOpenedExistentialInfo takes a SILBuilderContext because it may
+  // insert an uncheched cast to the concrete type, and it tracks the defintion
+  // of any opened archetype needed to use the concrete type.
   SILBuilderContext BuilderCtx(Builder.getModule(), Builder.getTrackingList());
   SILOpenedArchetypesTracker OpenedArchetypesTracker(&Builder.getFunction());
   BuilderCtx.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
-  llvm::SmallDenseMap<unsigned, ConcreteExistentialInfo> CEIs;
-  buildConcreteExistentialInfos(Apply, CEIs, BuilderCtx,
-                                OpenedArchetypesTracker);
+  llvm::SmallDenseMap<unsigned, ConcreteOpenedExistentialInfo> COEIs;
+  buildConcreteOpenedExistentialInfos(Apply, COEIs, BuilderCtx,
+                                      OpenedArchetypesTracker);
 
   // Bail, if no argument has a concrete existential to propagate.
-  if (CEIs.empty())
+  if (COEIs.empty())
     return nullptr;
-  auto SelfCEIIt =
-      CEIs.find(Apply.getCalleeArgIndex(Apply.getSelfArgumentOperand()));
 
-  // If no SelfCEI is found, then just update the Apply with new CEIs for
+  auto SelfCOEIIt =
+      COEIs.find(Apply.getCalleeArgIndex(Apply.getSelfArgumentOperand()));
+
+  // If no SelfCOEI is found, then just update the Apply with new COEIs for
   // other arguments.
-  if (SelfCEIIt == CEIs.end())
-    return createApplyWithConcreteType(Apply, CEIs, BuilderCtx);
+  if (SelfCOEIIt == COEIs.end())
+    return createApplyWithConcreteType(Apply, COEIs, BuilderCtx);
 
-  auto &SelfCEI = SelfCEIIt->second;
+  auto &SelfCOEI = SelfCOEIIt->second;
+  assert(SelfCOEI.isValid());
+
+  const ConcreteExistentialInfo &SelfCEI = *SelfCOEI.CEI;
   assert(SelfCEI.isValid());
 
   // Get the conformance of the init_existential type, which is passed as the
@@ -1026,8 +1056,8 @@
                              SelfConformance);
   }
 
-  // Try to rewrite the apply.
-  return createApplyWithConcreteType(Apply, CEIs, BuilderCtx);
+  /// Create the new apply instruction using concrete types for arguments.
+  return createApplyWithConcreteType(Apply, COEIs, BuilderCtx);
 }
 
 /// Rewrite a protocol extension lookup type from an archetype to a concrete
@@ -1049,17 +1079,18 @@
   // Try to derive the concrete type and the related conformance of self and
   // other existential arguments by searching either for a preceding
   // init_existential or looking up sole conforming type.
-  llvm::SmallDenseMap<unsigned, ConcreteExistentialInfo> CEIs;
+  llvm::SmallDenseMap<unsigned, ConcreteOpenedExistentialInfo> COEIs;
   SILBuilderContext BuilderCtx(Builder.getModule(), Builder.getTrackingList());
   SILOpenedArchetypesTracker OpenedArchetypesTracker(&Builder.getFunction());
   BuilderCtx.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
-  buildConcreteExistentialInfos(Apply, CEIs, BuilderCtx,
-                                OpenedArchetypesTracker);
+  buildConcreteOpenedExistentialInfos(Apply, COEIs, BuilderCtx,
+                                      OpenedArchetypesTracker);
 
   // Bail, if no argument has a concrete existential to propagate.
-  if (CEIs.empty())
+  if (COEIs.empty())
     return nullptr;
-  return createApplyWithConcreteType(Apply, CEIs, BuilderCtx);
+
+  return createApplyWithConcreteType(Apply, COEIs, BuilderCtx);
 }
 
 /// Check that all users of the apply are retain/release ignoring one
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
index 64d2141..d231d6b 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
@@ -289,16 +289,19 @@
 SILInstruction *
 SILCombiner::
 visitUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *UCCAI) {
-  CastOpt.optimizeUnconditionalCheckedCastAddrInst(UCCAI);
+  if (CastOpt.optimizeUnconditionalCheckedCastAddrInst(UCCAI))
+    MadeChange = true;
+
   return nullptr;
 }
 
 SILInstruction *
 SILCombiner::
 visitUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *UCCI) {
-  if (CastOpt.optimizeUnconditionalCheckedCastInst(UCCI))
+  if (CastOpt.optimizeUnconditionalCheckedCastInst(UCCI)) {
+    MadeChange = true;
     return nullptr;
-
+  }
   // FIXME: rename from RemoveCondFails to RemoveRuntimeAsserts.
   if (RemoveCondFails) {
     auto LoweredTargetType = UCCI->getType();
@@ -388,32 +391,6 @@
   return nullptr;
 }
 
-/// Helper function for simplifying conversions between
-/// thick and objc metatypes.
-static SILInstruction *
-visitMetatypeConversionInst(SILBuilder &Builder, ConversionInst *MCI,
-                            MetatypeRepresentation Representation) {
-  SILValue Op = MCI->getOperand(0);
-  // Instruction has a proper target type already.
-  SILType Ty = MCI->getType();
-  auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
-
-  if (MetatypeTy->getRepresentation() != Representation)
-    return nullptr;
-
-  if (isa<MetatypeInst>(Op))
-    return Builder.createMetatype(MCI->getLoc(), Ty);
-
-  if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op))
-    return Builder.createValueMetatype(MCI->getLoc(), Ty, VMI->getOperand());
-
-  if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op))
-    return Builder.createExistentialMetatype(MCI->getLoc(), Ty,
-                                             EMI->getOperand());
-
-  return nullptr;
-}
-
 SILInstruction *
 SILCombiner::visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *TTOCMI) {
   // Perform the following transformations:
@@ -425,8 +402,10 @@
   //
   // (thick_to_objc_metatype (existential_metatype @thick)) ->
   // (existential_metatype @objc_metatype)
-  return visitMetatypeConversionInst(Builder, TTOCMI,
-                                     MetatypeRepresentation::Thick);
+  if (CastOpt.optimizeMetatypeConversion(TTOCMI, MetatypeRepresentation::Thick))
+    MadeChange = true;
+
+  return nullptr;
 }
 
 SILInstruction *
@@ -440,20 +419,26 @@
   //
   // (objc_to_thick_metatype (existential_metatype @objc_metatype)) ->
   // (existential_metatype @thick)
-  return visitMetatypeConversionInst(Builder, OCTTMI,
-                                     MetatypeRepresentation::ObjC);
+  if (CastOpt.optimizeMetatypeConversion(OCTTMI, MetatypeRepresentation::ObjC))
+    MadeChange = true;
+
+  return nullptr;
 }
 
 SILInstruction *
 SILCombiner::visitCheckedCastBranchInst(CheckedCastBranchInst *CBI) {
-  CastOpt.optimizeCheckedCastBranchInst(CBI);
+  if (CastOpt.optimizeCheckedCastBranchInst(CBI))
+    MadeChange = true;
+
   return nullptr;
 }
 
 SILInstruction *
 SILCombiner::
 visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CCABI) {
-  CastOpt.optimizeCheckedCastAddrBranchInst(CCABI);
+  if (CastOpt.optimizeCheckedCastAddrBranchInst(CCABI))
+    MadeChange = true;
+
   return nullptr;
 }
 
diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
index 39ff21e..c34a123 100644
--- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
+++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
@@ -105,7 +105,7 @@
     /// The benefit of inlining an exclusivity-containing callee.
     /// The exclusivity needs to be: dynamic,
     /// has no nested conflict and addresses known storage
-    ExclusivityBenefit = RemovedCallBenefit + 300,
+    ExclusivityBenefit = RemovedCallBenefit + 125,
 
     /// The benefit of inlining class methods with -Osize.
     /// We only inline very small class methods with -Osize.
diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp
index e63f5ba..0d2dfe5 100644
--- a/lib/SILOptimizer/Utils/CastOptimizer.cpp
+++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp
@@ -1575,3 +1575,40 @@
 
   return nullptr;
 }
+
+/// Simplify conversions between thick and objc metatypes.
+SILInstruction *CastOptimizer::optimizeMetatypeConversion(
+    ConversionInst *MCI, MetatypeRepresentation Representation) {
+  SILValue Op = MCI->getOperand(0);
+  // Instruction has a proper target type already.
+  SILType Ty = MCI->getType();
+  auto MetatypeTy = Op->getType().getAs<AnyMetatypeType>();
+
+  if (MetatypeTy->getRepresentation() != Representation)
+    return nullptr;
+
+  // Rematerialize the incoming metatype instruction with the outgoing type.
+  auto replaceCast = [&](SingleValueInstruction *NewCast) {
+    assert(Ty.getAs<AnyMetatypeType>()->getRepresentation()
+           == NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation());
+    MCI->replaceAllUsesWith(NewCast);
+    EraseInstAction(MCI);
+    return NewCast;
+  };
+  if (auto *MI = dyn_cast<MetatypeInst>(Op)) {
+    return replaceCast(
+        SILBuilderWithScope(MCI).createMetatype(MCI->getLoc(), Ty));
+  }
+  // For metatype instructions that require an operand, generate the new
+  // metatype at the same position as the original to avoid extending the
+  // lifetime of `Op` past its destroy.
+  if (auto *VMI = dyn_cast<ValueMetatypeInst>(Op)) {
+    return replaceCast(SILBuilderWithScope(VMI).createValueMetatype(
+        MCI->getLoc(), Ty, VMI->getOperand()));
+  }
+  if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op)) {
+    return replaceCast(SILBuilderWithScope(EMI).createExistentialMetatype(
+        MCI->getLoc(), Ty, EMI->getOperand()));
+  }
+  return nullptr;
+}
diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp
index aa900c4..57d6a84 100644
--- a/lib/SILOptimizer/Utils/ConstExpr.cpp
+++ b/lib/SILOptimizer/Utils/ConstExpr.cpp
@@ -20,6 +20,7 @@
 #include "swift/SIL/FormalLinkage.h"
 #include "swift/SIL/SILBuilder.h"
 #include "swift/SIL/SILConstants.h"
+#include "swift/SILOptimizer/Utils/Devirtualize.h"
 #include "swift/Serialization/SerializedSILLoader.h"
 #include "llvm/ADT/PointerEmbeddedInt.h"
 #include "llvm/Support/TrailingObjects.h"
@@ -59,9 +60,6 @@
   /// substitutionMap specifies a mapping from all of the protocol and type
   /// requirements in the generic signature down to concrete conformances and
   /// concrete types.
-  /// TODO(constexpr patch): I have intentionally included this even though it's
-  /// unused, so that I don't have to add it back to all the function signatures
-  /// when I start using it.
   SubstitutionMap substitutionMap;
 
   /// This keeps track of the number of instructions we've evaluated.  If this
@@ -117,10 +115,15 @@
   llvm::Optional<SymbolicValue> computeOpaqueCallResult(ApplyInst *apply,
                                                         SILFunction *callee);
 
+  SymbolicValue getSingleWriterAddressValue(SILValue addr);
   SymbolicValue getConstAddrAndLoadResult(SILValue addr);
   SymbolicValue loadAddrValue(SILValue addr, SymbolicValue addrVal);
   llvm::Optional<SymbolicValue> computeFSStore(SymbolicValue storedCst,
                                                SILValue dest);
+
+private:
+  llvm::Optional<SymbolicValue>
+  initializeAddressFromSingleWriter(SILValue addr);
 };
 } // end anonymous namespace
 
@@ -134,6 +137,14 @@
 SymbolicValue ConstExprFunctionState::computeConstantValue(SILValue value) {
   assert(!calculatedValues.count(value));
 
+  // If the client is asking for the value of a stack object that hasn't been
+  // computed, and if fn is null, then we are in top level code, and the
+  // stack object must be a single store value.  Since this is a very different
+  // computation, split it out to its own path.
+  if (!fn && value->getType().isAddress() && isa<AllocStackInst>(value)) {
+    return getSingleWriterAddressValue(value);
+  }
+
   // If this a trivial constant instruction that we can handle, then fold it
   // immediately.
   if (auto *ili = dyn_cast<IntegerLiteralInst>(value))
@@ -221,6 +232,27 @@
   if (auto li = dyn_cast<LoadInst>(value))
     return getConstAddrAndLoadResult(li->getOperand());
 
+  // Try to resolve a witness method against our known conformances.
+  if (auto *wmi = dyn_cast<WitnessMethodInst>(value)) {
+    auto confResult = substitutionMap.lookupConformance(
+        wmi->getLookupType(), wmi->getConformance().getRequirement());
+    if (!confResult)
+      return evaluator.getUnknown(value, UnknownReason::Default);
+    auto conf = confResult.getValue();
+    auto &module = wmi->getModule();
+
+    // Look up the conformance's witness table and the member out of it.
+    SILFunction *fn =
+        module.lookUpFunctionInWitnessTable(conf, wmi->getMember()).first;
+    // If we were able to resolve it, then we can proceed.
+    if (fn)
+      return SymbolicValue::getFunction(fn);
+
+    LLVM_DEBUG(llvm::dbgs()
+               << "ConstExpr Unresolved witness: " << *value << "\n");
+    return evaluator.getUnknown(value, UnknownReason::Default);
+  }
+
   if (auto *builtin = dyn_cast<BuiltinInst>(value))
     return computeConstantValueBuiltin(builtin);
 
@@ -519,11 +551,66 @@
     paramConstants.push_back(argValue);
   }
 
-  // TODO(constexpr patch): This is currently unused, so we don't need to
-  // calculate the correct value. Eventually, include code that calculates the
-  // correct value.
+  // If we reached an external function that hasn't been deserialized yet, make
+  // sure to pull it in so we can see its body.  If that fails, then we can't
+  // analyze the function.
+  if (callee->isExternalDeclaration()) {
+    callee->getModule().loadFunction(callee);
+    if (callee->isExternalDeclaration())
+      return computeOpaqueCallResult(apply, callee);
+  }
+
+  // Compute the substitution map for the callee, which maps from all of its
+  // generic requirements to concrete conformances and concrete types.
   SubstitutionMap calleeSubMap;
 
+  auto calleeFnType = callee->getLoweredFunctionType();
+  assert(
+      !calleeFnType->hasSelfParam() ||
+      !calleeFnType->getSelfInstanceType()->getClassOrBoundGenericClass() &&
+      "class methods are not supported");
+  if (calleeFnType->getGenericSignature()) {
+    // Get the substitution map of the call.  This maps from the callee's space
+    // into the caller's world. Witness methods require additional work to
+    // compute a mapping that is valid for the callee.
+    SubstitutionMap callSubMap;
+
+    if (calleeFnType->getRepresentation() ==
+        SILFunctionType::Representation::WitnessMethod) {
+      auto protocol =
+          calleeFnType->getWitnessMethodConformance().getRequirement();
+      // Compute a mapping that maps the Self type of the protocol given by
+      // 'requirement' to the concrete type available in the substitutionMap.
+      auto protoSelfToConcreteType =
+          apply->getSubstitutionMap().subst(substitutionMap);
+      // Get a concrete protocol conformance by using the mapping for the
+      // Self type of the requirement.
+      auto conf = protoSelfToConcreteType.lookupConformance(
+          protocol->getSelfInterfaceType()->getCanonicalType(), protocol);
+      if (!conf.hasValue())
+        return evaluator.getUnknown((SILInstruction *)apply,
+                                    UnknownReason::Default);
+
+      callSubMap = getWitnessMethodSubstitutions(
+          apply->getModule(), ApplySite(apply), callee, conf.getValue());
+
+      /// Remark: If we ever start to care about evaluating classes,
+      /// getSubstitutionsForCallee() is the analogous mapping function we
+      /// should use to get correct mapping from caller to callee namespace.
+      /// Ideally, the function must be renamed as
+      /// getClassMethodSubstitutions().
+    } else {
+      callSubMap = apply->getSubstitutionMap();
+    }
+
+    // The substitution map for the callee is the composition of the callers
+    // substitution map, which is always type/conformance to a concrete type
+    // or conformance, with the mapping introduced by the call itself.  This
+    // ensures that the callee's substitution map can map from its type
+    // namespace back to concrete types and conformances.
+    calleeSubMap = callSubMap.subst(substitutionMap);
+  }
+
   // Now that we have successfully folded all of the parameters, we can evaluate
   // the call.
   evaluator.pushCallStack(apply->getLoc().getSourceLoc());
@@ -572,84 +659,283 @@
   return result;
 }
 
-/// Given an aggregate value like {{1, 2}, 3} and an access path like [0,1], and
-/// a new element like 4, return the aggregate value with the indexed element
-/// replaced with the new element, producing {{1, 4}, 3} in this case.
-/// If `writeOnlyOnce` is true, and the target aggregate element to update
-/// already has a constant value, fail on the update.
+/// This is a helper function for `getSingleWriterAddressValue`. Callers should
+/// use `getSingleWriterAddressValue`.
 ///
-/// This returns true on failure and false on success.
+/// If `addr` has no writing uses, returns None.
 ///
-static bool updateIndexedElement(SymbolicValue &aggregate,
-                                 ArrayRef<unsigned> indices,
-                                 SymbolicValue newElement, Type type,
-                                 bool writeOnlyOnce,
-                                 ASTContext &astContext) {
-  // We're done if we've run out of indices.
-  if (indices.empty()) {
-    aggregate = newElement;
-    return false;
-  }
+/// If the following conditions hold:
+///   * `addr` points at uninitialized memory;
+///   * there are write(s) to `addr` that, taken together, set the memory
+///     exactly once (e.g. a single "store" to `addr` OR multiple "store"s to
+///     different "tuple_element_addr"s of `addr`); and
+///   * the writes' value(s) can be const-evaluated;
+/// Then: initializes the memory at `addr` and returns None.
+///
+/// Otherwise, sets the memory at `addr` to an unknown SymbolicValue, and
+/// returns the unknown SymbolicValue.
+///
+/// Additional side effects: In all cases, this function might cache address
+/// values for `addr` and for addresses derived from `addr`.
+///
+/// Precondition: An address for `addr`, or an address that `addr` is derived
+/// from, must be cached in `computedValues`.
+llvm::Optional<SymbolicValue>
+ConstExprFunctionState::initializeAddressFromSingleWriter(SILValue addr) {
+  LLVM_DEBUG(llvm::dbgs() << "ConstExpr: initializeAddressFromSingleWriter "
+             << addr);
 
-  // If we have an uninit memory, then scalarize it into an aggregate to
-  // continue.  This happens when memory objects are initialized piecewise.
-  if (aggregate.getKind() == SymbolicValue::UninitMemory) {
-    unsigned numMembers;
-    // We need to have either a struct or a tuple type.
-    if (auto *decl = type->getStructOrBoundGenericStruct()) {
-      numMembers = std::distance(decl->getStoredProperties().begin(),
-                                 decl->getStoredProperties().end());
-    } else if (auto tuple = type->getAs<TupleType>()) {
-      numMembers = tuple->getNumElements();
-    } else {
-      return true;
+  SmallVector<unsigned, 4> accessPath;
+  auto *memoryObject = getConstantValue(addr).getAddressValue(accessPath);
+
+  // If we detect instructions that initialize an aggregate piecewise, then we
+  // set this flag, which tells us to verify that the entire aggregate has been
+  // initialized.
+  bool mustCheckAggregateInitialized = false;
+
+  // Sets the pointed-at memory to `value`.
+  auto setMemoryValue = [&](SymbolicValue value) {
+    memoryObject->setIndexedElement(accessPath, value,
+                                    evaluator.getASTContext());
+  };
+
+  // Gets the pointed-at memory value.
+  auto getMemoryValue = [&]() -> SymbolicValue {
+    return memoryObject->getIndexedElement(accessPath);
+  };
+
+  // Does all error-condition side-effects, and returns the appropriate error
+  // result.
+  // Precondition: `unknown` must be an unknown SymbolicValue.
+  auto error = [&](SymbolicValue unknown) -> SymbolicValue {
+    assert(unknown.getKind() == SymbolicValue::Unknown);
+    setMemoryValue(unknown);
+    return unknown;
+  };
+
+  // Checks that the pointed-at aggregate is fully initialized.
+  // Precondition: The pointed-at memory value is uninit memory or an
+  // aggregate.
+  auto checkAggregateInitialized = [&]() -> bool {
+    auto memoryValue = getMemoryValue();
+    return memoryValue.getKind() != SymbolicValue::UninitMemory &&
+           llvm::all_of(memoryValue.getAggregateValue(),
+                        [](SymbolicValue v) { return v.isConstant(); });
+  };
+
+  // Okay, check out all of the users of this value looking for semantic stores
+  // into the address.  If we find more than one, then this was a var or
+  // something else we can't handle.
+  // We must iterate over all uses, to make sure there is a single initializer.
+  // The only permitted early exit is when we know for sure that we have failed.
+  for (auto *use : addr->getUses()) {
+    auto user = use->getUser();
+
+    // Ignore markers, loads, and other things that aren't stores to this stack
+    // value.
+    if (isa<LoadInst>(user) || isa<DeallocStackInst>(user) ||
+        isa<DestroyAddrInst>(user) || isa<DebugValueAddrInst>(user))
+      continue;
+
+    // TODO: Allow BeginAccess/EndAccess users.
+
+    // If this is a store *to* the memory, analyze the input value.
+    if (auto *si = dyn_cast<StoreInst>(user)) {
+      if (use->getOperandNumber() == 1) {
+        // Forbid multiple assignment.
+        if (getMemoryValue().getKind() != SymbolicValue::UninitMemory)
+          return error(evaluator.getUnknown(addr, UnknownReason::Default));
+
+        auto result = getConstantValue(si->getOperand(0));
+        if (!result.isConstant())
+          return error(evaluator.getUnknown(addr, UnknownReason::Default));
+
+        setMemoryValue(result);
+        continue;
+      }
     }
 
-    SmallVector<SymbolicValue, 4> newElts(numMembers,
-                                          SymbolicValue::getUninitMemory());
-    aggregate = SymbolicValue::getAggregate(newElts, astContext);
+    if (auto *cai = dyn_cast<CopyAddrInst>(user)) {
+      // If this is a copy_addr *from* the memory, then it is a load, ignore it.
+      if (use->getOperandNumber() == 0)
+        continue;
+
+      // If this is a copy_addr *to* the memory, analyze the input value.
+      assert(use->getOperandNumber() == 1 && "copy_addr has two operands");
+
+      // Forbid multiple assignment.
+      if (getMemoryValue().getKind() != SymbolicValue::UninitMemory)
+        return error(evaluator.getUnknown(addr, UnknownReason::Default));
+
+      auto result = getConstAddrAndLoadResult(cai->getOperand(0));
+      if (!result.isConstant())
+        return error(evaluator.getUnknown(addr, UnknownReason::Default));
+
+      setMemoryValue(result);
+      continue;
+    }
+
+    // If this is an apply_inst passing the memory address as an indirect
+    // result operand, then we have a call that fills in this result.
+    if (auto *apply = dyn_cast<ApplyInst>(user)) {
+      auto conventions = apply->getSubstCalleeConv();
+
+      // If this is an out-parameter, it is like a store.  If not, this is an
+      // indirect read which is ok.
+      unsigned numIndirectResults = conventions.getNumIndirectSILResults();
+      unsigned opNum = use->getOperandNumber() - 1;
+      if (opNum >= numIndirectResults)
+        continue;
+
+      // Forbid multiple assignment.
+      if (getMemoryValue().getKind() != SymbolicValue::UninitMemory)
+        return error(evaluator.getUnknown(addr, UnknownReason::Default));
+
+      // The callee needs to be a direct call to a constant expression.
+      auto callResult = computeCallResult(apply);
+
+      // If the call failed, we're done.
+      if (callResult.hasValue())
+        return error(*callResult);
+
+      // computeCallResult will have figured out the result and cached it for
+      // us.
+      assert(getMemoryValue().isConstant());
+      continue;
+    }
+
+    // If it is an index_addr, make sure it is a different address from base.
+    if (auto *iai = dyn_cast<IndexAddrInst>(user)) {
+      assert(use->get() == iai->getBase());
+      if (auto *ili = dyn_cast<IntegerLiteralInst>(iai->getIndex())) {
+        if (ili->getValue().getLimitedValue() != 0)
+          continue;
+      }
+      return error(evaluator.getUnknown(addr, UnknownReason::Default));
+    }
+
+    if (auto *teai = dyn_cast<TupleElementAddrInst>(user)) {
+      // Try finding a writer among the users of `teai`. For example:
+      //   %179 = alloc_stack $(Int32, Int32, Int32, Int32)
+      //   %183 = tuple_element_addr %179 : $*(Int32, Int32, Int32, Int32), 3
+      //   copy_addr %114 to [initialization] %183 : $*Int32
+      //   %191 = tuple_element_addr %179 : $*(Int32, Int32, Int32, Int32), 3
+      //   copy_addr [take] %191 to [initialization] %178 : $*Int32
+      //
+      // The workflow is: when const-evaluating %178, we const-evaluate %191,
+      // which in turn triggers const-evaluating %179, thereby enter this
+      // function, where `addrInst` being %179. Among its users, %191 is not an
+      // initializer, so we skip it (`initializeAddressFromSingleWriter(teai)`
+      // below will act as a no-op on it). %183 is a good initializer and can
+      // be const-evaluated (by const-evaluating %114).
+
+      // We can't forbid multiple assignment here by checking for uninit memory,
+      // because previous TupleElementAddrInsts may have already partially
+      // initialized the memory. However, the recursive call to
+      // `initializeAddressFromSingleWriter` below detects and forbids multiple
+      // assignment, so we don't need to do it here.
+
+      if (auto failure = initializeAddressFromSingleWriter(teai))
+        return error(*failure);
+
+      // If this instruction partially initialized the memory, then we must
+      // remember to check later that the memory has been fully initialized.
+      if (getMemoryValue().getKind() != SymbolicValue::UninitMemory)
+        mustCheckAggregateInitialized = true;
+
+#ifndef NDEBUG
+      // If all aggregate elements are const, we have successfully
+      // const-evaluated the entire tuple!
+      if (checkAggregateInitialized())
+        LLVM_DEBUG(llvm::dbgs() << "Const-evaluated the entire tuple: ";
+                   getMemoryValue().dump());
+#endif // NDEBUG
+      continue;
+    }
+
+    LLVM_DEBUG(llvm::dbgs()
+               << "Unknown SingleStore ConstExpr user: " << *user << "\n");
+
+    // If this is some other user that we don't know about, then we should
+    // treat it conservatively, because it could store into the address.
+    return error(evaluator.getUnknown(addr, UnknownReason::Default));
   }
 
-  unsigned elementNo = indices.front();
+  if (mustCheckAggregateInitialized && !checkAggregateInitialized())
+    return error(evaluator.getUnknown(addr, UnknownReason::Default));
 
-  // If we have a non-aggregate then fail.
-  if (aggregate.getKind() != SymbolicValue::Aggregate)
-    return true;
+  return None;
+}
 
-  ArrayRef<SymbolicValue> oldElts;
-  Type eltType;
+/// Find the initializer (single writer) of `addr` among it users,
+/// const-evaluate it and store the result into a memory object.
+///
+/// Side effects: Creates a fully-initialized memory object (on success), or a
+/// memory object containing an unknown (on failure). Inserts the address of
+/// that memory object into `calculatedValues`, with key `addr`.
+///
+/// Returns the address of the memory object on success. Returns the unknown on
+/// failure.
+///
+/// Some use cases are:
+/// 1. When analyzing the top-level code involved in a constant expression, we
+/// can end up demanding values that are returned by address.  Handle this by
+/// finding the temporary stack value (an alloc_stack inst), and calling this
+/// method on it.
+/// 2. When const-evaluating an array via decodeAllocUninitializedArray(),
+/// do that by const-evaluating the writers of individual array elements.
+///
+///  There are a few forms of writers, such as:
+/// - store %3 to %4 ...
+/// - %8 = pointer_to_address %7 : $Builtin.RawPointer to [strict] $*Int32
+/// - %14 = index_addr %9 : $*Int32, %13 : $Builtin.Word
+/// - %180 = tuple_element_addr %179 : $*(Int32, Int32, Int32, Int32), 3
+///
+///  Note unlike getConstAddrAndLoadResult(), this method does *not*
+///  const-evaluate the input `addr` by evaluating its operand first, such as %7
+///  above. Instead, it finds a user of %8 who is the initializer, and uses that
+///  to set the const value for %7. In other words, this method propagates const
+///  info from result to operand (e.g. from %8 to %7), while
+///  getConstAddrAndLoadResult() propagates const info from operand to result.
+///
+///  As such, when const-evaluating an address-typed inst such as
+///  pointer_to_address, if the address is to be written to, caller should call
+///  this method (e.g. a[3] = 17). If the address is to be read (e.g. let v =
+///  a[3]), call getConstAddrAndLoadResult().
+SymbolicValue
+ConstExprFunctionState::getSingleWriterAddressValue(SILValue addr) {
+  // Check to see if we already have an answer.
+  auto it = calculatedValues.find(addr);
+  if (it != calculatedValues.end())
+    return it->second;
 
-  // We need to have a struct or a tuple type.
-  oldElts = aggregate.getAggregateValue();
+  assert(addr->getType().isAddress());
+  auto *addrInst = dyn_cast<SingleValueInstruction>(addr);
+  if (!addrInst)
+    return evaluator.getUnknown(addr, UnknownReason::Default);
 
-  if (auto *decl = type->getStructOrBoundGenericStruct()) {
-    auto it = decl->getStoredProperties().begin();
-    std::advance(it, elementNo);
-    eltType = (*it)->getType();
-  } else if (auto tuple = type->getAs<TupleType>()) {
-    assert(elementNo < tuple->getNumElements() && "invalid index");
-    eltType = tuple->getElement(elementNo).getType();
-  } else {
-    return true;
+  // Create a memory object to initialize, and point `addr` at it.
+  auto memoryAddress =
+      createMemoryObject(addr, SymbolicValue::getUninitMemory());
+  auto *memoryObject = memoryAddress.getAddressValueMemoryObject();
+
+  if (auto failure = initializeAddressFromSingleWriter(addr)) {
+    assert(failure->getKind() == SymbolicValue::Unknown);
+    memoryObject->setValue(*failure);
+    return *failure;
+  }
+  if (!memoryObject->getValue().isConstant()) {
+    auto unknown = evaluator.getUnknown(addr, UnknownReason::Default);
+    memoryObject->setValue(unknown);
+    return unknown;
   }
 
-  if (writeOnlyOnce &&
-      oldElts[elementNo].getKind() != SymbolicValue::UninitMemory) {
-    // Cannot overwrite an existing constant.
-    return true;
-  }
-
-  // Update the indexed element of the aggregate.
-  SmallVector<SymbolicValue, 4> newElts(oldElts.begin(), oldElts.end());
-  if (updateIndexedElement(newElts[elementNo], indices.drop_front(), newElement,
-                           eltType, writeOnlyOnce, astContext))
-    return true;
-
-  aggregate = SymbolicValue::getAggregate(newElts, astContext);
-  return false;
+  return memoryAddress;
 }
 
 /// Given the operand to a load, resolve it to a constant if possible.
+/// Also see the comments on getSingleWriterAddressValue() to contrast these 2
+/// APIs.
 SymbolicValue ConstExprFunctionState::getConstAddrAndLoadResult(SILValue addr) {
   auto addrVal = getConstantValue(addr);
   if (!addrVal.isConstant())
@@ -698,14 +984,8 @@
 
   SmallVector<unsigned, 4> accessPath;
   auto *memoryObject = it->second.getAddressValue(accessPath);
-  auto objectVal = memoryObject->getValue();
-  auto objectType = memoryObject->getType();
-
-  if (updateIndexedElement(objectVal, accessPath, storedCst, objectType,
-                           /*writeOnlyOnce*/ false, evaluator.getASTContext()))
-    return evaluator.getUnknown(dest, UnknownReason::Default);
-
-  memoryObject->setValue(objectVal);
+  memoryObject->setIndexedElement(accessPath, storedCst,
+                                  evaluator.getASTContext());
   return None;
 }
 
diff --git a/lib/SILOptimizer/Utils/Existential.cpp b/lib/SILOptimizer/Utils/Existential.cpp
index 6e32257..04d10a6 100644
--- a/lib/SILOptimizer/Utils/Existential.cpp
+++ b/lib/SILOptimizer/Utils/Existential.cpp
@@ -33,8 +33,8 @@
 /// apply pattern shown above) and that a valid init_existential_addr 
 /// value is returned only if it can prove that the value it 
 /// initializes is the same value at the use point.
-static SILValue findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI,
-                                                  SILInstruction *Insn) {
+static InitExistentialAddrInst *
+findInitExistentialFromGlobalAddr(GlobalAddrInst *GAI, SILInstruction *Insn) {
   /// Check for a single InitExistential usage for GAI and
   /// a simple dominance check: both InitExistential and Insn are in
   /// the same basic block and only one InitExistential
@@ -49,85 +49,36 @@
 
   /// No InitExistential found in the basic block.
   if (IEUses.empty())
-    return SILValue();
+    return nullptr;
 
   /// Walk backwards from Insn instruction till the begining of the basic block
   /// looking for an InitExistential.
-  SILValue SingleIE;
+  InitExistentialAddrInst *SingleIE = nullptr;
   for (auto II = Insn->getIterator().getReverse(),
             IE = Insn->getParent()->rend();
        II != IE; ++II) {
     if (!IEUses.count(&*II))
       continue;
     if (SingleIE)
-      return SILValue();
+      return nullptr;
 
     SingleIE = cast<InitExistentialAddrInst>(&*II);
   }
   return SingleIE;
 }
 
-/// Determine InitExistential from global_addr and copy_addr.
-/// %3 = global_addr @$P : $*SomeP
-/// %4 = init_existential_addr %3 : $*SomeP, $SomeC
-/// %5 = alloc_ref $SomeC
-/// store %5 to %4 : $*SomeC
-/// %8 = alloc_stack $SomeP
-/// copy_addr %3 to [initialization] %8 : $*SomeP
-SILValue
-swift::findInitExistentialFromGlobalAddrAndCopyAddr(GlobalAddrInst *GAI,
-                                                    CopyAddrInst *CAI) {
-  assert(CAI->getSrc() == SILValue(GAI) &&
-         "Broken Assumption! Global Addr is not the source of the passed in "
-         "copy_addr?!");
-  return findInitExistentialFromGlobalAddr(GAI, cast<SILInstruction>(CAI));
-}
-
-/// Determine InitExistential from global_addr and an apply argument.
-/// Pattern 1
-/// %3 = global_addr @$P : $*SomeP
-/// %4 = init_existential_addr %3 : $*SomeP, $SomeC
-/// %5 = alloc_ref $SomeC
-/// store %5 to %4 : $*SomeC
-/// %10 = apply %9(%3) : $@convention(thin) (@in_guaranteed SomeP)
-/// Pattern 2
-/// %3 = global_addr @$P : $*SomeP
-/// %9 = open_existential_addr mutable_access %3 : $*SomeP to $*@opened SomeP
-/// %15 = apply %11(%9) : $@convention(thin) (@in_guaranteed SomeP)
-SILValue swift::findInitExistentialFromGlobalAddrAndApply(GlobalAddrInst *GAI,
-                                                          ApplySite Apply,
-                                                          int ArgIdx) {
-  /// Code to ensure that we are calling only in two pattern matching scenarios.
-  bool isArg = false;
-  auto Arg = Apply.getArgument(ArgIdx);
-  if (auto *ApplyGAI = dyn_cast<GlobalAddrInst>(Arg)) {
-    if (ApplyGAI->isIdenticalTo(GAI)) {
-      isArg = true;
-    }
-  } else if (auto Open = dyn_cast<OpenExistentialAddrInst>(Arg)) {
-    auto Op = Open->getOperand();
-    if (auto *OpGAI = dyn_cast<GlobalAddrInst>(Op)) {
-      if (OpGAI->isIdenticalTo(GAI)) {
-        isArg = true;
-      }
-    }
-  }
-  assert(isArg && "Broken Assumption! Global Addr is not an argument to "
-                  "apply?!");
-  return findInitExistentialFromGlobalAddr(GAI, Apply.getInstruction());
-}
-
-/// Returns the address of an object with which the stack location \p ASI is
-/// initialized. This is either a init_existential_addr or the destination of a
-/// copy_addr. Returns a null value if the address does not dominate the
-/// alloc_stack user \p ASIUser.
-/// If the value is copied from another stack location, \p isCopied is set to
-/// true.
+/// Returns the instruction that initializes the given stack address. This is
+/// currently either a init_existential_addr, unconditional_checked_cast_addr,
+/// or copy_addr (if the instruction initializing the source of the copy cannot
+/// be determined). Returns nullptr if the initializer does not dominate the
+/// alloc_stack user \p ASIUser.  If the value is copied from another stack
+/// location, \p isCopied is set to true.
 ///
 /// allocStackAddr may either itself be an AllocStackInst or an
 /// InitEnumDataAddrInst that projects the value of an AllocStackInst.
-SILValue swift::getAddressOfStackInit(SILValue allocStackAddr,
-                                      SILInstruction *ASIUser, bool &isCopied) {
+static SILInstruction *getStackInitInst(SILValue allocStackAddr,
+                                        SILInstruction *ASIUser,
+                                        bool &isCopied) {
   SILInstruction *SingleWrite = nullptr;
   // Check that this alloc_stack is initialized only once.
   for (auto Use : allocStackAddr->getUses()) {
@@ -144,15 +95,25 @@
     if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
       if (CAI->getDest() == allocStackAddr) {
         if (SingleWrite)
-          return SILValue();
+          return nullptr;
         SingleWrite = CAI;
         isCopied = true;
       }
       continue;
     }
+    // An unconditional_checked_cast_addr also copies a value into this addr.
+    if (auto *UCCAI = dyn_cast<UnconditionalCheckedCastAddrInst>(User)) {
+      if (UCCAI->getDest() == allocStackAddr) {
+        if (SingleWrite)
+          return nullptr;
+        SingleWrite = UCCAI;
+        isCopied = true;
+      }
+      continue;
+    }
     if (isa<InitExistentialAddrInst>(User)) {
       if (SingleWrite)
-        return SILValue();
+        return nullptr;
       SingleWrite = User;
       continue;
     }
@@ -161,17 +122,19 @@
       auto Conv = FullApplySite(User).getArgumentConvention(*Use);
       if (Conv != SILArgumentConvention::Indirect_In &&
           Conv != SILArgumentConvention::Indirect_In_Guaranteed)
-        return SILValue();
+        return nullptr;
       continue;
     }
     // Bail if there is any unknown (and potentially writing) instruction.
-    return SILValue();
+    return nullptr;
   }
   if (!SingleWrite)
-    return SILValue();
+    return nullptr;
 
   // A very simple dominance check. As ASI is an operand of ASIUser,
-  // SingleWrite dominates ASIUser if it is in the same block as ASI or ASIUser.
+  // SingleWrite dominates ASIUser if it is in the same block as ASI or
+  // ASIUser. (SingleWrite can't occur after ASIUser because the address would
+  // be uninitialized on use).
   //
   // If allocStack holds an Optional, then ASI is an InitEnumDataAddrInst
   // projection and not strictly an operand of ASIUser. We rely on the guarantee
@@ -179,127 +142,192 @@
   // that was the source of the existential address.
   SILBasicBlock *BB = SingleWrite->getParent();
   if (BB != allocStackAddr->getParentBlock() && BB != ASIUser->getParent())
+    return nullptr;
+
+  if (auto *IE = dyn_cast<InitExistentialAddrInst>(SingleWrite))
+    return IE;
+
+  if (auto *UCCA = dyn_cast<UnconditionalCheckedCastAddrInst>(SingleWrite)) {
+    assert(isCopied && "isCopied not set for a unconditional_checked_cast_addr");
+    return UCCA;
+  }
+  auto *CAI = cast<CopyAddrInst>(SingleWrite);
+  assert(isCopied && "isCopied not set for a copy_addr");
+  // Attempt to recurse to find a concrete type.
+  if (auto *ASI = dyn_cast<AllocStackInst>(CAI->getSrc()))
+    return getStackInitInst(ASI, CAI, isCopied);
+
+  // Peek through a stack location holding an Enum.
+  //   %stack_adr = alloc_stack
+  //   %data_adr  = init_enum_data_addr %stk_adr
+  //   %enum_adr  = inject_enum_addr %stack_adr
+  //   %copy_src  = unchecked_take_enum_data_addr %enum_adr
+  // Replace %copy_src with %data_adr and recurse.
+  //
+  // TODO: a general Optional elimination sil-combine could
+  // supersede this check.
+  if (auto *UTEDAI = dyn_cast<UncheckedTakeEnumDataAddrInst>(CAI->getSrc())) {
+    if (InitEnumDataAddrInst *IEDAI = findInitAddressForTrivialEnum(UTEDAI))
+      return getStackInitInst(IEDAI, CAI, isCopied);
+  }
+
+  // Check if the CAISrc is a global_addr.
+  if (auto *GAI = dyn_cast<GlobalAddrInst>(CAI->getSrc()))
+    return findInitExistentialFromGlobalAddr(GAI, CAI);
+
+  // If the source of the copy cannot be determined, return the copy itself
+  // because the caller may have special handling for the source address.
+  return CAI;
+}
+
+/// Return the address of the value used to initialize the given stack location.
+/// If the value originates from init_existential_addr, then it will be a
+/// different type than \p allocStackAddr.
+static SILValue getAddressOfStackInit(SILValue allocStackAddr,
+                                      SILInstruction *ASIUser, bool &isCopied) {
+  SILInstruction *initI = getStackInitInst(allocStackAddr, ASIUser, isCopied);
+  if (!initI)
     return SILValue();
 
-  if (auto *CAI = dyn_cast<CopyAddrInst>(SingleWrite)) {
-    // Try to derive the type from the copy_addr that was used to
-    // initialize the alloc_stack.
-    assert(isCopied && "isCopied not set for a copy_addr");
-    SILValue CAISrc = CAI->getSrc();
-    if (auto *ASI = dyn_cast<AllocStackInst>(CAISrc))
-      return getAddressOfStackInit(ASI, CAI, isCopied);
+  if (auto *IEA = dyn_cast<InitExistentialAddrInst>(initI))
+    return IEA;
 
-    // Recognize a stack location holding an Optional.
-    //   %stack_adr = alloc_stack
-    //   %data_adr  = init_enum_data_addr %stk_adr
-    //   %enum_adr  = inject_enum_addr %stack_adr
-    //   %copy_src  = unchecked_take_enum_data_addr %enum_adr
-    // Replace %copy_src with %data_adr and recurse.
-    //
-    // TODO: a general Optional elimination sil-combine could
-    // supersede this check.
-    if (auto *UTEDAI = dyn_cast<UncheckedTakeEnumDataAddrInst>(CAISrc)) {
-      if (InitEnumDataAddrInst *IEDAI = findInitAddressForTrivialEnum(UTEDAI))
-        return getAddressOfStackInit(IEDAI, CAI, isCopied);
-    }
+  if (auto *CAI = dyn_cast<CopyAddrInst>(initI))
+    return CAI->getSrc();
 
-    // Check if the CAISrc is a global_addr.
-    if (auto *GAI = dyn_cast<GlobalAddrInst>(CAISrc)) {
-      return findInitExistentialFromGlobalAddrAndCopyAddr(GAI, CAI);
-    }
-    return CAISrc;
-  }
-  return cast<InitExistentialAddrInst>(SingleWrite);
+  return SILValue();
 }
 
-/// Find the init_existential, which could be used to determine a concrete
-/// type of the \p Self.
-/// If the value is copied from another stack location, \p isCopied is set to
-/// true.
-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, User, isCopied))
-      Self = Src;
+/// Check if the given operand originates from a recognized OpenArchetype
+/// instruction. If so, return the Opened, otherwise return nullptr.
+OpenedArchetypeInfo::OpenedArchetypeInfo(Operand &use) {
+  SILValue openedVal = use.get();
+  SILInstruction *user = use.getUser();
+  if (auto *instance = dyn_cast<AllocStackInst>(openedVal)) {
+    // Handle:
+    //   %opened = open_existential_addr
+    //   %instance = alloc $opened
+    //   copy_addr %opened to %stack
+    //   <opened_use> %instance
+    if (auto stackInitVal =
+            getAddressOfStackInit(instance, user, isOpenedValueCopied)) {
+      openedVal = stackInitVal;
+    }
   }
-
-  if (auto *Open = dyn_cast<OpenExistentialAddrInst>(Self)) {
-    auto Op = Open->getOperand();
-    auto *ASI = dyn_cast<AllocStackInst>(Op);
-    if (!ASI)
-      return nullptr;
-
-    SILValue StackWrite = getAddressOfStackInit(ASI, Open, isCopied);
-    if (!StackWrite)
-      return nullptr;
-
-    auto *IE = dyn_cast<InitExistentialAddrInst>(StackWrite);
-    if (!IE)
-      return nullptr;
-
+  if (auto *Open = dyn_cast<OpenExistentialAddrInst>(openedVal)) {
     OpenedArchetype = Open->getType().castTo<ArchetypeType>();
-    OpenedArchetypeDef = Open;
-    return IE;
+    OpenedArchetypeValue = Open;
+    ExistentialValue = Open->getOperand();
+    return;
   }
-
-  if (auto *Open = dyn_cast<OpenExistentialRefInst>(Self)) {
-    if (auto *IE = dyn_cast<InitExistentialRefInst>(Open->getOperand())) {
-      OpenedArchetype = Open->getType().castTo<ArchetypeType>();
-      OpenedArchetypeDef = Open;
-      return IE;
-    }
-    return nullptr;
+  if (auto *Open = dyn_cast<OpenExistentialRefInst>(openedVal)) {
+    OpenedArchetype = Open->getType().castTo<ArchetypeType>();
+    OpenedArchetypeValue = Open;
+    ExistentialValue = Open->getOperand();
+    return;
   }
-
-  if (auto *Open = dyn_cast<OpenExistentialMetatypeInst>(Self)) {
-    if (auto *IE = dyn_cast<InitExistentialMetatypeInst>(Open->getOperand())) {
-      auto Ty = Open->getType().getASTType();
-      while (auto Metatype = dyn_cast<MetatypeType>(Ty))
-        Ty = Metatype.getInstanceType();
-      OpenedArchetype = cast<ArchetypeType>(Ty);
-      OpenedArchetypeDef = Open;
-      return IE;
-    }
-    return nullptr;
+  if (auto *Open = dyn_cast<OpenExistentialMetatypeInst>(openedVal)) {
+    auto Ty = Open->getType().getASTType();
+    while (auto Metatype = dyn_cast<MetatypeType>(Ty))
+      Ty = Metatype.getInstanceType();
+    OpenedArchetype = cast<ArchetypeType>(Ty);
+    OpenedArchetypeValue = Open;
+    ExistentialValue = Open->getOperand();
   }
-  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)
+/// Initialize ExistentialSubs from the given conformance list, using the
+/// already initialized ExistentialType and ConcreteType.
+void ConcreteExistentialInfo::initializeSubstitutionMap(
+    ArrayRef<ProtocolConformanceRef> ExistentialConformances, SILModule *M) {
+
+  // Construct a single-generic-parameter substitution map directly to the
+  // ConcreteType with this existential's full list of conformances.
+  CanGenericSignature ExistentialSig =
+      M->getASTContext().getExistentialSignature(ExistentialType,
+                                                 M->getSwiftModule());
+  ExistentialSubs = SubstitutionMap::get(ExistentialSig, {ConcreteType},
+                                         ExistentialConformances);
+  assert(isValid());
+}
+
+/// If the ConcreteType is an opened existential, also initialize
+/// ConcreteTypeDef to the definition of that type.
+void ConcreteExistentialInfo::initializeConcreteTypeDef(
+    SILInstruction *typeConversionInst) {
+  if (!ConcreteType->isOpenedExistential())
     return;
 
-  ArrayRef<ProtocolConformanceRef> ExistentialConformances;
+  assert(isValid());
 
-  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)) {
+  // 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 (!typeConversionInst->getTypeDependentOperands().empty()) {
+    ConcreteTypeDef = cast<SingleValueInstruction>(
+        typeConversionInst->getTypeDependentOperands()[0].get());
+    return;
+  }
+
+  auto typeOperand =
+      cast<InitExistentialMetatypeInst>(typeConversionInst)->getOperand();
+  assert(typeOperand->getType().hasOpenedExistential()
+         && "init_existential is supposed to have a typedef operand");
+  ConcreteTypeDef = cast<SingleValueInstruction>(typeOperand);
+}
+
+/// Construct this ConcreteExistentialInfo based on the given existential use.
+///
+/// Finds the init_existential, or an address with concrete type used to
+/// initialize the given \p openedUse. If the value is copied
+/// from another stack location, \p isCopied is set to true.
+///
+/// If successful, ConcreteExistentialInfo will be valid upon return, with the
+/// following fields assigned:
+/// - ExistentialType
+/// - isCopied
+/// - ConcreteType
+/// - ConcreteValue
+/// - ConcreteTypeDef
+/// - ExistentialSubs
+ConcreteExistentialInfo::ConcreteExistentialInfo(SILValue existential,
+                                                 SILInstruction *user) {
+  if (existential->getType().isAddress()) {
+    auto *ASI = dyn_cast<AllocStackInst>(existential);
+    if (!ASI)
+      return;
+
+    SILInstruction *stackInit =
+        getStackInitInst(ASI, user, isConcreteValueCopied);
+    if (!stackInit)
+      return;
+
+    if (auto *IE = dyn_cast<InitExistentialAddrInst>(stackInit)) {
+      ExistentialType = IE->getOperand()->getType().getASTType();
+      ConcreteType = IE->getFormalConcreteType();
+      ConcreteValue = IE;
+      initializeSubstitutionMap(IE->getConformances(), &IE->getModule());
+      initializeConcreteTypeDef(IE);
+      return;
+    }
+    // TODO: Once we have a way to introduce more constrained archetypes, handle
+    // any unconditional_checked_cast that wasn't already statically eliminated.
+    //
+    // Unexpected stack write.
+    return;
+  }
+
+  if (auto *IER = dyn_cast<InitExistentialRefInst>(existential)) {
     ExistentialType = IER->getType().getASTType();
-    ExistentialConformances = IER->getConformances();
     ConcreteType = IER->getFormalConcreteType();
     ConcreteValue = IER->getOperand();
-  } else if (auto IEM =
-                 dyn_cast<InitExistentialMetatypeInst>(InitExistential)) {
+    initializeSubstitutionMap(IER->getConformances(), &IER->getModule());
+    initializeConcreteTypeDef(IER);
+    return;
+  }
+
+  if (auto *IEM = dyn_cast<InitExistentialMetatypeInst>(existential)) {
     ExistentialType = IEM->getType().getASTType();
-    ExistentialConformances = IEM->getConformances();
     ConcreteValue = IEM->getOperand();
     ConcreteType = ConcreteValue->getType().getASTType();
     while (auto InstanceType =
@@ -307,85 +335,33 @@
       ExistentialType = InstanceType.getInstanceType();
       ConcreteType = cast<MetatypeType>(ConcreteType).getInstanceType();
     }
-  } else {
-    assert(!isValid());
+    initializeSubstitutionMap(IEM->getConformances(), &IEM->getModule());
+    initializeConcreteTypeDef(IEM);
     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());
+  // Unrecognized opened existential producer.
+  return;
 }
 
-/// Initialize a ConcreteExistentialInfo based on the already computed concrete
-/// type and protocol declaration. It determines the OpenedArchetypeDef
-/// and SubstituionMap for the ArgOperand argument.
-/// We need the OpenedArchetypeDef to be able to cast it to the concrete type.
-/// findInitExistential helps us determine this OpenedArchetypeDef. For cases
-/// where OpenedArchetypeDef can not be found from findInitExistential (because
-/// there was no InitExistential), then we do
-/// extra effort in trying to find an OpenedArchetypeDef for AllocStackInst
-/// using getAddressOfStackInit.
-ConcreteExistentialInfo::ConcreteExistentialInfo(Operand &ArgOperand,
-                                                 CanType ConcreteTy,
-                                                 ProtocolDecl *Protocol)
-    : ConcreteExistentialInfo(ArgOperand) {
-
-  // If we found an InitExistential, assert that ConcreteType we determined is
-  // same as ConcreteTy argument.
-  if (InitExistential) {
-    assert(ConcreteType == ConcreteTy);
-    assert(isValid());
-    return;
-  }
-
-  ConcreteType = ConcreteTy;
-  OpenedArchetypeDef = ArgOperand.get();
-
-  // If findInitExistential call from the other constructor did not update the
-  // OpenedArchetypeDef (because it did not find an InitExistential) and that
-  // the original Arg is an alloc_stack instruction, then we determine the
-  // OpenedArchetypeDef using getAddressOfStackInit. Please keep in mind that an
-  // alloc_stack can be an argument to apply (which could have no associated
-  // InitExistential), thus we need to determine the OpenedArchetypeDef for it.
-  // This is the extra effort.
-  SILInstruction *User = ArgOperand.getUser();
-  SILModule &M = User->getModule();
-  if (auto *ASI = dyn_cast<AllocStackInst>(OpenedArchetypeDef)) {
-    bool copied = false;
-    if (SILValue Src = getAddressOfStackInit(ASI, User, copied)) {
-      OpenedArchetypeDef = Src;
-    }
-    isCopied = copied;
-  }
-
-  // Bail, if we did not find an opened existential.
-  if (!(isa<OpenExistentialRefInst>(OpenedArchetypeDef) ||
-        isa<OpenExistentialAddrInst>(OpenedArchetypeDef)))
-    return;
+/// Initialize a ConcreteExistentialInfo based on a concrete type and protocol
+/// declaration that has already been computed via whole module type
+/// inference. A cast instruction will be introduced to produce the concrete
+/// value from the opened value.
+///
+/// The simpler constructor taking only the existential value is preferred
+/// because it generates simpler SIL and does not require an extra
+/// cast. However, if that constructor fails to produce a valid
+/// ConcreteExistentialInfo, this constructor may succeed because it doesn't
+/// needs to rediscover the whole-module inferred ConcreteTypeCandidate.
+ConcreteExistentialInfo::ConcreteExistentialInfo(SILValue existential,
+                                                 SILInstruction *user,
+                                                 CanType ConcreteTypeCandidate,
+                                                 ProtocolDecl *Protocol) {
+  SILModule *M = existential->getModule();
 
   // We have the open_existential; we still need the conformance.
   auto ConformanceRef =
-      M.getSwiftModule()->lookupConformance(ConcreteType, Protocol);
+      M->getSwiftModule()->conformsToProtocol(ConcreteTypeCandidate, Protocol);
   if (!ConformanceRef)
     return;
 
@@ -393,18 +369,40 @@
   auto *ConcreteConformance = ConformanceRef.getValue().getConcrete();
   assert(ConcreteConformance->isComplete());
 
+  ConcreteType = ConcreteTypeCandidate;
+  // There is no ConcreteValue in this case.
+
   /// Determine the ExistentialConformances and SubstitutionMap.
   ExistentialType = Protocol->getDeclaredType()->getCanonicalType();
-  auto ExistentialSig = M.getASTContext().getExistentialSignature(
-      ExistentialType, M.getSwiftModule());
-  ExistentialSubs = SubstitutionMap::get(
-      ExistentialSig, {ConcreteType},
-      llvm::makeArrayRef(ProtocolConformanceRef(ConcreteConformance)));
+  initializeSubstitutionMap(ProtocolConformanceRef(ConcreteConformance), M);
 
-  /// Determine the OpenedArchetype.
-  OpenedArchetype =
-      OpenedArchetypeDef->getType().castTo<ArchetypeType>();
-
-  /// Check validity.
   assert(isValid());
 }
+
+ConcreteOpenedExistentialInfo::ConcreteOpenedExistentialInfo(Operand &use)
+    : OAI(use) {
+  if (!OAI.isValid())
+    return;
+
+  CEI.emplace(OAI.ExistentialValue, OAI.OpenedArchetypeValue);
+  if (!CEI->isValid()) {
+    CEI.reset();
+    return;
+  }
+  CEI->isConcreteValueCopied |= OAI.isOpenedValueCopied;
+}
+
+ConcreteOpenedExistentialInfo::ConcreteOpenedExistentialInfo(
+    Operand &use, CanType concreteType, ProtocolDecl *protocol)
+    : OAI(use) {
+  if (!OAI.isValid())
+    return;
+
+  CEI.emplace(OAI.ExistentialValue, OAI.OpenedArchetypeValue, concreteType,
+              protocol);
+  if (!CEI->isValid()) {
+    CEI.reset();
+    return;
+  }
+  CEI->isConcreteValueCopied |= OAI.isOpenedValueCopied;
+}
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 3e71875..590bf2d 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1876,7 +1876,7 @@
       (isa<OverloadedDeclRefExpr>(subExpr->getValueProvidingExpr()))) {
     return subExpr;
   }
-  
+
   // Save any existing type data of the subexpr tree, and reset it to null in
   // prep for re-type-checking the tree.  If things fail, we can revert the
   // types back to their original state.
@@ -1920,9 +1920,12 @@
   // holding on to an expression containing open existential types but
   // no OpenExistentialExpr, which breaks invariants enforced by the
   // ASTChecker.
-  if (isa<OpenExistentialExpr>(subExpr))
-    eraseOpenedExistentials(CS, subExpr);
-  
+  // Another reason why we need to do this is because diagnostics might pick
+  // constraint anchor for re-typechecking which would only have opaque value
+  // expression and not enclosing open existential, which is going to trip up
+  // sanitizer.
+  eraseOpenedExistentials(CS, subExpr);
+
   // If recursive type checking failed, then an error was emitted.  Return
   // null to indicate this to the caller.
   if (!resultTy)
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 9846d3e..9c2a5e0 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -1185,9 +1185,9 @@
       auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable);
       if (!canDeriveConformance(getConformanceContext(), Nominal,
                                 hashableProto)) {
-        TC.diagnose(ConformanceDecl->getLoc(), diag::type_does_not_conform,
-                    Nominal->getDeclaredType(),
-                    hashableProto->getDeclaredType());
+        ConformanceDecl->diagnose(diag::type_does_not_conform,
+                                  Nominal->getDeclaredType(),
+                                  hashableProto->getDeclaredType());
         return nullptr;
       }
 
@@ -1213,13 +1213,13 @@
       // hashValue has an explicit implementation, but hash(into:) doesn't.
       // Emit a deprecation warning, then derive hash(into:) in terms of
       // hashValue.
-      TC.diagnose(hashValueDecl->getLoc(), diag::hashvalue_implementation,
-                  Nominal->getDeclaredType());
+      hashValueDecl->diagnose(diag::hashvalue_implementation,
+                              Nominal->getDeclaredType());
       return deriveHashable_hashInto(*this,
                                      &deriveBodyHashable_compat_hashInto);
     }
   }
 
-  TC.diagnose(requirement->getLoc(), diag::broken_hashable_requirement);
+  requirement->diagnose(diag::broken_hashable_requirement);
   return nullptr;
 }
diff --git a/lib/Sema/DerivedConformanceError.cpp b/lib/Sema/DerivedConformanceError.cpp
index 9d25faf..6cb14e4 100644
--- a/lib/Sema/DerivedConformanceError.cpp
+++ b/lib/Sema/DerivedConformanceError.cpp
@@ -22,11 +22,40 @@
 #include "swift/AST/Expr.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/Types.h"
+#include "swift/AST/SwiftNameTranslation.h"
 
 using namespace swift;
+using namespace swift::objc_translation;
 
 static void deriveBodyBridgedNSError_enum_nsErrorDomain(
-              AbstractFunctionDecl *domainDecl, void *) {
+                    AbstractFunctionDecl *domainDecl, void *) {
+  // enum SomeEnum {
+  //   @derived
+  //   static var _nsErrorDomain: String {
+  //     return String(reflecting: self)
+  //   }
+  // }
+
+  auto M = domainDecl->getParentModule();
+  auto &C = M->getASTContext();
+  auto self = domainDecl->getImplicitSelfDecl();
+
+  auto selfRef = new (C) DeclRefExpr(self, DeclNameLoc(), /*implicit*/ true);
+  auto stringType = TypeExpr::createForDecl(SourceLoc(), C.getStringDecl(),
+                                            domainDecl, /*implicit*/ true);
+  auto initReflectingCall =
+    CallExpr::createImplicit(C, stringType,
+                             { selfRef }, { C.getIdentifier("reflecting") });
+  auto ret =
+    new (C) ReturnStmt(SourceLoc(), initReflectingCall, /*implicit*/ true);
+
+  auto body = BraceStmt::create(C, SourceLoc(), ASTNode(ret), SourceLoc());
+
+  domainDecl->setBody(body);
+}
+
+static void deriveBodyBridgedNSError_printAsObjCEnum_nsErrorDomain(
+                    AbstractFunctionDecl *domainDecl, void *) {
   // enum SomeEnum {
   //   @derived
   //   static var _nsErrorDomain: String {
@@ -39,10 +68,7 @@
   auto TC = domainDecl->getInnermostTypeContext();
   auto ED = TC->getSelfEnumDecl();
 
-  std::string buffer = M->getNameStr();
-  buffer += ".";
-  buffer += ED->getNameStr();
-  StringRef value(C.AllocateCopy(buffer));
+  StringRef value(C.AllocateCopy(getErrorDomainStringForObjC(ED)));
 
   auto string = new (C) StringLiteralExpr(value, SourceRange(), /*implicit*/ true);
   auto ret = new (C) ReturnStmt(SourceLoc(), string, /*implicit*/ true);
@@ -53,17 +79,15 @@
 }
 
 static ValueDecl *
-deriveBridgedNSError_enum_nsErrorDomain(DerivedConformance &derived) {
+deriveBridgedNSError_enum_nsErrorDomain(DerivedConformance &derived,
+                        void (*synthesizer)(AbstractFunctionDecl *, void*)) {
   // enum SomeEnum {
   //   @derived
   //   static var _nsErrorDomain: String {
-  //     return "\(self)"
+  //     ...
   //   }
   // }
 
-  // Note that for @objc enums the format is assumed to be "MyModule.SomeEnum".
-  // If this changes, please change PrintAsObjC as well.
-
   ASTContext &C = derived.TC.Context;
 
   auto stringTy = C.getStringDecl()->getDeclaredType();
@@ -78,7 +102,7 @@
   // Define the getter.
   auto getterDecl = derived.addGetterToReadOnlyDerivedProperty(
       derived.TC, propDecl, stringTy);
-  getterDecl->setBodySynthesizer(&deriveBodyBridgedNSError_enum_nsErrorDomain);
+  getterDecl->setBodySynthesizer(synthesizer);
 
   derived.addMembersToConformanceContext({getterDecl, propDecl, pbDecl});
 
@@ -89,8 +113,17 @@
   if (!isa<EnumDecl>(Nominal))
     return nullptr;
 
-  if (requirement->getBaseName() == TC.Context.Id_nsErrorDomain)
-    return deriveBridgedNSError_enum_nsErrorDomain(*this);
+  if (requirement->getBaseName() == TC.Context.Id_nsErrorDomain) {
+    auto synthesizer = deriveBodyBridgedNSError_enum_nsErrorDomain;
+
+    auto scope = Nominal->getFormalAccessScope(Nominal->getModuleScopeContext());
+    if (scope.isPublic() || scope.isInternal())
+      // PrintAsObjC may print this domain, so we should make sure we use the
+      // same string it will.
+      synthesizer = deriveBodyBridgedNSError_printAsObjCEnum_nsErrorDomain;
+
+    return deriveBridgedNSError_enum_nsErrorDomain(*this, synthesizer);
+  }
 
   TC.diagnose(requirement->getLoc(), diag::broken_errortype_requirement);
   return nullptr;
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 5577763..76f0150 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -1600,6 +1600,13 @@
     }
 
     NominalTypeDecl *nominal = extension->getExtendedNominal();
+
+    // Extension is ill-formed; suppress the attribute.
+    if (!nominal) {
+      attr->setInvalid();
+      return;
+    }
+
     AccessLevel typeAccess = nominal->getFormalAccess();
     if (attr->getAccess() > typeAccess) {
       TC.diagnose(attr->getLocation(), diag::access_control_extension_more,
@@ -1992,6 +1999,16 @@
                           access);
     return;
   }
+
+  // @inlinable cannot be applied to deinitializers in resilient classes.
+  if (auto *DD = dyn_cast<DestructorDecl>(D)) {
+    if (auto *CD = dyn_cast<ClassDecl>(DD->getDeclContext())) {
+      if (CD->isResilient()) {
+        diagnoseAndRemoveAttr(attr, diag::inlinable_resilient_deinit);
+        return;
+      }
+    }
+  }
 }
 
 void AttributeChecker::visitOptimizeAttr(OptimizeAttr *attr) {
@@ -2036,8 +2053,9 @@
                              replacement->getModuleScopeContext(), nullptr,
                              attr->getLocation());
     if (lookup.isSuccess()) {
-      for (auto entry : lookup.Results)
+      for (auto entry : lookup.Results) {
         results.push_back(entry.getValueDecl());
+      }
     }
     return;
   }
@@ -2051,6 +2069,28 @@
       {typeCtx}, replacedDeclName, NL_QualifiedDefault, results);
 }
 
+/// Remove any argument labels from the interface type of the given value that
+/// are extraneous from the type system's point of view, producing the
+/// type to compare against for the purposes of dynamic replacement.
+static Type getDynamicComparisonType(ValueDecl *value) {
+  unsigned numArgumentLabels = 0;
+
+  if (isa<AbstractFunctionDecl>(value)) {
+    ++numArgumentLabels;
+
+    if (value->getDeclContext()->isTypeContext())
+      ++numArgumentLabels;
+  } else if (isa<SubscriptDecl>(value)) {
+    ++numArgumentLabels;
+  }
+
+  auto interfaceType = value->getInterfaceType();
+  if (!interfaceType)
+    return ErrorType::get(value->getASTContext());
+
+  return interfaceType->removeArgumentLabels(numArgumentLabels);
+}
+
 static FuncDecl *findReplacedAccessor(DeclName replacedVarName,
                                       AccessorDecl *replacement,
                                       DynamicReplacementAttr *attr,
@@ -2060,13 +2100,47 @@
   SmallVector<ValueDecl *, 4> results;
   lookupReplacedDecl(replacedVarName, attr, replacement, results);
 
+  // Filter out any accessors that won't work.
+  if (!results.empty()) {
+    auto replacementStorage = replacement->getStorage();
+    TC.validateDecl(replacementStorage);
+    Type replacementStorageType = getDynamicComparisonType(replacementStorage);
+    results.erase(std::remove_if(results.begin(), results.end(),
+        [&](ValueDecl *result) {
+          // Check for static/instance mismatch.
+          if (result->isStatic() != replacementStorage->isStatic())
+            return true;
+
+          // Check for type mismatch.
+          TC.validateDecl(result);
+          auto resultType = getDynamicComparisonType(result);
+          if (!resultType->isEqual(replacementStorageType)) {
+            return true;
+          }
+
+          return false;
+        }),
+        results.end());
+  }
+
   if (results.empty()) {
     TC.diagnose(attr->getLocation(),
                 diag::dynamic_replacement_accessor_not_found, replacedVarName);
     attr->setInvalid();
     return nullptr;
   }
-  assert(results.size() == 1 && "Should only have on var or fun");
+
+  if (results.size() > 1) {
+    TC.diagnose(attr->getLocation(),
+                diag::dynamic_replacement_accessor_ambiguous, replacedVarName);
+    for (auto result : results) {
+      TC.diagnose(result,
+                  diag::dynamic_replacement_accessor_ambiguous_candidate,
+                  result->getModuleContext()->getFullName());
+    }
+    attr->setInvalid();
+    return nullptr;
+  }
 
   assert(!isa<FuncDecl>(results[0]));
   TC.validateDecl(results[0]);
@@ -2117,6 +2191,10 @@
   lookupReplacedDecl(replacedFunctionName, attr, replacement, results);
 
   for (auto *result : results) {
+    // Check for static/instance mismatch.
+    if (result->isStatic() != replacement->isStatic())
+      continue;
+
     TC.validateDecl(result);
     if (result->getInterfaceType()->getCanonicalType()->matches(
             replacement->getInterfaceType()->getCanonicalType(),
@@ -2342,9 +2420,7 @@
     }
     break;
   case ReferenceOwnershipOptionality::Allowed:
-    if (!isOptional)
-      break;
-    LLVM_FALLTHROUGH;
+    break;
   case ReferenceOwnershipOptionality::Required:
     if (var->isLet()) {
       diagnose(var->getStartLoc(), diag::invalid_ownership_is_let,
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 7c9a114..0a6d3f8 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -2356,31 +2356,29 @@
     ConstraintLocator *Locator;
 
     /// The type of the initializer.
-    llvm::PointerIntPair<Type, 1, bool> InitTypeAndInOut;
+    Type initType;
 
   public:
     explicit BindingListener(Pattern *&pattern, Expr *&initializer)
       : pattern(pattern), initializer(initializer),
-        Locator(nullptr), InitTypeAndInOut(Type(), false) { }
+        Locator(nullptr) { }
 
-    Type getInitType() const { return InitTypeAndInOut.getPointer(); }
-    bool isInOut() const { return InitTypeAndInOut.getInt(); }
+    Type getInitType() const { return initType; }
 
     bool builtConstraints(ConstraintSystem &cs, Expr *expr) override {
+      assert(!expr->isSemanticallyInOutExpr());
+
       // Save the locator we're using for the expression.
       Locator = cs.getConstraintLocator(expr);
 
       // Collect constraints from the pattern.
-      InitTypeAndInOut.setPointer(cs.generateConstraints(pattern, Locator));
-      InitTypeAndInOut.setInt(expr->isSemanticallyInOutExpr());
-      if (!InitTypeAndInOut.getPointer())
+      initType = cs.generateConstraints(pattern, Locator);
+      if (!initType)
         return true;
 
-      assert(!InitTypeAndInOut.getPointer()->is<InOutType>());
       // Add a conversion constraint between the types.
       cs.addConstraint(ConstraintKind::Conversion, cs.getType(expr),
-                       InitTypeAndInOut.getPointer(), Locator,
-                       /*isFavored*/true);
+                       initType, Locator, /*isFavored*/true);
 
       // The expression has been pre-checked; save it in case we fail later.
       initializer = expr;
@@ -2389,10 +2387,8 @@
 
     Expr *foundSolution(Solution &solution, Expr *expr) override {
       // Figure out what type the constraints decided on.
-      auto ty = solution.simplifyType(InitTypeAndInOut.getPointer());
-      InitTypeAndInOut.setPointer(
-          ty->getRValueType()->reconstituteSugar(/*recursive =*/false));
-      InitTypeAndInOut.setInt(expr->isSemanticallyInOutExpr());
+      auto ty = solution.simplifyType(initType);
+      initType = ty->getRValueType()->reconstituteSugar(/*recursive =*/false);
 
       // Just keep going.
       return expr;
@@ -2400,14 +2396,12 @@
 
     Expr *appliedSolution(Solution &solution, Expr *expr) override {
       // Convert the initializer to the type of the pattern.
-      // ignoreTopLevelInjection = Binding->isConditional()
-      expr = solution.coerceToType(expr, InitTypeAndInOut.getPointer(), Locator,
+      expr = solution.coerceToType(expr, initType, Locator,
                                    false /* ignoreTopLevelInjection */);
-      if (!expr) {
+      if (!expr)
         return nullptr;
-      }
 
-      assert(solution.getConstraintSystem().getType(expr)->isEqual(InitTypeAndInOut.getPointer()));
+      assert(solution.getConstraintSystem().getType(expr)->isEqual(initType));
 
       initializer = expr;
       return expr;
@@ -2442,7 +2436,6 @@
   // Type-check the initializer.
   auto resultTy = typeCheckExpression(initializer, DC, contextualType,
                                       contextualPurpose, flags, &listener);
-  assert(!listener.isInOut());
 
   if (resultTy) {
     TypeResolutionOptions options =
@@ -2491,7 +2484,6 @@
 
 bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
                                           unsigned patternNumber) {
-  auto &ctx = PBD->getASTContext();
   const auto &pbe = PBD->getPatternList()[patternNumber];
   Pattern *pattern = PBD->getPattern(patternNumber);
   Expr *init = PBD->getInit(patternNumber);
@@ -2514,30 +2506,8 @@
   PBD->setPattern(patternNumber, pattern, initContext);
   PBD->setInit(patternNumber, init);
 
-  // Add the attribute that preserves the "has an initializer" value across
-  // module generation, as required for TBDGen.
-  PBD->getPattern(patternNumber)->forEachVariable([&](VarDecl *VD) {
-    if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasInitialValueAttr>())
-      VD->getAttrs().add(new (ctx) HasInitialValueAttr(/*IsImplicit=*/true));
-  });
-
-  if (!hadError) {
-    // If we're performing an binding to a weak or unowned variable from a
-    // constructor call, emit a warning that the instance will be immediately
-    // deallocated.
-    diagnoseUnownedImmediateDeallocation(*this, pattern, pbe.getEqualLoc(),
-                                         init);
-
-    // If we entered an initializer context, contextualize any
-    // auto-closures we might have created.
-    if (initContext) {
-      // Check safety of error-handling in the declaration, too.
-      checkInitializerErrorHandling(initContext, init);
-      (void)contextualizeInitializer(initContext, init);
-    }
-  } else {
+  if (hadError)
     PBD->setInvalid();
-  }
 
   PBD->setInitializerChecked(patternNumber);
   return hadError;
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index b3b40fd..7a6fbb7 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -30,6 +30,7 @@
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/GenericSignatureBuilder.h"
+#include "swift/AST/Initializer.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/ProtocolConformance.h"
@@ -2120,14 +2121,17 @@
   }
 
   void visitBoundVariable(VarDecl *VD) {
-    TC.validateDecl(VD);
-
-    // Set up accessors.
-    maybeAddAccessorsToStorage(VD);
-
     // WARNING: Anything you put in this function will only be run when the
     // VarDecl is fully type-checked within its own file. It will NOT be run
     // when the VarDecl is merely used from another file.
+    TC.validateDecl(VD);
+
+    // Set up accessors, also lowering lazy and @NSManaged properties.
+    maybeAddAccessorsToStorage(VD);
+
+    // Add the '@_hasStorage' attribute if this property is stored.
+    if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
+      VD->getAttrs().add(new (TC.Context) HasStorageAttr(/*isImplicit=*/true));
 
     // Reject cases where this is a variable that has storage but it isn't
     // allowed.
@@ -2223,16 +2227,17 @@
           .fixItRemove(attr->getRange());
       }
     }
-  }
 
+    if (VD->getAttrs().hasAttribute<DynamicReplacementAttr>())
+      TC.checkDynamicReplacementAttribute(VD);
+  }
 
   void visitBoundVars(Pattern *P) {
     P->forEachVariable([&] (VarDecl *VD) { this->visitBoundVariable(VD); });
   }
 
   void visitPatternBindingDecl(PatternBindingDecl *PBD) {
-    if (PBD->isBeingValidated())
-      return;
+    DeclContext *DC = PBD->getDeclContext();
 
     // Check all the pattern/init pairs in the PBD.
     validatePatternBindingEntries(TC, PBD);
@@ -2250,10 +2255,6 @@
           PBD->getPattern(i)->hasStorage() &&
           !PBD->getPattern(i)->getType()->hasError()) {
 
-        // If we have a type-adjusting attribute (like ownership), apply it now.
-        if (auto var = PBD->getSingleVar())
-          TC.checkTypeModifyingDeclAttributes(var);
-
         // Decide whether we should suppress default initialization.
         //
         // Note: Swift 4 had a bug where properties with a desugared optional
@@ -2280,15 +2281,27 @@
           // If we got a default initializer, install it and re-type-check it
           // to make sure it is properly coerced to the pattern type.
           PBD->setInit(i, defaultInit);
-          TC.typeCheckPatternBinding(PBD, i);
         }
       }
+
+      if (PBD->getInit(i)) {
+        // Add the attribute that preserves the "has an initializer" value across
+        // module generation, as required for TBDGen.
+        PBD->getPattern(i)->forEachVariable([&](VarDecl *VD) {
+          if (VD->hasStorage() &&
+              !VD->getAttrs().hasAttribute<HasInitialValueAttr>()) {
+            auto *attr = new (TC.Context) HasInitialValueAttr(
+                /*IsImplicit=*/true);
+            VD->getAttrs().add(attr);
+          }
+        });
+      }
     }
 
     bool isInSILMode = false;
-    if (auto sourceFile = PBD->getDeclContext()->getParentSourceFile())
+    if (auto sourceFile = DC->getParentSourceFile())
       isInSILMode = sourceFile->Kind == SourceFileKind::SIL;
-    bool isTypeContext = PBD->getDeclContext()->isTypeContext();
+    bool isTypeContext = DC->isTypeContext();
 
     // If this is a declaration without an initializer, reject code if
     // uninitialized vars are not allowed.
@@ -2305,8 +2318,6 @@
         if (var->isInvalid() || PBD->isInvalid())
           return;
 
-        auto *varDC = var->getDeclContext();
-
         auto markVarAndPBDInvalid = [PBD, var] {
           PBD->setInvalid();
           var->setInvalid();
@@ -2324,9 +2335,9 @@
 
         // Static/class declarations require an initializer unless in a
         // protocol.
-        if (var->isStatic() && !isa<ProtocolDecl>(varDC)) {
+        if (var->isStatic() && !isa<ProtocolDecl>(DC)) {
           // ...but don't enforce this for SIL or parseable interface files.
-          switch (varDC->getParentSourceFile()->Kind) {
+          switch (DC->getParentSourceFile()->Kind) {
           case SourceFileKind::Interface:
           case SourceFileKind::SIL:
             return;
@@ -2343,8 +2354,8 @@
         }
 
         // Global variables require an initializer in normal source files.
-        if (varDC->isModuleScopeContext()) {
-          switch (varDC->getParentSourceFile()->Kind) {
+        if (DC->isModuleScopeContext()) {
+          switch (DC->getParentSourceFile()->Kind) {
           case SourceFileKind::Main:
           case SourceFileKind::REPL:
           case SourceFileKind::Interface:
@@ -2368,8 +2379,35 @@
 
     // If the initializers in the PBD aren't checked yet, do so now.
     for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
-      if (!PBD->isInitializerChecked(i) && PBD->getInit(i))
+      if (!PBD->getInit(i))
+        continue;
+
+      if (!PBD->isInitializerChecked(i))
         TC.typeCheckPatternBinding(PBD, i);
+
+      if (!PBD->isInvalid()) {
+        auto &entry = PBD->getPatternList()[i];
+        auto *init = PBD->getInit(i);
+
+        // If we're performing an binding to a weak or unowned variable from a
+        // constructor call, emit a warning that the instance will be immediately
+        // deallocated.
+        diagnoseUnownedImmediateDeallocation(TC, PBD->getPattern(i),
+                                              entry.getEqualLoc(),
+                                              init);
+
+        // If we entered an initializer context, contextualize any
+        // auto-closures we might have created.
+        if (!DC->isLocalContext()) {
+          auto *initContext = cast_or_null<PatternBindingInitializer>(
+              entry.getInitContext());
+          if (initContext) {
+            // Check safety of error-handling in the declaration, too.
+            TC.checkInitializerErrorHandling(initContext, init);
+            (void) TC.contextualizeInitializer(initContext, init);
+          }
+        }
+      }
     }
   }
 
@@ -2845,12 +2883,6 @@
   void visitVarDecl(VarDecl *VD) {
     // Delay type-checking on VarDecls until we see the corresponding
     // PatternBindingDecl.
-
-    // Except if there is a dynamic replacement attribute.
-    if (VD->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
-      TC.validateDecl(VD);
-      TC.checkDynamicReplacementAttribute(VD);
-    }
   }
 
   /// Determine whether the given declaration requires a definition.
@@ -3699,10 +3731,6 @@
     auto *VD = cast<VarDecl>(D);
     auto *PBD = VD->getParentPatternBinding();
 
-    // Add the '@_hasStorage' attribute if this property is stored.
-    if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
-      VD->getAttrs().add(new (Context) HasStorageAttr(/*isImplicit=*/true));
-
     // Note that we need to handle the fact that some VarDecls don't
     // have a PatternBindingDecl, for example the iterator in a
     // 'for ... in ...' loop.
diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp
index 1396b8e..6196585 100644
--- a/lib/Sema/TypeCheckDeclObjC.cpp
+++ b/lib/Sema/TypeCheckDeclObjC.cpp
@@ -1066,6 +1066,21 @@
     if (VD->getFormalAccess() <= AccessLevel::FilePrivate)
       return false;
 
+    if (auto accessor = dyn_cast<AccessorDecl>(VD)) {
+      switch (accessor->getAccessorKind()) {
+      case AccessorKind::DidSet:
+      case AccessorKind::Modify:
+      case AccessorKind::Read:
+      case AccessorKind::WillSet:
+        return false;
+
+      case AccessorKind::MutableAddress:
+      case AccessorKind::Address:
+      case AccessorKind::Get:
+      case AccessorKind::Set:
+        break;
+      }
+    }
     return true;
   };
 
@@ -1106,7 +1121,7 @@
        cast<ExtensionDecl>(VD->getDeclContext())->getAttrs()
         .hasAttribute<NonObjCAttr>()))
     return None;
-  if (isMemberOfObjCClassExtension(VD))
+  if (isMemberOfObjCClassExtension(VD) && canInferImplicitObjC())
     return ObjCReason(ObjCReason::MemberOfObjCExtension);
   if (isMemberOfObjCMembersClass(VD) && canInferImplicitObjC())
     return ObjCReason(ObjCReason::MemberOfObjCMembersClass);
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index b5616e7..133ddda 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -967,9 +967,12 @@
   assert(requirement->isProtocolRequirement());
   auto *PD = cast<ProtocolDecl>(requirement->getDeclContext());
   if (auto A = witness->getAttrs().getAttribute<ImplementsAttr>()) {
-    Type T = A->getProtocolType().getType();
-    if (T->castTo<ProtocolType>()->getDecl() == PD) {
-      return A->getMemberName() == requirement->getFullName();
+    if (Type T = A->getProtocolType().getType()) {
+      if (auto ProtoTy = T->getAs<ProtocolType>()) {
+        if (ProtoTy->getDecl() == PD) {
+          return A->getMemberName() == requirement->getFullName();
+        }
+      }
     }
   }
   return false;
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 8f6abea..5dfdd56 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1180,12 +1180,11 @@
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
     bool isLifetimeGuaranteed = Attr & 0x01;
-    bool isEscaped = Attr & 0x02;
     ResultVal = Builder.createConvertEscapeToNoEscape(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2)),
-        getSILType(MF->getType(TyID), (SILValueCategory)TyCategory), isEscaped,
+        getSILType(MF->getType(TyID), (SILValueCategory)TyCategory),
         isLifetimeGuaranteed);
     break;
   }
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index a60842c..ab159da 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -1489,8 +1489,6 @@
     if (SI.getKind() == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
       if (cast<ConvertEscapeToNoEscapeInst>(SI).isLifetimeGuaranteed())
         attrs |= 0x01;
-      if (cast<ConvertEscapeToNoEscapeInst>(SI).isEscapedByUser())
-        attrs |= 0x02;
     }
     if (SI.getKind() == SILInstructionKind::ConvertFunctionInst) {
       if (cast<ConvertFunctionInst>(SI).withoutActuallyEscaping())
diff --git a/stdlib/private/StdlibUnittest/CMakeLists.txt b/stdlib/private/StdlibUnittest/CMakeLists.txt
index c57d075..ffac1c3 100644
--- a/stdlib/private/StdlibUnittest/CMakeLists.txt
+++ b/stdlib/private/StdlibUnittest/CMakeLists.txt
@@ -10,8 +10,6 @@
   list(APPEND swift_stdlib_unittest_compile_flags "-DSWIFT_STDLIB_DEBUG")
 endif()
 
-# TODO: support this on non-POSIX platforms.  It cannot be currently as it
-# depends on pthreads.
 add_swift_target_library(swiftStdlibUnittest ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
   # This file should be listed the first.  Module name is inferred from the
   # filename.
@@ -42,7 +40,8 @@
   SWIFT_MODULE_DEPENDS_FREEBSD Glibc
   SWIFT_MODULE_DEPENDS_CYGWIN Glibc
   SWIFT_MODULE_DEPENDS_HAIKU Glibc
+  SWIFT_MODULE_DEPENDS_WINDOWS MSVCRT WinSDK
   SWIFT_COMPILE_FLAGS ${swift_stdlib_unittest_compile_flags}
-  TARGET_SDKS ALL_POSIX_PLATFORMS
   INSTALL_IN_COMPONENT stdlib-experimental)
+set_source_files_properties(InspectValue.cpp PROPERTIES COMPILE_FLAGS -std=c++14)
 
diff --git a/stdlib/private/StdlibUnittest/InterceptTraps.cpp b/stdlib/private/StdlibUnittest/InterceptTraps.cpp
index e8f7987..377397b 100644
--- a/stdlib/private/StdlibUnittest/InterceptTraps.cpp
+++ b/stdlib/private/StdlibUnittest/InterceptTraps.cpp
@@ -13,7 +13,16 @@
 #include <stdio.h>
 #include <signal.h>
 #include <string.h>
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 #include <unistd.h>
+#endif
+#if defined(_WIN32)
+#include <io.h>
+#include <process.h>
+#include <stdlib.h>
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#endif
 
 #include "swift/Runtime/Config.h"
 
@@ -21,29 +30,60 @@
   const char *Msg;
   switch (Sig) {
     case SIGILL:  Msg = "CRASHED: SIGILL\n";  break;
-    case SIGTRAP: Msg = "CRASHED: SIGTRAP\n"; break;
     case SIGABRT: Msg = "CRASHED: SIGABRT\n"; break;
     case SIGFPE:  Msg = "CRASHED: SIGFPE\n";  break;
-    case SIGBUS:  Msg = "CRASHED: SIGBUS\n";  break;
     case SIGSEGV: Msg = "CRASHED: SIGSEGV\n"; break;
+#if !defined(_WIN32)
+    case SIGTRAP: Msg = "CRASHED: SIGTRAP\n"; break;
+    case SIGBUS:  Msg = "CRASHED: SIGBUS\n";  break;
     case SIGSYS:  Msg = "CRASHED: SIGSYS\n";  break;
+#endif
     default:      Msg = "CRASHED: SIG????\n"; break;
   }
+#if defined(_WIN32)
+  _write(_fileno(stderr), Msg, strlen(Msg));
+#else
   write(STDERR_FILENO, Msg, strlen(Msg));
+#endif
   _exit(0);
 }
 
+#if defined(_WIN32)
+static LONG WINAPI
+VectoredCrashHandler(PEXCEPTION_POINTERS ExceptionInfo) {
+  switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
+  case EXCEPTION_ILLEGAL_INSTRUCTION:
+    _write(_fileno(stderr), "CRASHED: SIGTRAP\n", 17);
+    _exit(0);
+
+  case EXCEPTION_DATATYPE_MISALIGNMENT:
+    _write(_fileno(stderr), "CRASHED: SIGBUS\n", 16);
+    _exit(0);
+  }
+
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
 SWIFT_CC(swift) SWIFT_RUNTIME_LIBRARY_VISIBILITY extern "C"
 void installTrapInterceptor() {
   // Disable buffering on stdout so that everything is printed before crashing.
   setbuf(stdout, 0);
 
+#if defined(_WIN32)
+  _set_abort_behavior(0, _WRITE_ABORT_MSG);
+#endif
+
   signal(SIGILL,  CrashCatcher);
-  signal(SIGTRAP, CrashCatcher);
   signal(SIGABRT, CrashCatcher);
   signal(SIGFPE,  CrashCatcher);
-  signal(SIGBUS,  CrashCatcher);
   signal(SIGSEGV, CrashCatcher);
+#if defined(_WIN32)
+  AddVectoredExceptionHandler(TRUE, VectoredCrashHandler);
+#else
+  signal(SIGTRAP, CrashCatcher);
+  signal(SIGBUS,  CrashCatcher);
   signal(SIGSYS,  CrashCatcher);
+#endif
 }
 
diff --git a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift
index b3ec509..d4202a7 100644
--- a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift
+++ b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift
@@ -71,7 +71,7 @@
 @inline(never)
 public func getFloat64(_ x: Float64) -> Float64 { return _opaqueIdentity(x) }
 
-#if arch(i386) || arch(x86_64)
+#if !os(Windows) && (arch(i386) || arch(x86_64))
 @inline(never)
 public func getFloat80(_ x: Float80) -> Float80 { return _opaqueIdentity(x) }
 #endif
diff --git a/stdlib/private/StdlibUnittest/RaceTest.swift b/stdlib/private/StdlibUnittest/RaceTest.swift
index a36e706..1db9947 100644
--- a/stdlib/private/StdlibUnittest/RaceTest.swift
+++ b/stdlib/private/StdlibUnittest/RaceTest.swift
@@ -43,6 +43,9 @@
 import Darwin
 #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
 import Glibc
+#elseif os(Windows)
+import MSVCRT
+import WinSDK
 #endif
 
 #if _runtime(_ObjC)
@@ -508,6 +511,36 @@
 }
 
 /// One-shot sleep in one thread, allowing interrupt by another.
+#if os(Windows)
+class _InterruptibleSleep {
+  let event: HANDLE?
+  var completed: Bool = false
+
+  init() {
+    self.event = CreateEventW(nil, TRUE, FALSE, nil)
+    precondition(self.event != nil)
+  }
+
+  deinit {
+    CloseHandle(self.event)
+  }
+
+  func sleep(durationInSeconds duration: Int) {
+    guard completed == false else { return }
+
+    let result: DWORD = WaitForSingleObject(event, DWORD(duration * 1000))
+    precondition(result == WAIT_OBJECT_0)
+
+    completed = true
+  }
+
+  func wake() {
+    guard completed == false else { return }
+    let result: BOOL = SetEvent(self.event)
+    precondition(result == TRUE)
+  }
+}
+#else
 class _InterruptibleSleep {
   let writeEnd: CInt
   let readEnd: CInt
@@ -550,6 +583,13 @@
     precondition(ret >= 0)
   }
 }
+#endif
+
+#if os(Windows)
+typealias ThreadHandle = HANDLE
+#else
+typealias ThreadHandle = pthread_t
+#endif
 
 public func runRaceTest<RT : RaceTestWithPerTrialData>(
   _: RT.Type,
@@ -600,8 +640,8 @@
     _ = timeoutReached.fetchAndAdd(1)
   }
 
-  var testTids = [pthread_t]()
-  var alarmTid: pthread_t
+  var testTids = [ThreadHandle]()
+  var alarmTid: ThreadHandle
 
   // Create the master thread.
   do {
diff --git a/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift b/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift
index 5159289..6d9260e 100644
--- a/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift
+++ b/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift
@@ -16,6 +16,8 @@
 import Darwin
 #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
 import Glibc
+#elseif os(Windows)
+import MSVCRT
 #endif
 
 #if _runtime(_ObjC)
@@ -73,6 +75,7 @@
 #endif
 }
 
+#if !os(Windows)
 public func createTemporaryFile(
   _ fileNamePrefix: String, _ fileNameSuffix: String, _ contents: String
 ) -> String {
@@ -95,6 +98,7 @@
   }
   return fileName
 }
+#endif
 
 public final class Box<T> {
   public init(_ value: T) { self.value = value }
diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift b/stdlib/private/StdlibUnittest/StdlibUnittest.swift
index c28affd..f7e1d9a 100644
--- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift
+++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift
@@ -19,6 +19,9 @@
 import Darwin
 #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Cygwin) || os(Haiku)
 import Glibc
+#elseif os(Windows)
+import MSVCRT
+import WinSDK
 #endif
 
 #if _runtime(_ObjC)
@@ -718,7 +721,11 @@
   var isSwiftTrap: Bool {
     switch self {
     case .signal(let signal):
+#if os(Windows)
+      return CInt(signal) == SIGILL
+#else
       return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
+#endif
     default:
       // This default case is needed for standard library builds where
       // resilience is enabled.
@@ -749,12 +756,21 @@
 func _printDebuggingAdvice(_ fullTestName: String) {
   print("To debug, run:")
   var invocation = [CommandLine.arguments[0]]
+#if os(Windows)
+  var buffer: UnsafeMutablePointer<CChar>?
+  var length: Int = 0
+  if _dupenv_s(&buffer, &length, "SWIFT_INTERPRETER") != 0, let buffer = buffer {
+    invocation.insert(String(cString: buffer), at: 0)
+    free(buffer)
+  }
+#else
   let interpreter = getenv("SWIFT_INTERPRETER")
   if interpreter != nil {
     if let interpreterCmd = String(validatingUTF8: interpreter!) {
         invocation.insert(interpreterCmd, at: 0)
     }
   }
+#endif
   print("$ \(invocation.joined(separator: " ")) " +
     "--stdlib-unittest-in-process --stdlib-unittest-filter \"\(fullTestName)\"")
 }
@@ -829,11 +845,21 @@
   }
 }
 
-struct _ParentProcess {
+class _ParentProcess {
+#if os(Windows)
+  internal var _process: HANDLE = INVALID_HANDLE_VALUE
+  internal var _childStdin: _FDOutputStream =
+      _FDOutputStream(handle: INVALID_HANDLE_VALUE)
+  internal var _childStdout: _FDInputStream =
+      _FDInputStream(handle: INVALID_HANDLE_VALUE)
+  internal var _childStderr: _FDInputStream =
+      _FDInputStream(handle: INVALID_HANDLE_VALUE)
+#else
   internal var _pid: pid_t?
   internal var _childStdin: _FDOutputStream = _FDOutputStream(fd: -1)
   internal var _childStdout: _FDInputStream = _FDInputStream(fd: -1)
   internal var _childStderr: _FDInputStream = _FDInputStream(fd: -1)
+#endif
 
   internal var _runTestsInProcess: Bool
   internal var _filter: String?
@@ -845,16 +871,32 @@
     self._args = args
   }
 
-  mutating func _spawnChild() {
+  func _spawnChild() {
     let params = ["--stdlib-unittest-run-child"] + _args
+#if os(Windows)
+    let (hProcess, hStdIn, hStdOut, hStdErr) = spawnChild(params)
+    self._process = hProcess
+    self._childStdin = _FDOutputStream(handle: hStdIn)
+    self._childStdout = _FDInputStream(handle: hStdOut)
+    self._childStderr = _FDInputStream(handle: hStdErr)
+#else
     let (pid, childStdinFD, childStdoutFD, childStderrFD) = spawnChild(params)
     _pid = pid
     _childStdin = _FDOutputStream(fd: childStdinFD)
     _childStdout = _FDInputStream(fd: childStdoutFD)
     _childStderr = _FDInputStream(fd: childStderrFD)
+#endif
   }
 
-  mutating func _waitForChild() -> ProcessTerminationStatus {
+  func _waitForChild() -> ProcessTerminationStatus {
+#if os(Windows)
+    let status = waitProcess(_process)
+    _process = INVALID_HANDLE_VALUE
+
+    _childStdin.close()
+    _childStdout.close()
+    _childStderr.close()
+#else
     let status = posixWaitpid(_pid!)
     _pid = nil
     _childStdin.close()
@@ -863,13 +905,40 @@
     _childStdin = _FDOutputStream(fd: -1)
     _childStdout = _FDInputStream(fd: -1)
     _childStderr = _FDInputStream(fd: -1)
+#endif
     return status
   }
 
-  internal mutating func _readFromChild(
-    onStdoutLine: (String) -> (done: Bool, Void),
-    onStderrLine: (String) -> (done: Bool, Void)
+  internal func _readFromChild(
+    onStdoutLine: @escaping (String) -> (done: Bool, Void),
+    onStderrLine: @escaping (String) -> (done: Bool, Void)
   ) {
+#if os(Windows)
+    let (_, stdoutThread) = _stdlib_thread_create_block({
+      while !self._childStdout.isEOF {
+        self._childStdout.read()
+        while let line = self._childStdout.getline() {
+          var done: Bool
+          (done: done, ()) = onStdoutLine(line)
+          if done { return }
+        }
+      }
+    }, ())
+
+    let (_, stderrThread) = _stdlib_thread_create_block({
+      while !self._childStderr.isEOF {
+        self._childStderr.read()
+        while let line = self._childStderr.getline() {
+          var done: Bool
+          (done: done, ()) = onStderrLine(line)
+          if done { return }
+        }
+      }
+    }, ())
+
+    let (_, _) = _stdlib_thread_join(stdoutThread!, Void.self)
+    let (_, _) = _stdlib_thread_join(stderrThread!, Void.self)
+#else
     var readfds = _stdlib_fd_set()
     var writefds = _stdlib_fd_set()
     var errorfds = _stdlib_fd_set()
@@ -907,19 +976,26 @@
         continue
       }
     }
+#endif
   }
 
   /// Returns the values of the corresponding variables in the child process.
-  internal mutating func _runTestInChild(
+  internal func _runTestInChild(
     _ testSuite: TestSuite,
     _ testName: String,
     parameter: Int?
   ) -> (anyExpectFailed: Bool, seenExpectCrash: Bool,
         status: ProcessTerminationStatus?,
         crashStdout: [Substring], crashStderr: [Substring]) {
+#if os(Windows)
+    if _process == INVALID_HANDLE_VALUE {
+      _spawnChild()
+    }
+#else
     if _pid == nil {
       _spawnChild()
     }
+#endif
 
     print("\(testSuite.name);\(testName)", terminator: "", to: &_childStdin)
     if let parameter = parameter {
@@ -953,6 +1029,8 @@
                               omittingEmptySubsequences: false)
         switch controlMessage[1] {
         case "expectCrash":
+          fallthrough
+        case "expectCrash\r":
           if isStdout {
             stdoutSeenCrashDelimiter = true
             anyExpectFailedInChild = controlMessage[2] == "true"
@@ -961,6 +1039,8 @@
             expectingPreCrashMessage = String(controlMessage[2])
           }
         case "end":
+          fallthrough
+        case "end\r":
           if isStdout {
             stdoutEnd = true
             anyExpectFailedInChild = controlMessage[2] == "true"
@@ -972,7 +1052,11 @@
         }
         line = line[line.startIndex..<index]
         if line.isEmpty {
+#if os(Windows)
+          return (done: isStdout ? stdoutEnd : stderrEnd, ())
+#else
           return (done: stdoutEnd && stderrEnd, ())
+#endif
         }
       }
       if !expectingPreCrashMessage.isEmpty
@@ -1006,7 +1090,11 @@
       } else {
         print("stderr>>> \(line)")
       }
+#if os(Windows)
+      return (done: isStdout ? stdoutEnd : stderrEnd, ())
+#else
       return (done: stdoutEnd && stderrEnd, ())
+#endif
     }
 
     _readFromChild(
@@ -1042,12 +1130,20 @@
       status, capturedCrashStdout, capturedCrashStderr)
   }
 
-  internal mutating func _shutdownChild() -> (failed: Bool, Void) {
+  internal func _shutdownChild() -> (failed: Bool, Void) {
+#if os(Windows)
+    if _process == INVALID_HANDLE_VALUE {
+      // The child process is not running.  Report that it didn't fail during
+      // shutdown.
+      return (failed: false, ())
+    }
+#else
     if _pid == nil {
       // The child process is not running.  Report that it didn't fail during
       // shutdown.
       return (failed: false, ())
     }
+#endif
     print("\(_stdlibUnittestStreamPrefix);shutdown", to: &_childStdin)
 
     var childCrashed = false
@@ -1086,7 +1182,7 @@
     case xFail
   }
 
-  internal mutating func runOneTest(
+  internal func runOneTest(
     fullTestName: String,
     testSuite: TestSuite,
     test t: TestSuite._Test,
@@ -1172,7 +1268,7 @@
     }
   }
 
-  mutating func run() {
+  func run() {
     if let filter = _filter {
       print("StdlibUnittest: using filter: \(filter)")
     }
@@ -1347,7 +1443,7 @@
       i += 1
     }
 
-    var parent = _ParentProcess(
+    let parent = _ParentProcess(
       runTestsInProcess: runTestsInProcess, args: args, filter: filter)
     parent.run()
   }
diff --git a/stdlib/private/SwiftPrivate/CMakeLists.txt b/stdlib/private/SwiftPrivate/CMakeLists.txt
index 30dc0f2..9f229ef 100644
--- a/stdlib/private/SwiftPrivate/CMakeLists.txt
+++ b/stdlib/private/SwiftPrivate/CMakeLists.txt
@@ -11,7 +11,7 @@
   IO.swift
   ShardedAtomicCounter.swift
 
-  SWIFT_MODULE_DEPENDS_WINDOWS MSVCRT
+  SWIFT_MODULE_DEPENDS_WINDOWS MSVCRT WinSDK
   SWIFT_COMPILE_FLAGS ${swift_swiftprivate_compile_flags}
   INSTALL_IN_COMPONENT stdlib-experimental)
 
diff --git a/stdlib/private/SwiftPrivate/IO.swift b/stdlib/private/SwiftPrivate/IO.swift
index baaf6e8..b55ddd1 100644
--- a/stdlib/private/SwiftPrivate/IO.swift
+++ b/stdlib/private/SwiftPrivate/IO.swift
@@ -13,6 +13,73 @@
 import Swift
 import SwiftShims
 
+#if os(Windows)
+import MSVCRT
+import WinSDK
+#endif
+
+#if os(Windows)
+public struct _FDInputStream {
+  public var handle: HANDLE = INVALID_HANDLE_VALUE
+  public var isEOF: Bool = false
+  public var isClosed: Bool { return handle == INVALID_HANDLE_VALUE }
+
+  internal var _buffer: ContiguousArray<UInt8> =
+      ContiguousArray<UInt8>(repeating: 0, count: 256)
+  internal var _offset: Int = 0
+
+  public init(handle: HANDLE) {
+    self.handle = handle
+  }
+
+  public mutating func getline() -> String? {
+    // FIXME(compnerd) Windows uses \r\n for the line delimiter, we should split
+    // on that and remove the workaround in the test harness
+    if let index =
+        _buffer[0..<_offset].firstIndex(of: UInt8(Unicode.Scalar("\n").value)) {
+      let result = String(decoding: _buffer[0..<index], as: UTF8.self)
+      _buffer.removeSubrange(0...index)
+      _offset -= index + 1
+      return result
+    }
+    if isEOF && _offset > 0 {
+      let result = String(decoding: _buffer[0..<_offset], as: UTF8.self)
+      _buffer.removeAll()
+      _offset = 0
+      return result
+    }
+    return nil
+  }
+
+  public mutating func read() {
+    var space = _buffer.count - _offset
+    if space < 128 {
+      let capacity = _buffer.count + (128 - space)
+      _buffer.reserveCapacity(capacity)
+      for _ in _buffer.count..<capacity {
+        _buffer.append(0)
+      }
+      space = 128
+    }
+    let read: Int = _buffer.withUnsafeMutableBufferPointer { buffer in
+      var read: DWORD = 0
+      ReadFile(handle, buffer.baseAddress! + _offset, DWORD(space), &read, nil)
+      return Int(read)
+    }
+    if read == 0 {
+      isEOF = true
+    } else {
+      _offset += read
+    }
+  }
+
+  public mutating func close() {
+    if isClosed { return }
+    CloseHandle(handle)
+    handle = INVALID_HANDLE_VALUE
+  }
+}
+#else
 public struct _FDInputStream {
   public let fd: CInt
   public var isClosed: Bool = false
@@ -79,6 +146,7 @@
     isClosed = true
   }
 }
+#endif
 
 public struct _Stderr : TextOutputStream {
   public init() {}
@@ -90,6 +158,37 @@
   }
 }
 
+#if os(Windows)
+public struct _FDOutputStream : TextOutputStream {
+  public var handle: HANDLE
+
+  public init(handle: HANDLE) {
+    self.handle = handle
+  }
+
+  public mutating func write(_ string: String) {
+    string.utf8CString.withUnsafeBufferPointer { buffer in
+      let dwLength: DWORD = DWORD(buffer.count - 1)
+      var dwOffset: DWORD = 0
+      while dwOffset < dwLength {
+        var dwBytesWritten: DWORD = 0
+        if WriteFile(handle,
+                     UnsafeRawPointer(buffer.baseAddress! + Int(dwOffset)),
+                     dwLength - dwOffset, &dwBytesWritten, nil) == FALSE {
+          fatalError("WriteFile() failed")
+        }
+        dwOffset += dwBytesWritten
+      }
+    }
+  }
+
+  public mutating func close() {
+    if handle == INVALID_HANDLE_VALUE { return }
+    CloseHandle(handle)
+    handle = INVALID_HANDLE_VALUE
+  }
+}
+#else
 public struct _FDOutputStream : TextOutputStream {
   public let fd: CInt
   public var isClosed: Bool = false
@@ -127,3 +226,4 @@
     isClosed = true
   }
 }
+#endif
diff --git a/stdlib/public/Darwin/Foundation/NSDictionary.swift b/stdlib/public/Darwin/Foundation/NSDictionary.swift
index 4d2ec75..2b5b58b 100644
--- a/stdlib/public/Darwin/Foundation/NSDictionary.swift
+++ b/stdlib/public/Darwin/Foundation/NSDictionary.swift
@@ -61,6 +61,140 @@
                          to: NSDictionary.self)
   }
 
+  /***
+  Precondition: `buffer` points to a region of memory bound to `AnyObject`,
+    with a capacity large enough to fit at least `index`+1 elements of type `T`
+  
+  _bridgeInitialize rebinds the `index`th `T` of `buffer` to `T`,
+    and initializes it to `value`
+
+  Note: *not* the `index`th element of `buffer`, since T and AnyObject may be
+  different sizes. e.g. if T is String (2 words) then given a buffer like so:
+
+  [object:AnyObject, object:AnyObject, uninitialized, uninitialized]
+
+  `_bridgeInitialize(1, of: buffer, to: buffer[1] as! T)` will leave it as:
+
+  [object:AnyObject, object:AnyObject, string:String]
+
+  and `_bridgeInitialize(0, of: buffer, to: buffer[0] as! T)` will then leave:
+
+  [string:String, string:String]
+
+  Doing this in reverse order as shown above is required if T and AnyObject are
+  different sizes. Here's what we get if instead of 1, 0 we did 0, 1:
+
+  [object:AnyObject, object:AnyObject, uninitialized, uninitialized]
+  [string:String, uninitialized, uninitialized]
+  <segfault trying to treat the second word of 'string' as an AnyObject>
+
+  Note: if you have retained any of the objects in `buffer`, you must release
+  them separately, _bridgeInitialize will overwrite them without releasing them
+  */
+  @inline(__always)
+  private static func _bridgeInitialize<T>(index:Int,
+    of buffer: UnsafePointer<AnyObject>, to value: T) {
+    let typedBase = UnsafeMutableRawPointer(mutating:
+                      buffer).assumingMemoryBound(to: T.self)
+    let rawTarget = UnsafeMutableRawPointer(mutating: typedBase + index)
+    rawTarget.initializeMemory(as: T.self, repeating: value, count: 1)
+  }
+
+  @inline(__always)
+  private static func _verbatimForceBridge<T>(
+    _ buffer: UnsafeMutablePointer<AnyObject>,
+    count: Int,
+    to: T.Type
+  ) {
+    //doesn't have to iterate in reverse because sizeof(T) == sizeof(AnyObject)
+    for i in 0..<count {
+      _bridgeInitialize(index: i, of: buffer, to: buffer[i] as! T)
+    }
+  }
+
+  @inline(__always)
+  private static func _verbatimBridge<T>(
+    _ buffer: UnsafeMutablePointer<AnyObject>,
+    count: Int,
+    to type: T.Type
+  ) -> Int {
+    var numUninitialized = count
+    while numUninitialized > 0 {
+      guard let bridged = buffer[numUninitialized - 1] as? T else {
+        return numUninitialized
+      }
+      numUninitialized -= 1
+      _bridgeInitialize(index: numUninitialized, of: buffer, to: bridged)
+    }
+    return numUninitialized
+  }
+
+  @inline(__always)
+  private static func _nonVerbatimForceBridge<T>(
+    _ buffer: UnsafeMutablePointer<AnyObject>,
+    count: Int,
+    to: T.Type
+  ) {
+    for i in (0..<count).reversed() {
+      let bridged = Swift._forceBridgeFromObjectiveC(buffer[i], T.self)
+      _bridgeInitialize(index: i, of: buffer, to: bridged)
+    }
+  }
+  
+  @inline(__always)
+  private static func _nonVerbatimBridge<T>(
+    _ buffer: UnsafeMutablePointer<AnyObject>,
+    count: Int,
+    to: T.Type
+  ) -> Int {
+    var numUninitialized = count
+    while numUninitialized > 0 {
+      guard let bridged = Swift._conditionallyBridgeFromObjectiveC(
+        buffer[numUninitialized - 1], T.self)
+        else {
+        return numUninitialized
+      }
+      numUninitialized -= 1
+      _bridgeInitialize(index: numUninitialized, of: buffer, to: bridged)
+    }
+    return numUninitialized
+  }
+
+  @inline(__always)
+  private static func _forceBridge<T>(
+    _ buffer: UnsafeMutablePointer<AnyObject>,
+    count: Int,
+    to: T.Type
+  ) {
+    if _isBridgedVerbatimToObjectiveC(T.self) {
+      _verbatimForceBridge(buffer, count: count, to: T.self)
+    } else {
+      _nonVerbatimForceBridge(buffer, count: count, to: T.self)
+    }
+  }
+  
+  @inline(__always)
+  private static func _conditionallyBridge<T>(
+    _ buffer: UnsafeMutablePointer<AnyObject>,
+    count: Int,
+    to: T.Type
+  ) -> Bool {
+    let numUninitialized:Int
+    if _isBridgedVerbatimToObjectiveC(T.self) {
+      numUninitialized = _verbatimBridge(buffer, count: count, to: T.self)
+    } else {
+      numUninitialized = _nonVerbatimBridge(buffer, count: count, to: T.self)
+    }
+    if numUninitialized == 0 {
+      return true
+    }
+    let numInitialized = count - numUninitialized
+    (UnsafeMutableRawPointer(mutating: buffer).assumingMemoryBound(to:
+      T.self) + numUninitialized).deinitialize(count: numInitialized)
+    return false
+  }
+
+  @_specialize(where Key == String, Value == Any)
   public static func _forceBridgeFromObjectiveC(
     _ d: NSDictionary,
     result: inout Dictionary?
@@ -73,53 +207,120 @@
 
     if _isBridgedVerbatimToObjectiveC(Key.self) &&
        _isBridgedVerbatimToObjectiveC(Value.self) {
+      //Lazily type-checked on access
       result = [Key : Value](_cocoaDictionary: d)
       return
     }
 
-    if Key.self == String.self {
+    let keyStride = MemoryLayout<Key>.stride
+    let valueStride = MemoryLayout<Value>.stride
+    let objectStride = MemoryLayout<AnyObject>.stride
+
+    //If Key or Value are smaller than AnyObject, a Dictionary with N elements
+    //doesn't have large enough backing stores to hold the objects to be bridged
+    //For now we just handle that case the slow way.
+    if keyStride < objectStride || valueStride < objectStride {
+      var builder = _DictionaryBuilder<Key, Value>(count: d.count)
+      d.enumerateKeysAndObjects({ (anyKey: Any, anyValue: Any, _) in
+        let anyObjectKey = anyKey as AnyObject
+        let anyObjectValue = anyValue as AnyObject
+        builder.add(
+            key: Swift._forceBridgeFromObjectiveC(anyObjectKey, Key.self),
+            value: Swift._forceBridgeFromObjectiveC(anyObjectValue, Value.self))
+      })
+      result = builder.take()
+    } else {
+      defer { _fixLifetime(d) }
+    
+      let numElems = d.count
+      
       // String and NSString have different concepts of equality, so
       // string-keyed NSDictionaries may generate key collisions when bridged
       // over to Swift. See rdar://problem/35995647
-      var dict = Dictionary(minimumCapacity: d.count)
-      d.enumerateKeysAndObjects({ (anyKey: Any, anyValue: Any, _) in
-        let key = Swift._forceBridgeFromObjectiveC(
-          anyKey as AnyObject, Key.self)
-        let value = Swift._forceBridgeFromObjectiveC(
-          anyValue as AnyObject, Value.self)
-        // FIXME: Log a warning if `dict` already had a value for `key`
-        dict[key] = value
-      })
-      result = dict
-      return
+      let handleDuplicates = (Key.self == String.self)
+      
+      result = Dictionary(_unsafeUninitializedCapacity: numElems,
+        allowingDuplicates: handleDuplicates) { (keys, vals, outCount) in
+        
+        let objectKeys = UnsafeMutableRawPointer(mutating:
+          keys.baseAddress!).assumingMemoryBound(to: AnyObject.self)
+        let objectVals = UnsafeMutableRawPointer(mutating:
+          vals.baseAddress!).assumingMemoryBound(to: AnyObject.self)
+
+        //This initializes the first N AnyObjects of the Dictionary buffers.
+        //Any unused buffer space is left uninitialized
+        //This is fixed up in-place as we bridge elements, by _bridgeInitialize
+        __NSDictionaryGetObjects(d, objectVals, objectKeys, numElems)
+
+        _forceBridge(objectKeys, count: numElems, to: Key.self)
+        _forceBridge(objectVals, count: numElems, to: Value.self)
+        
+        outCount = numElems
+      }
     }
-
-    // `Dictionary<Key, Value>` where either `Key` or `Value` is a value type
-    // may not be backed by an NSDictionary.
-    var builder = _DictionaryBuilder<Key, Value>(count: d.count)
-    d.enumerateKeysAndObjects({ (anyKey: Any, anyValue: Any, _) in
-      let anyObjectKey = anyKey as AnyObject
-      let anyObjectValue = anyValue as AnyObject
-      builder.add(
-          key: Swift._forceBridgeFromObjectiveC(anyObjectKey, Key.self),
-          value: Swift._forceBridgeFromObjectiveC(anyObjectValue, Value.self))
-    })
-    result = builder.take()
   }
-
+  
+  @_specialize(where Key == String, Value == Any)
   public static func _conditionallyBridgeFromObjectiveC(
     _ x: NSDictionary,
     result: inout Dictionary?
   ) -> Bool {
-    let anyDict = x as [NSObject : AnyObject]
-    if _isBridgedVerbatimToObjectiveC(Key.self) &&
-       _isBridgedVerbatimToObjectiveC(Value.self) {
-      result = Swift._dictionaryDownCastConditional(anyDict)
+
+    if let native = [Key : Value]._bridgeFromObjectiveCAdoptingNativeStorageOf(
+        x as AnyObject) {
+      result = native
+      return true
+    }
+
+    let keyStride = MemoryLayout<Key>.stride
+    let valueStride = MemoryLayout<Value>.stride
+    let objectStride = MemoryLayout<AnyObject>.stride
+
+    //If Key or Value are smaller than AnyObject, a Dictionary with N elements
+    //doesn't have large enough backing stores to hold the objects to be bridged
+    //For now we just handle that case the slow way.
+    if keyStride < objectStride || valueStride < objectStride {
+      result = x as [NSObject : AnyObject] as? Dictionary
       return result != nil
     }
 
-    result = anyDict as? Dictionary
-    return result != nil
+    defer { _fixLifetime(x) }
+    
+    let numElems = x.count
+    var success = true
+    
+    // String and NSString have different concepts of equality, so
+    // string-keyed NSDictionaries may generate key collisions when bridged
+    // over to Swift. See rdar://problem/35995647
+    let handleDuplicates = (Key.self == String.self)
+    
+    let tmpResult = Dictionary(_unsafeUninitializedCapacity: numElems,
+      allowingDuplicates: handleDuplicates) { (keys, vals, outCount) in
+      
+      let objectKeys = UnsafeMutableRawPointer(mutating:
+        keys.baseAddress!).assumingMemoryBound(to: AnyObject.self)
+      let objectVals = UnsafeMutableRawPointer(mutating:
+        vals.baseAddress!).assumingMemoryBound(to: AnyObject.self)
+
+      //This initializes the first N AnyObjects of the Dictionary buffers.
+      //Any unused buffer space is left uninitialized
+      //This is fixed up in-place as we bridge elements, by _bridgeInitialize
+      __NSDictionaryGetObjects(x, objectVals, objectKeys, numElems)
+
+      success = _conditionallyBridge(objectKeys, count: numElems, to: Key.self)
+      if success {
+        success = _conditionallyBridge(objectVals,
+                                       count: numElems, to: Value.self)
+        if !success {
+          (UnsafeMutableRawPointer(mutating: objectKeys).assumingMemoryBound(to:
+            Key.self)).deinitialize(count: numElems)
+        }
+      }
+      outCount = success ? numElems : 0
+    }
+    
+    result = success ? tmpResult : nil
+    return success
   }
 
   @_effects(readonly)
diff --git a/stdlib/public/Platform/msvcrt.swift b/stdlib/public/Platform/msvcrt.swift
index 6970e41..18d9f99 100644
--- a/stdlib/public/Platform/msvcrt.swift
+++ b/stdlib/public/Platform/msvcrt.swift
@@ -13,3 +13,74 @@
 @_exported import ucrt // Clang module
 @_exported import visualc // Clang module
 
+@available(swift, deprecated: 3.0, message: "Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.")
+public let M_PI = Double.pi
+@available(swift, deprecated: 3.0, message: "Please use 'Double.pi / 2' or '.pi / 2' to get the value of correct type and avoid casting.")
+public let M_PI_2 = Double.pi / 2
+@available(swift, deprecated: 3.0, message: "Please use 'Double.pi / 4' or '.pi / 4' to get the value of correct type and avoid casting.")
+public let M_PI_4 = Double.pi / 4
+
+@available(swift, deprecated: 3.0, message: "Please use 2.squareRoot()'.")
+public let M_SQRT2 = 2.squareRoot()
+
+@available(swift, deprecated: 3.0, message: "Please use 0.5.squareRoot()'.")
+public let M_SQRT1_2 = 0.5.squareRoot()
+
+@available(swift, deprecated: 3.0, message: "Please use 'T.radix' to get the radix of a FloatingPoint type 'T'.")
+public let FLT_RADIX = Double.radix
+
+//  Where does the 1 come from? C counts the usually-implicit leading
+//  significand bit, but Swift does not. Neither is really right or wrong.
+@available(swift, deprecated: 3.0, message: "Please use 'Float.significandBitCount + 1'.")
+public let FLT_MANT_DIG = Float.significandBitCount + 1
+
+//  Where does the 1 come from? C models floating-point numbers as having a
+//  significand in [0.5, 1), but Swift (following IEEE 754) considers the
+//  significand to be in [1, 2). This rationale applies to FLT_MIN_EXP
+//  as well.
+@available(swift, deprecated: 3.0, message: "Please use 'Float.greatestFiniteMagnitude.exponent + 1'.")
+public let FLT_MAX_EXP = Float.greatestFiniteMagnitude.exponent + 1
+
+@available(swift, deprecated: 3.0, message: "Please use 'Float.leastNormalMagnitude.exponent + 1'.")
+public let FLT_MIN_EXP = Float.leastNormalMagnitude.exponent + 1
+
+@available(swift, deprecated: 3.0, message: "Please use 'Float.greatestFiniteMagnitude' or '.greatestFiniteMagnitude'.")
+public let FLT_MAX = Float.greatestFiniteMagnitude
+
+@available(swift, deprecated: 3.0, message: "Please use 'Float.ulpOfOne' or '.ulpOfOne'.")
+public let FLT_EPSILON = Float.ulpOfOne
+
+@available(swift, deprecated: 3.0, message: "Please use 'Float.leastNormalMagnitude' or '.leastNormalMagnitude'.")
+public let FLT_MIN = Float.leastNormalMagnitude
+
+@available(swift, deprecated: 3.0, message: "Please use 'Float.leastNonzeroMagnitude' or '.leastNonzeroMagnitude'.")
+public let FLT_TRUE_MIN = Float.leastNonzeroMagnitude
+
+
+//  Where does the 1 come from? C counts the usually-implicit leading
+//  significand bit, but Swift does not. Neither is really right or wrong.
+@available(swift, deprecated: 3.0, message: "Please use 'Double.significandBitCount + 1'.")
+public let DBL_MANT_DIG = Double.significandBitCount + 1
+
+//  Where does the 1 come from? C models floating-point numbers as having a
+//  significand in [0.5, 1), but Swift (following IEEE 754) considers the
+//  significand to be in [1, 2). This rationale applies to DBL_MIN_EXP
+//  as well.
+@available(swift, deprecated: 3.0, message: "Please use 'Double.greatestFiniteMagnitude.exponent + 1'.")
+public let DBL_MAX_EXP = Double.greatestFiniteMagnitude.exponent + 1
+
+@available(swift, deprecated: 3.0, message: "Please use 'Double.leastNormalMagnitude.exponent + 1'.")
+public let DBL_MIN_EXP = Double.leastNormalMagnitude.exponent + 1
+
+@available(swift, deprecated: 3.0, message: "Please use 'Double.greatestFiniteMagnitude' or '.greatestFiniteMagnitude'.")
+public let DBL_MAX = Double.greatestFiniteMagnitude
+
+@available(swift, deprecated: 3.0, message: "Please use 'Double.ulpOfOne' or '.ulpOfOne'.")
+public let DBL_EPSILON = Double.ulpOfOne
+
+@available(swift, deprecated: 3.0, message: "Please use 'Double.leastNormalMagnitude' or '.leastNormalMagnitude'.")
+public let DBL_MIN = Double.leastNormalMagnitude
+
+@available(swift, deprecated: 3.0, message: "Please use 'Double.leastNonzeroMagnitude' or '.leastNonzeroMagnitude'.")
+public let DBL_TRUE_MIN = Double.leastNonzeroMagnitude
+
diff --git a/stdlib/public/Platform/winsdk.modulemap b/stdlib/public/Platform/winsdk.modulemap
index e4d925b..a27f903 100644
--- a/stdlib/public/Platform/winsdk.modulemap
+++ b/stdlib/public/Platform/winsdk.modulemap
@@ -30,6 +30,12 @@
       export *
     }
 
+    // api-ms-win-heapapi-l1-1-0.dll
+    module heap {
+      header "heapapi.h"
+      export *
+    }
+
     // api-ms-win-core-interlocked-l1-1-0.dll
     module interlocked {
       header "interlockedapi.h"
@@ -48,6 +54,12 @@
       export *
     }
 
+    // api-ms-win-core-Path-l1-0.dll
+    module path {
+      header "PathCch.h"
+      export *
+    }
+
     // api-ms-win-core-processthreads-l1-1-2.dll
     module processthreads {
       header "processthreadsapi.h"
@@ -73,5 +85,9 @@
     }
   }
 
+  module Shell {
+    header "ShlObj.h"
+    export *
+  }
 }
 
diff --git a/stdlib/public/SwiftShims/CMakeLists.txt b/stdlib/public/SwiftShims/CMakeLists.txt
index 60779b3..fdfde20 100644
--- a/stdlib/public/SwiftShims/CMakeLists.txt
+++ b/stdlib/public/SwiftShims/CMakeLists.txt
@@ -86,11 +86,12 @@
 
 # Function to find LLVM or Clang headers
 function(find_llvm_clang_headers suffix description out_var)
+  file(TO_CMAKE_PATH "${SWIFT_PATH_TO_CLANG_BUILD}" PATH_TO_CLANG_BUILD)
+
   set(headers_locations
       "${LLVM_LIBRARY_DIR}${suffix}"
-
-      "${SWIFT_PATH_TO_CLANG_BUILD}/${CMAKE_CFG_INTDIR}/lib${suffix}"
-      "${SWIFT_PATH_TO_CLANG_BUILD}/${LLVM_BUILD_TYPE}/lib${suffix}")
+      "${PATH_TO_CLANG_BUILD}/${CMAKE_CFG_INTDIR}/lib${suffix}"
+      "${PATH_TO_CLANG_BUILD}/${LLVM_BUILD_TYPE}/lib${suffix}")
 
   set(headers_location)
   foreach(loc ${headers_locations})
@@ -150,7 +151,9 @@
 # Possibly install Clang headers under Clang's resource directory in case we
 # need to use a different version of the headers than the installed Clang. This
 # should be used in conjunction with clang-resource-dir-symlink.
+file(TO_CMAKE_PATH "${SWIFT_PATH_TO_CLANG_BUILD}"
+  _SWIFT_SHIMS_PATH_TO_CLANG_BUILD)
 swift_install_in_component(clang-builtin-headers-in-clang-resource-dir
-    DIRECTORY "${SWIFT_PATH_TO_CLANG_BUILD}/lib/clang"
+    DIRECTORY "${_SWIFT_SHIMS_PATH_TO_CLANG_BUILD}/lib/clang"
     DESTINATION "lib"
     PATTERN "*.h")
diff --git a/stdlib/public/SwiftShims/LibcOverlayShims.h b/stdlib/public/SwiftShims/LibcOverlayShims.h
index b11f54b..a4ec144 100644
--- a/stdlib/public/SwiftShims/LibcOverlayShims.h
+++ b/stdlib/public/SwiftShims/LibcOverlayShims.h
@@ -21,9 +21,8 @@
 #include "Visibility.h"
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
+#include <errno.h>
 #include <io.h>
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
 typedef int mode_t;
 #else
 #include <semaphore.h>
diff --git a/stdlib/public/SwiftShims/RuntimeShims.h b/stdlib/public/SwiftShims/RuntimeShims.h
index e108947..dc31840 100644
--- a/stdlib/public/SwiftShims/RuntimeShims.h
+++ b/stdlib/public/SwiftShims/RuntimeShims.h
@@ -56,6 +56,26 @@
 SWIFT_RUNTIME_STDLIB_API
 __swift_size_t _swift_stdlib_getHardwareConcurrency();
 
+/// Manually allocated memory is at least 16-byte aligned in Swift.
+///
+/// When swift_slowAlloc is called with "default" alignment (alignMask ==
+/// ~(size_t(0))), it will execute the "aligned allocation path" (AlignedAlloc)
+/// using this value for the alignment.
+///
+/// This is done so users do not need to specify the allocation alignment when
+/// manually deallocating memory via Unsafe[Raw][Buffer]Pointer. Any
+/// user-specified alignment less than or equal to _swift_MinAllocationAlignment
+/// results in a runtime request for "default" alignment. This guarantees that
+/// manual allocation always uses an "aligned" runtime allocation. If an
+/// allocation is "aligned" then it must be freed using an "aligned"
+/// deallocation. The converse must also hold. Since manual Unsafe*Pointer
+/// deallocation is always "aligned", the user never needs to specify alignment
+/// during deallocation.
+///
+/// This value is inlined (and constant propagated) in user code. On Windows,
+/// the Swift runtime and user binaries need to agree on this value.
+#define _swift_MinAllocationAlignment (__swift_size_t) 16
+
 #ifdef __cplusplus
 }} // extern "C", namespace swift
 #endif
diff --git a/stdlib/public/SwiftShims/Target.h b/stdlib/public/SwiftShims/Target.h
index f2a3870..265b847 100644
--- a/stdlib/public/SwiftShims/Target.h
+++ b/stdlib/public/SwiftShims/Target.h
@@ -26,6 +26,8 @@
 #if __has_builtin(__is_target_environment)
 # if __is_target_environment(simulator)
 #  define SWIFT_TARGET_OS_SIMULATOR 1
+# else
+#  define SWIFT_TARGET_OS_SIMULATOR 0
 # endif
 #endif
 
diff --git a/stdlib/public/Windows/WinSDK.swift b/stdlib/public/Windows/WinSDK.swift
index b38159b..a71cf3a 100644
--- a/stdlib/public/Windows/WinSDK.swift
+++ b/stdlib/public/Windows/WinSDK.swift
@@ -30,3 +30,6 @@
 // minwindef.h
 public let TRUE: BOOL = 1
 
+// handleapi.h
+public let INVALID_HANDLE_VALUE: HANDLE = HANDLE(bitPattern: -1)!
+
diff --git a/stdlib/public/core/AtomicInt.swift.gyb b/stdlib/public/core/AtomicInt.swift.gyb
index 6a20166..17d3484 100644
--- a/stdlib/public/core/AtomicInt.swift.gyb
+++ b/stdlib/public/core/AtomicInt.swift.gyb
@@ -72,8 +72,10 @@
 }
 
 
-@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
-internal func _swift_stdlib_atomicLoadInt(
+// FIXME: ideally it should not be here, at the very least not public, but
+// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
+public // Existing uses outside stdlib
+func _swift_stdlib_atomicLoadInt(
   object target: UnsafeMutablePointer<Int>) -> Int {
 #if arch(i386) || arch(arm)
   let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
@@ -97,8 +99,10 @@
 
 % for operation in ['Add', 'And', 'Or', 'Xor']:
 // Warning: no overflow checking.
-@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
-internal func _swift_stdlib_atomicFetch${operation}Int(
+// FIXME: ideally it should not be here, at the very least not public, but
+// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
+public // Existing uses outside stdlib
+func _swift_stdlib_atomicFetch${operation}Int(
   object target: UnsafeMutablePointer<Int>,
   operand: Int) -> Int {
   let rawTarget = UnsafeMutableRawPointer(target)
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index f5f8fda..761df17 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -242,8 +242,6 @@
   return Builtin.castReference(x)
 }
 
-import SwiftShims
-
 @inlinable
 @inline(__always)
 public func _getUnsafePointerToStoredProperties(_ x: AnyObject)
@@ -255,6 +253,18 @@
     storedPropertyOffset
 }
 
+/// Get the minimum alignment for manually allocated memory.
+///
+/// Memory allocated via UnsafeMutable[Raw][Buffer]Pointer must never pass
+/// an alignment less than this value to Builtin.allocRaw. This
+/// ensures that the memory can be deallocated without specifying the
+/// alignment.
+@inlinable
+@inline(__always)
+internal func _minAllocationAlignment() -> Int {
+  return _swift_MinAllocationAlignment
+}
+
 //===----------------------------------------------------------------------===//
 // Branch hints
 //===----------------------------------------------------------------------===//
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index e0cc9f2..7dfaece 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -220,7 +220,7 @@
 set(swift_core_framework_depends)
 set(swift_core_private_link_libraries)
 set(swift_stdlib_compile_flags "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}")
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+if(SWIFT_PRIMARY_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS)
   list(APPEND swift_core_link_flags "-all_load")
   list(APPEND swift_core_framework_depends Foundation)
   list(APPEND swift_core_framework_depends CoreFoundation)
@@ -238,24 +238,21 @@
   #set(LINK_FLAGS
   #  -Wl,--whole-archive swiftRuntime -Wl,--no-whole-archive)
   if("${SWIFT_PATH_TO_LIBICU_BUILD}" STREQUAL "")
-    list(APPEND swift_core_private_link_libraries
-      ICU_UC ICU_I18N)
+    list(APPEND swift_core_private_link_libraries ICU_UC ICU_I18N)
   else()
     list(APPEND swift_core_private_link_libraries -licui18nswift -licuucswift -licudataswift)
   endif()
 endif()
 
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
-  execute_process(COMMAND "cygpath" "-u" "$ENV{SYSTEMROOT}"
-      OUTPUT_VARIABLE ENV_SYSTEMROOT)
-
-  list(APPEND swift_core_link_flags "${ENV_SYSTEMROOT}/system32/psapi.dll")
+  # TODO(compnerd) cache this variable to permit re-configuration
+  execute_process(COMMAND "cygpath" "-u" "$ENV{SYSTEMROOT}" OUTPUT_VARIABLE ENV_SYSTEMROOT)
+  list(APPEND swift_core_private_link_libraries "${ENV_SYSTEMROOT}/system32/psapi.dll")
 endif()
 
-if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+if(SWIFT_PRIMARY_VARIANT_SDK STREQUAL FREEBSD)
   find_library(EXECINFO_LIBRARY execinfo)
-  list(APPEND swift_core_private_link_libraries
-      ${EXECINFO_LIBRARY})
+  list(APPEND swift_core_private_link_libraries ${EXECINFO_LIBRARY})
 endif()
 
 option(SWIFT_CHECK_ESSENTIAL_STDLIB
@@ -280,11 +277,11 @@
 
 
 set(shared_only_libs)
-if(SWIFT_BUILD_STATIC_STDLIB AND "${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX")
+if(SWIFT_BUILD_STATIC_STDLIB AND "${SWIFT_PRIMARY_VARIANT_SDK}" STREQUAL "LINUX")
    list(APPEND swift_core_private_link_libraries swiftImageInspectionShared)
 endif()
 
-if(SWIFT_PRIMARY_VARIANT_SDK STREQUAL Windows)
+if(SWIFT_PRIMARY_VARIANT_SDK STREQUAL WINDOWS)
   list(APPEND swift_core_private_link_libraries shell32)
 endif()
 
diff --git a/stdlib/public/core/CharacterProperties.swift b/stdlib/public/core/CharacterProperties.swift
index 4e1c0c5..0232d11 100644
--- a/stdlib/public/core/CharacterProperties.swift
+++ b/stdlib/public/core/CharacterProperties.swift
@@ -22,15 +22,31 @@
     ) == self.unicodeScalars.endIndex
   }
 
-  /// Whether this Character is ASCII.
+  /// A Boolean value indicating whether this is an ASCII character.
   @inlinable
   public var isASCII: Bool {
     return asciiValue != nil
   }
 
-  /// Returns the ASCII encoding value of this Character, if ASCII.
+  /// The ASCII encoding value of this character, if it is an ASCII character.
   ///
-  /// Note: "\r\n" (CR-LF) is normalized to "\n" (LF), which will return 0x0A
+  ///     let chars: [Character] = ["a", " ", "™"]
+  ///     for ch in chars {
+  ///         print(ch, "-->", ch.properties.numericValue)
+  ///     }
+  ///     // a --> 97
+  ///     //   --> 32
+  ///     // ™ --> nil
+  ///
+  /// A character with the value "\r\n" (CR-LF) is normalized to "\n" (LF) and
+  /// has an `asciiValue` property equal to 10.
+  ///
+  ///     let cr = "\r" as Character
+  ///     // cr.asciiValue == 13
+  ///     let lf = "\n" as Character
+  ///     // lf.asciiValue == 10
+  ///     let crlf = "\r\n" as Character
+  ///     // crlf.asciiValue == 10
   @inlinable
   public var asciiValue: UInt8? {
     if _slowPath(self == "\r\n") { return 0x000A /* LINE FEED (LF) */ }
@@ -38,30 +54,31 @@
     return UInt8(_firstScalar.value)
   }
 
-  /// Whether this Character represents whitespace, including newlines.
+  /// A Boolean value indicating whether this character represents whitespace,
+  /// including newlines.
   ///
-  /// Examples:
-  ///   * "\t" (U+0009 CHARACTER TABULATION)
-  ///   * " " (U+0020 SPACE)
-  ///   * U+2029 PARAGRAPH SEPARATOR
-  ///   * U+3000 IDEOGRAPHIC SPACE
+  /// For example, the following characters all represent whitespace:
   ///
+  /// - "\t" (U+0009 CHARACTER TABULATION)
+  /// - " " (U+0020 SPACE)
+  /// - U+2029 PARAGRAPH SEPARATOR
+  /// - U+3000 IDEOGRAPHIC SPACE
   public var isWhitespace: Bool {
     return _firstScalar.properties.isWhitespace
   }
 
-  /// Whether this Character represents a newline.
+  /// A Boolean value indicating whether this character represents a newline.
   ///
-  /// Examples:
-  ///   * "\n" (U+000A): LINE FEED (LF)
-  ///   * U+000B: LINE TABULATION (VT)
-  ///   * U+000C: FORM FEED (FF)
-  ///   * "\r" (U+000D): CARRIAGE RETURN (CR)
-  ///   * "\r\n" (U+000A U+000D): CR-LF
-  ///   * U+0085: NEXT LINE (NEL)
-  ///   * U+2028: LINE SEPARATOR
-  ///   * U+2029: PARAGRAPH SEPARATOR
+  /// For example, the following characters all represent newlines:
   ///
+  /// - "\n" (U+000A): LINE FEED (LF)
+  /// - U+000B: LINE TABULATION (VT)
+  /// - U+000C: FORM FEED (FF)
+  /// - "\r" (U+000D): CARRIAGE RETURN (CR)
+  /// - "\r\n" (U+000D U+000A): CR-LF
+  /// - U+0085: NEXT LINE (NEL)
+  /// - U+2028: LINE SEPARATOR
+  /// - U+2029: PARAGRAPH SEPARATOR
   @inlinable
   public var isNewline: Bool {
     switch _firstScalar.value {
@@ -73,54 +90,78 @@
     }
   }
 
-  /// Whether this Character represents a number.
+  /// A Boolean value indicating whether this character represents a number.
   ///
-  /// Examples:
-  ///   * "7" (U+0037 DIGIT SEVEN)
-  ///   * "⅚" (U+215A VULGAR FRACTION FIVE SIXTHS)
-  ///   * "㊈" (U+3288 CIRCLED IDEOGRAPH NINE)
-  ///   * "𝟠" (U+1D7E0 MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT)
-  ///   * "๒" (U+0E52 THAI DIGIT TWO)
+  /// For example, the following characters all represent numbers:
   ///
+  /// - "7" (U+0037 DIGIT SEVEN)
+  /// - "⅚" (U+215A VULGAR FRACTION FIVE SIXTHS)
+  /// - "㊈" (U+3288 CIRCLED IDEOGRAPH NINE)
+  /// - "𝟠" (U+1D7E0 MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT)
+  /// - "๒" (U+0E52 THAI DIGIT TWO)
   public var isNumber: Bool {
     return _firstScalar.properties.numericType != nil
   }
 
-  /// Whether this Character represents a whole number. See
-  /// `Character.wholeNumberValue`
+  /// A Boolean value indicating whether this character represents a whole
+  /// number.
+  ///
+  /// For example, the following characters all represent whole numbers:
+  ///
+  /// - "1" (U+0031 DIGIT ONE) => 1
+  /// - "५" (U+096B DEVANAGARI DIGIT FIVE) => 5
+  /// - "๙" (U+0E59 THAI DIGIT NINE) => 9
+  /// - "万" (U+4E07 CJK UNIFIED IDEOGRAPH-4E07) => 10_000
   @inlinable
   public var isWholeNumber: Bool {
     return wholeNumberValue != nil
   }
 
-  /// If this Character is a whole number, return the value it represents, else
-  /// nil.
+  /// The numeric value this character represents, if it represents a whole
+  /// number.
   ///
-  /// Examples:
-  ///   * "1" (U+0031 DIGIT ONE) => 1
-  ///   * "५" (U+096B DEVANAGARI DIGIT FIVE) => 5
-  ///   * "๙" (U+0E59 THAI DIGIT NINE) => 9
-  ///   * "万" (U+4E07 CJK UNIFIED IDEOGRAPH-4E07) => 10_000
+  /// If this character does not represent a whole number, or the value is too
+  /// large to represent as an `Int`, the value of this property is `nil`.
   ///
-  /// Note: Returns nil on 32-bit platforms if the result would overflow `Int`.
+  ///     let chars: [Character] = ["4", "④", "万", "a"]
+  ///     for ch in chars {
+  ///         print(ch, "-->", ch.properties.numericValue)
+  ///     }
+  ///     // 4 --> 4
+  ///     // ④ --> 4
+  ///     // 万 --> 10000
+  ///     // a --> nil
   public var wholeNumberValue: Int? {
     guard _isSingleScalar else { return nil }
     guard let value = _firstScalar.properties.numericValue else { return nil }
     return Int(exactly: value)
   }
 
-  /// Whether this Character represents a hexadecimal digit.
+  /// A Boolean value indicating whether this character represents a
+  /// hexadecimal digit.
   ///
   /// Hexadecimal digits include 0-9, Latin letters a-f and A-F, and their
-  /// fullwidth compatibility forms. To get their value, see
-  /// `Character.hexDigitValue`
+  /// fullwidth compatibility forms. To get the character's value, use the
+  /// `hexDigitValue` property.
   @inlinable
   public var isHexDigit: Bool {
     return hexDigitValue != nil
   }
 
-  /// If this Character is a hexadecimal digit, returns the value it represents,
-  /// else nil.
+  /// The numeric value this character represents, if it is a hexadecimal digit.
+  ///
+  /// Hexadecimal digits include 0-9, Latin letters a-f and A-F, and their
+  /// fullwidth compatibility forms. If the character does not represent a
+  /// hexadecimal digit, the value of this property is `nil`.
+  ///
+  ///     let chars: [Character] = ["1", "a", "F", "g"]
+  ///     for ch in chars {
+  ///         print(ch, "-->", ch.hexDigitValue)
+  ///     }
+  ///     // 1 --> 1
+  ///     // a --> 10
+  ///     // F --> 15
+  ///     // g --> nil
   public var hexDigitValue: Int? {
     guard _isSingleScalar else { return nil }
     let value = _firstScalar.value
@@ -142,48 +183,51 @@
     }
   }
 
-  /// Whether this Character is a letter.
+  /// A Boolean value indicating whether this character is a letter.
   ///
-  /// Examples:
-  ///   * "A" (U+0041 LATIN CAPITAL LETTER A)
-  ///   * "é" (U+0065 LATIN SMALL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///   * "ϴ" (U+03F4 GREEK CAPITAL THETA SYMBOL)
-  ///   * "ڈ" (U+0688 ARABIC LETTER DDAL)
-  ///   * "日" (U+65E5 CJK UNIFIED IDEOGRAPH-65E5)
-  ///   * "ᚨ" (U+16A8 RUNIC LETTER ANSUZ A)
+  /// For example, the following characters are all letters:
   ///
+  /// - "A" (U+0041 LATIN CAPITAL LETTER A)
+  /// - "é" (U+0065 LATIN SMALL LETTER E, U+0301 COMBINING ACUTE ACCENT)
+  /// - "ϴ" (U+03F4 GREEK CAPITAL THETA SYMBOL)
+  /// - "ڈ" (U+0688 ARABIC LETTER DDAL)
+  /// - "日" (U+65E5 CJK UNIFIED IDEOGRAPH-65E5)
+  /// - "ᚨ" (U+16A8 RUNIC LETTER ANSUZ A)
   public var isLetter: Bool {
     return _firstScalar.properties.isAlphabetic
   }
 
-  /// Perform case conversion to uppercase
+  /// Returns an uppercased version of this character.
   ///
-  /// Examples:
-  ///   * "é" (U+0065 LATIN SMALL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///     => "É" (U+0045 LATIN CAPITAL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///   * "и" (U+0438 CYRILLIC SMALL LETTER I)
-  ///     => "И" (U+0418 CYRILLIC CAPITAL LETTER I)
-  ///   * "π" (U+03C0 GREEK SMALL LETTER PI)
-  ///     => "Π" (U+03A0 GREEK CAPITAL LETTER PI)
-  ///   * "ß" (U+00DF LATIN SMALL LETTER SHARP S)
-  ///     => "SS" (U+0053 LATIN CAPITAL LETTER S, U+0053 LATIN CAPITAL LETTER S)
+  /// Because case conversion can result in multiple characters, the result
+  /// of `uppercased()` is a string.
   ///
-  /// Note: Returns a String as case conversion can result in multiple
-  /// Characters.
+  ///     let chars: [Character] = ["e", "é", "и", "π", "ß", "1"]
+  ///     for ch in chars {
+  ///         print(ch, "-->", ch.uppercased())
+  ///     }
+  ///     // e --> E
+  ///     // é --> É
+  ///     // и --> И
+  ///     // π --> Π
+  ///     // ß --> SS
+  ///     // 1 --> 1
   public func uppercased() -> String { return String(self).uppercased() }
 
-  /// Perform case conversion to lowercase
+  /// Returns a lowercased version of this character.
   ///
-  /// Examples:
-  ///   * "É" (U+0045 LATIN CAPITAL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///     => "é" (U+0065 LATIN SMALL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///   * "И" (U+0418 CYRILLIC CAPITAL LETTER I)
-  ///     => "и" (U+0438 CYRILLIC SMALL LETTER I)
-  ///   * "Π" (U+03A0 GREEK CAPITAL LETTER PI)
-  ///     => "π" (U+03C0 GREEK SMALL LETTER PI)
+  /// Because case conversion can result in multiple characters, the result
+  /// of `lowercased()` is a string.
   ///
-  /// Note: Returns a String as case conversion can result in multiple
-  /// Characters.
+  ///     let chars: [Character] = ["E", "É", "И", "Π", "1"]
+  ///     for ch in chars {
+  ///         print(ch, "-->", ch.lowercased())
+  ///     }
+  ///     // E --> e
+  ///     // É --> é
+  ///     // И --> и
+  ///     // Π --> π
+  ///     // 1 --> 1
   public func lowercased() -> String { return String(self).lowercased() }
 
   @usableFromInline
@@ -191,16 +235,14 @@
   @usableFromInline
   internal var _isLowercased: Bool { return String(self) == self.lowercased() }
 
-  /// Whether this Character is considered uppercase.
+  /// A Boolean value indicating whether this character is considered uppercase.
   ///
-  /// Uppercase Characters vary under case-conversion to lowercase, but not when
-  /// converted to uppercase.
+  /// Uppercase characters vary under case-conversion to lowercase, but not when
+  /// converted to uppercase. The following characters are all uppercase:
   ///
-  /// Examples:
-  ///   * "É" (U+0045 LATIN CAPITAL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///   * "И" (U+0418 CYRILLIC CAPITAL LETTER I)
-  ///   * "Π" (U+03A0 GREEK CAPITAL LETTER PI)
-  ///
+  /// - "É" (U+0045 LATIN CAPITAL LETTER E, U+0301 COMBINING ACUTE ACCENT)
+  /// - "И" (U+0418 CYRILLIC CAPITAL LETTER I)
+  /// - "Π" (U+03A0 GREEK CAPITAL LETTER PI)
   @inlinable
   public var isUppercase: Bool {
     if _fastPath(_isSingleScalar && _firstScalar.properties.isUppercase) {
@@ -209,16 +251,14 @@
     return _isUppercased && isCased
   }
 
-  /// Whether this Character is considered lowercase.
+  /// A Boolean value indicating whether this character is considered lowercase.
   ///
-  /// Lowercase Characters vary under case-conversion to uppercase, but not when
-  /// converted to lowercase.
+  /// Lowercase characters change when converted to uppercase, but not when
+  /// converted to lowercase. The following characters are all lowercase:
   ///
-  /// Examples:
-  ///   * "é" (U+0065 LATIN SMALL LETTER E, U+0301 COMBINING ACUTE ACCENT)
-  ///   * "и" (U+0438 CYRILLIC SMALL LETTER I)
-  ///   * "π" (U+03C0 GREEK SMALL LETTER PI)
-  ///
+  /// - "é" (U+0065 LATIN SMALL LETTER E, U+0301 COMBINING ACUTE ACCENT)
+  /// - "и" (U+0438 CYRILLIC SMALL LETTER I)
+  /// - "π" (U+03C0 GREEK SMALL LETTER PI)
   @inlinable
   public var isLowercase: Bool {
     if _fastPath(_isSingleScalar && _firstScalar.properties.isLowercase) {
@@ -227,7 +267,8 @@
     return _isLowercased && isCased
   }
 
-  /// Whether this Character changes under any form of case conversion.
+  /// A Boolean value indicating whether this character changes under any form
+  /// of case conversion.
   @inlinable
   public var isCased: Bool {
     if _fastPath(_isSingleScalar && _firstScalar.properties.isCased) {
@@ -236,53 +277,64 @@
     return !_isUppercased || !_isLowercased
   }
 
-  /// Whether this Character represents a symbol
+  /// A Boolean value indicating whether this character represents a symbol.
   ///
-  /// Examples:
-  ///   * "®" (U+00AE REGISTERED SIGN)
-  ///   * "⌹" (U+2339 APL FUNCTIONAL SYMBOL QUAD DIVIDE)
-  ///   * "⡆" (U+2846 BRAILLE PATTERN DOTS-237)
+  /// This property is `true` only for characters composed of scalars in the
+  /// "Math_Symbol", "Currency_Symbol", "Modifier_Symbol", or "Other_Symbol"
+  /// categories in the
+  /// [Unicode Standard](https://unicode.org/reports/tr44/#General_Category_Values).
   ///
+  /// For example, the following characters all represent symbols:
+  ///
+  /// - "®" (U+00AE REGISTERED SIGN)
+  /// - "⌹" (U+2339 APL FUNCTIONAL SYMBOL QUAD DIVIDE)
+  /// - "⡆" (U+2846 BRAILLE PATTERN DOTS-237)
   public var isSymbol: Bool {
     return _firstScalar.properties.generalCategory._isSymbol
   }
 
-  /// Whether this Character represents a symbol used mathematical formulas
+  /// A Boolean value indicating whether this character represents a symbol
+  /// that naturally appears in mathematical contexts.
   ///
-  /// Examples:
-  ///   * "+" (U+002B PLUS SIGN)
-  ///   * "∫" (U+222B INTEGRAL)
-  ///   * "ϰ" (U+03F0 GREEK KAPPA SYMBOL)
+  /// For example, the following characters all represent math symbols:
   ///
-  /// Note: This is not a strict subset of isSymbol. This includes characters
-  /// used both as letters and commonly in mathematical formulas. For example,
-  /// "ϰ" (U+03F0 GREEK KAPPA SYMBOL) is considered a both mathematical symbol
-  /// and a letter.
+  /// - "+" (U+002B PLUS SIGN)
+  /// - "∫" (U+222B INTEGRAL)
+  /// - "ϰ" (U+03F0 GREEK KAPPA SYMBOL)
   ///
+  /// The set of characters that have an `isMathSymbol` value of `true` is not
+  /// a strict subset of those for which `isSymbol` is `true`. This includes
+  /// characters used both as letters and commonly in mathematical formulas.
+  /// For example, "ϰ" (U+03F0 GREEK KAPPA SYMBOL) is considered both a
+  /// mathematical symbol and a letter.
+  ///
+  /// This property corresponds to the "Math" property in the
+  /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isMathSymbol: Bool {
     return _firstScalar.properties.isMath
   }
 
-  /// Whether this Character represents a currency symbol
+  /// A Boolean value indicating whether this character represents a currency
+  /// symbol.
   ///
-  /// Examples:
-  ///   * "$" (U+0024 DOLLAR SIGN)
-  ///   * "¥" (U+00A5 YEN SIGN)
-  ///   * "€" (U+20AC EURO SIGN)
+  /// For example, the following characters all represent currency symbols:
   ///
+  /// - "$" (U+0024 DOLLAR SIGN)
+  /// - "¥" (U+00A5 YEN SIGN)
+  /// - "€" (U+20AC EURO SIGN)
   public var isCurrencySymbol: Bool {
     return _firstScalar.properties.generalCategory == .currencySymbol
   }
 
-  /// Whether this Character represents punctuation
+  /// A Boolean value indicating whether this character represents punctuation.
   ///
-  /// Examples:
-  ///   * "!" (U+0021 EXCLAMATION MARK)
-  ///   * "؟" (U+061F ARABIC QUESTION MARK)
-  ///   * "…" (U+2026 HORIZONTAL ELLIPSIS)
-  ///   * "—" (U+2014 EM DASH)
-  ///   * "“" (U+201C LEFT DOUBLE QUOTATION MARK)
+  /// For example, the following characters all represent punctuation:
   ///
+  /// - "!" (U+0021 EXCLAMATION MARK)
+  /// - "؟" (U+061F ARABIC QUESTION MARK)
+  /// - "…" (U+2026 HORIZONTAL ELLIPSIS)
+  /// - "—" (U+2014 EM DASH)
+  /// - "“" (U+201C LEFT DOUBLE QUOTATION MARK)
   public var isPunctuation: Bool {
     return _firstScalar.properties.generalCategory._isPunctuation
   }
diff --git a/stdlib/public/core/CompilerProtocols.swift b/stdlib/public/core/CompilerProtocols.swift
index d055c2c..fa2fc4f 100644
--- a/stdlib/public/core/CompilerProtocols.swift
+++ b/stdlib/public/core/CompilerProtocols.swift
@@ -709,45 +709,49 @@
 ///     print(message)
 ///     // Prints "One cookie: $2, 3 cookies: $6."
 /// 
-/// Extending default interpolation behavior
-/// ========================================
+/// Extending the Default Interpolation Behavior
+/// ============================================
 /// 
-/// Clients which want to add new interpolation behavior to existing types
-/// should extend `DefaultStringInterpolation`, the type which implements
-/// interpolation for types like `String` and `Substring`, to add an overload of
-/// `appendInterpolation(_:)` with their new behavior. See the
-/// `DefaultStringInterpolation` and `StringInterpolationProtocol` documentation
-/// for more details.
-/// 
-/// Creating a type which supports default string interpolation
-/// ===========================================================
-/// 
-/// Clients which want to create new types supporting string literals and
-/// interpolation, but which do not need any custom behavior, should conform
-/// their type to `ExpressibleByStringInterpolation` and implement an
-/// `init(stringLiteral: String)` method. Swift will automatically use
-/// `DefaultStringInterpolation` and provide an `init(stringInterpolation:)`
-/// implementation which passes the interpolated literal's contents to
-/// `init(stringLiteral:)`, so you won't need to implement anything special.
+/// Add new interpolation behavior to existing types by extending
+/// `DefaultStringInterpolation`, the type that implements interpolation for
+/// types like `String` and `Substring`, to add an overload of
+/// `appendInterpolation(_:)` with their new behavior.
 ///
-/// Creating a type which supports custom string interpolation
-/// ==========================================================
+/// For more information, see the `DefaultStringInterpolation` and
+/// `StringInterpolationProtocol` documentation.
 /// 
-/// If a conforming type wants to differentiate between literal and interpolated
-/// segments, restrict the types which can be interpolated into it, support
-/// different interpolators from the ones on `String`, or avoid constructing a
-/// `String` containing the data, it must specify a custom `StringInterpolation`
-/// associated type. This type must conform to `StringInterpolationProtocol` and
-/// must have a matching `StringLiteralType`.
+/// Creating a Type That Supports the Default String Interpolation
+/// ==============================================================
+/// 
+/// To create a new type that supports string literals and interpolation, but
+/// that doesn't need any custom behavior, conform the type to
+/// `ExpressibleByStringInterpolation` and implement the
+/// `init(stringLiteral: String)` initializer declared by the
+/// `ExpressibleByStringLiteral` protocol. Swift will automatically use
+/// `DefaultStringInterpolation` as the interpolation type and provide an
+/// implementation for `init(stringInterpolation:)` that passes the
+/// interpolated literal's contents to `init(stringLiteral:)`, so you don't
+/// need to implement anything specific to this protocol.
 ///
-/// See the `StringLiteralProtocol` documentation for more details about how to
-/// do this.
+/// Creating a Type That Supports Custom String Interpolation
+/// =========================================================
+///
+/// If you want a conforming type to differentiate between literal and
+/// interpolated segments, restrict the types that can be interpolated,
+/// support different interpolators from the ones on `String`, or avoid
+/// constructing a `String` containing the data, the type must specify a custom
+/// `StringInterpolation` associated type. This type must conform to
+/// `StringInterpolationProtocol` and have a matching `StringLiteralType`.
+///
+/// For more information, see the `StringInterpolationProtocol` documentation.
 public protocol ExpressibleByStringInterpolation
   : ExpressibleByStringLiteral {
   
   /// The type each segment of a string literal containing interpolations
-  /// should be appended to. Its `StringLiteralType` should match the
-  /// `StringLiteralType` of this type.
+  /// should be appended to.
+  ///
+  /// The `StringLiteralType` of an interpolation type must match the
+  /// `StringLiteralType` of the conforming type.
   associatedtype StringInterpolation : StringInterpolationProtocol
     = DefaultStringInterpolation
     where StringInterpolation.StringLiteralType == StringLiteralType
@@ -770,7 +774,7 @@
   
   /// Creates a new instance from an interpolated string literal.
   /// 
-  /// Do not call this initializer directly. It is used by the compiler when
+  /// Don't call this initializer directly. It's used by the compiler when
   /// you create a string using string interpolation. Instead, use string
   /// interpolation to create a new string by including values, literals,
   /// variables, or expressions enclosed in parentheses, prefixed by a
@@ -782,14 +786,13 @@
   ///                   If one cookie costs \(price) dollars, \
   ///                   \(number) cookies cost \(price * number) dollars.
   ///                   """
-  ///     print(message)
-  ///     // Prints "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
+  ///     // message == "If one cookie costs 2 dollars, 3 cookies cost 6 dollars."
   public init(stringInterpolation: DefaultStringInterpolation) {
     self.init(stringLiteral: stringInterpolation.make())
   }
 }
 
-/// Represents the contents of a string literal with interpolations while it is
+/// Represents the contents of a string literal with interpolations while it's
 /// being built up.
 /// 
 /// Each `ExpressibleByStringInterpolation` type has an associated
@@ -809,60 +812,78 @@
 /// The `StringInterpolation` type is responsible for collecting the segments
 /// passed to its `appendLiteral(_:)` and `appendInterpolation` methods and
 /// assembling them into a whole, converting as necessary. Once all of the
-/// segments have been appended, the interpolation will be passed to an
+/// segments are appended, the interpolation is passed to an
 /// `init(stringInterpolation:)` initializer on the type being created, which
 /// must extract the accumulated data from the `StringInterpolation`.
 /// 
-/// In simple cases, types conforming to `ExpressibleByStringInterpolation`
-/// can use `DefaultStringInterpolation` instead of writing their own. All they
-/// must do is conform to `ExpressibleByStringInterpolation` and implement
-/// `init(stringLiteral: String)`; interpolated string literals will then go
-/// through that initializer just as any other string literal would.
+/// In simple cases, you can use `DefaultStringInterpolation` as the
+/// interpolation type for types that conform to the
+/// `ExpressibleByStringLiteral` protocol. To use the default interpolation,
+/// conform a type to `ExpressibleByStringInterpolation` and implement
+/// `init(stringLiteral: String)`. Values in interpolations are converted to
+/// strings, and then passed to that initializer just like any other string
+/// literal.
 /// 
-/// The `appendInterpolation` Method
-/// ================================
-/// 
-/// Each interpolated segment is translated into a call to a
-/// `StringInterpolationProtocol.appendInterpolation(...)` method, with the
-/// contents of the interpolation's parentheses treated as the call's argument
-/// list. That argument list can include multiple arguments and argument labels.
-/// For example:
-/// 
-/// | If you write... | Swift calls...                    |
-/// |---------------- | --------------------------------- |
-/// | `\(x)`          | `appendInterpolation(x)`          |
-/// | `\(x, y)`       | `appendInterpolation(x, y)`       |
-/// | `\(foo: x)`     | `appendInterpolation(foo: x)`     |
-/// | `\(x, foo: y)`  | `appendInterpolation(x, foo: y)`  |
-/// 
-/// `appendInterpolation` methods should return `Void` and should not be
-/// `static`. They otherwise support virtually all features of methods: they can
-/// have any number of parameters, can specify labels for any or all of them,
-/// can provide default values for parameters, can have variadic parameters, and
-/// can have parameters with generic types. Most importantly, they can be
-/// overloaded, so a `StringInterpolationProtocol`-conforming type can provide
-/// several different `appendInterpolation` methods with different behaviors.
-/// `appendInterpolation` methods can also throw; when a user uses one of these,
-/// they must mark the string literal with `try` or one of its variants.
+/// Handling String Interpolations
+/// ==============================
+///
+/// With a custom interpolation type, each interpolated segment is translated
+/// into a call to a special `appendInterpolation` method. The contents of
+/// the interpolation's parentheses are treated as the call's argument list.
+/// That argument list can include multiple arguments and argument labels.
+///
+/// The following examples show how string interpolations are translated into
+/// calls to `appendInterpolation`:
+///
+/// - `\(x)` translates to `appendInterpolation(x)`
+/// - `\(x, y)` translates to `appendInterpolation(x, y)`
+/// - `\(foo: x)` translates to `appendInterpolation(foo: x)`
+/// - `\(x, foo: y)` translates to `appendInterpolation(x, foo: y)`
+///
+/// The `appendInterpolation` methods in your custom type must be mutating
+/// instance methods that return `Void`. This code shows a custom interpolation
+/// type's declaration of an `appendInterpolation` method that provides special
+/// validation for user input:
+///
+///     extension MyString.StringInterpolation {
+///         mutating func appendInterpolation(validating input: String) {
+///             // Perform validation of `input` and store for later use
+///         }
+///     }
+///
+/// To use this interpolation method, create a string literal with an
+/// interpolation using the `validating` parameter label.
+///
+///     let userInput = readLine() ?? ""
+///     let myString = "The user typed '\(validating: userInput)'." as MyString
+///
+/// `appendInterpolation` methods support virtually all features of methods:
+/// they can have any number of parameters, can specify labels for any or all
+/// of their parameters, can provide default values, can have variadic
+/// parameters, and can have parameters with generic types. Most importantly,
+/// they can be overloaded, so a type that conforms to
+/// `StringInterpolationProtocol` can provide several different
+/// `appendInterpolation` methods with different behaviors. An
+/// `appendInterpolation` method can also throw; when a user writes a literal
+/// with one of these interpolations, they must mark the string literal with
+/// `try` or one of its variants.
 public protocol StringInterpolationProtocol {
   /// The type that should be used for literal segments.
   associatedtype StringLiteralType : _ExpressibleByBuiltinStringLiteral
 
   /// Creates an empty instance ready to be filled with string literal content.
   /// 
-  /// Do not call this initializer directly. Instead, initialize a variable or
+  /// Don't call this initializer directly. Instead, initialize a variable or
   /// constant using a string literal with interpolated expressions.
   /// 
   /// Swift passes this initializer a pair of arguments specifying the size of
   /// the literal segments and the number of interpolated segments. Use this
-  /// information to estimate the amount of storage you will need and
-  /// pre-allocate it with a method like
-  /// `RangeReplaceableCollection.reserveCapacity(_:)`.
+  /// information to estimate the amount of storage you will need.
   /// 
   /// - Parameter literalCapacity: The approximate size of all literal segments
   ///   combined. This is meant to be passed to `String.reserveCapacity(_:)`;
-  ///   it may be slightly larger or smaller than the sum of `String.count`
-  ///   called on each literal segment.
+  ///   it may be slightly larger or smaller than the sum of the counts of each
+  ///   literal segment.
   /// - Parameter interpolationCount: The number of interpolations which will be
   ///   appended. Use this value to estimate how much additional capacity will
   ///   be needed for the interpolated segments.
@@ -870,15 +891,15 @@
 
   /// Appends a literal segment to the interpolation.
   /// 
-  /// Do not call this method directly. Instead, initialize a variable or
+  /// Don't call this method directly. Instead, initialize a variable or
   /// constant using a string literal with interpolated expressions.
   /// 
-  /// Interpolated expressions do not pass through this method; instead, Swift
-  /// selects an overload of `appendInterpolation`. See the top-level
-  /// `StringInterpolationProtocol` documentation for more details.
+  /// Interpolated expressions don't pass through this method; instead, Swift
+  /// selects an overload of `appendInterpolation`. For more information, see
+  /// the top-level `StringInterpolationProtocol` documentation.
   /// 
   /// - Parameter literal: A string literal containing the characters
-  ///             that appear next in the string literal.
+  ///   that appear next in the string literal.
   mutating func appendLiteral(_ literal: StringLiteralType)
 
   // Informal requirement: Any desired appendInterpolation overloads, e.g.:
diff --git a/stdlib/public/core/ContiguouslyStored.swift b/stdlib/public/core/ContiguouslyStored.swift
index 41da8c1..84ff264 100644
--- a/stdlib/public/core/ContiguouslyStored.swift
+++ b/stdlib/public/core/ContiguouslyStored.swift
@@ -57,6 +57,22 @@
     return try body(UnsafeRawBufferPointer(start: ptr, count: len))
   }
 }
+extension UnsafeRawBufferPointer: _HasContiguousBytes {
+  @inlinable @inline(__always)
+  func withUnsafeBytes<R>(
+    _ body: (UnsafeRawBufferPointer) throws -> R
+  ) rethrows -> R {
+    return try body(self)
+  }
+}
+extension UnsafeMutableRawBufferPointer: _HasContiguousBytes {
+  @inlinable @inline(__always)
+  func withUnsafeBytes<R>(
+    _ body: (UnsafeRawBufferPointer) throws -> R
+  ) rethrows -> R {
+    return try body(UnsafeRawBufferPointer(self))
+  }
+}
 extension String: _HasContiguousBytes {
   @inlinable
   internal var _providesContiguousBytesNoCopy: Bool {
diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift
index 298f8a8..9f0a733 100644
--- a/stdlib/public/core/Dictionary.swift
+++ b/stdlib/public/core/Dictionary.swift
@@ -340,7 +340,7 @@
 ///
 ///     let glyphIndex = imagePaths.firstIndex(where: { $0.value.hasPrefix("/glyphs") })
 ///     if let index = glyphIndex {
-///         print("The '\(imagesPaths[index].key)' image is a glyph.")
+///         print("The '\(imagePaths[index].key)' image is a glyph.")
 ///     } else {
 ///         print("No glyphs found!")
 ///     }
@@ -921,10 +921,10 @@
   }
 
   /// Returns a new dictionary containing only the key-value pairs that have
-  /// non-`nil` values as the result from the transform by the given closure.
+  /// non-`nil` values as the result of transformation by the given closure.
   ///
-  /// Use this method to receive a dictionary of non-optional values when your
-  /// transformation can produce an optional value.
+  /// Use this method to receive a dictionary with non-optional values when
+  /// your transformation produces optional values.
   ///
   /// In this example, note the difference in the result of using `mapValues`
   /// and `compactMapValues` with a transformation that returns an optional
diff --git a/stdlib/public/core/DictionaryBuilder.swift b/stdlib/public/core/DictionaryBuilder.swift
index 68ec578..0178c92 100644
--- a/stdlib/public/core/DictionaryBuilder.swift
+++ b/stdlib/public/core/DictionaryBuilder.swift
@@ -42,3 +42,134 @@
     return Dictionary(_native: _target)
   }
 }
+
+extension Dictionary {
+  /// Creates a new dictionary with the specified capacity, then calls the given
+  /// closure to initialize its contents.
+  ///
+  /// Foundation uses this initializer to bridge the contents of an NSDictionary
+  /// instance without allocating a pair of intermediary buffers.  Pass the
+  /// required capacity and a closure that can intialize the dictionary's
+  /// elements. The closure must return `c`, the number of initialized elements
+  /// in both buffers, such that the elements in the range `0..<c` are
+  /// initialized and the elements in the range `c..<capacity` are
+  /// uninitialized.
+  ///
+  /// The resulting dictionary has a `count` less than or equal to `c`. The
+  /// actual count is less iff some of the initialized keys were duplicates.
+  /// (This cannot happen if `allowingDuplicates` is false.)
+  ///
+  /// The buffers passed to the closure are only valid for the duration of the
+  /// call.  After the closure returns, this initializer moves all initialized
+  /// elements into their correct buckets.
+  ///
+  /// - Parameters:
+  ///   - capacity: The capacity of the new dictionary.
+  ///   - allowingDuplicates: If false, then the caller guarantees that all keys
+  ///     are unique. This promise isn't verified -- if it turns out to be
+  ///     false, then the resulting dictionary won't be valid.
+  ///   - body: A closure that can initialize the dictionary's elements. This
+  ///     closure must return the count of the initialized elements, starting at
+  ///     the beginning of the buffer.
+  @inlinable
+  public // SPI(Foundation)
+  init(
+    _unsafeUninitializedCapacity capacity: Int,
+    allowingDuplicates: Bool,
+    initializingWith initializer: (
+      _ keys: UnsafeMutableBufferPointer<Key>,
+      _ values: UnsafeMutableBufferPointer<Value>,
+      _ initializedCount: inout Int
+    ) -> Void
+  ) {
+    self.init(_native: _NativeDictionary(
+        _unsafeUninitializedCapacity: capacity,
+        allowingDuplicates: allowingDuplicates,
+        initializingWith: initializer))
+  }
+}
+
+extension _NativeDictionary {
+  @inlinable
+  internal init(
+    _unsafeUninitializedCapacity capacity: Int,
+    allowingDuplicates: Bool,
+    initializingWith initializer: (
+      _ keys: UnsafeMutableBufferPointer<Key>,
+      _ values: UnsafeMutableBufferPointer<Value>,
+      _ initializedCount: inout Int
+    ) -> Void
+  ) {
+    self.init(capacity: capacity)
+    var initializedCount = 0
+    initializer(
+      UnsafeMutableBufferPointer(start: _keys, count: capacity),
+      UnsafeMutableBufferPointer(start: _values, count: capacity),
+      &initializedCount)
+    _precondition(count >= 0 && count <= capacity)
+    _storage._count = initializedCount
+
+    // Hash initialized elements and move each of them into their correct
+    // buckets.
+    //
+    // - We have some number of unprocessed elements at the start of the
+    //   key/value buffers -- buckets up to and including `bucket`. Everything
+    //   in this region is either unprocessed or in use. There are no
+    //   uninitialized entries in it.
+    //
+    // - Everything after `bucket` is either uninitialized or in use. This
+    //   region works exactly like regular dictionary storage.
+    //
+    // - "in use" is tracked by the bitmap in `hashTable`, the same way it would
+    //   be for a working Dictionary.
+    //
+    // Each iteration of the loop below processes an unprocessed element, and/or
+    // reduces the size of the unprocessed region, while ensuring the above
+    // invariants.
+    var bucket = _HashTable.Bucket(offset: initializedCount - 1)
+    while bucket.offset >= 0 {
+      if hashTable._isOccupied(bucket) {
+        // We've moved an element here in a previous iteration.
+        bucket.offset -= 1
+        continue
+      }
+      // Find the target bucket for this entry and mark it as in use.
+      let target: Bucket
+      if _isDebugAssertConfiguration() || allowingDuplicates {
+        let (b, found) = find(_keys[bucket.offset])
+        if found {
+          _internalInvariant(b != bucket)
+          _precondition(allowingDuplicates, "Duplicate keys found")
+          // Discard duplicate entry.
+          uncheckedDestroy(at: bucket)
+          _storage._count -= 1
+          bucket.offset -= 1
+          continue
+        }
+        hashTable.insert(b)
+        target = b
+      } else {
+        let hashValue = self.hashValue(for: _keys[bucket.offset])
+        target = hashTable.insertNew(hashValue: hashValue)
+      }
+
+      if target > bucket {
+        // The target is outside the unprocessed region.  We can simply move the
+        // entry, leaving behind an uninitialized bucket.
+        moveEntry(from: bucket, to: target)
+        // Restore invariants by lowering the region boundary.
+        bucket.offset -= 1
+      } else if target == bucket {
+        // Already in place.
+        bucket.offset -= 1
+      } else {
+        // The target bucket is also in the unprocessed region. Swap the current
+        // item into place, then try again with the swapped-in value, so that we
+        // don't lose it.
+        swapEntry(target, with: bucket)
+      }
+    }
+    // When there are no more unprocessed entries, we're left with a valid
+    // Dictionary.
+  }
+}
diff --git a/stdlib/public/core/ExistentialCollection.swift.gyb b/stdlib/public/core/ExistentialCollection.swift.gyb
index da2a0a9..e7d2b0c 100644
--- a/stdlib/public/core/ExistentialCollection.swift.gyb
+++ b/stdlib/public/core/ExistentialCollection.swift.gyb
@@ -503,30 +503,36 @@
     return _base.suffix(maxLength)
   }
 %   else:
+  @inline(__always)
   @inlinable
   internal override func _drop(
     while predicate: (Element) throws -> Bool
   ) rethrows -> _Any${Kind}Box<Element> {
     return try _${Kind}Box<S.SubSequence>(_base: _base.drop(while: predicate))
   }
+  @inline(__always)
   @inlinable
   internal override func _dropFirst(_ n: Int) -> _Any${Kind}Box<Element> {
     return _${Kind}Box<S.SubSequence>(_base: _base.dropFirst(n))
   }
+  @inline(__always)
   @inlinable
   internal override func _dropLast(_ n: Int) -> _Any${Kind}Box<Element> {
     return _${Kind}Box<S.SubSequence>(_base: _base.dropLast(n))
   }
+  @inline(__always)
   @inlinable
   internal override func _prefix(
     while predicate: (Element) throws -> Bool
   ) rethrows -> _Any${Kind}Box<Element> {
     return try _${Kind}Box<S.SubSequence>(_base: _base.prefix(while: predicate))
   }
+  @inline(__always)
   @inlinable
   internal override func _prefix(_ maxLength: Int) -> _Any${Kind}Box<Element> {
     return _${Kind}Box<S.SubSequence>(_base: _base.prefix(maxLength))
   }
+  @inline(__always)
   @inlinable
   internal override func _suffix(_ maxLength: Int) -> _Any${Kind}Box<Element> {
     return _${Kind}Box<S.SubSequence>(_base: _base.suffix(maxLength))
diff --git a/stdlib/public/core/HashTable.swift b/stdlib/public/core/HashTable.swift
index 198dc6b..3ad9f42 100644
--- a/stdlib/public/core/HashTable.swift
+++ b/stdlib/public/core/HashTable.swift
@@ -127,7 +127,6 @@
     @inlinable
     @inline(__always)
     internal init(offset: Int) {
-      _internalInvariant(offset >= 0)
       self.offset = offset
     }
 
diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift
index fbf687b..bd1cb6e 100644
--- a/stdlib/public/core/Integers.swift
+++ b/stdlib/public/core/Integers.swift
@@ -27,12 +27,45 @@
 //===--- AdditiveArithmetic -----------------------------------------------===//
 //===----------------------------------------------------------------------===//
 
-// FIXME: Add doc comment.
+/// A type with values that support addition and subtraction.
+///
+/// The `AdditiveArithmetic` protocol provides a suitable basis for additive
+/// arithmetic on scalar values, such as integers and floating-point numbers,
+/// or vectors. You can write generic methods that operate on any numeric type
+/// in the standard library by using the `AdditiveArithmetic` protocol as a
+/// generic constraint.
+///
+/// The following code declares a method that calculates the total of any
+/// sequence with `Numeric` elements.
+///
+///     extension Sequence where Element: AdditiveArithmetic {
+///         func sum() -> Element {
+///             return reduce(.zero, +)
+///         }
+///     }
+///
+/// The `sum()` method is now available on any sequence with values that
+/// conform to `AdditiveArithmetic`, whether it is an array of `Double` or a
+/// range of `Int`.
+///
+///     let arraySum = [1.1, 2.2, 3.3, 4.4, 5.5].sum()
+///     // arraySum == 16.5
+///
+///     let rangeSum = (1..<10).sum()
+///     // rangeSum == 45
+///
+/// Conforming to the AdditiveArithmetic Protocol
+/// =============================================
+///
+/// To add `AdditiveArithmetic` protocol conformance to your own custom type,
+/// implement the required operators, and provide a static `zero` property
+/// using a type that can represent the magnitude of any value of your custom
+/// type.
 public protocol AdditiveArithmetic : Equatable {
   /// The zero value.
   ///
-  /// - Note: Zero is the identity element for addition; for any value,
-  ///   `x + .zero == x` and `.zero + x == x`.
+  /// Zero is the identity element for addition. For any value,
+  /// `x + .zero == x` and `.zero + x == x`.
   static var zero: Self { get }
 
   /// Adds two values and produces their sum.
@@ -96,6 +129,10 @@
 }
 
 public extension AdditiveArithmetic where Self : ExpressibleByIntegerLiteral {
+  /// The zero value.
+  ///
+  /// Zero is the identity element for addition. For any value,
+  /// `x + .zero == x` and `.zero + x == x`.
   static var zero: Self {
     return 0
   }
@@ -105,41 +142,41 @@
 //===--- Numeric ----------------------------------------------------------===//
 //===----------------------------------------------------------------------===//
 
-// FIXME: Update comment based on the `AdditiveArithmetic` change.
-/// Declares methods backing binary arithmetic operators--such as `+`, `-` and
-/// `*`--and their mutating counterparts.
+/// A type with values that support multiplication.
 ///
 /// The `Numeric` protocol provides a suitable basis for arithmetic on
 /// scalar values, such as integers and floating-point numbers. You can write
 /// generic methods that operate on any numeric type in the standard library
 /// by using the `Numeric` protocol as a generic constraint.
 ///
-/// The following example declares a method that calculates the total of any
-/// sequence with `Numeric` elements.
+/// The following example extends `Sequence` with a method that returns an
+/// array with the sequence's values multiplied by two.
 ///
 ///     extension Sequence where Element: Numeric {
-///         func sum() -> Element {
-///             return reduce(0, +)
+///         func doublingAll() -> [Element] {
+///             return map { $0 * 2 }
 ///         }
 ///     }
 ///
-/// The `sum()` method is now available on any sequence or collection with
-/// numeric values, whether it is an array of `Double` or a countable range of
-/// `Int`.
+/// With this extension, any sequence with elements that conform to `Numeric`
+/// has the `doublingAll()` method. For example, you can double the elements of
+/// an array of doubles or a range of integers:
 ///
-///     let arraySum = [1.1, 2.2, 3.3, 4.4, 5.5].sum()
-///     // arraySum == 16.5
+///     let observations = [1.5, 2.0, 3.25, 4.875, 5.5]
+///     let doubledObservations = observations.doublingAll()
+///     // doubledObservations == [3.0, 4.0, 6.5, 9.75, 11.0]
 ///
-///     let rangeSum = (1..<10).sum()
-///     // rangeSum == 45
+///     let integers = 0..<8
+///     let doubledIntegers = integers.doublingAll()
+///     // doubledIntegers == [0, 2, 4, 6, 8, 10, 12, 14]
 ///
 /// Conforming to the Numeric Protocol
-/// =====================================
+/// ==================================
 ///
 /// To add `Numeric` protocol conformance to your own custom type, implement
-/// the required mutating methods. Extensions to `Numeric` provide default
-/// implementations for the protocol's nonmutating methods based on the
-/// mutating variants.
+/// the required initializer and operators, and provide a `magnitude` property
+/// using a type that can represent the magnitude of any value of your custom
+/// type.
 public protocol Numeric : AdditiveArithmetic, ExpressibleByIntegerLiteral {
   /// Creates a new instance from the given integer, if it can be represented
   /// exactly.
@@ -216,7 +253,7 @@
 /// `Numeric` protocol to include a value's additive inverse.
 ///
 /// Conforming to the SignedNumeric Protocol
-/// ===========================================
+/// ========================================
 ///
 /// Because the `SignedNumeric` protocol provides default implementations of
 /// both of its required methods, you don't need to do anything beyond
@@ -1163,19 +1200,20 @@
   func quotientAndRemainder(dividingBy rhs: Self)
     -> (quotient: Self, remainder: Self)
 
-  /// Returns true if this value is a multiple of `other`, and false otherwise.
+  /// Returns `true` if this value is a multiple of the given value, and `false`
+  /// otherwise.
   ///
-  /// For two integers a and b, a is a multiple of b if there exists a third
-  /// integer q such that a = q*b. For example, 6 is a multiple of 3, because
-  /// 6 = 2*3, and zero is a multiple of everything, because 0 = 0*x, for any
-  /// integer x.
+  /// For two integers *a* and *b*, *a* is a multiple of *b* if there exists a
+  /// third integer *q* such that _a = q*b_. For example, *6* is a multiple of
+  /// *3* because _6 = 2*3_. Zero is a multiple of everything because _0 = 0*x_
+  /// for any integer *x*.
   ///
   /// Two edge cases are worth particular attention:
   /// - `x.isMultiple(of: 0)` is `true` if `x` is zero and `false` otherwise.
   /// - `T.min.isMultiple(of: -1)` is `true` for signed integer `T`, even
-  ///   though the quotient `T.min / -1` is not representable in type `T`.
+  ///   though the quotient `T.min / -1` isn't representable in type `T`.
   ///
-  /// - Parameter other: the value to test.
+  /// - Parameter other: The value to test.
   func isMultiple(of other: Self) -> Bool
 
   /// Returns `-1` if this value is negative and `1` if it's positive;
diff --git a/stdlib/public/core/NativeDictionary.swift b/stdlib/public/core/NativeDictionary.swift
index 39df16d..f6abdaf 100644
--- a/stdlib/public/core/NativeDictionary.swift
+++ b/stdlib/public/core/NativeDictionary.swift
@@ -137,7 +137,7 @@
   @inline(__always)
   internal func uncheckedDestroy(at bucket: Bucket) {
     defer { _fixLifetime(self) }
-    _internalInvariant(hashTable.isOccupied(bucket))
+    _internalInvariant(hashTable.isValid(bucket))
     (_keys + bucket.offset).deinitialize(count: 1)
     (_values + bucket.offset).deinitialize(count: 1)
   }
@@ -620,11 +620,22 @@
   @inlinable
   @inline(__always)
   internal func moveEntry(from source: Bucket, to target: Bucket) {
+    _internalInvariant(hashTable.isValid(source))
+    _internalInvariant(hashTable.isValid(target))
     (_keys + target.offset)
       .moveInitialize(from: _keys + source.offset, count: 1)
     (_values + target.offset)
       .moveInitialize(from: _values + source.offset, count: 1)
   }
+
+  @inlinable
+  @inline(__always)
+  internal func swapEntry(_ left: Bucket, with right: Bucket) {
+    _internalInvariant(hashTable.isValid(left))
+    _internalInvariant(hashTable.isValid(right))
+    swap(&_keys[left.offset], &_keys[right.offset])
+    swap(&_values[left.offset], &_values[right.offset])
+  }
 }
 
 extension _NativeDictionary { // Deletion
diff --git a/stdlib/public/core/Result.swift b/stdlib/public/core/Result.swift
index fdd742e..c6386bf 100644
--- a/stdlib/public/core/Result.swift
+++ b/stdlib/public/core/Result.swift
@@ -27,7 +27,7 @@
   /// instance when it represents a success. The following example transforms
   /// the integer success value of a result into a string:
   ///
-  ///     func getNextInteger() -> Result<Int, Error> { ... }
+  ///     func getNextInteger() -> Result<Int, Error> { /* ... */ }
   ///
   ///     let integerResult = getNextInteger()
   ///     // integerResult == .success(5)
@@ -66,7 +66,7 @@
   ///         }
   ///     }
   ///
-  ///     let result: Result<Int, Error> = ...
+  ///     let result: Result<Int, Error> = // ...
   ///     // result == .failure(<error value>)
   ///     let resultWithDatedError = result.mapError({ e in DatedError(e) })
   ///     // result == .failure(DatedError(error: <error value>, date: <date>))
@@ -136,7 +136,7 @@
   ///     }
   ///     // Prints "The value is 5."
   ///
-  /// - Returns: The success value, if the instance represent a success.
+  /// - Returns: The success value, if the instance represents a success.
   /// - Throws: The failure value, if the instance represents a failure.
   public func get() throws -> Success {
     switch self {
diff --git a/stdlib/public/core/SIMDVector.swift b/stdlib/public/core/SIMDVector.swift
index e1ccb42..79d0d7d 100644
--- a/stdlib/public/core/SIMDVector.swift
+++ b/stdlib/public/core/SIMDVector.swift
@@ -15,25 +15,30 @@
 infix operator .|= : AssignmentPrecedence
 prefix operator .!
 
-/// A SIMD vector type that may not have any computational operations.
+/// A type that provides storage for a SIMD vector type.
 ///
-/// This protocol only defines a storage layout and provides elementwise
-/// accesses. Computational operations are defined on SIMDVector, which
-/// refines this protocol, or on the concrete types that conform.
+/// The `SIMDStorage` protocol defines a storage layout and provides
+/// elementwise accesses. Computational operations are defined on the `SIMD`
+/// protocol, which refines this protocol, and on the concrete types that
+/// conform to `SIMD`.
 public protocol SIMDStorage {
   /// The type of scalars in the vector space.
   associatedtype Scalar : Hashable
   
-  /// The number of scalars/elements in the vector.
+  /// The number of scalars, or elements, in the vector.
   var scalarCount: Int { get }
   
-  /// A vector with zero in all lanes.
+  /// Creates a vector with zero in all lanes.
   init()
   
-  /// Element access to the vector.
+  /// Accesses the element at the specified index.
+  ///
+  /// - Parameter index: The index of the element to access. `index` must be in
+  ///   the range `0..<scalarCount`.
   subscript(index: Int) -> Scalar { get set }
 }
 
+/// A type that can be used as an element in a SIMD vector.
 public protocol SIMDScalar {
   associatedtype SIMDMaskScalar : SIMDScalar & FixedWidthInteger & SignedInteger
   associatedtype SIMD2Storage : SIMDStorage where SIMD2Storage.Scalar == Self
@@ -44,6 +49,7 @@
   associatedtype SIMD64Storage : SIMDStorage where SIMD64Storage.Scalar == Self
 }
 
+/// A SIMD vector of a fixed number of elements.
 public protocol SIMD : SIMDStorage,
                        Hashable,
                        CustomStringConvertible,
@@ -58,14 +64,14 @@
   @_transparent
   var indices: Range<Int> { return 0 ..< scalarCount }
   
-  /// A vector with value in all lanes.
+  /// A vector with the specified value in all lanes.
   @_transparent
   init(repeating value: Scalar) {
     self.init()
     for i in indices { self[i] = value }
   }
   
-  /// Conformance to Equatable
+  /// Returns a Boolean value indicating whether two vectors are equal.
   @_transparent
   static func ==(lhs: Self, rhs: Self) -> Bool {
     var result = true
@@ -73,20 +79,20 @@
     return result
   }
   
-  /// Conformance to Hashable
+  /// Hashes the elements of the vector using the given hasher.
   @inlinable
   func hash(into hasher: inout Hasher) {
     for i in indices { hasher.combine(self[i]) }
   }
   
-  /// Conformance to CustomStringConvertible
+  /// A textual description of the vector.
   var description: String {
     get {
       return "\(Self.self)(" + indices.map({"\(self[$0])"}).joined(separator: ", ") + ")"
     }
   }
   
-  /// Pointwise equality
+  /// Returns a vector mask with the result of a pointwise equality comparison.
   @_transparent
   static func .==(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
     var result = SIMDMask<MaskStorage>()
@@ -94,6 +100,8 @@
     return result
   }
   
+  /// Returns a vector mask with the result of a pointwise inequality
+  /// comparison.
   @_transparent
   static func .!=(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
     var result = SIMDMask<MaskStorage>()
@@ -101,18 +109,26 @@
     return result
   }
   
-  /// Replaces elements of this vector with `other` in the lanes where
-  /// `mask` is `true`.
+  /// Replaces elements of this vector with elements of `other` in the lanes
+  /// where `mask` is `true`.
   @_transparent
   mutating func replace(with other: Self, where mask: SIMDMask<MaskStorage>) {
     for i in indices { self[i] = mask[i] ? other[i] : self[i] }
   }
   
+  /// Creates a vector from the specified elements.
+  ///
+  /// - Parameter scalars: The elements to use in the vector. `scalars` must
+  ///   have the same number of elements as the vector type.
   @inlinable
   init(arrayLiteral scalars: Scalar...) {
     self.init(scalars)
   }
   
+  /// Creates a vector from the given sequence.
+  ///
+  /// - Parameter scalars: The elements to use in the vector. `scalars` must
+  ///   have the same number of elements as the vector type.
   @inlinable
   init<S: Sequence>(_ scalars: S) where S.Element == Scalar {
     self.init()
@@ -133,7 +149,8 @@
 //  Implementations of comparison operations. These should eventually all
 //  be replaced with @_semantics to lower directly to vector IR nodes.
 public extension SIMD where Scalar : Comparable {
-  /// Pointwise less than
+  /// Returns a vector mask with the result of a pointwise less than
+  /// comparison.
   @_transparent
   static func .<(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
     var result = SIMDMask<MaskStorage>()
@@ -141,7 +158,8 @@
     return result
   }
   
-  /// Pointwise less than or equal to
+  /// Returns a vector mask with the result of a pointwise less than or equal
+  /// comparison.
   @_transparent
   static func .<=(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
     var result = SIMDMask<MaskStorage>()
@@ -153,16 +171,27 @@
 //  These operations should never need @_semantics; they should be trivial
 //  wrappers around the core operations defined above.
 public extension SIMD {
+  /// Returns a vector mask with the result of a pointwise equality comparison.
   @_transparent static func .==(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .== rhs }
+
+  /// Returns a vector mask with the result of a pointwise inequality comparison.
   @_transparent static func .!=(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .!= rhs }
+
+  /// Returns a vector mask with the result of a pointwise equality comparison.
   @_transparent static func .==(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .== Self(repeating: rhs) }
+
+  /// Returns a vector mask with the result of a pointwise inequality comparison.
   @_transparent static func .!=(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .!= Self(repeating: rhs) }
   
+  /// Replaces elements of this vector with `other` in the lanes where `mask`
+  /// is `true`.
   @_transparent
   mutating func replace(with other: Scalar, where mask: SIMDMask<MaskStorage>) {
     replace(with: Self(repeating: other), where: mask)
   }
   
+  /// Returns a copy of this vector, with elements replaced by elements of
+  /// `other` in the lanes where `mask` is `true`.
   @_transparent
   func replacing(with other: Self, where mask: SIMDMask<MaskStorage>) -> Self {
     var result = self
@@ -170,6 +199,8 @@
     return result
   }
   
+  /// Returns a copy of this vector, with elements `other` in the lanes where
+  /// `mask` is `true`.
   @_transparent
   func replacing(with other: Scalar, where mask: SIMDMask<MaskStorage>) -> Self {
     return replacing(with: Self(repeating: other), where: mask)
@@ -177,21 +208,51 @@
 }
 
 public extension SIMD where Scalar : Comparable {
+  /// Returns a vector mask with the result of a pointwise greater than or
+  /// equal comparison.
   @_transparent static func .>=(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> { return rhs .<= lhs }
+
+  /// Returns a vector mask with the result of a pointwise greater than
+  /// comparison.
   @_transparent static func .>(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> { return rhs .< lhs }
+
+  /// Returns a vector mask with the result of a pointwise less than comparison.
   @_transparent static func .<(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .< rhs }
+
+  /// Returns a vector mask with the result of a pointwise less than or equal
+  /// comparison.
   @_transparent static func .<=(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .<= rhs }
+
+  /// Returns a vector mask with the result of a pointwise greater than or
+  /// equal comparison.
   @_transparent static func .>=(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .>= rhs }
+
+  /// Returns a vector mask with the result of a pointwise greater than
+  /// comparison.
   @_transparent static func .>(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .> rhs }
+
+  /// Returns a vector mask with the result of a pointwise less than comparison.
   @_transparent static func .<(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .< Self(repeating: rhs) }
+
+  /// Returns a vector mask with the result of a pointwise less than or equal
+  /// comparison.
   @_transparent static func .<=(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .<= Self(repeating: rhs) }
+
+  /// Returns a vector mask with the result of a pointwise greater than or
+  /// equal comparison.
   @_transparent static func .>=(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .>= Self(repeating: rhs) }
+
+  /// Returns a vector mask with the result of a pointwise greater than
+  /// comparison.
   @_transparent static func .>(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .> Self(repeating: rhs) }
 }
 
 public extension SIMD where Scalar : FixedWidthInteger {
+  /// A vector with zero in all lanes.
   @_transparent static var zero: Self { return Self() }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes, using the given generator as a source for randomness.
   @inlinable
   static func random<T: RandomNumberGenerator>(
     in range: Range<Scalar>,
@@ -204,12 +265,16 @@
     return result
   }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes.
   @inlinable
   static func random(in range: Range<Scalar>) -> Self {
     var g = SystemRandomNumberGenerator()
     return Self.random(in: range, using: &g)
   }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes, using the given generator as a source for randomness.
   @inlinable
   static func random<T: RandomNumberGenerator>(
     in range: ClosedRange<Scalar>,
@@ -222,6 +287,8 @@
     return result
   }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes.
   @inlinable
   static func random(in range: ClosedRange<Scalar>) -> Self {
     var g = SystemRandomNumberGenerator()
@@ -230,11 +297,14 @@
 }
 
 public extension SIMD where Scalar : FloatingPoint {
+  /// A vector with zero in all lanes.
   @_transparent static var zero: Self { return Self() }
 }
 
 public extension SIMD
 where Scalar : BinaryFloatingPoint, Scalar.RawSignificand : FixedWidthInteger {
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes, using the given generator as a source for randomness.
   @inlinable
   static func random<T: RandomNumberGenerator>(
     in range: Range<Scalar>,
@@ -247,12 +317,16 @@
     return result
   }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes.
   @inlinable
   static func random(in range: Range<Scalar>) -> Self {
     var g = SystemRandomNumberGenerator()
     return Self.random(in: range, using: &g)
   }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes, using the given generator as a source for randomness.
   @inlinable
   static func random<T: RandomNumberGenerator>(
     in range: ClosedRange<Scalar>,
@@ -265,6 +339,8 @@
     return result
   }
   
+  /// Returns a vector with random values from within the specified range in
+  /// all lanes.
   @inlinable
   static func random(in range: ClosedRange<Scalar>) -> Self {
     var g = SystemRandomNumberGenerator()
@@ -313,6 +389,8 @@
 }
 
 public extension SIMDMask {
+  /// Returns a vector mask with `true` or `false` randomly assigned in each
+  /// lane, using the given generator as a source for randomness.
   @inlinable
   static func random<T: RandomNumberGenerator>(using generator: inout T) -> SIMDMask {
     var result = SIMDMask()
@@ -320,6 +398,8 @@
     return result
   }
   
+  /// Returns a vector mask with `true` or `false` randomly assigned in each
+  /// lane.
   @inlinable
   static func random() -> SIMDMask {
     var g = SystemRandomNumberGenerator()
diff --git a/stdlib/public/core/SIMDVectorTypes.swift.gyb b/stdlib/public/core/SIMDVectorTypes.swift.gyb
index a2ed3f5..6a3e13e 100644
--- a/stdlib/public/core/SIMDVectorTypes.swift.gyb
+++ b/stdlib/public/core/SIMDVectorTypes.swift.gyb
@@ -3,10 +3,16 @@
 word_bits = int(CMAKE_SIZEOF_VOID_P) * 8
 storagescalarCounts = [2,4,8,16,32,64]
 vectorscalarCounts = storagescalarCounts + [3]
+spelledNumbers = {
+  2: 'two', 4: 'four', 8: 'eight', 16: '16', 32: '32', 64: '64',
+  3: 'three'
+}
+ordinalPositions = ['first', 'second', 'third', 'fourth']
 }%
 
 %for n in vectorscalarCounts:
 % storageN = 4 if n == 3 else n
+/// A vector of ${spelledNumbers[n]} scalar values.
 @_fixed_layout
 public struct SIMD${n}<Scalar> : SIMD where Scalar: SIMDScalar {
 
@@ -14,16 +20,19 @@
 
   public typealias MaskStorage = SIMD${n}<Scalar.SIMDMaskScalar>
 
+  /// The number of scalars in the vector.
   @_transparent
   public var scalarCount: Int {
     return ${n}
   }
 
+  /// Creates a vector with zero in all lanes.
   @_transparent
   public init() {
     _storage = Scalar.SIMD${storageN}Storage()
   }
 
+  /// Accesses the scalar at the specified position.
   public subscript(index: Int) -> Scalar {
     @_transparent get {
       _precondition(indices.contains(index))
@@ -35,6 +44,7 @@
     }
   }
 
+  /// Creates a new vector from the given elements.
   @_transparent
   public init(${', '.join(['_ v' + str(i) + ': Scalar' for i in range(n)])}) {
     self.init()
@@ -44,12 +54,19 @@
   }
 
 % if n <= 4:
+  /// Creates a new vector from the given elements.
+  ///
+  /// - Parameters:
+  %  for i in range(n):
+  ///   - ${'xyzw'[i]}: The ${ordinalPositions[i]} element of the vector.
+  %  end
   @_transparent
   public init(${', '.join([c + ': Scalar' for c in 'xyzw'[:n]])}) {
     self.init(${', '.join('xyzw'[:n])})
   }
 
 %  for i in range(n):
+  /// The ${ordinalPositions[i]} element of the vector.
   @_transparent
   public var ${'xyzw'[i]}: Scalar {
     @_transparent get { return self[${i}]}
@@ -59,6 +76,7 @@
 %  end
 % end
 % if n >= 4:
+  /// Creates a new vector from two half-length vectors.
   @_transparent
   public init(lowHalf: SIMD${n/2}<Scalar>, highHalf: SIMD${n/2}<Scalar>) {
     self.init()
@@ -67,6 +85,7 @@
   }
 
 %  for (half,indx) in [('low','i'), ('high',str(n/2)+'+i'), ('even','2*i'), ('odd','2*i+1')]:
+  /// A half-length vector made up of the ${half} elements of the vector.
   public var ${half}Half: SIMD${n/2}<Scalar> {
     @inlinable get {
       var result = SIMD${n/2}<Scalar>()
@@ -83,6 +102,10 @@
 }
 
 public extension SIMD${n} where Scalar : FixedWidthInteger {
+  /// Creates a new vector from the given vector, truncating the bit patterns
+  /// of the given vector's elements if necessary.
+  ///
+  /// - Parameter other: The vector to convert.
   @inlinable
   init<Other>(truncatingIfNeeded other: SIMD${n}<Other>)
   where Other : FixedWidthInteger {
@@ -90,6 +113,10 @@
     for i in indices { self[i] = Scalar(truncatingIfNeeded: other[i]) }
   }
 
+  /// Creates a new vector from the given vector, clamping the values of the
+  /// given vector's elements if necessary.
+  ///
+  /// - Parameter other: The vector to convert.
   @inlinable
   init<Other>(clamping other: SIMD${n}<Other>)
   where Other : FixedWidthInteger {
@@ -97,6 +124,13 @@
     for i in indices { self[i] = Scalar(clamping: other[i]) }
   }
 
+  /// Creates a new vector from the given vector, rounding the given vector's
+  /// of elements using the specified rounding rule.
+  ///
+  /// - Parameters:
+  ///   - other: The vector to convert.
+  ///   - rule: The round rule to use when converting elements of `other.` The
+  ///     default is `.towardZero`.
   @inlinable
   init<Other>(
     _ other: SIMD${n}<Other>,
@@ -118,6 +152,9 @@
 }
 
 public extension SIMD${n} where Scalar : BinaryFloatingPoint {
+  /// Creates a new vector from the given vector of integers.
+  ///
+  /// - Parameter other: The vector to convert.
   @inlinable
   init<Other>(_ other: SIMD${n}<Other>)
   where Other : FixedWidthInteger {
@@ -125,6 +162,9 @@
     for i in indices { self[i] = Scalar(other[i]) }
   }
 
+  /// Creates a new vector from the given vector of floating-point values.
+  ///
+  /// - Parameter other: The vector to convert.
   @inlinable
   init<Other>(_ other: SIMD${n}<Other>)
   where Other : BinaryFloatingPoint {
@@ -145,6 +185,7 @@
 
 % for n in storagescalarCounts:
 %  bytes = n * self_type.bits / 8
+  /// Storage for a vector of ${spelledNumbers[n]} integers.
   @_fixed_layout
   @_alignment(${bytes if bytes <= 16 else 16})
   public struct SIMD${n}Storage : SIMDStorage {
@@ -189,6 +230,7 @@
 
 % for n in storagescalarCounts:
 %  bytes = n * bits / 8
+  /// Storage for a vector of ${spelledNumbers[n]} floating-point values.
   @_fixed_layout
   @_alignment(${bytes if bytes <= 16 else 16})
   public struct SIMD${n}Storage : SIMDStorage {
diff --git a/stdlib/public/core/SequenceAlgorithms.swift b/stdlib/public/core/SequenceAlgorithms.swift
index b0a24e4..94834a0 100644
--- a/stdlib/public/core/SequenceAlgorithms.swift
+++ b/stdlib/public/core/SequenceAlgorithms.swift
@@ -581,7 +581,7 @@
   /// predicate.
   ///
   /// You can use this method to count the number of elements that pass a test.
-  /// For example, this code finds the number of names that are fewer than
+  /// The following example finds the number of names that are fewer than
   /// five characters long:
   ///
   ///     let names = ["Jacqueline", "Ian", "Amy", "Juan", "Soroush", "Tiffany"]
@@ -589,7 +589,7 @@
   ///     // shortNameCount == 3
   ///
   /// To find the number of times a specific element appears in the sequence,
-  /// use the equal-to operator (`==`) in the closure to test for a match.
+  /// use the equal to operator (`==`) in the closure to test for a match.
   ///
   ///     let birds = ["duck", "duck", "duck", "duck", "goose"]
   ///     let duckCount = birds.count(where: { $0 == "duck" })
diff --git a/stdlib/public/core/StringStorage.swift b/stdlib/public/core/StringStorage.swift
index afb33ec..260d958 100644
--- a/stdlib/public/core/StringStorage.swift
+++ b/stdlib/public/core/StringStorage.swift
@@ -76,9 +76,8 @@
       fallthrough
     case (_cocoaUTF8Encoding, _):
       guard maxLength >= count + 1 else { return 0 }
-      let buffer =
-        UnsafeMutableBufferPointer(start: outputPtr, count: maxLength)
-      buffer.initialize(from: UnsafeBufferPointer(start: start, count: count))
+      let buffer = UnsafeMutableBufferPointer(start: outputPtr, count: maxLength)
+      _ = buffer.initialize(from: UnsafeBufferPointer(start: start, count: count))
       buffer[count] = 0
       return 1
     default:
diff --git a/stdlib/public/core/UnicodeScalar.swift b/stdlib/public/core/UnicodeScalar.swift
index 1f16ae2..18215e5 100644
--- a/stdlib/public/core/UnicodeScalar.swift
+++ b/stdlib/public/core/UnicodeScalar.swift
@@ -474,6 +474,9 @@
   ) rethrows -> Result {
     let encodedScalar = UTF8.encode(self)!
     var (codeUnits, utf8Count) = encodedScalar._bytes
+
+    // The first code unit is in the least significant byte of codeUnits.
+    codeUnits = codeUnits.littleEndian
     return try Swift.withUnsafePointer(to: &codeUnits) {
       return try $0.withMemoryRebound(to: UInt8.self, capacity: 4) {
         return try body(UnsafeBufferPointer(start: $0, count: utf8Count))
diff --git a/stdlib/public/core/UnicodeScalarProperties.swift b/stdlib/public/core/UnicodeScalarProperties.swift
index ad4b8e1..21a6796 100644
--- a/stdlib/public/core/UnicodeScalarProperties.swift
+++ b/stdlib/public/core/UnicodeScalarProperties.swift
@@ -19,7 +19,6 @@
 
   /// A value that provides access to properties of a Unicode scalar that are
   /// defined by the Unicode standard.
-
   public struct Properties {
     @usableFromInline
     internal var _scalar: Unicode.Scalar
@@ -34,8 +33,17 @@
     }
   }
 
-  /// A value that provides access to properties of the Unicode scalar that are
-  /// defined by the Unicode standard.
+  /// Properties of this scalar defined by the Unicode standard.
+  ///
+  /// Use this property to access the Unicode properties of a Unicode scalar
+  /// value. The following code tests whether a string contains any math
+  /// symbols:
+  ///
+  ///     let question = "Which is larger, 3 * 3 * 3 or 10 + 10 + 10?"
+  ///     let hasMathSymbols = question.unicodeScalars.contains(where: {
+  ///         $0.properties.isMath
+  ///     })
+  ///     // hasMathSymbols == true
   public var properties: Properties {
     return Properties(self)
   }
@@ -50,61 +58,61 @@
     return __swift_stdlib_u_hasBinaryProperty(icuValue, property) != 0
   }
 
-  /// A Boolean property indicating whether the scalar is alphabetic.
+  /// A Boolean value indicating whether the scalar is alphabetic.
   ///
   /// Alphabetic scalars are the primary units of alphabets and/or syllabaries.
   ///
-  /// This property corresponds to the `Alphabetic` property in the
+  /// This property corresponds to the "Alphabetic" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isAlphabetic: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_ALPHABETIC)
   }
 
-  /// A Boolean property indicating whether the scalar is an ASCII character
+  /// A Boolean value indicating whether the scalar is an ASCII character
   /// commonly used for the representation of hexadecimal numbers.
   ///
-  /// The only scalars for which this property is true are:
+  /// The only scalars for which this property is `true` are:
   ///
   /// * U+0030...U+0039: DIGIT ZERO...DIGIT NINE
   /// * U+0041...U+0046: LATIN CAPITAL LETTER A...LATIN CAPITAL LETTER F
   /// * U+0061...U+0066: LATIN SMALL LETTER A...LATIN SMALL LETTER F
   ///
-  /// This property corresponds to the `ASCII_Hex_Digit` property in the
+  /// This property corresponds to the "ASCII_Hex_Digit" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isASCIIHexDigit: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_ASCII_HEX_DIGIT)
   }
 
-  /// A Boolean property indicating whether the scalar is a format control
+  /// A Boolean value indicating whether the scalar is a format control
   /// character that has a specific function in the Unicode Bidrectional
   /// Algorithm.
   ///
-  /// This property corresponds to the `Bidi_Control` property in the
+  /// This property corresponds to the "Bidi_Control" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isBidiControl: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_BIDI_CONTROL)
   }
 
-  /// A Boolean property indicating whether the scalar is mirrored in
+  /// A Boolean value indicating whether the scalar is mirrored in
   /// bidirectional text.
   ///
-  /// This property corresponds to the `Bidi_Mirrored` property in the
+  /// This property corresponds to the "Bidi_Mirrored" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isBidiMirrored: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_BIDI_MIRRORED)
   }
 
-  /// A Boolean property indicating whether the scalar is a punctuation
+  /// A Boolean value indicating whether the scalar is a punctuation
   /// symbol explicitly called out as a dash in the Unicode Standard or a
   /// compatibility equivalent.
   ///
-  /// This property corresponds to the `Dash` property in the
+  /// This property corresponds to the "Dash" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isDash: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_DASH)
   }
 
-  /// A Boolean property indicating whether the scalar is a default-ignorable
+  /// A Boolean value indicating whether the scalar is a default-ignorable
   /// code point.
   ///
   /// Default-ignorable code points are those that should be ignored by default
@@ -112,100 +120,103 @@
   /// advance width in and of themselves, although they may affect the display,
   /// positioning, or adornment of adjacent or surrounding characters.
   ///
-  /// This property corresponds to the `Default_Ignorable_Code_Point` property
+  /// This property corresponds to the "Default_Ignorable_Code_Point" property
   /// in the [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isDefaultIgnorableCodePoint: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_DEFAULT_IGNORABLE_CODE_POINT)
   }
 
-  /// A Boolean property indicating whether the scalar is deprecated.
+  /// A Boolean value indicating whether the scalar is deprecated.
   ///
   /// Scalars are never removed from the Unicode Standard, but the usage of
   /// deprecated scalars is strongly discouraged.
   ///
-  /// This property corresponds to the `Deprecated` property in the
+  /// This property corresponds to the "Deprecated" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isDeprecated: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_DEPRECATED)
   }
 
-  /// A Boolean property indicating whether the scalar is a diacritic.
+  /// A Boolean value indicating whether the scalar is a diacritic.
   ///
   /// Diacritics are scalars that linguistically modify the meaning of another
-  /// scalar to which they apply. Scalars for which this property is true are
+  /// scalar to which they apply. Scalars for which this property is `true` are
   /// frequently, but not always, combining marks or modifiers.
   ///
-  /// This property corresponds to the `Diacritic` property in the
+  /// This property corresponds to the "Diacritic" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isDiacritic: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_DIACRITIC)
   }
 
-  /// A Boolean property indicating whether the scalar's principal function is
+  /// A Boolean value indicating whether the scalar's principal function is
   /// to extend the value or shape of a preceding alphabetic scalar.
   ///
   /// Typical extenders are length and iteration marks.
   ///
-  /// This property corresponds to the `Extender` property in the
+  /// This property corresponds to the "Extender" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isExtender: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_EXTENDER)
   }
 
-  /// A Boolean property indicating whether the scalar is excluded from
+  /// A Boolean value indicating whether the scalar is excluded from
   /// composition when performing Unicode normalization.
   ///
-  /// This property corresponds to the `Full_Composition_Exclusion` property in
+  /// This property corresponds to the "Full_Composition_Exclusion" property in
   /// the [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isFullCompositionExclusion: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_FULL_COMPOSITION_EXCLUSION)
   }
 
-  /// A Boolean property indicating whether the scalar is a grapheme base.
+  /// A Boolean value indicating whether the scalar is a grapheme base.
   ///
   /// A grapheme base can be thought of as a space-occupying glyph above or
   /// below which other non-spacing modifying glyphs can be applied. For
-  /// example, when the character `é` is represented in NFD form, the grapheme
-  /// base is "e" (U+0065 LATIN SMALL LETTER E) and it is followed by a single
-  /// grapheme extender, U+0301 COMBINING ACUTE ACCENT.
+  /// example, when the character `é` is represented in its decomposed form,
+  /// the grapheme base is "e" (U+0065 LATIN SMALL LETTER E) and it is followed
+  /// by a single grapheme extender, U+0301 COMBINING ACUTE ACCENT.
   ///
-  /// The set of scalars for which `isGraphemeBase` is true is disjoint by
-  /// definition from the set for which `isGraphemeExtend` is true.
+  /// The set of scalars for which `isGraphemeBase` is `true` is disjoint by
+  /// definition from the set for which `isGraphemeExtend` is `true`.
   ///
-  /// This property corresponds to the `Grapheme_Base` property in the
+  /// This property corresponds to the "Grapheme_Base" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isGraphemeBase: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_GRAPHEME_BASE)
   }
 
-  /// A Boolean property indicating whether the scalar is a grapheme extender.
+  /// A Boolean value indicating whether the scalar is a grapheme extender.
   ///
   /// A grapheme extender can be thought of primarily as a non-spacing glyph
-  /// that is applied above or below another glyph.
+  /// that is applied above or below another glyph. For example, when the
+  /// character `é` is represented in its decomposed form, the grapheme base is
+  /// "e" (U+0065 LATIN SMALL LETTER E) and it is followed by a single grapheme
+  /// extender, U+0301 COMBINING ACUTE ACCENT.
   ///
-  /// The set of scalars for which `isGraphemeExtend` is true is disjoint by
-  /// definition from the set for which `isGraphemeBase` is true.
+  /// The set of scalars for which `isGraphemeExtend` is `true` is disjoint by
+  /// definition from the set for which `isGraphemeBase` is `true`.
   ///
-  /// This property corresponds to the `Grapheme_Extend` property in the
+  /// This property corresponds to the "Grapheme_Extend" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isGraphemeExtend: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_GRAPHEME_EXTEND)
   }
 
-  /// A Boolean property indicating whether the scalar is one that is commonly
+  /// A Boolean value indicating whether the scalar is one that is commonly
   /// used for the representation of hexadecimal numbers or a compatibility
   /// equivalent.
   ///
-  /// This property is true for all scalars for which `isASCIIHexDigit` is true
-  /// as well as for their CJK halfwidth and fullwidth variants.
+  /// This property is `true` for all scalars for which `isASCIIHexDigit` is
+  /// `true` as well as for their CJK halfwidth and fullwidth variants.
   ///
-  /// This property corresponds to the `Hex_Digit` property in the
+  /// This property corresponds to the "Hex_Digit" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isHexDigit: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_HEX_DIGIT)
   }
 
-  /// A Boolean property indicating whether the scalar is one which is
+  /// A Boolean value indicating whether the scalar is one which is
   /// recommended to be allowed to appear in a non-starting position in a
   /// programming language identifier.
   ///
@@ -213,13 +224,13 @@
   /// use `isXIDContinue` to check whether a scalar is a valid identifier
   /// character.
   ///
-  /// This property corresponds to the `ID_Continue` property in the
+  /// This property corresponds to the "ID_Continue" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isIDContinue: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_ID_CONTINUE)
   }
 
-  /// A Boolean property indicating whether the scalar is one which is
+  /// A Boolean value indicating whether the scalar is one which is
   /// recommended to be allowed to appear in a starting position in a
   /// programming language identifier.
   ///
@@ -227,13 +238,13 @@
   /// use `isXIDStart` to check whether a scalar is a valid identifier
   /// character.
   ///
-  /// This property corresponds to the `ID_Start` property in the
+  /// This property corresponds to the "ID_Start" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isIDStart: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_ID_START)
   }
 
-  /// A Boolean property indicating whether the scalar is considered to be a
+  /// A Boolean value indicating whether the scalar is considered to be a
   /// CJKV (Chinese, Japanese, Korean, and Vietnamese) or other siniform
   /// (Chinese writing-related) ideograph.
   ///
@@ -241,13 +252,13 @@
   /// not include characters of other logographic scripts such as Cuneiform or
   /// Egyptian Hieroglyphs.
   ///
-  /// This property corresponds to the `Ideographic` property in the
+  /// This property corresponds to the "Ideographic" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isIdeographic: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_IDEOGRAPHIC)
   }
 
-  /// A Boolean property indicating whether the scalar is an ideographic
+  /// A Boolean value indicating whether the scalar is an ideographic
   /// description character that determines how the two ideographic characters
   /// or ideographic description sequences that follow it are to be combined to
   /// form a single character.
@@ -256,13 +267,13 @@
   /// but advanced rendering engines may use them to approximate ideographs that
   /// are otherwise unrepresentable.
   ///
-  /// This property corresponds to the `IDS_Binary_Operator` property in the
+  /// This property corresponds to the "IDS_Binary_Operator" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isIDSBinaryOperator: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_IDS_BINARY_OPERATOR)
   }
 
-  /// A Boolean property indicating whether the scalar is an ideographic
+  /// A Boolean value indicating whether the scalar is an ideographic
   /// description character that determines how the three ideographic characters
   /// or ideographic description sequences that follow it are to be combined to
   /// form a single character.
@@ -271,17 +282,17 @@
   /// but advanced rendering engines may use them to approximate ideographs that
   /// are otherwise unrepresentable.
   ///
-  /// This property corresponds to the `IDS_Trinary_Operator` property in the
+  /// This property corresponds to the "IDS_Trinary_Operator" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isIDSTrinaryOperator: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_IDS_TRINARY_OPERATOR)
   }
 
-  /// A Boolean property indicating whether the scalar is a format control
+  /// A Boolean value indicating whether the scalar is a format control
   /// character that has a specific function in controlling cursive joining and
   /// ligation.
   ///
-  /// There are two scalars for which this property is true:
+  /// There are two scalars for which this property is `true`:
   ///
   /// * When U+200C ZERO WIDTH NON-JOINER is inserted between two characters, it
   ///   directs the rendering engine to render them separately/disconnected when
@@ -297,13 +308,13 @@
   ///   For example, the various "family" emoji are encoded as sequences of man,
   ///   woman, or child emoji that are interleaved with zero width joiners.
   ///
-  /// This property corresponds to the `Join_Control` property in the
+  /// This property corresponds to the "Join_Control" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isJoinControl: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_JOIN_CONTROL)
   }
 
-  /// A Boolean property indicating whether the scalar requires special handling
+  /// A Boolean value indicating whether the scalar requires special handling
   /// for operations involving ordering, such as sorting and searching.
   ///
   /// This property applies to a small number of spacing vowel letters occurring
@@ -311,125 +322,125 @@
   /// order display model. Such letters are stored in text ahead of
   /// syllable-initial consonants.
   ///
-  /// This property corresponds to the `Logical_Order_Exception` property in the
+  /// This property corresponds to the "Logical_Order_Exception" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isLogicalOrderException: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_LOGICAL_ORDER_EXCEPTION)
   }
 
-  /// A Boolean property indicating whether the scalar's letterform is
+  /// A Boolean value indicating whether the scalar's letterform is
   /// considered lowercase.
   ///
-  /// This property corresponds to the `Lowercase` property in the
+  /// This property corresponds to the "Lowercase" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isLowercase: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_LOWERCASE)
   }
 
-  /// A Boolean property indicating whether the scalar is one that naturally
+  /// A Boolean value indicating whether the scalar is one that naturally
   /// appears in mathematical contexts.
   ///
-  /// The set of scalars for which this property is true includes mathematical
+  /// The set of scalars for which this property is `true` includes mathematical
   /// operators and symbols as well as specific Greek and Hebrew letter
   /// variants that are categorized as symbols. Notably, it does _not_ contain
   /// the standard digits or Latin/Greek letter blocks; instead, it contains the
   /// mathematical Latin, Greek, and Arabic letters and numbers defined in the
   /// Supplemental Multilingual Plane.
   ///
-  /// This property corresponds to the `Math` property in the
+  /// This property corresponds to the "Math" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isMath: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_MATH)
   }
 
-  /// A Boolean property indicating whether the scalar is permanently reserved
+  /// A Boolean value indicating whether the scalar is permanently reserved
   /// for internal use.
   ///
-  /// This property corresponds to the `Noncharacter_Code_Point` property in the
+  /// This property corresponds to the "Noncharacter_Code_Point" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isNoncharacterCodePoint: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_NONCHARACTER_CODE_POINT)
   }
 
-  /// A Boolean property indicating whether the scalar is one that is used in
+  /// A Boolean value indicating whether the scalar is one that is used in
   /// writing to surround quoted text.
   ///
-  /// This property corresponds to the `Quotation_Mark` property in the
+  /// This property corresponds to the "Quotation_Mark" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isQuotationMark: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_QUOTATION_MARK)
   }
 
-  /// A Boolean property indicating whether the scalar is a radical component of
+  /// A Boolean value indicating whether the scalar is a radical component of
   /// CJK characters, Tangut characters, or Yi syllables.
   ///
   /// These scalars are often the components of ideographic description
   /// sequences, as defined by the `isIDSBinaryOperator` and
   /// `isIDSTrinaryOperator` properties.
   ///
-  /// This property corresponds to the `Radical` property in the
+  /// This property corresponds to the "Radical" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isRadical: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_RADICAL)
   }
 
-  /// A Boolean property indicating whether the scalar has a "soft dot" that
+  /// A Boolean value indicating whether the scalar has a "soft dot" that
   /// disappears when a diacritic is placed over the scalar.
   ///
   /// For example, "i" is soft dotted because the dot disappears when adding an
   /// accent mark, as in "í".
   ///
-  /// This property corresponds to the `Soft_Dotted` property in the
+  /// This property corresponds to the "Soft_Dotted" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isSoftDotted: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_SOFT_DOTTED)
   }
 
-  /// A Boolean property indicating whether the scalar is a punctuation symbol
+  /// A Boolean value indicating whether the scalar is a punctuation symbol
   /// that typically marks the end of a textual unit.
   ///
-  /// This property corresponds to the `Terminal_Punctuation` property in the
+  /// This property corresponds to the "Terminal_Punctuation" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isTerminalPunctuation: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_TERMINAL_PUNCTUATION)
   }
 
-  /// A Boolean property indicating whether the scalar is one of the unified
+  /// A Boolean value indicating whether the scalar is one of the unified
   /// CJK ideographs in the Unicode Standard.
   ///
   /// This property is false for CJK punctuation and symbols, as well as for
   /// compatibility ideographs (which canonically decompose to unified
   /// ideographs).
   ///
-  /// This property corresponds to the `Unified_Ideograph` property in the
+  /// This property corresponds to the "Unified_Ideograph" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isUnifiedIdeograph: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_UNIFIED_IDEOGRAPH)
   }
 
-  /// A Boolean property indicating whether the scalar's letterform is
+  /// A Boolean value indicating whether the scalar's letterform is
   /// considered uppercase.
   ///
-  /// This property corresponds to the `Uppercase` property in the
+  /// This property corresponds to the "Uppercase" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isUppercase: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_UPPERCASE)
   }
 
-  /// A Boolean property indicating whether the scalar is a whitespace
+  /// A Boolean value indicating whether the scalar is a whitespace
   /// character.
   ///
-  /// This property is true for scalars that are spaces, separator characters,
+  /// This property is `true` for scalars that are spaces, separator characters,
   /// and other control characters that should be treated as whitespace for the
   /// purposes of parsing text elements.
   ///
-  /// This property corresponds to the `White_Space` property in the
+  /// This property corresponds to the "White_Space" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isWhitespace: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_WHITE_SPACE)
   }
 
-  /// A Boolean property indicating whether the scalar is one which is
+  /// A Boolean value indicating whether the scalar is one which is
   /// recommended to be allowed to appear in a non-starting position in a
   /// programming language identifier, with adjustments made for NFKC normalized
   /// form.
@@ -438,13 +449,13 @@
   /// under NFKC normalization by removing any scalars whose normalized form is
   /// not of the form `[:ID_Continue:]*`.
   ///
-  /// This property corresponds to the `XID_Continue` property in the
+  /// This property corresponds to the "XID_Continue" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isXIDContinue: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_XID_CONTINUE)
   }
 
-  /// A Boolean property indicating whether the scalar is one which is
+  /// A Boolean value indicating whether the scalar is one which is
   /// recommended to be allowed to appear in a starting position in a
   /// programming language identifier, with adjustments made for NFKC normalized
   /// form.
@@ -453,132 +464,127 @@
   /// NFKC normalization by removing any scalars whose normalized form is not of
   /// the form `[:ID_Start:] [:ID_Continue:]*`.
   ///
-  /// This property corresponds to the `XID_Start` property in the
+  /// This property corresponds to the "XID_Start" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isXIDStart: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_XID_START)
   }
 
-  /// A Boolean property indicating whether the scalar is a punctuation mark
+  /// A Boolean value indicating whether the scalar is a punctuation mark
   /// that generally marks the end of a sentence.
   ///
-  /// This property corresponds to the `Sentence_Terminal` property in the
+  /// This property corresponds to the "Sentence_Terminal" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isSentenceTerminal: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_S_TERM)
   }
 
-  /// A Boolean property indicating whether the scalar is a variation selector.
+  /// A Boolean value indicating whether the scalar is a variation selector.
   ///
   /// Variation selectors allow rendering engines that support them to choose
   /// different glyphs to display for a particular code point.
   ///
-  /// This property corresponds to the `Variation_Selector` property in the
+  /// This property corresponds to the "Variation_Selector" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isVariationSelector: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_VARIATION_SELECTOR)
   }
 
-  /// A Boolean property indicating whether the scalar is recommended to have
+  /// A Boolean value indicating whether the scalar is recommended to have
   /// syntactic usage in patterns represented in source code.
   ///
-  /// This property corresponds to the `Pattern_Syntax` property in the
+  /// This property corresponds to the "Pattern_Syntax" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isPatternSyntax: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_PATTERN_SYNTAX)
   }
 
-  /// A Boolean property indicating whether the scalar is recommended to be
+  /// A Boolean value indicating whether the scalar is recommended to be
   /// treated as whitespace when parsing patterns represented in source code.
   ///
-  /// This property corresponds to the `Pattern_White_Space` property in the
+  /// This property corresponds to the "Pattern_White_Space" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isPatternWhitespace: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_PATTERN_WHITE_SPACE)
   }
 
-  /// A Boolean property indicating whether the scalar is considered to be
+  /// A Boolean value indicating whether the scalar is considered to be
   /// either lowercase, uppercase, or titlecase.
   ///
-  /// Though similar in name, this property is _not_ equivalent to
-  /// `changesWhenCaseMapped`. The set of scalars for which `isCased` is true is
-  /// a superset of those for which `changesWhenCaseMapped` is true. An example
-  /// of scalars that only have `isCased` as true are the Latin small capitals
-  /// that are used by the International Phonetic Alphabet. These letters have a
-  /// case but do not change when they are mapped to any of the other cases.
+  /// Though similar in name, this property is *not* equivalent to
+  /// `changesWhenCaseMapped`. The set of scalars for which `isCased` is `true`
+  /// is a superset of those for which `changesWhenCaseMapped` is `true`. For
+  /// example, the Latin small capitals that are used by the International
+  /// Phonetic Alphabet have a case, but do not change when they are mapped to
+  /// any of the other cases.
   ///
-  /// This property corresponds to the `Cased` property in the
+  /// This property corresponds to the "Cased" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isCased: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CASED)
   }
 
-  /// A Boolean property indicating whether the scalar is ignored for casing
+  /// A Boolean value indicating whether the scalar is ignored for casing
   /// purposes.
   ///
-  /// This property corresponds to the `Case_Ignorable` property in the
+  /// This property corresponds to the "Case_Ignorable" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var isCaseIgnorable: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CASE_IGNORABLE)
   }
 
-  /// A Boolean property indicating whether the scalar's normalized form differs
+  /// A Boolean value indicating whether the scalar's normalized form differs
   /// from the `lowercaseMapping` of each constituent scalar.
   ///
-  /// This property corresponds to the `Changes_When_Lowercased` property in the
+  /// This property corresponds to the "Changes_When_Lowercased" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var changesWhenLowercased: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CHANGES_WHEN_LOWERCASED)
   }
 
-  /// A Boolean property indicating whether the scalar's normalized form differs
+  /// A Boolean value indicating whether the scalar's normalized form differs
   /// from the `uppercaseMapping` of each constituent scalar.
   ///
-  /// This property corresponds to the `Changes_When_Uppercased` property in the
+  /// This property corresponds to the "Changes_When_Uppercased" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var changesWhenUppercased: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CHANGES_WHEN_UPPERCASED)
   }
 
-  /// A Boolean property indicating whether the scalar's normalized form differs
+  /// A Boolean value indicating whether the scalar's normalized form differs
   /// from the `titlecaseMapping` of each constituent scalar.
   ///
-  /// This property corresponds to the `Changes_When_Titlecased` property in the
+  /// This property corresponds to the "Changes_When_Titlecased" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var changesWhenTitlecased: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CHANGES_WHEN_TITLECASED)
   }
 
-  /// A Boolean property indicating whether the scalar's normalized form differs
+  /// A Boolean value indicating whether the scalar's normalized form differs
   /// from the case-fold mapping of each constituent scalar.
   ///
-  /// This property corresponds to the `Changes_When_Casefolded` property in the
+  /// This property corresponds to the "Changes_When_Casefolded" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var changesWhenCaseFolded: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CHANGES_WHEN_CASEFOLDED)
   }
 
-  /// A Boolean property indicating whether the scalar may change when it
+  /// A Boolean value indicating whether the scalar may change when it
   /// undergoes case mapping.
   ///
-  /// For any scalar `s`, it holds by definition that
+  /// This property is `true` whenever one or more of `changesWhenLowercased`,
+  /// `changesWhenUppercased`, or `changesWhenTitlecased` are `true`.
   ///
-  /// ```
-  /// s.changesWhenCaseMapped = s.changesWhenLowercased ||
-  ///                           s.changesWhenUppercased ||
-  ///                           s.changesWhenTitlecased
-  /// ```
-  ///
-  /// This property corresponds to the `Changes_When_Casemapped` property in the
+  /// This property corresponds to the "Changes_When_Casemapped" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var changesWhenCaseMapped: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CHANGES_WHEN_CASEMAPPED)
   }
 
-  /// A Boolean property indicating whether the scalar is one that is not
+  /// A Boolean value indicating whether the scalar is one that is not
   /// identical to its NFKC case-fold mapping.
   ///
-  /// This property corresponds to the `Changes_When_NFKC_Casefolded` property
+  /// This property corresponds to the "Changes_When_NFKC_Casefolded" property
   /// in the [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var changesWhenNFKCCaseFolded: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED)
@@ -590,7 +596,7 @@
   // non-Darwin platforms for now; bundling ICU with the toolchain would resolve
   // this and other inconsistencies (https://bugs.swift.org/browse/SR-6076).
 
-  /// A Boolean property indicating whether the scalar has an emoji
+  /// A Boolean value indicating whether the scalar has an emoji
   /// presentation, whether or not it is the default.
   ///
   /// This property is true for scalars that are rendered as emoji by default
@@ -598,18 +604,13 @@
   /// by U+FE0F VARIATION SELECTOR-16. This includes some scalars that are not
   /// typically considered to be emoji:
   ///
-  /// ```
-  /// let sunglasses: Unicode.Scalar = "😎"
-  /// let dollar: Unicode.Scalar = "$"
-  /// let zero: Unicode.Scalar = "0"
-  ///
-  /// print(sunglasses.isEmoji)
-  /// // Prints "true"
-  /// print(dollar.isEmoji)
-  /// // Prints "false"
-  /// print(zero.isEmoji)
-  /// // Prints "true"
-  /// ```
+  ///     let scalars: [Unicode.Scalar] = ["😎", "$", "0"]
+  ///     for s in scalars {
+  ///         print(s, "-->", s.isEmoji)
+  ///     }
+  ///     // 😎 --> true
+  ///     // $ --> false
+  ///     // 0 --> true
   ///
   /// The final result is true because the ASCII digits have non-default emoji
   /// presentations; some platforms render these with an alternate appearance.
@@ -622,48 +623,48 @@
   /// determine whether it is followed by a variation selector that would modify
   /// the presentation.
   ///
-  /// This property corresponds to the `Emoji` property in the
+  /// This property corresponds to the "Emoji" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   @available(macOS 10.12.2, iOS 10.2, tvOS 10.1, watchOS 3.1.1, *)
   public var isEmoji: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_EMOJI)
   }
 
-  /// A Boolean property indicating whether the scalar is one that should be
+  /// A Boolean value indicating whether the scalar is one that should be
   /// rendered with an emoji presentation, rather than a text presentation, by
   /// default.
   ///
-  /// Scalars that have emoji presentation by default can be followed by
+  /// Scalars that have default to emoji presentation can be followed by
   /// U+FE0E VARIATION SELECTOR-15 to request the text presentation of the
   /// scalar instead. Likewise, scalars that default to text presentation can
   /// be followed by U+FE0F VARIATION SELECTOR-16 to request the emoji
   /// presentation.
   ///
-  /// This property corresponds to the `Emoji_Presentation` property in the
+  /// This property corresponds to the "Emoji_Presentation" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   @available(macOS 10.12.2, iOS 10.2, tvOS 10.1, watchOS 3.1.1, *)
   public var isEmojiPresentation: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_EMOJI_PRESENTATION)
   }
 
-  /// A Boolean property indicating whether the scalar is one that can modify
+  /// A Boolean value indicating whether the scalar is one that can modify
   /// a base emoji that precedes it.
   ///
   /// The Fitzpatrick skin types are examples of emoji modifiers; they change
   /// the appearance of the preceding emoji base (that is, a scalar for which
   /// `isEmojiModifierBase` is true) by rendering it with a different skin tone.
   ///
-  /// This property corresponds to the `Emoji_Modifier` property in the
+  /// This property corresponds to the "Emoji_Modifier" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   @available(macOS 10.12.2, iOS 10.2, tvOS 10.1, watchOS 3.1.1, *)
   public var isEmojiModifier: Bool {
     return _hasBinaryProperty(__swift_stdlib_UCHAR_EMOJI_MODIFIER)
   }
 
-  /// A Boolean property indicating whether the scalar is one whose appearance
+  /// A Boolean value indicating whether the scalar is one whose appearance
   /// can be changed by an emoji modifier that follows it.
   ///
-  /// This property corresponds to the `Emoji_Modifier_Base` property in the
+  /// This property corresponds to the "Emoji_Modifier_Base" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   @available(macOS 10.12.2, iOS 10.2, tvOS 10.1, watchOS 3.1.1, *)
   public var isEmojiModifierBase: Bool {
@@ -725,7 +726,7 @@
   /// WITH DOT ABOVE) becomes two scalars (U+0069 LATIN SMALL LETTER I, U+0307
   /// COMBINING DOT ABOVE) when converted to lowercase.
   ///
-  /// This property corresponds to the `Lowercase_Mapping` property in the
+  /// This property corresponds to the "Lowercase_Mapping" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var lowercaseMapping: String {
     return _applyMapping(__swift_stdlib_u_strToLower)
@@ -739,7 +740,7 @@
   /// becomes "Fi" (U+0046 LATIN CAPITAL LETTER F, U+0069 LATIN SMALL LETTER I)
   /// when converted to titlecase.
   ///
-  /// This property corresponds to the `Titlecase_Mapping` property in the
+  /// This property corresponds to the "Titlecase_Mapping" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var titlecaseMapping: String {
     return _applyMapping { ptr, cap, src, len, locale, err in
@@ -755,7 +756,7 @@
   /// SHARP S) becomes "SS" (U+0053 LATIN CAPITAL LETTER S, U+0053 LATIN CAPITAL
   /// LETTER S) when converted to uppercase.
   ///
-  /// This property corresponds to the `Uppercase_Mapping` property in the
+  /// This property corresponds to the "Uppercase_Mapping" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var uppercaseMapping: String {
     return _applyMapping(__swift_stdlib_u_strToUpper)
@@ -764,7 +765,7 @@
 
 extension Unicode {
 
-  /// A version of the Unicode Standard represented by its `major.minor`
+  /// A version of the Unicode Standard represented by its major and minor
   /// components.
   public typealias Version = (major: Int, minor: Int)
 }
@@ -774,9 +775,9 @@
   /// The earliest version of the Unicode Standard in which the scalar was
   /// assigned.
   ///
-  /// This value will be nil for code points that have not yet been assigned.
+  /// This value is `nil` for code points that have not yet been assigned.
   ///
-  /// This property corresponds to the `Age` property in the
+  /// This property corresponds to the "Age" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var age: Unicode.Version? {
     var versionInfo: __swift_stdlib_UVersionInfo = (0, 0, 0, 0)
@@ -1074,7 +1075,7 @@
 
   /// The general category (most usual classification) of the scalar.
   ///
-  /// This property corresponds to the `General_Category` property in the
+  /// This property corresponds to the "General_Category" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var generalCategory: Unicode.GeneralCategory {
     let rawValue = __swift_stdlib_UCharCategory(
@@ -1117,15 +1118,16 @@
   /// The published name of the scalar.
   ///
   /// Some scalars, such as control characters, do not have a value for this
-  /// property in the UCD. For such scalars, this property will be nil.
+  /// property in the Unicode Character Database. For such scalars, this
+  /// property is `nil`.
   ///
-  /// This property corresponds to the `Name` property in the
+  /// This property corresponds to the "Name" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var name: String? {
     return _scalarName(__swift_stdlib_U_UNICODE_CHAR_NAME)
   }
 
-  /// The normative formal alias of the scalar, or nil if it has no alias.
+  /// The normative formal alias of the scalar.
   ///
   /// The name of a scalar is immutable and never changed in future versions of
   /// the Unicode Standard. The `nameAlias` property is provided to issue
@@ -1134,7 +1136,9 @@
   /// (note that "BRACKET" is misspelled). The `nameAlias` property then
   /// contains the corrected name.
   ///
-  /// This property corresponds to the `Name_Alias` property in the
+  /// If a scalar has no alias, this property is `nil`.
+  ///
+  /// This property corresponds to the "Name_Alias" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var nameAlias: String? {
     return _scalarName(__swift_stdlib_U_CHAR_NAME_ALIAS)
@@ -1159,10 +1163,10 @@
   /// `"\u{0041}\u{0316}\u{0301}"`, so two strings that differ only by the
   /// ordering of those scalars would compare as equal:
   ///
-  /// ```
-  /// print("\u{0041}\u{0316}\u{0301}" == "\u{0041}\u{0301}\u{0316}")
-  /// // Prints "true"
-  /// ```
+  ///     let aboveBeforeBelow = "\u{0041}\u{0301}\u{0316}"
+  ///     let belowBeforeAbove = "\u{0041}\u{0316}\u{0301}"
+  ///     print(aboveBeforeBelow == belowBeforeAbove)
+  ///     // Prints "true"
   ///
   /// Named and Unnamed Combining Classes
   /// ===================================
@@ -1172,15 +1176,13 @@
   /// symbolic names to a subset of these combining classes.
   ///
   /// The `CanonicalCombiningClass` type conforms to `RawRepresentable` with a
-  /// raw value of type `UInt8`. Instances of the type can be created from the
-  /// actual numeric value using the `init(rawValue:)` initializer, and
-  /// combining classes with symbolic names can also be referenced using the
-  /// static members that share those names.
+  /// raw value of type `UInt8`. You can create instances of the type by using
+  /// the static members named after the symbolic names, or by using the
+  /// `init(rawValue:)` initializer.
   ///
-  /// ```
-  /// print(Unicode.CanonicalCombiningClass(rawValue: 1) == .overlay)
-  /// // Prints "true"
-  /// ```
+  ///     let overlayClass = Unicode.CanonicalCombiningClass(rawValue: 1)
+  ///     let overlayClassIsOverlay = overlayClass == .overlay
+  ///     // overlayClassIsOverlay == true
   public struct CanonicalCombiningClass:
     Comparable, Hashable, RawRepresentable
   {
@@ -1286,7 +1288,7 @@
 
   /// The canonical combining class of the scalar.
   ///
-  /// This property corresponds to the `Canonical_Combining_Class` property in
+  /// This property corresponds to the "Canonical_Combining_Class" property in
   /// the [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var canonicalCombiningClass: Unicode.CanonicalCombiningClass {
     let rawValue = UInt8(__swift_stdlib_u_getIntPropertyValue(
@@ -1308,32 +1310,35 @@
   /// from incorrectly interpreting them as numbers in non-numeric contexts.
   public enum NumericType {
 
-    /// Digits that are commonly understood to form base-10 numbers.
+    /// A digit that is commonly understood to form base-10 numbers.
     ///
     /// Specifically, scalars have this numeric type if they occupy a contiguous
     /// range of code points representing numeric values `0...9`.
     case decimal
 
-    /// Decimal digits that otherwise do not meet the requirements of numeric
-    /// type `decimal`.
+    /// A digit that does not meet the requirements of the `decimal` numeric
+    /// type.
     ///
     /// Scalars with this numeric type are often those that represent a decimal
-    /// digit but would not typically be used to write a base-10 number, such as
-    /// "④" (U+2463 CIRCLED DIGIT FOUR).
+    /// digit but would not typically be used to write a base-10 number, such
+    /// as "④" (U+2463 CIRCLED DIGIT FOUR).
     ///
-    /// In practice, the distinction between `digit` and `numeric` has not
-    /// proven to be valuable. As of Unicode 6.3, any new scalars that represent
-    /// numbers but do not meet the requirements of `decimal` will have numeric
-    /// type `numeric`, and programs can treat `digit` and `numeric`
-    /// equivalently.
+    /// As of Unicode 6.3, any new scalars that represent numbers but do not
+    /// meet the requirements of `decimal` will have numeric type `numeric`,
+    /// and programs can treat `digit` and `numeric` equivalently.
     case digit
 
-    /// Numbers that are not decimal digits.
+    /// A digit that does not meet the requirements of the `decimal` numeric
+    /// type or a non-digit numeric value.
     ///
-    /// This numeric type includes fractions such as "⅕" (U+2155 VULGAR FRACITON
-    /// ONE FIFTH), numerical CJK ideographs like "兆" (U+5146 CJK UNIFIED
-    /// IDEOGRAPH-5146), and other scalars that are not decimal digits used
-    /// positionally in the writing of base-10 numbers.
+    /// This numeric type includes fractions such as "⅕" (U+2155 VULGAR
+    /// FRACITON ONE FIFTH), numerical CJK ideographs like "兆" (U+5146 CJK
+    /// UNIFIED IDEOGRAPH-5146), and other scalars that are not decimal digits
+    /// used positionally in the writing of base-10 numbers.
+    ///
+    /// As of Unicode 6.3, any new scalars that represent numbers but do not
+    /// meet the requirements of `decimal` will have numeric type `numeric`,
+    /// and programs can treat `digit` and `numeric` equivalently.
     case numeric
 
     internal init?(rawValue: __swift_stdlib_UNumericType) {
@@ -1353,21 +1358,19 @@
 
   /// The numeric type of the scalar.
   ///
-  /// The value of this property is nil for scalars that do not represent a
-  /// number.
+  /// For scalars that represent a number, `numericType` is the numeric type
+  /// of the scalar. For all other scalars, this property is `nil`.
   ///
-  /// ```
-  /// print("X", ("X" as Unicode.Scalar).properties.numericType ?? "nil")
-  /// // Prints "X nil"
-  /// print("4", ("4" as Unicode.Scalar).properties.numericType ?? "nil")
-  /// // Prints "4 decimal"
-  /// print("\u{2463}", ("\u{2463}" as Unicode.Scalar).properties.numericType ?? "nil")
-  /// // Prints "④ digit"
-  /// print("\u{2155}", ("\u{2155}" as Unicode.Scalar).properties.numericType ?? "nil")
-  /// // Prints "⅕ numeric"
-  /// ```
+  ///     let scalars: [Unicode.Scalar] = ["4", "④", "⅕", "X"]
+  ///     for scalar in scalars {
+  ///         print(scalar, "-->", scalar.properties.numericType)
+  ///     }
+  ///     // 4 --> decimal
+  ///     // ④ --> digit
+  ///     // ⅕ --> numeric
+  ///     // X --> nil
   ///
-  /// This property corresponds to the `Numeric_Type` property in the
+  /// This property corresponds to the "Numeric_Type" property in the
   /// [Unicode Standard](http://www.unicode.org/versions/latest/).
   public var numericType: Unicode.NumericType? {
     let rawValue = __swift_stdlib_UNumericType(
@@ -1379,25 +1382,20 @@
 
   /// The numeric value of the scalar.
   ///
-  /// The value of this property is nil for scalars that do not represent a
-  /// number.
+  /// For scalars that represent a numeric value, `numericValue` is the whole
+  /// or fractional value. For all other scalars, this property is `nil`.
   ///
-  /// The numeric value of a scalar is represented as a `Double` because some
-  /// scalars represent fractions:
+  ///     let scalars: [Unicode.Scalar] = ["4", "④", "⅕", "X"]
+  ///     for scalar in scalars {
+  ///         print(scalar, "-->", scalar.properties.numericValue)
+  ///     }
+  ///     // 4 --> 4.0
+  ///     // ④ --> 4.0
+  ///     // ⅕ --> 0.2
+  ///     // X --> nil
   ///
-  /// ```
-  /// print("X", ("X" as Unicode.Scalar).properties.numericValue ?? "nil")
-  /// // Prints "X nil"
-  /// print("4", ("4" as Unicode.Scalar).properties.numericValue ?? "nil")
-  /// // Prints "4 4.0"
-  /// print("\u{2463}", ("\u{2463}" as Unicode.Scalar).properties.numericValue ?? "nil")
-  /// // Prints "④ 4.0"
-  /// print("\u{2155}", ("\u{2155}" as Unicode.Scalar).properties.numericValue ?? "nil")
-  /// // Prints "⅕ 0.2"
-  /// ```
-  ///
-  /// This property corresponds to the `Numeric_Value` property in the
-  /// [Unicode Standard](http://www.unicode.org/versions/latest/).
+  /// This property corresponds to the "Numeric_Value" property in the [Unicode
+  /// Standard](http://www.unicode.org/versions/latest/).
   public var numericValue: Double? {
     let icuNoNumericValue: Double = -123456789
     let result = __swift_stdlib_u_getNumericValue(icuValue)
diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
index 6b882ad..2648f47 100644
--- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
@@ -567,7 +567,22 @@
   public static func allocate(capacity count: Int) 
     -> UnsafeMutableBufferPointer<Element> {
     let size = MemoryLayout<Element>.stride * count
-    let raw  = Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Element.self))
+    // For any alignment <= _minAllocationAlignment, force alignment = 0.
+    // This forces the runtime's "aligned" allocation path so that
+    // deallocation does not require the original alignment.
+    //
+    // The runtime guarantees:
+    //
+    // align == 0 || align > _minAllocationAlignment:
+    //   Runtime uses "aligned allocation".
+    //
+    // 0 < align <= _minAllocationAlignment:
+    //   Runtime may use either malloc or "aligned allocation".
+    var align = Builtin.alignof(Element.self)
+    if Int(align) <= _minAllocationAlignment() {
+      align = (0)._builtinWordValue
+    }
+    let raw  = Builtin.allocRaw(size._builtinWordValue, align)
     Builtin.bindMemory(raw, count._builtinWordValue, Element.self)
     return UnsafeMutableBufferPointer(
       start: UnsafeMutablePointer(raw), count: count)
diff --git a/stdlib/public/core/UnsafePointer.swift b/stdlib/public/core/UnsafePointer.swift
index 0103779..0735a38 100644
--- a/stdlib/public/core/UnsafePointer.swift
+++ b/stdlib/public/core/UnsafePointer.swift
@@ -225,7 +225,11 @@
   /// block. The memory must not be initialized or `Pointee` must be a trivial type.
   @inlinable
   public func deallocate() {
-    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (-1)._builtinWordValue)
+    // Passing zero alignment to the runtime forces "aligned
+    // deallocation". Since allocation via `UnsafeMutable[Raw][Buffer]Pointer`
+    // always uses the "aligned allocation" path, this ensures that the
+    // runtime's allocation and deallocation paths are compatible.
+    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (0)._builtinWordValue)
   }
 
   /// Accesses the instance referenced by this pointer.
@@ -568,8 +572,22 @@
   public static func allocate(capacity count: Int)
     -> UnsafeMutablePointer<Pointee> {
     let size = MemoryLayout<Pointee>.stride * count
-    let rawPtr =
-      Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Pointee.self))
+    // For any alignment <= _minAllocationAlignment, force alignment = 0.
+    // This forces the runtime's "aligned" allocation path so that
+    // deallocation does not require the original alignment.
+    //
+    // The runtime guarantees:
+    //
+    // align == 0 || align > _minAllocationAlignment:
+    //   Runtime uses "aligned allocation".
+    //
+    // 0 < align <= _minAllocationAlignment:
+    //   Runtime may use either malloc or "aligned allocation".
+    var align = Builtin.alignof(Pointee.self)
+    if Int(align) <= _minAllocationAlignment() {
+      align = (0)._builtinWordValue
+    }
+    let rawPtr = Builtin.allocRaw(size._builtinWordValue, align)
     Builtin.bindMemory(rawPtr, count._builtinWordValue, Pointee.self)
     return UnsafeMutablePointer(rawPtr)
   }
@@ -580,8 +598,11 @@
   /// block. The memory must not be initialized or `Pointee` must be a trivial type.
   @inlinable
   public func deallocate() {
-    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue,
-                       Builtin.alignof(Pointee.self))
+    // Passing zero alignment to the runtime forces "aligned
+    // deallocation". Since allocation via `UnsafeMutable[Raw][Buffer]Pointer`
+    // always uses the "aligned allocation" path, this ensures that the
+    // runtime's allocation and deallocation paths are compatible.
+    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (0)._builtinWordValue)
   }
 
   /// Accesses the instance referenced by this pointer.
diff --git a/stdlib/public/core/UnsafeRawPointer.swift b/stdlib/public/core/UnsafeRawPointer.swift
index 73cad75..3b23b08 100644
--- a/stdlib/public/core/UnsafeRawPointer.swift
+++ b/stdlib/public/core/UnsafeRawPointer.swift
@@ -241,7 +241,11 @@
   /// trivial type.
   @inlinable
   public func deallocate() {
-    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (-1)._builtinWordValue)
+    // Passing zero alignment to the runtime forces "aligned
+    // deallocation". Since allocation via `UnsafeMutable[Raw][Buffer]Pointer`
+    // always uses the "aligned allocation" path, this ensures that the
+    // runtime's allocation and deallocation paths are compatible.
+    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (0)._builtinWordValue)
   }
 
   /// Binds the memory to the specified type and returns a typed pointer to the
@@ -577,6 +581,21 @@
   public static func allocate(
     byteCount: Int, alignment: Int
   ) -> UnsafeMutableRawPointer {
+    // For any alignment <= _minAllocationAlignment, force alignment = 0.
+    // This forces the runtime's "aligned" allocation path so that
+    // deallocation does not require the original alignment.
+    //
+    // The runtime guarantees:
+    //
+    // align == 0 || align > _minAllocationAlignment:
+    //   Runtime uses "aligned allocation".
+    //
+    // 0 < align <= _minAllocationAlignment:
+    //   Runtime may use either malloc or "aligned allocation".
+    var alignment = alignment
+    if alignment <= _minAllocationAlignment() {
+      alignment = 0
+    }
     return UnsafeMutableRawPointer(Builtin.allocRaw(
         byteCount._builtinWordValue, alignment._builtinWordValue))
   }
@@ -587,7 +606,11 @@
   /// trivial type.
   @inlinable
   public func deallocate() {
-    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (-1)._builtinWordValue)
+    // Passing zero alignment to the runtime forces "aligned
+    // deallocation". Since allocation via `UnsafeMutable[Raw][Buffer]Pointer`
+    // always uses the "aligned allocation" path, this ensures that the
+    // runtime's allocation and deallocation paths are compatible.
+    Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (0)._builtinWordValue)
   }
 
   /// Binds the memory to the specified type and returns a typed pointer to the
diff --git a/stdlib/public/core/Zip.swift b/stdlib/public/core/Zip.swift
index fc29c6f..9c9c9be 100644
--- a/stdlib/public/core/Zip.swift
+++ b/stdlib/public/core/Zip.swift
@@ -144,4 +144,12 @@
       _sequence1.makeIterator(),
       _sequence2.makeIterator())
   }
+
+  @inlinable // generic-performance
+  public var underestimatedCount: Int {
+    return Swift.min(
+      _sequence1.underestimatedCount,
+      _sequence2.underestimatedCount
+    )
+  }
 }
diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp
index 8f7258a..46e133a 100644
--- a/stdlib/public/runtime/Heap.cpp
+++ b/stdlib/public/runtime/Heap.cpp
@@ -18,6 +18,7 @@
 #include "swift/Runtime/Heap.h"
 #include "Private.h"
 #include "swift/Runtime/Debug.h"
+#include "../SwiftShims/RuntimeShims.h"
 #include <algorithm>
 #include <stdlib.h>
 
@@ -48,19 +49,61 @@
 
 #endif
 
+// This assert ensures that manually allocated memory always uses the
+// AlignedAlloc path. The stdlib will use "default" alignment for any user
+// requested alignment less than or equal to _swift_MinAllocationAlignment. The
+// runtime must ensure that any alignment > _swift_MinAllocationAlignment also
+// uses the "aligned" deallocation path.
+static_assert(_swift_MinAllocationAlignment > MALLOC_ALIGN_MASK,
+              "Swift's default alignment must exceed platform malloc mask.");
 
-
+// When alignMask == ~(size_t(0)), allocation uses the "default"
+// _swift_MinAllocationAlignment. This is different than calling swift_slowAlloc
+// with `alignMask == _swift_MinAllocationAlignment - 1` because it forces
+// the use of AlignedAlloc. This allows manually allocated to memory to always
+// be deallocated with AlignedFree without knowledge of its original allocation
+// alignment.
+//
+// For alignMask > (_minAllocationAlignment-1)
+// i.e. alignment == 0 || alignment > _minAllocationAlignment:
+//   The runtime must use AlignedAlloc, and the standard library must
+//   deallocate using an alignment that meets the same condition.
+//
+// For alignMask <= (_minAllocationAlignment-1)
+// i.e. 0 < alignment <= _minAllocationAlignment:
+//   The runtime may use either malloc or AlignedAlloc, and the standard library
+//   must deallocate using an identical alignment.
 void *swift::swift_slowAlloc(size_t size, size_t alignMask) {
   void *p;
+  // This check also forces "default" alignment to use AlignedAlloc.
   if (alignMask <= MALLOC_ALIGN_MASK) {
     p = malloc(size);
   } else {
-    p = AlignedAlloc(size, alignMask + 1);
+    size_t alignment = (alignMask == ~(size_t(0)))
+                           ? _swift_MinAllocationAlignment
+                           : alignMask + 1;
+    p = AlignedAlloc(size, alignment);
   }
   if (!p) swift::crash("Could not allocate memory.");
   return p;
 }
 
+// Unknown alignment is specified by passing alignMask == ~(size_t(0)), forcing
+// the AlignedFree deallocation path for unknown alignment. The memory
+// deallocated with unknown alignment must have been allocated with either
+// "default" alignment, or alignment > _swift_MinAllocationAlignment, to
+// guarantee that it was allocated with AlignedAlloc.
+//
+// The standard library assumes the following behavior:
+//
+// For alignMask > (_minAllocationAlignment-1)
+// i.e. alignment == 0 || alignment > _minAllocationAlignment:
+//   The runtime must use AlignedFree.
+//
+// For alignMask <= (_minAllocationAlignment-1)
+// i.e. 0 < alignment <= _minAllocationAlignment:
+//   The runtime may use either `free` or AlignedFree as long as it is
+//   consistent with allocation with the same alignment.
 void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) {
   if (alignMask <= MALLOC_ALIGN_MASK) {
     free(ptr);
diff --git a/stdlib/public/runtime/ThreadLocalStorage.h b/stdlib/public/runtime/ThreadLocalStorage.h
index c3a50a2..c15db88 100644
--- a/stdlib/public/runtime/ThreadLocalStorage.h
+++ b/stdlib/public/runtime/ThreadLocalStorage.h
@@ -90,7 +90,7 @@
 
 #  define SWIFT_THREAD_KEY_CREATE _stdlib_thread_key_create
 #  define SWIFT_THREAD_GETSPECIFIC FlsGetValue
-#  define SWIFT_THREAD_SETSPECIFIC(key, value) (FlsSetValue(key, value) == TRUE)
+#  define SWIFT_THREAD_SETSPECIFIC(key, value) (FlsSetValue(key, value) == FALSE)
 
 # else
 // Otherwise use the pthread API.
diff --git a/stdlib/public/stubs/Stubs.cpp b/stdlib/public/stubs/Stubs.cpp
index 231dc66..486103e 100644
--- a/stdlib/public/stubs/Stubs.cpp
+++ b/stdlib/public/stubs/Stubs.cpp
@@ -371,6 +371,47 @@
   return nptr + pos;
 }
 
+#if defined(_WIN32)
+template <>
+static const char *
+_swift_stdlib_strtoX_clocale_impl<float>(const char *str, float *result) {
+  if (swift_stringIsSignalingNaN(str)) {
+    *result = std::numeric_limits<float>::signaling_NaN();
+    return str + std::strlen(str);
+  }
+
+  char *end;
+  *result = std::strtof(str, &end);
+  return end;
+}
+
+template <>
+static const char *
+_swift_stdlib_strtoX_clocale_impl<double>(const char *str, double *result) {
+  if (swift_stringIsSignalingNaN(str)) {
+    *result = std::numeric_limits<double>::signaling_NaN();
+    return str + std::strlen(str);
+  }
+
+  char *end;
+  *result = std::strtod(str, &end);
+  return end;
+}
+
+template <>
+static const char *
+_swift_stdlib_strtoX_clocale_impl<long double>(const char *str, long double *result) {
+  if (swift_stringIsSignalingNaN(str)) {
+    *result = std::numeric_limits<long double>::signaling_NaN();
+    return str + std::strlen(str);
+  }
+
+  char *end;
+  *result = std::strtold(str, &end);
+  return end;
+}
+#endif
+
 const char *swift::_swift_stdlib_strtold_clocale(
     const char *nptr, void *outResult) {
   return _swift_stdlib_strtoX_clocale_impl(
diff --git a/stdlib/public/stubs/ThreadLocalStorage.cpp b/stdlib/public/stubs/ThreadLocalStorage.cpp
index 3da65bd..219a13c 100644
--- a/stdlib/public/stubs/ThreadLocalStorage.cpp
+++ b/stdlib/public/stubs/ThreadLocalStorage.cpp
@@ -43,7 +43,9 @@
 _stdlib_thread_key_create(__swift_thread_key_t * _Nonnull key,
                           __swift_thread_key_destructor _Nullable destructor) {
   *key = FlsAlloc(destroyTLS_CCAdjustmentThunk);
-  return *key != FLS_OUT_OF_INDEXES;
+  if (*key == FLS_OUT_OF_INDEXES)
+    return GetLastError();
+  return 0;
 }
 
 #endif
diff --git a/test/ClangImporter/static_inline.swift b/test/ClangImporter/static_inline.swift
index f6e6e95..d82adfd 100644
--- a/test/ClangImporter/static_inline.swift
+++ b/test/ClangImporter/static_inline.swift
@@ -6,7 +6,7 @@
 // RUN: %FileCheck < %t/static_inline.sil %s
 // RUN: %target-swift-frontend -parse-as-library -module-name=static_inline -O -emit-ir %t/static_inline.sil -enable-objc-interop -import-objc-header %S/Inputs/static_inline.h | %FileCheck --check-prefix=CHECK-IR %s
 
-// CHECK: sil shared [serializable] [clang c_inline_func] @c_inline_func : $@convention(c) (Int32) -> Int32
+// CHECK: sil shared [clang c_inline_func] @c_inline_func : $@convention(c) (Int32) -> Int32
 
 // CHECK-IR-LABEL: define{{.*}} i32 @"$s13static_inline6testit1xs5Int32VAE_tF"(i32)
 // CHECK-IR: = add {{.*}}, 27
diff --git a/test/Constraints/rdar46544601.swift b/test/Constraints/rdar46544601.swift
new file mode 100644
index 0000000..7002cde
--- /dev/null
+++ b/test/Constraints/rdar46544601.swift
@@ -0,0 +1,34 @@
+// RUN: %target-typecheck-verify-swift
+
+struct D {}
+
+class Future<T> {
+  func then<U>(_ fn: @escaping (T) -> Future<U>) -> Future<U> { fatalError() }
+  func thenThrowing<U>(_ fn: @escaping (T) throws -> U) -> Future<U> { fatalError() }
+  func whenFailure(_ fn: @escaping (Error) -> Void) {}
+
+  func and<U>(result: U) -> Future<(T,U)> { fatalError() }
+}
+
+protocol P {
+  func foo(arr: [D], data: ArraySlice<UInt8>) -> Future<D>
+  // expected-note@-1 {{found this candidate}}
+  func bar(root: D, from: P) -> Future<D>
+}
+
+extension P {
+  func foo(arr: [D] = [], data: [UInt8]) -> Future<D> { fatalError() }
+  // expected-note@-1 {{found this candidate}}
+}
+
+func crash(_ p: P, payload: [UInt8]) throws {
+  p.foo(data: payload).then { _ in
+    return Future<(D, [D])>()
+  }.then { (id, arr) in
+    p.foo(arr: arr, data: []).and(result: (id, arr))
+    // expected-error@-1 {{mbiguous reference to member 'foo(arr:data:)'}}
+  }.then { args0 in
+    let (parentID, args1) = args0
+    p.bar(root: parentID, from: p).and(args1)
+  }.whenFailure { _ in }
+}
diff --git a/test/Generics/rdar45957015.swift b/test/Generics/rdar45957015.swift
deleted file mode 100644
index 031a7b7..0000000
--- a/test/Generics/rdar45957015.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %target-typecheck-verify-swift
-
-protocol C {
-  associatedtype T : Collection where T.Element == Self
-}
-
-protocol V : C, RawRepresentable where RawValue == String {}
-
-protocol P {
-  associatedtype A: V
-}
-
-extension P {
-  func foo<U: Collection>(_ args: U) -> String where U.Element == A {
-    return args.reduce("", { $1.rawValue }) // Ok
-  }
-}
diff --git a/test/Generics/same_type_constraints.swift b/test/Generics/same_type_constraints.swift
index 53b4ec6..47abdbc 100644
--- a/test/Generics/same_type_constraints.swift
+++ b/test/Generics/same_type_constraints.swift
@@ -353,9 +353,9 @@
 func intercomponentMoreThanSpanningTree<T: P10>(_: T)
   where T.A == T.B,
         T.B == T.C,
-        T.D == T.E, // expected-note {{previous same-type constraint 'T.D' == 'T.E' written here}}
+        T.D == T.E, // expected-note{{previous same-type constraint 'T.D' == 'T.E' written here}}
         T.D == T.B,
-        T.E == T.B  // expected-warning {{redundant same-type constraint 'T.E' == 'T.B'}}
+        T.E == T.B  // expected-warning{{redundant same-type constraint 'T.E' == 'T.B'}}
         { }
 
 func trivialRedundancy<T: P10>(_: T) where T.A == T.A { } // expected-warning{{redundant same-type constraint 'T.A' == 'T.A'}}
diff --git a/test/IRGen/class_resilience.sil b/test/IRGen/class_resilience.sil
index e057b79..f5a912f 100644
--- a/test/IRGen/class_resilience.sil
+++ b/test/IRGen/class_resilience.sil
@@ -37,7 +37,7 @@
 sil @allocResilientOutsideParent : $@convention(thin) () -> () {
 bb0:
   %c = alloc_ref $ResilientOutsideParent
-  dealloc_ref %c : $ResilientOutsideParent
+  strong_release %c : $ResilientOutsideParent
   %result = tuple ()
   return %result : $()
 }
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index 286c596..d71a08f 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -87,6 +87,17 @@
 // CHECK-32-SAME: <i32 0x0380_0008> }>
 // CHECK-64-SAME: <i32 0x0380_0010> }>
 
+// -- %d1: C1.x
+// CHECK: [[KP_D1:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
+//               -- instantiable in-line, size 4
+// CHECK-SAME: <i32 0x8000_0004>,
+// -- 0x0300_0000 (class) + mutable + offset of C.x
+// CHECK-32-SAME: <i32 0x0380_0008> }>
+// CHECK-64-SAME: <i32 0x0380_0010> }>
+
 // -- %e: C.y
 // CHECK: [[KP_E:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
 // CHECK-SAME: [[WORD]]* @keypath_once
@@ -218,9 +229,10 @@
   %b = keypath $KeyPath<S, String>, (root $S; stored_property #S.y : $String)
   // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_C]] to i8*), i8* undef)
   %c = keypath $KeyPath<S, C>, (root $S; stored_property #S.z : $C)
-
   // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_D]] to i8*), i8* undef)
   %d = keypath $KeyPath<C, Int>, (root $C; stored_property #C.x : $Int)
+  // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_D1]] to i8*), i8* undef)
+  %d1 = keypath $KeyPath<C1, Int>, (root $C1; stored_property #C.x : $Int)
   // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_E]] to i8*), i8* undef)
   %e = keypath $KeyPath<C, String>, (root $C; stored_property #C.y : $String)
   // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_F]] to i8*), i8* undef)
diff --git a/test/Interpreter/builtin_bridge_object.swift b/test/Interpreter/builtin_bridge_object.swift
index a49ed02..4b7ad1a 100644
--- a/test/Interpreter/builtin_bridge_object.swift
+++ b/test/Interpreter/builtin_bridge_object.swift
@@ -30,7 +30,7 @@
 #elseif arch(arm64)
 
 // We have ObjC tagged pointers in the highest bit
-let NATIVE_SPARE_BITS: UInt = 0x7F00_0000_0000_0007
+let NATIVE_SPARE_BITS: UInt = 0x7000_0000_0000_0007
 let OBJC_TAGGED_POINTER_BITS: UInt = 0x8000_0000_0000_0000
 
 #elseif arch(powerpc64) || arch(powerpc64le)
diff --git a/test/Interpreter/existential_transform.swift b/test/Interpreter/existential_transform.swift
new file mode 100644
index 0000000..5100185
--- /dev/null
+++ b/test/Interpreter/existential_transform.swift
@@ -0,0 +1,32 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -O -wmo %s -o %t/a.out
+// RUN: %target-codesign %t/a.out
+// RUN: %target-run %t/a.out | %FileCheck %s
+// REQUIRES: executable_test
+
+protocol Foo {
+  var myName: String { get }
+}
+
+struct MyURL {
+}
+
+extension MyURL : Foo {
+  var myName : String { return "MyURL" }
+}
+
+struct MyStruct : Foo {
+  var myName : String { return "MyStruct" }
+}
+
+@inline(never) func getName(_ f: Foo) -> String {
+  return f.myName
+}
+
+@inline(never) func getName_wrapper() {
+  let u = MyURL()
+  // CHECK: MyURL
+  print(getName(u))
+}
+getName_wrapper()
+
diff --git a/test/ParseableInterface/ObjC.swiftinterface b/test/ParseableInterface/ObjC.swiftinterface
index cf3a1f0..0d6ab77 100644
--- a/test/ParseableInterface/ObjC.swiftinterface
+++ b/test/ParseableInterface/ObjC.swiftinterface
@@ -29,10 +29,9 @@
     @inlinable get { return 0 }
     @inlinable set {}
   }
-  @objc @inlinable deinit {
-    print("bye")
-  }
+  @objc deinit
 }
+
 public class SomeNSObject : NSObject {
   @objc init?(_: Any)
   @objc func foo()
@@ -53,7 +52,5 @@
     @inlinable get { return 0 }
     @inlinable set {}
   }
-  @objc @inlinable deinit {
-    print("bye")
-  }
+  @objc deinit
 }
diff --git a/test/ParseableInterface/fixed-layout-property-initializers.swift b/test/ParseableInterface/fixed-layout-property-initializers.swift
index 099a214..08e6c87 100644
--- a/test/ParseableInterface/fixed-layout-property-initializers.swift
+++ b/test/ParseableInterface/fixed-layout-property-initializers.swift
@@ -1,37 +1,38 @@
 // RUN: %empty-directory(%t)
 
 // RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.swiftinterface %s
-// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t.swiftinterface
+// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix NONRESILIENT --check-prefix COMMON < %t.swiftinterface
 
 // RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t-resilient.swiftinterface -enable-resilience %s
-// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t-resilient.swiftinterface
+// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix RESILIENT --check-prefix COMMON < %t-resilient.swiftinterface
 
 // RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule %t.swiftinterface -disable-objc-attr-requires-foundation-module
-// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -module-name Test -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -module-name Test -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix FROMMODULE --check-prefix NONRESILIENT --check-prefix COMMON
 
 // RUN: %target-swift-frontend -emit-module -o %t/TestResilient.swiftmodule -enable-resilience %t-resilient.swiftinterface -disable-objc-attr-requires-foundation-module
-// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/TestResilient.swiftmodule -module-name TestResilient -enable-resilience -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/TestResilient.swiftmodule -module-name TestResilient -enable-resilience -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix FROMMODULE --check-prefix RESILIENT --check-prefix COMMON
 
-// CHECK: @_fixed_layout public struct MyStruct {
+// COMMON: @_fixed_layout public struct MyStruct {
 @_fixed_layout
 public struct MyStruct {
-  // CHECK: public var publicVar: [[BOOL:(Swift\.)?Bool]] = false
+  // COMMON: public var publicVar: [[BOOL:(Swift\.)?Bool]] = false
   public var publicVar: Bool = false
 
-  // CHECK: internal var internalVar: ([[BOOL]], [[BOOL]]) = (false, true)
+  // COMMON: internal var internalVar: ([[BOOL]], [[BOOL]]) = (false, true)
   internal var internalVar: (Bool, Bool) = (false, true)
 
-  // CHECK: private var privateVar: [[BOOL]] = Bool(4 < 10)
+  // COMMON: private var privateVar: [[BOOL]] = Bool(4 < 10)
   private var privateVar: Bool = Bool(4 < 10)
 
-  // CHECK: @usableFromInline
-  // CHECK-NEXT: internal var ufiVar: [[BOOL]] = true
+  // COMMON: @usableFromInline
+  // COMMON-NEXT: internal var ufiVar: [[BOOL]] = true
   @usableFromInline internal var ufiVar: Bool = true
 
-  // CHECK: public var multiVar1: [[BOOL]] = Bool(false), (multiVar2, multiVar3): ([[BOOL]], [[BOOL]]) = (true, 3 == 0)
+  // COMMON: public var multiVar1: [[BOOL]] = Bool(false), (multiVar2, multiVar3): ([[BOOL]], [[BOOL]]) = (true, 3 == 0)
   public var multiVar1: Bool = Bool(false), (multiVar2, multiVar3): (Bool, Bool) = (true, 3 == 0)
 
-  // CHECK: @_hasInitialValue public static var staticVar: [[BOOL]]
+  // NONRESILIENT: @_hasInitialValue public static var staticVar: [[BOOL]]
+  // RESILIENT: {{^}}  public static var staticVar: [[BOOL]]
   public static var staticVar: Bool = Bool(true && false)
 
   // FROMSOURCE: @inlinable internal init() {}
@@ -39,23 +40,24 @@
   @inlinable init() {}
 }
 
-// CHECK: @_fixed_layout public class MyClass {
+// COMMON: @_fixed_layout public class MyClass {
 @_fixed_layout
 public class MyClass {
-  // CHECK: public var publicVar: [[BOOL]] = false
+  // COMMON: public var publicVar: [[BOOL]] = false
   public var publicVar: Bool = false
 
-  // CHECK: internal var internalVar: [[BOOL]] = false
+  // COMMON: internal var internalVar: [[BOOL]] = false
   internal var internalVar: Bool = false
 
-  // CHECK: private var privateVar: {{(Swift\.)?}}UInt8 = UInt8(2)
+  // COMMON: private var privateVar: {{(Swift\.)?}}UInt8 = UInt8(2)
   private var privateVar: UInt8 = UInt8(2)
 
-  // CHECK: @usableFromInline
-  // CHECK-NEXT: internal var ufiVar: [[BOOL]] = true
+  // COMMON: @usableFromInline
+  // COMMON-NEXT: internal var ufiVar: [[BOOL]] = true
   @usableFromInline internal var ufiVar: Bool = true
 
-  // CHECK: @_hasInitialValue public static var staticVar: [[BOOL]]
+  // NONRESILIENT: @_hasInitialValue public static var staticVar: [[BOOL]]
+  // RESILIENT: {{^}}  public static var staticVar: [[BOOL]]
   public static var staticVar: Bool = Bool(true && false)
 
   // FROMSOURCE: @inlinable internal init() {}
@@ -63,5 +65,6 @@
   @inlinable init() {}
 }
 
-// CHECK: @_hasInitialValue public var topLevelVar: [[BOOL]]
+// NONRESILIENT: @_hasInitialValue public var topLevelVar: [[BOOL]]
+// RESILIENT: {{^}}public var topLevelVar: [[BOOL]]
 public var topLevelVar: Bool = Bool(false && !true)
diff --git a/test/ParseableInterface/stored-properties.swift b/test/ParseableInterface/stored-properties.swift
index 774553e..a4392e1 100644
--- a/test/ParseableInterface/stored-properties.swift
+++ b/test/ParseableInterface/stored-properties.swift
@@ -53,7 +53,7 @@
   private var privateVar: Bool
 
   // CHECK: @_hasStorage @_hasInitialValue public var storedWithObserversInitialValue: [[INT]] {
-  // RESILIENT: {{^}}  @_hasInitialValue public var storedWithObserversInitialValue: [[INT]] {
+  // RESILIENT: {{^}}  public var storedWithObserversInitialValue: [[INT]] {
   // COMMON-NEXT: get
   // COMMON-NEXT: set
   // COMMON-NEXT: }
diff --git a/test/Reflection/typeref_lowering.swift b/test/Reflection/typeref_lowering.swift
index 7570f5c..64c8c11 100644
--- a/test/Reflection/typeref_lowering.swift
+++ b/test/Reflection/typeref_lowering.swift
@@ -1044,7 +1044,7 @@
 // CHECK-64-NEXT:       (field name=Indirect offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=multiPayloadConcrete offset=24
-// CHECK-64-NEXT:     (multi_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=2045 bitwise_takable=1
+// CHECK-64-NEXT:     (multi_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants={{(2045|125)}} bitwise_takable=1
 // CHECK-64-NEXT:       (field name=Left offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:       (field name=Right offset=0
diff --git a/test/Runtime/demangleToMetadataObjC.swift b/test/Runtime/demangleToMetadataObjC.swift
index fba76ef..8a0db73 100644
--- a/test/Runtime/demangleToMetadataObjC.swift
+++ b/test/Runtime/demangleToMetadataObjC.swift
@@ -108,5 +108,9 @@
   expectEqual(F<P3>.self, _typeByName("4main1FCyAA2P3PG")!)
 }
 
+DemangleToMetadataTests.test("Objective-C generics") {
+  expectEqual(NSArray.self, _typeByName("So7NSArrayCySo8NSStringCG")!)
+}
+
 runAllTests()
 
diff --git a/test/SIL/Parser/apply_with_conformance.sil b/test/SIL/Parser/apply_with_conformance.sil
index 2aeafe8..85c600d 100644
--- a/test/SIL/Parser/apply_with_conformance.sil
+++ b/test/SIL/Parser/apply_with_conformance.sil
@@ -18,7 +18,7 @@
 // test.S.foo (test.S)<A : test.P>(A) -> ()
 sil @_TFV4test1S3foofS0_US_1P__FQ_T_ : $@convention(method) <T where T : P> (@in T, S) -> ()
 
-// CHECK-LABEL: define{{( protected)?}} swiftcc void @_TF4test3barFTVS_1SVS_1X_T_()
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @_TF4test3barFTVS_1SVS_1X_T_()
 // CHECK: call
 // test.bar (test.S, test.X) -> ()
 sil [ossa] @_TF4test3barFTVS_1SVS_1X_T_ : $@convention(thin) (S, X) -> () {
diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil
index 0562ed6..d4dbf35 100644
--- a/test/SIL/Parser/basic.sil
+++ b/test/SIL/Parser/basic.sil
@@ -1344,15 +1344,11 @@
 // CHECK-LABEL: sil @convert_function_trivial
 // CHECK:  %1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
 // CHECK:  %2 = convert_escape_to_noescape [not_guaranteed] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
-// CHECK:  %3 = convert_escape_to_noescape [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
-// CHECK:  %4 = convert_escape_to_noescape [not_guaranteed] [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
 // CHECK: return
 sil @convert_function_trivial : $@convention(thin) (@owned @callee_guaranteed (AnyObject) -> Optional<AnyObject>) -> () {
 entry(%0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject>):
   %1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
   %2 = convert_escape_to_noescape [not_guaranteed] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
-  %3 = convert_escape_to_noescape [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
-  %4 = convert_escape_to_noescape [not_guaranteed] [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
   return undef : $()
 }
 
diff --git a/test/SIL/Parser/final.swift b/test/SIL/Parser/final.swift
index 7f0e30f..6be8eef 100644
--- a/test/SIL/Parser/final.swift
+++ b/test/SIL/Parser/final.swift
@@ -1,7 +1,7 @@
 // RUN: %target-swift-frontend %s -emit-silgen | %FileCheck %s
 
 // CHECK: final class Rect
-// CHECK: @_hasInitialValue @_hasStorage final var orgx: Double
+// CHECK: @_hasStorage @_hasInitialValue final var orgx: Double
 final class Rect {
   var orgx = 0.0
 }
diff --git a/test/SIL/Parser/overloaded_member.sil b/test/SIL/Parser/overloaded_member.sil
index 1e0dffe..05e8b03 100644
--- a/test/SIL/Parser/overloaded_member.sil
+++ b/test/SIL/Parser/overloaded_member.sil
@@ -37,3 +37,26 @@
   destroy_value %2 : $<τ_0_0> { var τ_0_0 } <X>
   return %15 : $X
 }
+
+// rdar://46650834
+//   Don't complain that the first lookup result lacks an accessor when a
+//   later lookup result provides it.
+class B {
+  typealias Index = Int
+  typealias Element = String
+
+  subscript(owned index: Index) -> Element { get }
+
+  @_borrowed
+  subscript(borrowed index: Index) -> Element { get }
+}
+
+sil [ossa] @test_overloaded_subscript : $@convention(thin) (@guaranteed B, B.Index) -> () {
+bb0(%0 : $B, %1 : $B.Index):
+  %reader = class_method %0 : $B, #B.subscript!read.1 : (B) -> (B.Index) -> (), $@convention(method) @yield_once (B.Index, @guaranteed B) -> @yields @guaranteed B.Element
+  (%element, %token) = begin_apply %reader(%1, %0) : $@convention(method) @yield_once (B.Index, @guaranteed B) -> @yields @guaranteed B.Element
+  end_apply %token
+
+  %result = tuple ()
+  return %result : $()
+}
diff --git a/test/SIL/Serialization/boxes.sil b/test/SIL/Serialization/boxes.sil
index 2b348c0..dca8fb5 100644
--- a/test/SIL/Serialization/boxes.sil
+++ b/test/SIL/Serialization/boxes.sil
@@ -1,7 +1,7 @@
 // First parse this and then emit a *.sib. Then read in the *.sib, then recreate
 // RUN: %empty-directory(%t)
 // RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name boxes
-// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.2.sib -module-name boxes
+// RUN: %target-sil-opt %t/tmp.sib -emit-sib -o %t/tmp.2.sib -module-name boxes
 // RUN: %target-sil-opt %t/tmp.2.sib -module-name boxes | %FileCheck %s
 
 sil_stage canonical
diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil
index bcadb84..e6892f3 100644
--- a/test/SIL/Serialization/keypath.sil
+++ b/test/SIL/Serialization/keypath.sil
@@ -1,48 +1,48 @@
 
 // First parse this and then emit a *.sib. Then read in the *.sib, then recreate
 // RUN: %empty-directory(%t)
-// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name boxes
-// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.2.sib -module-name boxes
-// RUN: %target-sil-opt %t/tmp.2.sib -module-name boxes | %FileCheck %s
+// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name keypaths
+// RUN: %target-sil-opt %t/tmp.sib -emit-sib -o %t/tmp.2.sib -module-name keypaths
+// RUN: %target-sil-opt %t/tmp.2.sib -module-name keypaths | %FileCheck %s
 
 sil_stage canonical
 
 import Swift
 
-struct S: Hashable {
-  var x: Int
-  let y: String
-  var z: C
+public struct S: Hashable {
+  public var x: Int
+  public let y: String
+  public var z: C
 
-  func hash(into hasher: inout Hasher)
-  static func ==(x: S, y: S) -> Bool
+  public func hash(into hasher: inout Hasher)
+  public static func ==(x: S, y: S) -> Bool
 }
-class C: Hashable {
-  final var x: Int
-  final let y: String
-  final var z: S
+public class C: Hashable {
+  public final var x: Int
+  public final let y: String
+  public final var z: S
 
-  init()
-  var overridable: Int {
+  public init()
+  public var overridable: Int {
     get set
   }
 
-  func hash(into hasher: inout Hasher)
-  static func ==(x: C, y: C) -> Bool
+  public func hash(into hasher: inout Hasher)
+  public static func ==(x: C, y: C) -> Bool
 }
 
 protocol P {}
 protocol Q {}
 protocol R {}
 
-struct Gen<A: P, B: Q, C: R> {
-  var x: A
-  let y: B
-  var z: C
+public struct Gen<A: P, B: Q, C: R> {
+  public var x: A
+  public let y: B
+  public var z: C
 }
 
 public struct External<T> {
-  var ro: T
+  public var ro: T
 
   subscript<U: Hashable>(ro _: U) -> T { get }
 
diff --git a/test/SILGen/collection_upcast.swift b/test/SILGen/collection_upcast.swift
index fcd4167..6a2d7fd 100644
--- a/test/SILGen/collection_upcast.swift
+++ b/test/SILGen/collection_upcast.swift
@@ -1,8 +1,7 @@
 
-// RUN: %target-swift-emit-silgen -module-name collection_upcast -sdk %S/Inputs -I %S/Inputs -enable-source-import %s | %FileCheck %s
+// RUN: %target-swift-emit-silgen -module-name collection_upcast -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -enable-objc-interop -disable-objc-attr-requires-foundation-module | %FileCheck %s
 
 // FIXME: rdar://problem/19648117 Needs splitting objc parts out
-// XFAIL: linux
 
 import Foundation
 
diff --git a/test/SILGen/enum_raw_representable_objc.swift b/test/SILGen/enum_raw_representable_objc.swift
index 8ff91fc..26921c6 100644
--- a/test/SILGen/enum_raw_representable_objc.swift
+++ b/test/SILGen/enum_raw_representable_objc.swift
@@ -1,21 +1,28 @@
 // RUN: %target-swift-emit-silgen -emit-sorted-sil -enable-objc-interop -disable-objc-attr-requires-foundation-module %s | %FileCheck %s
 // RUN: %target-swift-emit-silgen -emit-sorted-sil -enable-objc-interop -disable-objc-attr-requires-foundation-module -enable-resilience %s | %FileCheck -check-prefix=CHECK-RESILIENT %s
 
+#if os(Windows) && arch(x86_64)
+@objc public enum CLike: Int32 {
+  case a, b, c
+}
+#else
 @objc public enum CLike: Int {
   case a, b, c
 }
+#endif
 
-// CHECK-LABEL: sil [serialized] [ossa] @$s27enum_raw_representable_objc5CLikeO0B5ValueACSgSi_tcfC
+// CHECK-LABEL: sil [serialized] [ossa] @$s27enum_raw_representable_objc5CLikeO0B5ValueACSg{{Si|s5Int32V}}_tcfC
 
-// CHECK-LABEL: sil [serialized] [ossa] @$s27enum_raw_representable_objc5CLikeO0B5ValueSivg
+// CHECK-LABEL: sil [serialized] [ossa] @$s27enum_raw_representable_objc5CLikeO0B5Value{{Si|s5Int32V}}vg
 // CHECK-DAG: [[RESULT_BOX:%.+]] = alloc_stack $Int
 // CHECK-DAG: [[INPUT_BOX:%.+]] = alloc_stack $CLike
-// CHECK: [[RAW_TYPE:%.+]] = metatype $@thick Int.Type
+// CHECK: [[RAW_TYPE:%.+]] = metatype $@thick Int{{(32)?}}.Type
 // CHECK: [[CAST_FUNC:%.+]] = function_ref @$ss13unsafeBitCast_2toq_x_q_mtr0_lF
-// CHECK: = apply [[CAST_FUNC]]<CLike, Int>([[RESULT_BOX]], [[INPUT_BOX]], [[RAW_TYPE]])
+// CHECK: = apply [[CAST_FUNC]]<CLike, Int{{(32)?}}>([[RESULT_BOX]], [[INPUT_BOX]], [[RAW_TYPE]])
 // CHECK: [[RESULT:%.+]] = load [trivial] [[RESULT_BOX]]
 // CHECK: return [[RESULT]]
-// CHECK: end sil function '$s27enum_raw_representable_objc5CLikeO0B5ValueSivg'
+// CHECK: end sil function '$s27enum_raw_representable_objc5CLikeO0B5Value{{Si|s5Int32V}}vg'
 
-// CHECK-RESILIENT-DAG: sil [ossa] @$s27enum_raw_representable_objc5CLikeO0B5ValueSivg
-// CHECK-RESILIENT-DAG: sil [ossa] @$s27enum_raw_representable_objc5CLikeO0B5ValueACSgSi_tcfC
+// CHECK-RESILIENT-DAG: sil [ossa] @$s27enum_raw_representable_objc5CLikeO0B5Value{{Si|s5Int32V}}vg
+// CHECK-RESILIENT-DAG: sil [ossa] @$s27enum_raw_representable_objc5CLikeO0B5ValueACSg{{Si|s5Int32V}}_tcfC
+
diff --git a/test/SILGen/imported_struct_array_field.swift b/test/SILGen/imported_struct_array_field.swift
index 80214b4..dcfb357 100644
--- a/test/SILGen/imported_struct_array_field.swift
+++ b/test/SILGen/imported_struct_array_field.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-emit-silgen -import-objc-header %S/Inputs/array_typedef.h %s | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/array_typedef.h %s | %FileCheck %s
 
 // CHECK-LABEL: sil shared [transparent] [serializable] [ossa] @$sSo4NameV{{[_0-9a-zA-Z]*}}fC : $@convention(method) (UInt8, UInt8, UInt8, UInt8, @thin Name.Type) -> Name
 func useImportedArrayTypedefInit() -> Name {
diff --git a/test/SILGen/inlinable_attribute_objc.swift b/test/SILGen/inlinable_attribute_objc.swift
index 365b50a..98ab898 100644
--- a/test/SILGen/inlinable_attribute_objc.swift
+++ b/test/SILGen/inlinable_attribute_objc.swift
@@ -10,9 +10,22 @@
 
 public class Horse : NSObject {
   @objc public dynamic func gallop() {}
+  @objc public func someMethod() {}
+  @objc public convenience init(saddle: ()) {
+    self.init()
+  }
+  @objc public override init() {}
 }
 
-// Make sure we can reference dynamic thunks and curry thunks
+// @objc thunks are not serialized, since they are only referenced from
+// method tables.
+
+// CHECK-LABEL: sil [thunk] [ossa] @$s24inlinable_attribute_objc5HorseC6gallopyyFTo : $@convention(objc_method) (Horse) -> ()
+// CHECK-LABEL: sil [thunk] [ossa] @$s24inlinable_attribute_objc5HorseC10someMethodyyFTo : $@convention(objc_method) (Horse) -> ()
+// CHECK-LABEL: sil [thunk] [ossa] @$s24inlinable_attribute_objc5HorseC6saddleACyt_tcfcTo : $@convention(objc_method) (@owned Horse) -> @owned Horse
+// CHECK-LABEL: sil [thunk] [ossa] @$s24inlinable_attribute_objc5HorseCACycfcTo : $@convention(objc_method) (@owned Horse) -> @owned Horse
+
+// However, make sure we can reference dynamic thunks and curry thunks
 // from inlinable scopes
 
 // CHECK-LABEL: sil [serialized] [ossa] @$s24inlinable_attribute_objc15talkAboutAHorse1hyAA5HorseC_tF : $@convention(thin) (@guaranteed Horse) -> () {
diff --git a/test/SILGen/lying_about_optional_return.swift b/test/SILGen/lying_about_optional_return.swift
index 915743b..590d7d2 100644
--- a/test/SILGen/lying_about_optional_return.swift
+++ b/test/SILGen/lying_about_optional_return.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-emit-silgen -import-objc-header %S/Inputs/c_function_pointer_in_c_struct.h %s | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/c_function_pointer_in_c_struct.h %s | %FileCheck %s
 
 // CHECK-LABEL: sil hidden [ossa] @$s27lying_about_optional_return0C37ChainingForeignFunctionTypeProperties{{[_0-9a-zA-Z]*}}F
 func optionalChainingForeignFunctionTypeProperties(a: SomeCallbacks?) {
diff --git a/test/SILGen/pointer_conversion.swift b/test/SILGen/pointer_conversion.swift
index cd09c6d..4e0ade7 100644
--- a/test/SILGen/pointer_conversion.swift
+++ b/test/SILGen/pointer_conversion.swift
@@ -1,8 +1,8 @@
 
-// RUN: %target-swift-emit-silgen -module-name pointer_conversion -sdk %S/Inputs -I %S/Inputs -enable-source-import %s | %FileCheck %s
+// RUN: %target-swift-emit-silgen -module-name pointer_conversion -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -enable-objc-interop | %FileCheck %s
 
 // FIXME: rdar://problem/19648117 Needs splitting objc parts out
-// XFAIL: linux
+// REQUIRES: objc_interop
 
 import Foundation
 
diff --git a/test/SILGen/subscript_accessor.swift b/test/SILGen/subscript_accessor.swift
index ca460b8..71e4a61 100644
--- a/test/SILGen/subscript_accessor.swift
+++ b/test/SILGen/subscript_accessor.swift
@@ -12,7 +12,20 @@
   }
 }
 
-  // CHECK: sil{{.*}}s18subscript_accessor9testXRead1xxAA1XVyxG_tlF
+// Don't crash dealing with T? in a non-generic context.
+// rdar://44762116
+struct WillBeConcretelyConstrained<T> {}
+extension WillBeConcretelyConstrained where T == Int {
+  subscript(key: Int) -> T? {
+    get { return nil }
+    set {}
+  }
+}
+
+// CHECK-LABEL: sil hidden [transparent] @$s18subscript_accessor27WillBeConcretelyConstrainedVAASiRszlEySiSgSiciM
+// CHECK-SAME: $@yield_once @convention(method) (Int, @inout WillBeConcretelyConstrained<Int>) -> @yields @inout Optional<Int>
+
+// CHECK: sil{{.*}}s18subscript_accessor9testXRead1xxAA1XVyxG_tlF
 @_specialize(where T == (Int, Int))
 func testXRead<T>(x: X<T>) -> T {
   return x[]!
diff --git a/test/SILGen/witness_tables_serialized.swift b/test/SILGen/witness_tables_serialized.swift
index d4d4a40..4fd419b 100644
--- a/test/SILGen/witness_tables_serialized.swift
+++ b/test/SILGen/witness_tables_serialized.swift
@@ -16,15 +16,17 @@
 @usableFromInline
 internal struct InternalStruct : PublicProtocol, InternalProtocol {}
 
-// CHECK: sil_witness_table [serialized] PublicStruct: PublicProtocol
-// CHECK: sil_witness_table [serialized] PublicStruct: InternalProtocol
+// CHECK-DAG: sil_witness_table [serialized] PublicStruct: PublicProtocol
+// CHECK-DAG: sil_witness_table [serialized] PublicStruct: InternalProtocol
 
-// CHECK-NONRESILIENT: sil_witness_table [serialized] PublicResilientStruct: PublicProtocol
-// CHECK-NONRESILIENT: sil_witness_table [serialized] PublicResilientStruct: InternalProtocol
-// CHECK-RESILIENT: sil_witness_table PublicResilientStruct: PublicProtocol
-// CHECK-RESILIENT: sil_witness_table PublicResilientStruct: InternalProtocol
+// CHECK-RESILIENT-DAG: sil_witness_table InternalStruct: InternalProtocol
+// CHECK-RESILIENT-DAG: sil_witness_table InternalStruct: PublicProtocol
 
-// CHECK-NONRESILIENT: sil_witness_table [serialized] InternalStruct: PublicProtocol
-// CHECK-NONRESILIENT: sil_witness_table [serialized] InternalStruct: InternalProtocol
-// CHECK-RESILIENT: sil_witness_table InternalStruct: PublicProtocol
-// CHECK-RESILIENT: sil_witness_table InternalStruct: InternalProtocol
+// CHECK-RESILIENT-DAG: sil_witness_table PublicResilientStruct: PublicProtocol
+// CHECK-RESILIENT-DAG: sil_witness_table PublicResilientStruct: InternalProtocol
+
+// CHECK-NONRESILIENT-DAG: sil_witness_table [serialized] InternalStruct: InternalProtocol
+// CHECK-NONRESILIENT-DAG: sil_witness_table [serialized] InternalStruct: PublicProtocol
+
+// CHECK-NONRESILIENT-DAG: sil_witness_table [serialized] PublicResilientStruct: PublicProtocol
+// CHECK-NONRESILIENT-DAG: sil_witness_table [serialized] PublicResilientStruct: InternalProtocol
diff --git a/test/SILOptimizer/capturepromotion-wrong-lexicalscope.swift b/test/SILOptimizer/capturepromotion-wrong-lexicalscope.swift
index 6b82184..8345e18 100644
--- a/test/SILOptimizer/capturepromotion-wrong-lexicalscope.swift
+++ b/test/SILOptimizer/capturepromotion-wrong-lexicalscope.swift
@@ -1,6 +1,6 @@
 // Make sure project_box gets assigned the correct lexical scope when we create it.
 // RUN: %target-swift-frontend -primary-file %s -Onone -emit-sil -Xllvm -sil-print-after=capture-promotion -Xllvm \
-// RUN:   -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
+// RUN:   -sil-print-debuginfo -o /dev/null -module-name null 2>&1 | %FileCheck %s
 
 // CHECK: sil hidden [ossa] @$s4null19captureStackPromoteSiycyF : $@convention(thin) () -> @owned @callee_guaranteed () -> Int {
 // CHECK: bb0:
diff --git a/test/SILOptimizer/dead_array_elim.sil b/test/SILOptimizer/dead_array_elim.sil
index e6939a9..54b053e 100644
--- a/test/SILOptimizer/dead_array_elim.sil
+++ b/test/SILOptimizer/dead_array_elim.sil
@@ -1,7 +1,8 @@
 // RUN: %target-sil-opt -sil-print-debuginfo -enable-sil-verify-all -deadobject-elim %s | %FileCheck %s
 
-// Linux doesn't have the same symbol name for _ArrayBuffer.
-// XFAIL: linux
+// Linux doesn't have the same symbol name for _ArrayBuffer, which is part of
+// the ObjC runtime interop.  Use `_ContiguousArrayBuffer instead.
+// REQUIRES: objc_interop
 
 import Swift
 import Builtin
diff --git a/test/SILOptimizer/definite-init-wrongscope.swift b/test/SILOptimizer/definite-init-wrongscope.swift
index c61bfa1..3149ed2 100644
--- a/test/SILOptimizer/definite-init-wrongscope.swift
+++ b/test/SILOptimizer/definite-init-wrongscope.swift
@@ -1,7 +1,7 @@
 // RUN: %target-swift-frontend -primary-file %s -Onone -emit-sil -Xllvm \
 // RUN:   -sil-print-after=raw-sil-inst-lowering -Xllvm \
 // RUN:   -sil-print-only-functions=$s3del1MC4fromAcA12WithDelegate_p_tKcfc \
-// RUN:   -Xllvm -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
+// RUN:   -Xllvm -sil-print-debuginfo -o /dev/null -module-name del 2>&1 | %FileCheck %s
 
 public protocol DelegateA {}
 public protocol DelegateB {}
diff --git a/test/SILOptimizer/definite_init_cross_module.swift b/test/SILOptimizer/definite_init_cross_module.swift
index 111a1c4..73fbfa4 100644
--- a/test/SILOptimizer/definite_init_cross_module.swift
+++ b/test/SILOptimizer/definite_init_cross_module.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -emit-module-path=%t/OtherModule.swiftmodule %S/Inputs/definite_init_cross_module/OtherModule.swift
-// RUN: %target-swift-frontend -emit-sil -verify -I %t -swift-version 5 %s > /dev/null -import-objc-header %S/Inputs/definite_init_cross_module/BridgingHeader.h
+// RUN: %target-swift-frontend -emit-sil -verify -I %t -swift-version 5 %s > /dev/null -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/definite_init_cross_module/BridgingHeader.h
 
 import OtherModule
 
diff --git a/test/SILOptimizer/definite_init_cross_module_swift4.swift b/test/SILOptimizer/definite_init_cross_module_swift4.swift
index 05bada4..935499d 100644
--- a/test/SILOptimizer/definite_init_cross_module_swift4.swift
+++ b/test/SILOptimizer/definite_init_cross_module_swift4.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -emit-module-path=%t/OtherModule.swiftmodule %S/Inputs/definite_init_cross_module/OtherModule.swift
-// RUN: %target-swift-frontend -emit-sil -verify -verify-ignore-unknown -I %t -swift-version 4 %s > /dev/null -import-objc-header %S/Inputs/definite_init_cross_module/BridgingHeader.h
+// RUN: %target-swift-frontend -emit-sil -verify -verify-ignore-unknown -I %t -swift-version 4 %s > /dev/null -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/definite_init_cross_module/BridgingHeader.h
 
 import OtherModule
 
diff --git a/test/SILOptimizer/devirt_class_witness_method.sil b/test/SILOptimizer/devirt_class_witness_method.sil
index e1c7f51..2500567 100644
--- a/test/SILOptimizer/devirt_class_witness_method.sil
+++ b/test/SILOptimizer/devirt_class_witness_method.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer -sil-combine -enable-resilience -save-optimization-record-path=%t.opt.yaml | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-verify-all %/s -devirtualizer -sil-combine -enable-resilience -save-optimization-record-path=%t.opt.yaml | %FileCheck %s
 sil_stage canonical
 // RUN: %FileCheck -check-prefix=YAML -input-file=%t.opt.yaml %s
 
diff --git a/test/SILOptimizer/devirt_conditional_conformance.swift b/test/SILOptimizer/devirt_conditional_conformance.swift
index b1437b8..96f5481 100644
--- a/test/SILOptimizer/devirt_conditional_conformance.swift
+++ b/test/SILOptimizer/devirt_conditional_conformance.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -O -Xllvm -sil-inline-generics=false -Xllvm -sil-disable-pass=GlobalOpt %s -emit-sil -sil-verify-all | tee /tmp/xxx | %FileCheck %s
+// RUN: %target-swift-frontend -O -Xllvm -sil-inline-generics=false -Xllvm -sil-disable-pass=GlobalOpt %s -emit-sil -sil-verify-all | %FileCheck %s
 
 
 public protocol Foo {
@@ -81,4 +81,4 @@
 // CHECK: return
 public func testFish() {
   callFish(Outer(x: 0))
-}
\ No newline at end of file
+}
diff --git a/test/SILOptimizer/devirt_protocol_method_invocations.swift b/test/SILOptimizer/devirt_protocol_method_invocations.swift
index d788fbb..2b4476f 100644
--- a/test/SILOptimizer/devirt_protocol_method_invocations.swift
+++ b/test/SILOptimizer/devirt_protocol_method_invocations.swift
@@ -264,3 +264,27 @@
   }
 }
 
+// Check that we don't attempt to cast an opened type to a concrete
+// type inferred via ProtocolConformanceAnalysis if the type requires
+// reabstraction when erased by an existential.
+protocol ReabstractedP {
+  func f()
+}
+extension Optional : ReabstractedP {
+  func f() {}
+}
+
+// CHECK-LABEL: sil hidden [noinline] @$s34devirt_protocol_method_invocations23testReabstractedWitnessyyAA0F1P_pF : $@convention(thin) (@in_guaranteed ReabstractedP) -> () {
+// CHECK: bb0(%0 : $*ReabstractedP):
+// CHECK: [[OPEN:%.*]] = open_existential_addr immutable_access %0 : $*ReabstractedP to $*@opened([[ID:.*]]) ReabstractedP
+// CHECK: [[WM:%.*]] = witness_method $@opened([[ID]]) ReabstractedP, #ReabstractedP.f!1 : <Self where Self : ReabstractedP> (Self) -> () -> (), [[OPEN]] : $*@opened([[ID]]) ReabstractedP : $@convention(witness_method: ReabstractedP) <τ_0_0 where τ_0_0 : ReabstractedP> (@in_guaranteed τ_0_0) -> ()
+// CHECK: apply [[WM]]<@opened([[ID]]) ReabstractedP>([[OPEN]]) : $@convention(witness_method: ReabstractedP) <τ_0_0 where τ_0_0 : ReabstractedP> (@in_guaranteed τ_0_0) -> ()
+// CHECK-LABEL: } // end sil function '$s34devirt_protocol_method_invocations23testReabstractedWitnessyyAA0F1P_pF'
+@inline(never)
+func testReabstractedWitness(_ f: ReabstractedP) {
+  f.f()
+}
+
+public func testReabstracted(f: Optional<()->()>) {
+  testReabstractedWitness(f)
+}
diff --git a/test/SILOptimizer/devirt_speculate.swift b/test/SILOptimizer/devirt_speculate.swift
index fcd1217..047dc57 100644
--- a/test/SILOptimizer/devirt_speculate.swift
+++ b/test/SILOptimizer/devirt_speculate.swift
@@ -1,6 +1,6 @@
-// RUN: %target-swift-frontend %s -parse-as-library -O -emit-sil -save-optimization-record-path %t.opt.yaml | %FileCheck %s
+// RUN: %target-swift-frontend %/s -parse-as-library -O -emit-sil -save-optimization-record-path %t.opt.yaml | %FileCheck %s
 // RUN: %FileCheck -check-prefix=YAML -input-file=%t.opt.yaml %s
-// RUN: %target-swift-frontend %s -parse-as-library -Osize -emit-sil | %FileCheck %s --check-prefix=OSIZE
+// RUN: %target-swift-frontend %/s -parse-as-library -Osize -emit-sil | %FileCheck %s --check-prefix=OSIZE
 //
 // Test speculative devirtualization.
 
diff --git a/test/SILOptimizer/devirtualize.sil b/test/SILOptimizer/devirtualize.sil
index f2af7a6..f021a1d 100644
--- a/test/SILOptimizer/devirtualize.sil
+++ b/test/SILOptimizer/devirtualize.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer -dce -save-optimization-record-path=%t.yaml | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-verify-all %/s -devirtualizer -dce -save-optimization-record-path=%t.yaml | %FileCheck %s
 // RUN: %FileCheck -check-prefix=YAML -input-file=%t.yaml %s
 
 sil_stage canonical
diff --git a/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift b/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift
index 7c2f6f8..0ada539 100644
--- a/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift
+++ b/test/SILOptimizer/diagnostic_constant_propagation_floats_x86.swift
@@ -1,6 +1,7 @@
 // RUN: %target-swift-frontend -emit-sil -primary-file %s -o /dev/null -verify
 //
 // REQUIRES: CPU=i386 || CPU=x86_64
+// UNSUPPORTED: OS=windows-msvc
 //
 // These are tests for diagnostics produced by constant propagation pass
 // on floating-point operations that are specific to x86 architectures,
diff --git a/test/SILOptimizer/existential_transform.swift b/test/SILOptimizer/existential_transform.swift
index 2e5b046..fc27a4f 100644
--- a/test/SILOptimizer/existential_transform.swift
+++ b/test/SILOptimizer/existential_transform.swift
@@ -358,6 +358,42 @@
   return wrap_gcp_arch(a, k, &b)
 }
 
+protocol Foo {
+  var myName: String { get }
+}
+
+struct MyURL {
+}
+
+extension MyURL : Foo {
+  var myName : String { return "MyURL" }
+}
+
+struct MyStruct : Foo {
+  var myName : String { return "MyStruct" }
+}
+
+// CHECK-LABEL: sil shared [noinline] @$s21existential_transform7getNameySSAA3Foo_pFTf4e_n : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> @owned String {
+// CHECK: bb0(%0 : $*τ_0_0):
+// CHECK:   alloc_stack
+// CHECK:   init_existential_addr
+// CHECK:   copy_addr
+// CHECK:   debug_value_addr 
+// CHECK:   open_existential_addr
+// CHECK:   witness_method 
+// CHECK:   apply
+// CHECK:   dealloc_stack
+// CHECK:   return
+// CHECK-LABEL: } // end sil function '$s21existential_transform7getNameySSAA3Foo_pFTf4e_n'
+@inline(never) func getName(_ f: Foo) -> String {
+  return f.myName
+}
+
+@inline(never) func getName_wrapper() -> Int32{
+  let u = MyURL()
+  return getName(u) == "MyStruct" ? 0 : 1
+}
+
 @_optimize(none) public func foo() -> Int {
 cp()
 ncp()
@@ -371,5 +407,6 @@
 let y:Int = gcp(GC())
 var a:Array<GC> = [GC()]
 let z:Int = gcp_arch(GC(), &a) 
-return x + y + z
+let zz:Int32 = getName_wrapper()
+return x + y + z + Int(zz)
 }
diff --git a/test/SILOptimizer/globalopt_resilience.swift b/test/SILOptimizer/globalopt_resilience.swift
new file mode 100644
index 0000000..98ecf53
--- /dev/null
+++ b/test/SILOptimizer/globalopt_resilience.swift
@@ -0,0 +1,19 @@
+// RUN: %target-swift-frontend  -O -module-name=test -enable-resilience -emit-sil -primary-file %s | %FileCheck %s
+
+// Check if GlobalOpt generates the optimal getter for a static property with a resilient type.
+// The (resilient) getter should just return the literal (and not lazily initialize a global variable).
+
+// CHECK-LABEL: sil @$s4test15ResilientStructV9staticValACvgZ :
+// CHECK:     bb0(%0 : $*ResilientStruct{{.*}}):
+// CHECK:       [[L:%[0-9]+]] = integer_literal {{.*}}, 27
+// CHECK:       [[I:%[0-9]+]] = struct $Int ([[L]] : {{.*}})
+// CHECK:       [[S:%[0-9]+]] = struct $ResilientStruct ([[I]] : $Int)
+// CHECK:       store [[S]] to %0
+// CHECK:       return
+
+public struct ResilientStruct {
+  var rawValue: Int
+
+  public static let staticVal = ResilientStruct(rawValue: 27)
+}
+
diff --git a/test/SILOptimizer/no-external-defs-onone.sil b/test/SILOptimizer/no-external-defs-onone.sil
index 1a99174..fe592f3 100644
--- a/test/SILOptimizer/no-external-defs-onone.sil
+++ b/test/SILOptimizer/no-external-defs-onone.sil
@@ -1,7 +1,7 @@
 // RUN: %target-swift-frontend -module-name=test -Onone -emit-ir %s | %FileCheck %s
 
 // CHECK-DAG: define linkonce_odr hidden swiftcc void @shared_external_test()
-// CHECK-DAG: declare swiftcc void @public_external_test()
+// CHECK-DAG: declare {{(dllimport )?}}swiftcc void @public_external_test()
 // Non-public external symbols are emitted into clients.
 // CHECK-DAG: define available_externally hidden swiftcc void @hidden_external_test()
 // CHECK-NOT: public_external_unused_test
diff --git a/test/SILOptimizer/pound_assert.sil b/test/SILOptimizer/pound_assert.sil
index 930cea4..ee56609 100644
--- a/test/SILOptimizer/pound_assert.sil
+++ b/test/SILOptimizer/pound_assert.sil
@@ -30,9 +30,9 @@
   return undef : $()
 }
 
-// Tests that piecewise initialization of memory works, by piecewise
-// initializing a tuple.
-sil @piecewiseInit : $@convention(thin) () -> Bool {
+// Tests that piecewise initialization of memory works during flow-sensitive
+// evaluation, by piecewise initializing a tuple in a function.
+sil @piecewiseInitFlowSensitive : $@convention(thin) () -> Bool {
 bb0:
   // Allocate and initialize the tuple to (1, 2).
   %0 = alloc_stack $(Int64, Int64), var, name "tup"
@@ -61,6 +61,16 @@
   return %15 : $Bool
 }
 
+sil @invokePiecewiseInitFlowSensitiveTest : $@convention(thin) () -> () {
+  %0 = function_ref @piecewiseInitFlowSensitive : $@convention(thin) () -> Bool
+  %1 = apply %0() : $@convention(thin) () -> Bool
+  %2 = struct_extract %1 : $Bool, #Bool._value
+  %3 = string_literal utf8 ""
+  %4 = builtin "poundAssert"(%2 : $Builtin.Int1, %3 : $Builtin.RawPointer) : $()
+  %ret = tuple ()
+  return %ret : $()
+}
+
 // Tests copy_addr interpretation.
 sil @copyAddr : $@convention(thin) () -> Bool {
   // Allocate an initialize an Int64 to 1.
@@ -87,19 +97,169 @@
   return %10 : $Bool
 }
 
-sil @invokeTests : $@convention(thin) () -> () {
-  %0 = function_ref @piecewiseInit : $@convention(thin) () -> Bool
+sil @invokeCopyAddrTest : $@convention(thin) () -> () {
+  %0 = function_ref @copyAddr : $@convention(thin) () -> Bool
   %1 = apply %0() : $@convention(thin) () -> Bool
   %2 = struct_extract %1 : $Bool, #Bool._value
   %3 = string_literal utf8 ""
   %4 = builtin "poundAssert"(%2 : $Builtin.Int1, %3 : $Builtin.RawPointer) : $()
+  %ret = tuple ()
+  return %ret : $()
+}
 
-  %5 = function_ref @copyAddr : $@convention(thin) () -> Bool
-  %6 = apply %5() : $@convention(thin) () -> Bool
-  %7 = struct_extract %6 : $Bool, #Bool._value
+// A function with @out result to help with some tests.
+sil @setInt64To1 : $@convention(thin) () -> (@out Int64) {
+bb0(%0 : $*Int64):
+  %1 = integer_literal $Builtin.Int64, 1
+  %2 = struct $Int64 (%1 : $Builtin.Int64)
+  store %2 to %0 : $*Int64
+  %ret = tuple ()
+  return %ret : $()
+}
+
+// Tests that initialization of memory using `store` works during top-level
+// evaluation.
+sil @storeInitTopLevel : $@convention(thin) () -> () {
+  %0 = alloc_stack $Int64
+  %1 = integer_literal $Builtin.Int64, 1
+  %2 = struct $Int64 (%1 : $Builtin.Int64)
+  store %2 to %0 : $*Int64
+  %4 = load %0 : $*Int64
+  %5 = struct_extract %4 : $Int64, #Int64._value
+  %6 = builtin "cmp_eq_Int64"(%1 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
+  %7 = string_literal utf8 ""
+  %8 = builtin "poundAssert"(%6 : $Builtin.Int1, %7 : $Builtin.RawPointer) : $()
+  dealloc_stack %0 : $*Int64
+  %ret = tuple ()
+  return %ret : $()
+}
+
+// Tests that initialization of memory using `copy_addr` works during top-level
+// evaluation.
+sil @copyInitTopLevel : $@convention(thin) () -> () {
+  %0 = alloc_stack $Int64
+  %1 = alloc_stack $Int64
+  %2 = integer_literal $Builtin.Int64, 1
+  %3 = struct $Int64 (%2 : $Builtin.Int64)
+  store %3 to %0 : $*Int64
+  copy_addr %0 to %1 : $*Int64
+  %6 = load %1 : $*Int64
+  %7 = struct_extract %6 : $Int64, #Int64._value
+  %8 = builtin "cmp_eq_Int64"(%2 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1
+  %9 = string_literal utf8 ""
+  %10 = builtin "poundAssert"(%8 : $Builtin.Int1, %9 : $Builtin.RawPointer) : $()
+  dealloc_stack %1 : $*Int64
+  dealloc_stack %0 : $*Int64
+  %ret = tuple ()
+  return %ret : $()
+}
+
+// Tests that initialization of memory using `apply` works during top-level
+// evaluation.
+sil @applyInitTopLevel : $@convention(thin) () -> () {
+  %0 = alloc_stack $Int64
+  %1 = function_ref @setInt64To1: $@convention(thin) () -> (@out Int64)
+  %2 = apply %1(%0) : $@convention(thin) () -> (@out Int64)
+  %3 = load %0 : $*Int64
+  %4 = struct_extract %3 : $Int64, #Int64._value
+  %5 = integer_literal $Builtin.Int64, 1
+  %6 = builtin "cmp_eq_Int64"(%4 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1
+  %7 = string_literal utf8 ""
+  %8 = builtin "poundAssert"(%6 : $Builtin.Int1, %7 : $Builtin.RawPointer) : $()
+  dealloc_stack %0 : $*Int64
+  %ret = tuple ()
+  return %ret : $()
+}
+
+// Tests that piecewise initialization of tuple memory works during top-level
+// evaluation.
+sil @piecewiseInitTopLevel : $@convention(thin) () -> () {
+bb0:
+  // Allocate and initialize the tuple to (1, 2).
+  %0 = alloc_stack $(Int64, Int64), var, name "tup"
+  %1 = tuple_element_addr %0 : $*(Int64, Int64), 0
+  %2 = tuple_element_addr %0 : $*(Int64, Int64), 1
+  %3 = integer_literal $Builtin.Int64, 1
+  %4 = struct $Int64 (%3 : $Builtin.Int64)
+  store %4 to %1 : $*Int64
+  %6 = integer_literal $Builtin.Int64, 2
+  %7 = struct $Int64 (%6 : $Builtin.Int64)
+  store %7 to %2 : $*Int64
+
+  // Read the first element from the tuple.
+  // TODO: Allow `begin_access` in top level initialization.
+  // %9 = begin_access [read] [static] %0 : $*(Int64, Int64)
+  %10 = tuple_element_addr %0 : $*(Int64, Int64), 0
+  %11 = load %10 : $*Int64
+  // end_access %9 : $*(Int64, Int64)
+
+  // Check that the first element is what we put in.
+  %13 = struct_extract %11 : $Int64, #Int64._value
+  %14 = builtin "cmp_eq_Int64"(%3 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %15 = string_literal utf8 ""
+  %16 = builtin "poundAssert"(%14 : $Builtin.Int1, %15 : $Builtin.RawPointer) : $()
+
+  // Deallocate and return.
+  dealloc_stack %0 : $*(Int64, Int64)
+  %ret = tuple ()
+  return %ret : $()
+}
+
+// Tests that top-level evaluation detects memory that gets written to twice.
+sil @doubleWriteTopLevel : $@convention(thin) () -> () {
+  // expected-note @+1 {{could not fold operation}}
+  %0 = alloc_stack $Int64
+  %1 = integer_literal $Builtin.Int64, 1
+  %2 = struct $Int64 (%1 : $Builtin.Int64)
+  store %2 to %0 : $*Int64
+  store %2 to %0 : $*Int64
+  %5 = load %0 : $*Int64
+  %6 = struct_extract %5 : $Int64, #Int64._value
+  %7 = builtin "cmp_eq_Int64"(%1 : $Builtin.Int64, %6 : $Builtin.Int64) : $Builtin.Int1
   %8 = string_literal utf8 ""
+  // expected-error @+1 {{#assert condition not constant}}
   %9 = builtin "poundAssert"(%7 : $Builtin.Int1, %8 : $Builtin.RawPointer) : $()
+  dealloc_stack %0 : $*Int64
+  %ret = tuple ()
+  return %ret : $()
+}
 
+// There was a bug where the evalutor would not detect a double-write to a
+// tuple element at the top level if one of the writes writes an unknown value.
+sil @doubleWriteTupleElement : $@convention(thin) (Int64) -> () {
+bb0(%arg : $Int64):
+  // Allocate and initialize the tuple to (1, 2).
+  %0 = alloc_stack $(Int64, Int64), var, name "tup"
+  %1 = tuple_element_addr %0 : $*(Int64, Int64), 0
+  %2 = tuple_element_addr %0 : $*(Int64, Int64), 1
+  %3 = integer_literal $Builtin.Int64, 1
+  %4 = struct $Int64 (%3 : $Builtin.Int64)
+  store %4 to %1 : $*Int64
+  %6 = integer_literal $Builtin.Int64, 2
+  %7 = struct $Int64 (%6 : $Builtin.Int64)
+  store %7 to %2 : $*Int64
+
+  // Store %arg, whose value is unknown, to the first element of the tuple.
+  // expected-note @+1 {{could not fold operation}}
+  %addr = tuple_element_addr %0 : $*(Int64, Int64), 0
+  store %arg to %addr : $*Int64
+
+  // Read the first element from the tuple.
+  // TODO: Allow `begin_access` in top level initialization.
+  // %9 = begin_access [read] [static] %0 : $*(Int64, Int64)
+  %10 = tuple_element_addr %0 : $*(Int64, Int64), 0
+  %11 = load %10 : $*Int64
+  // end_access %9 : $*(Int64, Int64)
+
+  // Check that the first element is what we put in.
+  %13 = struct_extract %11 : $Int64, #Int64._value
+  %14 = builtin "cmp_eq_Int64"(%3 : $Builtin.Int64, %13 : $Builtin.Int64) : $Builtin.Int1
+  %15 = string_literal utf8 ""
+  // expected-error @+1 {{#assert condition not constant}}
+  %16 = builtin "poundAssert"(%14 : $Builtin.Int1, %15 : $Builtin.RawPointer) : $()
+
+  // Deallocate and return.
+  dealloc_stack %0 : $*(Int64, Int64)
   %ret = tuple ()
   return %ret : $()
 }
diff --git a/test/SILOptimizer/pound_assert.swift b/test/SILOptimizer/pound_assert.swift
index 297aa1f..dc3d66c 100644
--- a/test/SILOptimizer/pound_assert.swift
+++ b/test/SILOptimizer/pound_assert.swift
@@ -223,3 +223,235 @@
   #assert(replaceAggregate())
   #assert(shouldNotAlias())
 }
+
+//===----------------------------------------------------------------------===//
+// Evaluating generic functions
+//===----------------------------------------------------------------------===//
+
+func genericAdd<T: Numeric>(_ a: T, _ b: T) -> T {
+  return a + b
+}
+
+func test_genericAdd() {
+  #assert(genericAdd(1, 1) == 2)
+}
+
+func test_tupleAsGeneric() {
+  func identity<T>(_ t: T) -> T {
+    return t
+  }
+  #assert(identity((1, 2)) == (1, 2))
+}
+
+//===----------------------------------------------------------------------===//
+// Reduced testcase propagating substitutions around.
+//===----------------------------------------------------------------------===//
+protocol SubstitutionsP {
+  init<T: SubstitutionsP>(something: T)
+
+  func get() -> Int
+}
+
+struct SubstitutionsX : SubstitutionsP {
+  var state : Int
+  init<T: SubstitutionsP>(something: T) {
+    state = something.get()
+  }
+  func get() -> Int {
+    fatalError()
+  }
+
+  func getState() -> Int {
+    return state
+  }
+}
+
+struct SubstitutionsY : SubstitutionsP {
+  init() {}
+  init<T: SubstitutionsP>(something: T) {
+  }
+
+  func get() -> Int {
+    return 123
+  }
+}
+func substitutionsF<T: SubstitutionsP>(_: T.Type) -> T {
+  return T(something: SubstitutionsY())
+}
+
+func testProto() {
+  #assert(substitutionsF(SubstitutionsX.self).getState() == 123)
+}
+
+//===----------------------------------------------------------------------===//
+// Structs with generics
+//===----------------------------------------------------------------------===//
+
+// Test 1
+struct S<X, Y> {
+  func method<Z>(_ z: Z) -> Int {
+    return 0
+  }
+}
+
+func callerOfSMethod<U, V, W>(_ s: S<U, V>, _ w: W) -> Int {
+  return s.method(w)
+}
+
+func toplevel() {
+  let s = S<Int, Float>()
+  #assert(callerOfSMethod(s, -1) == 0)
+}
+
+// Test 2: test a struct method returning its generic argument.
+struct S2<X> {
+  func method<Z>(_ z: Z) -> Z {
+    return z
+  }
+}
+
+func callerOfS2Method<U, V>(_ s: S2<U>, _ v: V) -> V {
+  return s.method(v)
+}
+
+func testStructMethodReturningGenericParam() {
+  let s = S2<Float>()
+  #assert(callerOfS2Method(s, -1) == -1)
+}
+
+//===----------------------------------------------------------------------===//
+// Test that the order in which the generic parameters are declared doesn't
+// affect the interpreter.
+//===----------------------------------------------------------------------===//
+
+protocol Proto {
+  func amethod<U>(_ u: U) -> Int
+}
+
+func callMethod<U, T: Proto>(_ a: T, _ u: U) -> Int {
+  return a.amethod(u)
+}
+
+// Test 1
+struct Sp : Proto {
+  func amethod<U>(_ u: U) -> Int {
+    return 0
+  }
+}
+
+func testProtocolMethod() {
+  let s = Sp()
+  #assert(callMethod(s, 10) == 0)
+}
+
+// Test 2
+struct GenericS<P>: Proto {
+  func amethod<U>(_ u: U) -> Int {
+    return 12
+  }
+}
+
+func testProtocolMethodForGenericStructs() {
+  let s = GenericS<Int>()
+  #assert(callMethod(s, 10) == 12)
+}
+
+// Test 3 (with generic fields)
+struct GenericS2<P: Equatable>: Proto {
+  var fld1: P
+  var fld2: P
+
+  init(_ p: P, _ q: P) {
+    fld1 = p
+    fld2 = q
+  }
+
+  func amethod<U>(_ u: U) -> Int {
+    if (fld1 == fld2) {
+      return 15
+    }
+    return 0
+  }
+}
+
+func testProtocolMethodForStructsWithGenericFields() {
+  let s = GenericS2<Int>(1, 1)
+  #assert(callMethod(s, 10) == 15)
+}
+
+//===----------------------------------------------------------------------===//
+// Structs with generics and protocols with associated types.
+//===----------------------------------------------------------------------===//
+
+protocol ProtoWithAssocType {
+  associatedtype U
+
+  func amethod(_ u: U) -> U
+}
+
+struct St<X, Y> : ProtoWithAssocType {
+  typealias U = X
+
+  func amethod(_ x: X) -> X {
+    return x
+  }
+}
+
+func callerOfStMethod<P, Q>(_ s: St<P, Q>, _ p: P) -> P {
+  return s.amethod(p)
+}
+
+func testProtoWithAssocTypes() {
+  let s = St<Int, Float>()
+  #assert(callerOfStMethod(s, 11) == 11)
+}
+
+// Test 2: test a protocol method returning its generic argument.
+protocol ProtoWithGenericMethod {
+  func amethod<U>(_ u: U) -> U
+}
+
+
+struct SProtoWithGenericMethod<X> : ProtoWithGenericMethod {
+  func amethod<Z>(_ z: Z) -> Z {
+    return z
+  }
+}
+
+func callerOfGenericProtoMethod<S: ProtoWithGenericMethod, V>(_ s: S,
+                                                              _ v: V) -> V {
+  return s.amethod(v)
+}
+
+func testProtoWithGenericMethod() {
+  let s = SProtoWithGenericMethod<Float>()
+  #assert(callerOfGenericProtoMethod(s, -1) == -1)
+}
+
+//===----------------------------------------------------------------------===//
+// Converting a struct instance to protocol instance is not supported yet.
+// This requires handling init_existential_addr instruction. Once they are
+// supported, the following static assert must pass. For now, a workaround is
+// to use generic parameters with protocol constraints in the interpretable
+// code fragments.
+//===----------------------------------------------------------------------===//
+
+protocol ProtoSimple {
+  func amethod() -> Int
+}
+
+func callProtoSimpleMethod(_ p: ProtoSimple) -> Int {
+  return p.amethod()
+}
+
+struct SPsimp : ProtoSimple {
+  func amethod() -> Int {
+    return 0
+  }
+}
+
+func testStructPassedAsProtocols() {
+  let s = SPsimp()
+  #assert(callProtoSimpleMethod(s) == 0) // expected-error {{#assert condition not constant}}
+    // expected-note@-1 {{could not fold operation}}
+}
diff --git a/test/SILOptimizer/predictable_memopt.sil b/test/SILOptimizer/predictable_memopt.sil
index 8610488..407beac 100644
--- a/test/SILOptimizer/predictable_memopt.sil
+++ b/test/SILOptimizer/predictable_memopt.sil
@@ -43,6 +43,63 @@
   return %d : $Int
 }
 
+// In this example we create two boxes. The first box is initialized and then
+// taken from to initialize the second box. This means that the first box must
+// be dealloc_boxed (since its underlying memory is considered invalid). In
+// contrast, the 2nd box must be released so that we destroy the underlying
+// input object.
+//
+// CHECK-LABEL: sil @simple_reg_promotion_nontrivial_memory : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK: strong_release
+// CHECK-NOT: dealloc_box
+// CHECK: } // end sil function 'simple_reg_promotion_nontrivial_memory'
+sil @simple_reg_promotion_nontrivial_memory : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+  %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>, 0
+  store %0 to %1a : $*Builtin.NativeObject
+
+  %3 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+  %3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>, 0
+  %4 = load %1a : $*Builtin.NativeObject
+  store %4 to %3a : $*Builtin.NativeObject
+  strong_release %3 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+  dealloc_box %1 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// Same as the last test but with release_value to be defensive in the cast that
+// someone passes us such SIL.
+//
+// CHECK-LABEL: sil @simple_reg_promotion_nontrivial_memory_release_value : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// The retain value is on the dealloc_box.
+// CHECK-NOT: retain_value
+// CHECK: release_value
+// CHECK-NOT: dealloc_box
+// CHECK: } // end sil function 'simple_reg_promotion_nontrivial_memory_release_value'
+sil @simple_reg_promotion_nontrivial_memory_release_value : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+  %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>, 0
+  store %0 to %1a : $*Builtin.NativeObject
+
+  // Also verify that we skip a retain_value on the dealloc_box.
+  retain_value %1 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+
+  %3 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+  %3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>, 0
+  %4 = load %1a : $*Builtin.NativeObject
+  store %4 to %3a : $*Builtin.NativeObject
+  release_value %3 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+  dealloc_box %1 : $<τ_0_0> { var τ_0_0 } <Builtin.NativeObject>
+
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+
 sil @takes_Int_inout : $@convention(thin) (@inout Int) -> ()
 sil @takes_NativeObject_inout : $@convention(thin) (@inout Builtin.NativeObject) -> ()
 
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 90a4db6..7869ea5 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -3575,3 +3575,42 @@
   return %4 : $Builtin.Int64
 }
 
+// <rdar://46746188> crash in swift_getObjCClassFromObject
+// class TestDocument: NSPersistentDocument {
+//   override init() {
+//     super.init()
+//   }
+//   convenience init(type: String) throws {
+//     self.init()
+//   }
+// }
+// After inlining the __allocating_init, we have two uses of the value_metatype.
+// The second use goes through a thick_to_objc_metatype. When SILCombine replaces 
+// thick_to_objc_metatype with value_metatype, it cannot extend the liverange
+// of value_metatype's operand.
+@objc class TestObjCInit {
+  init()
+
+  convenience init(type: String) throws
+}
+// CHECK-LABEL: sil hidden [thunk] @objc_init_partial_dealloc : $@convention(objc_method) (@owned TestObjCInit) -> Optional<TestObjCInit> {
+// CHECK: bb0(%0 : $TestObjCInit):
+// CHECK:   [[VMT2:%.*]] = value_metatype $@objc_metatype TestObjCInit.Type, %0 : $TestObjCInit
+// CHECK:   [[VMT:%.*]] = value_metatype $@thick TestObjCInit.Type, %0 : $TestObjCInit
+// CHECK:   dealloc_partial_ref %0 : $TestObjCInit, [[VMT]] : $@thick TestObjCInit.Type
+// CHECK-NOT: value_metatype
+// CHECK:   [[O:%.*]] = alloc_ref_dynamic [objc] [[VMT2]] : $@objc_metatype TestObjCInit.Type, $TestObjCInit
+// CHECK:   [[M:%.*]] = objc_method [[O]] : $TestObjCInit, #TestObjCInit.init!initializer.1.foreign : (TestObjCInit.Type) -> () -> TestObjCInit, $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+// CHECK:   apply [[M]]([[O]]) : $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+// CHECK-LABEL: } // end sil function 'objc_init_partial_dealloc'
+sil hidden [thunk] @objc_init_partial_dealloc : $@convention(objc_method) (@owned TestObjCInit) -> Optional<TestObjCInit> {
+bb0(%2 : $TestObjCInit):
+  %8 = value_metatype $@thick TestObjCInit.Type, %2 : $TestObjCInit
+  dealloc_partial_ref %2 : $TestObjCInit, %8 : $@thick TestObjCInit.Type
+  %11 = thick_to_objc_metatype %8 : $@thick TestObjCInit.Type to $@objc_metatype TestObjCInit.Type
+  %12 = alloc_ref_dynamic [objc] %11 : $@objc_metatype TestObjCInit.Type, $TestObjCInit
+  %13 = objc_method %12 : $TestObjCInit, #TestObjCInit.init!initializer.1.foreign : (TestObjCInit.Type) -> () -> TestObjCInit, $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+  %14 = apply %13(%12) : $@convention(objc_method) (@owned TestObjCInit) -> @owned TestObjCInit
+  %19 = enum $Optional<TestObjCInit>, #Optional.some!enumelt.1, %14 : $TestObjCInit
+  return %19 : $Optional<TestObjCInit>
+}
diff --git a/test/SILOptimizer/specialize.sil b/test/SILOptimizer/specialize.sil
index 057fff1..0d085d0 100644
--- a/test/SILOptimizer/specialize.sil
+++ b/test/SILOptimizer/specialize.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-verify-all -sil-partial-specialization -generic-specializer -save-optimization-record-path=%t.yaml %s | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-verify-all -sil-partial-specialization -generic-specializer -save-optimization-record-path=%t.yaml %/s | %FileCheck %s
 // RUN: %FileCheck -check-prefix=YAML %s < %t.yaml
 
 sil_stage canonical
diff --git a/test/SILOptimizer/specialize_no_definition.sil b/test/SILOptimizer/specialize_no_definition.sil
index b8180a5..a09a48c 100644
--- a/test/SILOptimizer/specialize_no_definition.sil
+++ b/test/SILOptimizer/specialize_no_definition.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer -save-optimization-record-path=%t.yaml -o /dev/null %s
+// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer -save-optimization-record-path=%t.yaml -o /dev/null %/s
 // RUN: %FileCheck %s < %t.yaml
 
 import Builtin
diff --git a/test/SILOptimizer/stack-nesting-wrong-scope.swift b/test/SILOptimizer/stack-nesting-wrong-scope.swift
index a312ebf..5d74b5b 100644
--- a/test/SILOptimizer/stack-nesting-wrong-scope.swift
+++ b/test/SILOptimizer/stack-nesting-wrong-scope.swift
@@ -1,7 +1,7 @@
 // RUN: %target-swift-frontend -emit-sil -enable-sil-ownership %s -Onone -Xllvm \
 // RUN:   -sil-print-after=allocbox-to-stack -Xllvm \
 // RUN:   -sil-print-only-functions=$s3red19ThrowAddrOnlyStructV016throwsOptionalToG0ACyxGSgSi_tcfC \
-// RUN:   -Xllvm -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
+// RUN:   -Xllvm -sil-print-debuginfo -o %t -module-name red 2>&1 | %FileCheck %s
 
 // CHECK: bb5(%33 : @owned $Error):
 // CHECK:   dealloc_stack %6 : $*ThrowAddrOnlyStruct<T>, loc {{.*}}:27:68, scope 2
diff --git a/test/SILOptimizer/switch_enum_objc.swift b/test/SILOptimizer/switch_enum_objc.swift
index 9829e9a..b9e9f06 100644
--- a/test/SILOptimizer/switch_enum_objc.swift
+++ b/test/SILOptimizer/switch_enum_objc.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend -emit-sil -O -primary-file %s -import-objc-header %S/Inputs/switch_enum_objc.h | %FileCheck %s
-// RUN: %target-swift-frontend -emit-sil -Osize -primary-file %s -import-objc-header %S/Inputs/switch_enum_objc.h | %FileCheck %s
+// RUN: %target-swift-frontend -emit-sil -O -primary-file %s -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/switch_enum_objc.h | %FileCheck %s
+// RUN: %target-swift-frontend -emit-sil -Osize -primary-file %s -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %S/Inputs/switch_enum_objc.h | %FileCheck %s
 
 @inline(never)
 func action0() {}
diff --git a/test/Serialization/Recovery/Inputs/custom-modules/IndirectImport.h b/test/Serialization/Recovery/Inputs/custom-modules/IndirectImport.h
index 7bf2a70..ee09040 100644
--- a/test/Serialization/Recovery/Inputs/custom-modules/IndirectImport.h
+++ b/test/Serialization/Recovery/Inputs/custom-modules/IndirectImport.h
@@ -1,3 +1,3 @@
 #if !BAD
-# import <IndirectlyImported.h>
+#include <IndirectlyImported.h>
 #endif
diff --git a/test/Serialization/Recovery/Inputs/custom-modules/IndirectlyImported.h b/test/Serialization/Recovery/Inputs/custom-modules/IndirectlyImported.h
index a97df43..72a7db6 100644
--- a/test/Serialization/Recovery/Inputs/custom-modules/IndirectlyImported.h
+++ b/test/Serialization/Recovery/Inputs/custom-modules/IndirectlyImported.h
@@ -1,3 +1,9 @@
+#ifndef INDIRECTLY_IMPORTED_H
+#define INDIRECTLY_IMPORTED_H
+
 struct IndirectlyImportedStruct {
   int value;
 };
+
+#endif
+
diff --git a/test/Serialization/autolinking-inlinable-inferred.swift b/test/Serialization/autolinking-inlinable-inferred.swift
index 4dfbc08..0e64b63 100644
--- a/test/Serialization/autolinking-inlinable-inferred.swift
+++ b/test/Serialization/autolinking-inlinable-inferred.swift
@@ -7,7 +7,7 @@
 // RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_indirect.swift -emit-module-path %t/autolinking_indirect.swiftmodule -module-link-name autolinking_indirect -I %t -swift-version 4
 
 // RUN: %target-swift-frontend -emit-module %S/Inputs/autolinking_module_inferred.swift -emit-module-path %t/autolinking_module_inferred.swiftmodule -module-link-name autolinking_module_inferred -I %t -swift-version 4
-// RUN: %target-swift-frontend -emit-ir %s -I %t -swift-version 4 | %FileCheck %s
+// RUN: %target-swift-frontend -emit-ir %s -I %t -swift-version 4 -enable-objc-interop | %FileCheck %s
 
 // Linux uses a different autolinking mechanism, based on
 // swift-autolink-extract. This file tests the Darwin mechanism.
@@ -22,15 +22,15 @@
 
 // CHECK: !llvm.linker.options = !{[[MODULE:![0-9]+]], [[PUBLIC:![0-9]+]], [[SWIFTONONESUPPORT:![0-9]+]], [[SWIFTCORE:![0-9]+]], [[PRIVATE:![0-9]+]], [[OTHER:![0-9]+]], [[INDIRECT:![0-9]+]], [[OTHER2:![0-9]+]], [[OBJC:![0-9]+]]}
 
-// CHECK-DAG: [[SWIFTCORE]] = !{!"-lswiftCore"}
-// CHECK-DAG: [[SWIFTONONESUPPORT]] = !{!"-lswiftSwiftOnoneSupport"}
-// CHECK-DAG: [[MODULE]] = !{!"-lautolinking_module_inferred"}
-// CHECK-DAG: [[PUBLIC]] = !{!"-lautolinking_public"}
-// CHECK-DAG: [[OTHER]] = !{!"-lautolinking_other"}
-// CHECK-DAG: [[OTHER2]] = !{!"-lautolinking_other2"}
-// CHECK-DAG: [[OBJC]] = !{!"-lobjc"}
+// CHECK-DAG: [[SWIFTCORE]] = !{!{{"-lswiftCore"|"/DEFAULTLIB:swiftCore.lib"}}}
+// CHECK-DAG: [[SWIFTONONESUPPORT]] = !{!{{"-lswiftSwiftOnoneSupport"|"/DEFAULTLIB:swiftSwiftOnoneSupport.lib"}}}
+// CHECK-DAG: [[MODULE]] = !{!{{"-lautolinking_module_inferred"|"/DEFAULTLIB:autolinking_module_inferred.lib"}}}
+// CHECK-DAG: [[PUBLIC]] = !{!{{"-lautolinking_public"|"/DEFAULTLIB:autolinking_public.lib"}}}
+// CHECK-DAG: [[OTHER]] = !{!{{"-lautolinking_other"|"/DEFAULTLIB:autolinking_other.lib"}}}
+// CHECK-DAG: [[OTHER2]] = !{!{{"-lautolinking_other2"|"/DEFAULTLIB:autolinking_other2.lib"}}}
+// CHECK-DAG: [[OBJC]] = !{!{{"-lobjc"|"/DEFAULTLIB:objc.lib"}}}
 
 // We don't actually care about these two. As long as we autolink the libraries
 // that get used, we're okay.
-// CHECK-DAG: [[PRIVATE]] = !{!"-lautolinking_private"}
-// CHECK-DAG: [[INDIRECT]] = !{!"-lautolinking_indirect"}
+// CHECK-DAG: [[PRIVATE]] = !{!{{"-lautolinking_private"|"/DEFAULTLIB:autolinking_private.lib"}}}
+// CHECK-DAG: [[INDIRECT]] = !{!{{"-lautolinking_indirect"|"/DEFAULTLIB:autolinking_indirect.lib"}}}
diff --git a/test/Serialization/autolinking.swift b/test/Serialization/autolinking.swift
index f8e9ab1..10c4726 100644
--- a/test/Serialization/autolinking.swift
+++ b/test/Serialization/autolinking.swift
@@ -29,25 +29,25 @@
 import someModule
 
 // CHECK: !llvm.linker.options = !{
-// CHECK-DAG: !{{[0-9]+}} = !{!"-lmagic"}
-// CHECK-DAG: !{{[0-9]+}} = !{!"-lmodule"}
+// CHECK-DAG: !{{[0-9]+}} = !{!{{"-lmagic"|"/DEFAULTLIB:magic.lib"}}}
+// CHECK-DAG: !{{[0-9]+}} = !{!{{"-lmodule"|"/DEFAULTLIB:module.lib"}}}
 
 // FRAMEWORK: !llvm.linker.options = !{
-// FRAMEWORK-DAG: !{{[0-9]+}} = !{!"-lmagic"}
-// FRAMEWORK-DAG: !{{[0-9]+}} = !{!"-lmodule"}
+// FRAMEWORK-DAG: !{{[0-9]+}} = !{!{{"-lmagic"|"/DEFAULTLIB:magic.lib"}}}
+// FRAMEWORK-DAG: !{{[0-9]+}} = !{!{{"-lmodule"|"/DEFAULTLIB:module.lib"}}}
 // FRAMEWORK-DAG: !{{[0-9]+}} = !{!"-framework", !"someModule"}
 
 // NO-FORCE-LOAD-NOT: FORCE_LOAD
-// FORCE-LOAD: define void @"_swift_FORCE_LOAD_$_module"() {
+// FORCE-LOAD: define{{( dllexport)?}} void @"_swift_FORCE_LOAD_$_module"() {
 // FORCE-LOAD:   ret void
 // FORCE-LOAD: }
-// FORCE-LOAD-HEX: define void @"_swift_FORCE_LOAD_$306d6f64756c65"() {
+// FORCE-LOAD-HEX: define{{( dllexport)?}} void @"_swift_FORCE_LOAD_$306d6f64756c65"() {
 // FORCE-LOAD-HEX:   ret void
 // FORCE-LOAD-HEX: }
 
-// FORCE-LOAD-CLIENT: @"_swift_FORCE_LOAD_$_module_$_autolinking" = weak hidden constant void ()* @"_swift_FORCE_LOAD_$_module"
+// FORCE-LOAD-CLIENT: @"_swift_FORCE_LOAD_$_module_$_autolinking" = weak_odr hidden constant void ()* @"_swift_FORCE_LOAD_$_module"
 // FORCE-LOAD-CLIENT: @llvm.used = appending global [{{[0-9]+}} x i8*] [
 // FORCE-LOAD-CLIENT: i8* bitcast (void ()** @"_swift_FORCE_LOAD_$_module_$_autolinking" to i8*)
 // FORCE-LOAD-CLIENT: ], section "llvm.metadata"
-// FORCE-LOAD-CLIENT: declare void @"_swift_FORCE_LOAD_$_module"()
+// FORCE-LOAD-CLIENT: declare {{(dllimport )?}}void @"_swift_FORCE_LOAD_$_module"()
 
diff --git a/test/Serialization/class-determinism.swift b/test/Serialization/class-determinism.swift
index 5472649..911956d 100644
--- a/test/Serialization/class-determinism.swift
+++ b/test/Serialization/class-determinism.swift
@@ -1,14 +1,17 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -module-name def_class -emit-module-path %t/def_class.1.swiftmodule %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop
 // RUN: %target-swift-frontend -module-name def_class -emit-module-path %t/def_class.2.swiftmodule %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop
-// RUN: diff <(llvm-bcanalyzer -dump %t/def_class.1.swiftmodule | sed -e 's/\.[0-9]\.swiftmodule/\.x\.swiftmodule/g') <(llvm-bcanalyzer -dump %t/def_class.2.swiftmodule | sed -e 's/\.[0-9]\.swiftmodule/\.x\.swiftmodule/g')
+// RUN: llvm-bcanalyzer -dump %t/def_class.1.swiftmodule | sed -e 's/\.[0-9]\.swiftmodule/\.x\.swiftmodule/g' > %t.1
+// RUN: llvm-bcanalyzer -dump %t/def_class.2.swiftmodule | sed -e 's/\.[0-9]\.swiftmodule/\.x\.swiftmodule/g' > %t.2
+// RUN: cmp %t.1 %t.2
 
 // Compiling the same set of files twice, without modifying them (and without
 // generating inlinable SIL) should produce the same swiftmodule. We don't
 // promise more than that at this time...
 
-// RUN: %S/../Inputs/getmtime.py %t/def_class.1.swiftmodule > %t/orig-mtime.txt
+// RUN: %{python} %S/../Inputs/getmtime.py %t/def_class.1.swiftmodule > %t/orig-mtime.txt
 // RUN: %target-swift-frontend -module-name def_class -emit-module-path %t/def_class.1.swiftmodule %S/Inputs/def_class.swift -disable-objc-attr-requires-foundation-module -enable-objc-interop
-// RUN: diff %t/orig-mtime.txt <(%S/../Inputs/getmtime.py %t/def_class.1.swiftmodule)
+// RUN: %{python} %S/../Inputs/getmtime.py %t/def_class.1.swiftmodule > %t.3
+// RUN: cmp %t/orig-mtime.txt %t.3
 
 // We shouldn't re-emit the module if it hasn't changed.
diff --git a/test/Serialization/load-file-permissions.swift b/test/Serialization/load-file-permissions.swift
index 42ee232..d864308 100644
--- a/test/Serialization/load-file-permissions.swift
+++ b/test/Serialization/load-file-permissions.swift
@@ -1,4 +1,4 @@
-// RUN: if [[ -d %t ]]; then chmod -R u+rwx %t && rm -rf %t; fi
+// RUN: %empty-directory(%t)
 // RUN: %empty-directory(%t/good)
 // RUN: %empty-directory(%t/bad)
 // RUN: chmod a-rx %t/bad
diff --git a/test/Serialization/load-invalid-arch.swift b/test/Serialization/load-invalid-arch.swift
index 8f3c468..2ac1f70 100644
--- a/test/Serialization/load-invalid-arch.swift
+++ b/test/Serialization/load-invalid-arch.swift
@@ -5,17 +5,17 @@
 // RUN: touch %t/new_module.swiftmodule/ppc65.swiftmodule
 // RUN: touch %t/new_module.swiftmodule/i387.swiftdoc
 // RUN: touch %t/new_module.swiftmodule/ppc65.swiftdoc
-// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
+// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%target-cpu
 
 // RUN: %empty-directory(%t)
 // RUN: mkdir -p %t/new_module.framework/Modules/new_module.swiftmodule/
 // RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/i387.swiftmodule
 // RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/ppc65.swiftmodule
-// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
+// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%target-cpu
 
 // RUN: %empty-directory(%t)
 // RUN: mkdir %t/new_module.swiftmodule
-// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK-EMPTY -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
+// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK-EMPTY -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=%target
 
 // CHECK-ALL-NOT: error:
 // CHECK: {{.*}} error: could not find module 'new_module' for architecture '[[TARGET_ARCHITECTURE]]'; found: {{ppc65, i387|i387, ppc65}}
diff --git a/test/Serialization/search-paths-relative.swift b/test/Serialization/search-paths-relative.swift
index cd190cb..39fae2a 100644
--- a/test/Serialization/search-paths-relative.swift
+++ b/test/Serialization/search-paths-relative.swift
@@ -18,13 +18,13 @@
 
 // CHECK-LABEL: <OPTIONS_BLOCK
 // CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-working-directory'
-// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '{{.+}}/secret'
+// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '{{.+}}{{/|\\}}secret'
 // CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-DDUMMY'
 // CHECK: </OPTIONS_BLOCK>
 
 // CHECK-LABEL: <INPUT_BLOCK
-// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=1 op1=0/> blob data = '{{.+}}/secret/../Frameworks'
-// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=0 op1=0/> blob data = '{{.+}}/secret/.'
+// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=1 op1=0/> blob data = '{{.+}}{{/|\\}}secret{{/|\\}}../Frameworks'
+// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=0 op1=0/> blob data = '{{.+}}{{/|\\}}secret{{/|\\}}.'
 // CHECK: </INPUT_BLOCK>
 
 // NEGATIVE-NOT: '.'
diff --git a/test/Serialization/sil_partial_apply_ownership.sil b/test/Serialization/sil_partial_apply_ownership.sil
index 8175617..221d2ae 100644
--- a/test/Serialization/sil_partial_apply_ownership.sil
+++ b/test/Serialization/sil_partial_apply_ownership.sil
@@ -48,8 +48,6 @@
 // CHECK-LABEL: sil @partial_apply_convert
 // CHECK:   convert_escape_to_noescape %{{.*}} : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
 // CHECK:   convert_escape_to_noescape [not_guaranteed] %
-// CHECK:   convert_escape_to_noescape [escaped] %
-// CHECK:   convert_escape_to_noescape [not_guaranteed] [escaped] %
 sil @partial_apply_convert : $@convention(thin) () -> () {
 entry:
   %f = function_ref @subject : $@convention(thin) (Builtin.Int64) -> ()
@@ -57,8 +55,6 @@
   %e = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
   %n = convert_escape_to_noescape %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
   %x2 = convert_escape_to_noescape [not_guaranteed] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-  %x3 = convert_escape_to_noescape [escaped] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-  %x4 = convert_escape_to_noescape [not_guaranteed] [escaped] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
   %n2 = mark_dependence %n : $@noescape @callee_guaranteed () -> () on %e : $@callee_guaranteed () -> ()
   %f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   apply %f2(%n2) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
diff --git a/test/Serialization/target-incompatible.swift b/test/Serialization/target-incompatible.swift
index 3bae1a7..0bfa589 100644
--- a/test/Serialization/target-incompatible.swift
+++ b/test/Serialization/target-incompatible.swift
@@ -1,21 +1,21 @@
 // RUN: %empty-directory(%t)
 
 // RUN: %swift -target x86_64-unknown-darwin14 -o %t/mips-template.swiftmodule -parse-stdlib -emit-module -module-name mips %S/../Inputs/empty.swift
-// RUN: %S/Inputs/binary_sub.py x86_64-unknown-darwin14 mips64-unknown-darwin14 < %t/mips-template.swiftmodule > %t/mips.swiftmodule
+// RUN: %{python} -u %S/Inputs/binary_sub.py x86_64-unknown-darwin14 mips64-unknown-darwin14 < %t/mips-template.swiftmodule > %t/mips.swiftmodule
 // RUN: not %target-swift-frontend -I %t -typecheck -parse-stdlib %s -DMIPS 2>&1 | %FileCheck -check-prefix=CHECK-MIPS %s
 
 // RUN: %swift -target x86_64-unknown-darwin14 -o %t/solaris-template.swiftmodule -parse-stdlib -emit-module -module-name solaris %S/../Inputs/empty.swift
-// RUN: %S/Inputs/binary_sub.py x86_64-unknown-darwin14 x86_64-unknown-solaris8 < %t/solaris-template.swiftmodule > %t/solaris.swiftmodule
+// RUN: %{python} -u %S/Inputs/binary_sub.py x86_64-unknown-darwin14 x86_64-unknown-solaris8 < %t/solaris-template.swiftmodule > %t/solaris.swiftmodule
 // RUN: not %target-swift-frontend -I %t -typecheck -parse-stdlib %s -DSOLARIS 2>&1 | %FileCheck -check-prefix=CHECK-SOLARIS %s
 
 // These checks should still hold with -enable-resilience.
 
 // RUN: %swift -target x86_64-unknown-darwin14 -o %t/mips-template.swiftmodule -parse-stdlib -emit-module -module-name mips %S/../Inputs/empty.swift -enable-resilience
-// RUN: %S/Inputs/binary_sub.py x86_64-unknown-darwin14 mips64-unknown-darwin14 < %t/mips-template.swiftmodule > %t/mips.swiftmodule
+// RUN: %{python} -u %S/Inputs/binary_sub.py x86_64-unknown-darwin14 mips64-unknown-darwin14 < %t/mips-template.swiftmodule > %t/mips.swiftmodule
 // RUN: not %target-swift-frontend -I %t -typecheck -parse-stdlib %s -DMIPS 2>&1 | %FileCheck -check-prefix=CHECK-MIPS %s
 
 // RUN: %swift -target x86_64-unknown-darwin14 -o %t/solaris-template.swiftmodule -parse-stdlib -emit-module -module-name solaris %S/../Inputs/empty.swift -enable-resilience
-// RUN: %S/Inputs/binary_sub.py x86_64-unknown-darwin14 x86_64-unknown-solaris8 < %t/solaris-template.swiftmodule > %t/solaris.swiftmodule
+// RUN: %{python} -u %S/Inputs/binary_sub.py x86_64-unknown-darwin14 x86_64-unknown-solaris8 < %t/solaris-template.swiftmodule > %t/solaris.swiftmodule
 // RUN: not %target-swift-frontend -I %t -typecheck -parse-stdlib %s -DSOLARIS 2>&1 | %FileCheck -check-prefix=CHECK-SOLARIS %s
 
 #if MIPS
diff --git a/test/Serialization/xref-nested-clang-type.swift b/test/Serialization/xref-nested-clang-type.swift
index 6f0bb01..5924624 100644
--- a/test/Serialization/xref-nested-clang-type.swift
+++ b/test/Serialization/xref-nested-clang-type.swift
@@ -4,13 +4,13 @@
 
 // RUN: %empty-directory(%t)
 // RUN: cp %S/Inputs/xref-nested-clang-type/NestedClangTypes.h %t
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t -import-objc-header %t/NestedClangTypes.h -I %S/Inputs/xref-nested-clang-type/ %s -module-name Lib -DNO_MODULE
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %t -I %S/Inputs/xref-nested-clang-type/ -import-objc-header %t/NestedClangTypes.h %s -DCLIENT -verify
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %t/NestedClangTypes.h -I %S/Inputs/xref-nested-clang-type/ %s -module-name Lib -DNO_MODULE
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %t -I %S/Inputs/xref-nested-clang-type/ -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %t/NestedClangTypes.h %s -DCLIENT -verify
 
 // RUN: %empty-directory(%t)
 // RUN: cp %S/Inputs/xref-nested-clang-type/NestedClangTypes.h %t
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t -import-objc-header %t/NestedClangTypes.h -I %S/Inputs/xref-nested-clang-type/ -pch-output-dir %t/PCHCache %s -module-name Lib -DNO_MODULE
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %t -I %S/Inputs/xref-nested-clang-type/ -pch-output-dir %t/PCHCache -import-objc-header %t/NestedClangTypes.h %s -DCLIENT -verify
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %t/NestedClangTypes.h -I %S/Inputs/xref-nested-clang-type/ -pch-output-dir %t/PCHCache %s -module-name Lib -DNO_MODULE
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %t -I %S/Inputs/xref-nested-clang-type/ -pch-output-dir %t/PCHCache -enable-objc-interop -disable-objc-attr-requires-foundation-module -import-objc-header %t/NestedClangTypes.h %s -DCLIENT -verify
 
 #if _runtime(_ObjC)
 import Foundation
diff --git a/test/SourceKit/CursorInfo/undefined-default-value.swift b/test/SourceKit/CursorInfo/undefined-default-value.swift
new file mode 100644
index 0000000..9dde0d1
--- /dev/null
+++ b/test/SourceKit/CursorInfo/undefined-default-value.swift
@@ -0,0 +1,9 @@
+enum LogLevel { case error }
+
+func logAsync(level: LogLevel = undefined, messageProducer producer
+
+// RUN: %sourcekitd-test -req=cursor -pos=3:44 %s -- %s | %FileCheck %s
+
+// CHECK: source.lang.swift.decl.function.free (3:6-3:68)
+// CHECK: logAsync(level:messageProducer:)
+// CHECK: LogLevel</Type> = &lt;&lt;empty&gt;&gt
diff --git a/test/attr/Inputs/dynamicReplacementA.swift b/test/attr/Inputs/dynamicReplacementA.swift
new file mode 100644
index 0000000..3572996
--- /dev/null
+++ b/test/attr/Inputs/dynamicReplacementA.swift
@@ -0,0 +1,2 @@
+public struct TheReplaceables {
+}
diff --git a/test/attr/Inputs/dynamicReplacementB.swift b/test/attr/Inputs/dynamicReplacementB.swift
new file mode 100644
index 0000000..7b2918b
--- /dev/null
+++ b/test/attr/Inputs/dynamicReplacementB.swift
@@ -0,0 +1,9 @@
+import A
+
+public extension TheReplaceables {
+  dynamic var property1: Int { return 0 }
+  dynamic var property2: Int { return 0 }
+
+  dynamic subscript (i: Int) -> Int { return 0 }
+  dynamic subscript (i: Int) -> String { return "" }
+}
diff --git a/test/attr/Inputs/dynamicReplacementC.swift b/test/attr/Inputs/dynamicReplacementC.swift
new file mode 100644
index 0000000..25b4a8f
--- /dev/null
+++ b/test/attr/Inputs/dynamicReplacementC.swift
@@ -0,0 +1,9 @@
+import A
+
+public extension TheReplaceables {
+  dynamic var property1: Int { return 0 }
+  dynamic var property2: String { return "" }
+
+  dynamic subscript (i: Int) -> Int { return 0 }
+  dynamic subscript (s: String) -> String { return "" }
+}
diff --git a/test/attr/attr_inlinable_deinit.swift b/test/attr/attr_inlinable_deinit.swift
new file mode 100644
index 0000000..309770d
--- /dev/null
+++ b/test/attr/attr_inlinable_deinit.swift
@@ -0,0 +1,9 @@
+// RUN: %target-typecheck-verify-swift -enable-resilience
+
+public class ResilientClass {
+    @inlinable deinit {} // expected-error {{deinitializer can only be '@inlinable' if the class is '@_fixed_layout'}}
+}
+
+@_fixed_layout public class FixedLayoutClass {
+    @inlinable deinit {}
+}
\ No newline at end of file
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index c1ef536..ebfe523 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -839,7 +839,7 @@
   }
 
   var observingAccessorsVar1: Int {
-  // CHECK: @_hasStorage @objc var observingAccessorsVar1: Int {
+  // CHECK: @objc @_hasStorage var observingAccessorsVar1: Int {
     willSet {}
     // CHECK-NEXT: {{^}} @objc get
     didSet {}
@@ -1709,7 +1709,7 @@
 
   @NSManaged
   var goodManaged: Class_ObjC1
-  // CHECK-LABEL: {{^}}  @objc @NSManaged @_hasStorage dynamic var goodManaged: Class_ObjC1 {
+  // CHECK-LABEL: {{^}}  @objc @NSManaged dynamic var goodManaged: Class_ObjC1 {
   // CHECK-NEXT: {{^}} @objc get
   // CHECK-NEXT: {{^}} @objc set
   // CHECK-NEXT: {{^}} }
@@ -1719,7 +1719,7 @@
   // expected-error@-1 {{property cannot be marked @NSManaged because its type cannot be represented in Objective-C}}
   // expected-note@-2 {{Swift structs cannot be represented in Objective-C}}
   // expected-error@-3{{'dynamic' property 'badManaged' must also be '@objc'}}
-  // CHECK-LABEL: {{^}}  @NSManaged @_hasStorage var badManaged: PlainStruct {
+  // CHECK-LABEL: {{^}}  @NSManaged var badManaged: PlainStruct {
   // CHECK-NEXT: {{^}} get
   // CHECK-NEXT: {{^}} set
   // CHECK-NEXT: {{^}} }
@@ -2312,3 +2312,18 @@
 protocol ObjCProtocolWithUnownedProperty {
    unowned var unownedProp: AnyObject { get set } // okay
 }
+
+// rdar://problem/46699152: errors about read/modify accessors being implicitly
+// marked @objc.
+@objc class MyObjCClass: NSObject {}
+
+@objc
+extension MyObjCClass {
+    @objc
+    static var objCVarInObjCExtension: Bool {
+        get {
+            return true
+        }
+        set {}
+    }
+}
diff --git a/test/attr/attributes.swift b/test/attr/attributes.swift
index 4458ed9..5905819 100644
--- a/test/attr/attributes.swift
+++ b/test/attr/attributes.swift
@@ -273,3 +273,12 @@
 @_invalid_attribute_ // expected-error {{unknown attribute '_invalid_attribute_'}}
 @inline(__always)
 public func sillyFunction() {}
+
+// rdar://problem/45732251: unowned/unowned(unsafe) optional lets are permitted
+func unownedOptionals(x: C) {
+  unowned let y: C? = x
+  unowned(unsafe) let y2: C? = x
+
+  _ = y
+  _ = y2
+}
diff --git a/test/attr/dynamicReplacement.swift b/test/attr/dynamicReplacement.swift
new file mode 100644
index 0000000..48aaf28
--- /dev/null
+++ b/test/attr/dynamicReplacement.swift
@@ -0,0 +1,40 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -swift-version 5 -enable-implicit-dynamic %S/Inputs/dynamicReplacementA.swift -o %t -module-name A
+// RUN: %target-swift-frontend -emit-module -swift-version 5 -enable-implicit-dynamic -c %S/Inputs/dynamicReplacementB.swift -o %t -I %t -module-name B
+// RUN: %target-swift-frontend -emit-module -swift-version 5 -enable-implicit-dynamic -c %S/Inputs/dynamicReplacementC.swift -o %t -I %t -module-name C
+// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-implicit-dynamic  -I %t
+import A
+import B
+import C
+
+// rdar://problem/46737657: static properties
+struct StaticProperties {
+  dynamic var property: Int { return 1 }
+  dynamic static var property: Int { return 11 }
+}
+
+extension StaticProperties {
+  @_dynamicReplacement(for: property)
+  var replacement_property: Int { return 2 }
+}
+
+// Replacements involving different types.
+extension TheReplaceables {
+  @_dynamicReplacement(for: property1) // expected-error{{replaced accessor for 'property1' occurs in multiple places}}
+  var replace_property1: Int { return 0 }
+  
+  @_dynamicReplacement(for: property2)
+  var replace_property2_int: Int { return 1 }
+  
+  @_dynamicReplacement(for: property2)
+  var replace_property2_string: String { return "replaced" }
+
+  @_dynamicReplacement(for: subscript(_:)) // expected-error{{replaced accessor for 'subscript(_:)' occurs in multiple places}}
+  subscript (int_int i: Int) -> Int { return 0 }
+
+  @_dynamicReplacement(for: subscript(_:))
+  subscript (int_string i: Int) -> String { return "" }
+
+  @_dynamicReplacement(for: subscript(_:))
+  subscript (string_string i: String) -> String { return "" }
+}
diff --git a/test/attr/hasInitialValue.swift b/test/attr/hasInitialValue.swift
index 42594ab..e259b24 100644
--- a/test/attr/hasInitialValue.swift
+++ b/test/attr/hasInitialValue.swift
@@ -12,7 +12,7 @@
     // CHECK: {{^}}  @_implicitly_unwrapped_optional @_hasInitialValue var iuo: Int!
     var iuo: Int!
 
-    // CHECK: {{^}}  @_hasStorage lazy var lazyIsntARealInit: Int
+    // CHECK: {{^}}  lazy var lazyIsntARealInit: Int
     lazy var lazyIsntARealInit: Int = 0
 
     init() {
diff --git a/test/benchmark/Benchmark_O.test.md b/test/benchmark/Benchmark_O.test.md
index f55965d..752c0c2 100644
--- a/test/benchmark/Benchmark_O.test.md
+++ b/test/benchmark/Benchmark_O.test.md
@@ -163,7 +163,7 @@
 MEASUREENV: VCS {{[0-9]+}} - {{[0-9]+}} = {{[0-9]+}}
 RUNJUSTONCE-LABEL: 1,Ackermann
 RUNJUSTONCE-NOT: 1,Ackermann
-LOGFORMAT: ,{{[0-9]+}},{{[0-9]+}},,{{,|[0-9]+}},{{[0-9]+}}
+LOGFORMAT: ,{{[0-9]+}},{{[0-9]+}},,{{[0-9]*}},{{[0-9]+}}
 LOGVERBOSE-LABEL: Running AngryPhonebook
 LOGVERBOSE: Collecting 2 samples.
 ````
diff --git a/test/decl/protocol/req/associated_type_ambiguity.swift b/test/decl/protocol/req/associated_type_ambiguity.swift
index 2b08b98..e0eded0 100644
--- a/test/decl/protocol/req/associated_type_ambiguity.swift
+++ b/test/decl/protocol/req/associated_type_ambiguity.swift
@@ -15,7 +15,7 @@
 }
 
 protocol P2 {
-  associatedtype T // expected-note 2 {{found this candidate}}
+  associatedtype T // expected-note {{found this candidate}}
 }
 
 // FIXME: This extension's generic signature is still minimized differently from
@@ -36,7 +36,7 @@
 // Same as above, but now we have two visible associated types with the same
 // name.
 protocol P3 {
-  associatedtype T // expected-note {{found this candidate}}
+  associatedtype T
 }
 
 // FIXME: This extension's generic signature is still minimized differently from
@@ -48,7 +48,7 @@
 }
 
 extension P2 where Self : P3 {
-  func takeT1(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
+  func takeT1(_: T) {}
   func takeT2(_: Self.T) {}
 }
 
diff --git a/test/lit.cfg b/test/lit.cfg
index 1652b03..46a40c3 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -802,12 +802,12 @@
     config.target_runtime = 'native'
 
     config.target_build_swift =                                                  \
-            ('%r -target %s %s %s %s %s %s' % (config.swiftc,                    \
-                                               config.variant_triple,            \
-                                               resource_dir_opt, mcp_opt,        \
-                                               config.swift_test_options,        \
-                                               config.swift_driver_test_options, \
-                                               swift_execution_tests_extra_flags))
+            ('%r -target %s %s %s %s %s' % (config.swiftc,                       \
+                                            config.variant_triple,               \
+                                            resource_dir_opt,                    \
+                                            config.swift_test_options,           \
+                                            config.swift_driver_test_options,    \
+                                            swift_execution_tests_extra_flags))
 
     config.target_run = ''
 
@@ -1150,12 +1150,13 @@
 
 
 if not getattr(config, 'target_run_simple_swift', None):
-    config.target_run_simple_swift_parameterized = (
-        '%%empty-directory(%%t) && '
-        '%s %s %%s \\1 -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_parameterized =                               \
+        (SubstituteCaptures('%%empty-directory(%%t) && '
+                            '%s %s %%s \\1 -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 = (
         '%%empty-directory(%%t) && '
         '%s %s %%s -o %%t/a.out -module-name main && '
@@ -1277,12 +1278,14 @@
 
 config.substitutions.append(
     (r'%hardlink-or-copy\(from: *(.*), *to: *(.*)\)',
-     r'ln \1 \2 || cp \1 \2'))
+     SubstituteCaptures(r'ln \1 \2 || cp \1 \2')))
 
 config.substitutions.append(('%utils', config.swift_utils))
 config.substitutions.append(('%line-directive', '%r %s' % (sys.executable, config.line_directive)))
 config.substitutions.append(('%gyb', '%r %s' % (sys.executable, config.gyb)))
-config.substitutions.append(('%round-trip-syntax-test', config.round_trip_syntax_test))
+config.substitutions.append(('%round-trip-syntax-test',
+                             '%r %s' % (sys.executable,
+                                        config.round_trip_syntax_test)))
 config.substitutions.append(('%rth', config.rth))
 config.substitutions.append(('%scale-test',
                              '{} --swiftc-binary={} --tmpdir=%t'.format(
diff --git a/test/multifile/default-arguments/two-modules/main.swift b/test/multifile/default-arguments/two-modules/main.swift
index 6bc0b47..83dc600 100644
--- a/test/multifile/default-arguments/two-modules/main.swift
+++ b/test/multifile/default-arguments/two-modules/main.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
 
 // RUN: mkdir -p %t/onone %t/wmo
-// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library1.swift %S/Inputs/library2.swift -o %t/onone/library%{target-shared-library-suffix} -swift-version 4
-// RUN: %target-build-swift %S/main.swift %t/onone/library%{target-shared-library-suffix} -I %t/onone/ -o %t/onone/main -swift-version 4
+// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library1.swift %S/Inputs/library2.swift -o %t/onone/%target-library-name(rary) -swift-version 4
+// RUN: %target-build-swift %S/main.swift -I %t/onone/ -o %t/onone/main -swift-version 4 -L%t/onone -lrary
 
-// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library1.swift %S/Inputs/library2.swift -o %t/wmo/library%{target-shared-library-suffix} -swift-version 4
-// RUN: %target-build-swift %S/main.swift %t/wmo/library%{target-shared-library-suffix} -I %t/wmo/ -o %t/wmo/main -swift-version 4
+// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library1.swift %S/Inputs/library2.swift -o %t/wmo/%target-library-name(rary) -swift-version 4
+// RUN: %target-build-swift %S/main.swift -I %t/wmo/ -o %t/wmo/main -swift-version 4 -L%t/wmo -lrary
 
 import library
 
diff --git a/test/multifile/extensions/two-modules/main.swift b/test/multifile/extensions/two-modules/main.swift
index 4cc81d4..3cf87ba 100644
--- a/test/multifile/extensions/two-modules/main.swift
+++ b/test/multifile/extensions/two-modules/main.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
 
 // RUN: mkdir -p %t/onone %t/wmo
-// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library.swift -o %t/onone/library%{target-shared-library-suffix}
-// RUN: %target-build-swift %S/main.swift %t/onone/library%{target-shared-library-suffix} -I %t/onone/ -o %t/onone/main
+// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library.swift -o %t/onone/%target-library-name(rary)
+// RUN: %target-build-swift %S/main.swift -I %t/onone/ -o %t/onone/main -L%t/onone -lrary
 
-// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library.swift -o %t/wmo/library%{target-shared-library-suffix}
-// RUN: %target-build-swift %S/main.swift %t/wmo/library%{target-shared-library-suffix} -I %t/wmo/ -o %t/wmo/main
+// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library.swift -o %t/wmo/%target-library-name(rary)
+// RUN: %target-build-swift %S/main.swift -I %t/wmo/ -o %t/wmo/main -L%t/wmo -lrary
 
 import library
 
diff --git a/test/multifile/multiconformanceimpls/main.swift b/test/multifile/multiconformanceimpls/main.swift
index f4be408..915a8802 100644
--- a/test/multifile/multiconformanceimpls/main.swift
+++ b/test/multifile/multiconformanceimpls/main.swift
@@ -1,13 +1,18 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift-dylib(%t/%{target-shared-library-prefix}A%{target-shared-library-suffix}) %S/Inputs/A.swift -emit-module -emit-module-path %t/A.swiftmodule -module-name A
+//
+// RUN: %target-build-swift-dylib(%t/%target-library-name(A)) %S/Inputs/A.swift -emit-module -emit-module-path %t/A.swiftmodule -module-name A
 // RUN: %target-codesign %t/%target-library-name(A)
-// RUN: %target-build-swift-dylib(%t/%{target-shared-library-prefix}B%{target-shared-library-suffix}) %S/Inputs/B.swift -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I%t -L%t -lA
+//
+// RUN: %target-build-swift-dylib(%t/%target-library-name(B)) %S/Inputs/B.swift -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I%t -L%t -lA
 // RUN: %target-codesign %t/%target-library-name(B)
-// RUN: %target-build-swift-dylib(%t/%{target-shared-library-prefix}C%{target-shared-library-suffix}) %S/Inputs/C.swift -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I%t -L%t -lA
+//
+// RUN: %target-build-swift-dylib(%t/%target-library-name(C)) %S/Inputs/C.swift -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I%t -L%t -lA
 // RUN: %target-codesign %t/%target-library-name(C)
-// RUN: %target-build-swift %s -I %t -o %t/a.out -L %t %target-rpath(%t) -lA -lB -lC
-// RUN: %target-codesign %t/a.out
-// RUN: %target-run %t/a.out %t/%target-library-name(A) %t/%target-library-name(B) %t/%target-library-name(C) |  %FileCheck %s
+//
+// RUN: %target-build-swift %s -I %t -o %t/main.out -L %t %target-rpath(%t) -lA -lB -lC
+// RUN: %target-codesign %t/main.out
+//
+// RUN: %target-run %t/main.out %t/%target-library-name(A) %t/%target-library-name(B) %t/%target-library-name(C) |  %FileCheck %s
 
 // REQUIRES: executable_test
 
diff --git a/test/multifile/protocol-conformance-member.swift b/test/multifile/protocol-conformance-member.swift
index c2f16b6..abd79c6 100644
--- a/test/multifile/protocol-conformance-member.swift
+++ b/test/multifile/protocol-conformance-member.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -emit-library %s %S/Inputs/protocol-conformance-member-helper.swift -o %t/libTest.dylib -module-name Test
-// RUN: llvm-nm %t/libTest.dylib | %FileCheck %s
+// RUN: %target-build-swift -emit-library %s %S/Inputs/protocol-conformance-member-helper.swift -o %t/%target-library-name(Test) -module-name Test
+// RUN: llvm-nm %t/%target-library-name(Test) | %FileCheck %s
 
 // CHECK: $s4Test10CoolStructV10coolFactorSdvg
 
diff --git a/test/multifile/synthesized-accessors/two-modules/main.swift b/test/multifile/synthesized-accessors/two-modules/main.swift
index 0c18766..cb163f4 100644
--- a/test/multifile/synthesized-accessors/two-modules/main.swift
+++ b/test/multifile/synthesized-accessors/two-modules/main.swift
@@ -1,11 +1,11 @@
 // RUN: %empty-directory(%t)
 
 // RUN: mkdir -p %t/onone %t/wmo
-// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library.swift -o %t/onone/library%{target-shared-library-suffix}
-// RUN: %target-build-swift %S/main.swift %t/onone/library%{target-shared-library-suffix} -I %t/onone/ -o %t/onone/main
+// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library.swift -o %t/onone/%target-library-name(rary)
+// RUN: %target-build-swift %S/main.swift -I %t/onone/ -o %t/onone/main -L%t/onone -lrary
 
-// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library.swift -o %t/wmo/library%{target-shared-library-suffix}
-// RUN: %target-build-swift %S/main.swift %t/wmo/library%{target-shared-library-suffix} -I %t/wmo/ -o %t/wmo/main
+// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library.swift -o %t/wmo/%target-library-name(rary)
+// RUN: %target-build-swift %S/main.swift -I %t/wmo/ -o %t/wmo/main -L%t/wmo -lrary
 
 import library
 
diff --git a/test/stdlib/ErrorBridged.swift b/test/stdlib/ErrorBridged.swift
index 6a90d1c..958ed7c 100644
--- a/test/stdlib/ErrorBridged.swift
+++ b/test/stdlib/ErrorBridged.swift
@@ -722,4 +722,49 @@
     === nsError)
 }
 
+// SR-9389
+class ParentA: NSObject {
+  @objc(ParentAError) enum Error: Int, Swift.Error {
+    case failed
+  }
+}
+class ParentB: NSObject {
+  @objc(ParentBError) enum Error: Int, Swift.Error {
+    case failed
+  }
+}
+private class NonPrintAsObjCClass: NSObject {
+  @objc enum Error: Int, Swift.Error {
+    case foo
+  }
+}
+@objc private enum NonPrintAsObjCError: Int, Error {
+  case bar
+}
+
+ErrorBridgingTests.test("@objc error domains for nested types") {
+  // Domain strings should correspond to Swift types, including parent types.
+  expectEqual(ParentA.Error.failed._domain, "main.ParentA.Error")
+  expectEqual(ParentB.Error.failed._domain, "main.ParentB.Error")
+
+  func makeNSError(like error: Error) -> NSError {
+    return NSError(domain: error._domain, code: error._code)
+  }
+
+  // NSErrors corresponding to Error types with the same name but nested in
+  // different enclosing types should not be castable to the wrong error type.
+  expectTrue(makeNSError(like: ParentA.Error.failed) is ParentA.Error)
+  expectFalse(makeNSError(like: ParentA.Error.failed) is ParentB.Error)
+  expectFalse(makeNSError(like: ParentB.Error.failed) is ParentA.Error)
+  expectTrue(makeNSError(like: ParentB.Error.failed) is ParentB.Error)
+
+  // If an @objc enum error is not eligible for PrintAsObjC, we should treat it
+  // as though it inherited the default implementation, which calls
+  // String(reflecting:).
+  expectEqual(NonPrintAsObjCClass.Error.foo._domain,
+              String(reflecting: NonPrintAsObjCClass.Error.self))
+  expectEqual(NonPrintAsObjCError.bar._domain,
+              String(reflecting: NonPrintAsObjCError.self))
+}
+
 runAllTests()
diff --git a/test/stdlib/UnavailableStringAPIs.swift.gyb b/test/stdlib/UnavailableStringAPIs.swift.gyb
index 537fbb4..c1adb14 100644
--- a/test/stdlib/UnavailableStringAPIs.swift.gyb
+++ b/test/stdlib/UnavailableStringAPIs.swift.gyb
@@ -2,8 +2,6 @@
 // RUN: %gyb -D_runtime=%target-runtime %s -o %t/main.swift
 // RUN: %line-directive %t/main.swift -- %target-swift-frontend -typecheck -verify %t/main.swift
 
-// REQUIRES: rdar44572521
-
 func test_StringSubscriptByInt(
   x: String,
   i: Int,
@@ -15,13 +13,6 @@
   _ = x[r2] // expected-error {{'subscript(_:)' is unavailable: cannot subscript String with an integer range, see the documentation comment for discussion}} {{none}}
 }
 
-% if _runtime == 'objc':
-func test_UTF16ViewSubscriptByInt(x: String.UTF16View, i: Int, r: Range<Int>) {
-  _ = x[i] // expected-error {{'subscript(_:)' is unavailable: Indexing a String's UTF16View requires a String.UTF16View.Index, which can be constructed from Int when Foundation is imported}} {{none}}
-  _ = x[r] // expected-error {{'subscript(_:)' is unavailable: Slicing a String's UTF16View requires a Range<String.UTF16View.Index>, String.UTF16View.Index can be constructed from Int when Foundation is imported}} {{none}}
-}
-% end
-
 func test_UTF8View(s: String.UTF8View, i: String.UTF8View.Index, d: Int) {
   _ = s.index(after: i) // OK
   _ = s.index(before: i) // OK
diff --git a/tools/SourceKit/tools/swift-lang/SwiftLang.swift b/tools/SourceKit/tools/swift-lang/SwiftLang.swift
index 22451b3..75b9980 100644
--- a/tools/SourceKit/tools/swift-lang/SwiftLang.swift
+++ b/tools/SourceKit/tools/swift-lang/SwiftLang.swift
@@ -12,6 +12,8 @@
 // This file provides Swift language support by invoking SourceKit internally.
 //===----------------------------------------------------------------------===//
 
+import Foundation
+
 enum SourceKitdError: Error, CustomStringConvertible {
   case EditorOpenError(message: String)
   case EditorCloseError(message: String)
@@ -26,19 +28,132 @@
   }
 }
 
-public class SwiftLang {
+// MARK: Public APIs
 
-  fileprivate static func parse(content: String, name: String, isURL: Bool) throws -> String {
+public enum SwiftLang {
+  /// Synchronously parses Swift source code into a syntax tree.
+  ///
+  /// - Parameter url: A file URL pointing to a Swift source file.
+  /// - Parameter format: The format to use for the returned syntax tree.
+  /// - Returns: The syntax tree in the indicated format.
+  /// - Throws: If SourceKit responds to the request with an error. This is
+  ///           usually a communication or configuration error, not a
+  ///           syntax error in the code being parsed.
+  /// - Precondition: `url` must be a file URL.
+  public static func parse<Tree>(
+    contentsOf url: URL, into format: SyntaxTreeFormat<Tree>
+  ) throws -> Tree {
+    precondition(url.isFileURL, "Can only parse files at file URLs")
+    return try parse(SourceFile(path: url.path), into: format)
+  }
+}
+
+extension SwiftLang.SyntaxTreeFormat {
+  /// Return the syntax tree serialized in JSON format. JSON is easy to inspect
+  /// and test with but very inefficient to deserialize. Use it for testing and
+  /// debugging.
+  public static var json: SwiftLang.SyntaxTreeFormat<Data> {
+    return jsonString.withTreeMapped { $0.data(using: .utf8)! }
+  }
+
+  /// Return the syntax tree serialized as ByteTree. ByteTree is fast and
+  /// compact but difficult to inspect or manipulate with textual tools.
+  /// It's recommended in production.
+  public static var byteTree: SwiftLang.SyntaxTreeFormat<Data> {
+    return .init(kind: .kind_SyntaxTreeSerializationByteTree) { dict in
+      dict.getData(syntaxTreeKey)
+    }
+  }
+
+  /// Creates a new `SyntaxTreeFormat` instance which converts the tree of an
+  /// existing format.
+  ///
+  /// You can use this method to add new `SyntaxTreeFormat`s; simply declare a
+  /// new static constant in an extension of `SyntaxTreeFormat` which maps one
+  /// of the existing formats.
+  ///
+  /// - Parameter transform: A function which converts `self`'s Tree type to
+  ///             the result type's Tree type.
+  /// - Returns: A new format which creates a tree in `self`'s format, then
+  ///            applies `transform` to the tree to convert it.
+  public func withTreeMapped<NewTree>(
+    by transform: @escaping (Tree) throws -> NewTree
+  ) -> SwiftLang.SyntaxTreeFormat<NewTree> {
+    return .init(kind: kind) { [makeTree] dict in
+      try transform(makeTree(dict))
+    }
+  }
+}
+
+// MARK: Deprecated APIs
+
+extension SwiftLang {
+  /// Parses the Swift file at the provided URL into a `Syntax` tree in Json
+  /// serialization format by querying SourceKitd service. This function isn't
+  /// thread safe.
+  /// - Parameter path: The URL you wish to parse.
+  /// - Returns: The syntax tree in Json format string.
+  @available(swift, deprecated: 5.0, renamed: "parse(_:into:)")
+  public static func parse(path: String) throws -> String {
+    return try parse(SourceFile(path: path), into: .jsonString)
+  }
+
+  /// Parses a given source buffer into a `Syntax` tree in Json serialization
+  /// format by querying SourceKitd service. This function isn't thread safe.
+  /// - Parameter source: The source buffer you wish to parse.
+  /// - Returns: The syntax tree in Json format string.
+  @available(swift, deprecated: 5.0, message: "use parse(_:into:) with a file instead")
+  public static func parse(source: String) throws -> String {
+    let content = SourceFile(
+      name: "foo", contentKey: .key_SourceText, contentValue: source
+    )
+    return try parse(content, into: .jsonString)
+  }
+}
+
+// MARK: Internals
+
+extension SwiftLang {
+  /// The format to serialize the syntax tree in.
+  public struct SyntaxTreeFormat<Tree> {
+    /// Value for EditorOpen's key_SyntaxTreeSerializationFormat key.
+    fileprivate let kind: SourceKitdUID
+
+    /// Extracts the syntax tree from the response dictionary and converts it
+    /// into a value of type Tree.
+    fileprivate let makeTree: (SourceKitdResponse.Dictionary) throws -> Tree
+
+    /// Serialize the syntax tree into a JSON string. For backwards
+    /// compatibility only.
+    fileprivate static var jsonString: SyntaxTreeFormat<String> {
+      return .init(kind: .kind_SyntaxTreeSerializationJSON) { dict in
+        dict.getString(syntaxTreeKey)
+      }
+    }
+  }
+}
+
+extension SwiftLang {
+  fileprivate struct SourceFile {
+    let name: String
+    let contentKey: SourceKitdUID
+    let contentValue: String
+  }
+
+  /// Parses the SourceFile in question using the provided serialization format.
+  fileprivate static func parse<Tree>(
+    _ content: SourceFile, into format: SyntaxTreeFormat<Tree>
+  ) throws -> Tree {
     let Service = SourceKitdService()
     let Request = SourceKitdRequest(uid: .request_EditorOpen)
-    if isURL {
-      Request.addParameter(.key_SourceFile, value: content)
-    } else {
-      Request.addParameter(.key_SourceText, value: content)
-    }
-    Request.addParameter(.key_Name, value: name)
+
+    Request.addParameter(content.contentKey, value: content.contentValue)
+    Request.addParameter(.key_Name, value: content.name)
+
     Request.addParameter(.key_SyntaxTreeTransferMode,
                          value: .kind_SyntaxTreeFull)
+    Request.addParameter(.key_SyntaxTreeSerializationFormat,
+                         value: format.kind)
     Request.addParameter(.key_EnableSyntaxMap, value: 0)
     Request.addParameter(.key_EnableStructure, value: 0)
     Request.addParameter(.key_SyntacticOnly, value: 1)
@@ -50,28 +165,19 @@
     }
 
     let CloseReq = SourceKitdRequest(uid: .request_EditorClose)
-    CloseReq.addParameter(.key_Name, value: name)
+    CloseReq.addParameter(.key_Name, value: content.name)
     let CloseResp = Service.sendSyn(request: CloseReq)
     if CloseResp.isError {
       throw SourceKitdError.EditorCloseError(message: CloseResp.description)
     }
-    return Resp.value.getString(.key_SerializedSyntaxTree)
-  }
-
-  /// Parses the Swift file at the provided URL into a `Syntax` tree in Json
-  /// serialization format by querying SourceKitd service. This function isn't
-  /// thread safe.
-  /// - Parameter url: The URL you wish to parse.
-  /// - Returns: The syntax tree in Json format string.
-  public static func parse(path: String) throws -> String {
-    return try parse(content: path, name: path, isURL: true)
-  }
-
-  /// Parses a given source buffer into a `Syntax` tree in Json serialization
-  /// format by querying SourceKitd service. This function isn't thread safe.
-  /// - Parameter source: The source buffer you wish to parse.
-  /// - Returns: The syntax tree in Json format string.
-  public static func parse(source: String) throws -> String {
-    return try parse(content: source, name: "foo", isURL: false)
+    return try format.makeTree(Resp.value)
   }
 }
+
+extension SwiftLang.SourceFile {
+  init(path: String) {
+    self.init(name: path, contentKey: .key_SourceFile, contentValue: path)
+  }
+}
+
+private let syntaxTreeKey = SourceKitdUID.key_SerializedSyntaxTree
diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp
index d48f505..16ff181 100644
--- a/tools/sil-opt/SILOpt.cpp
+++ b/tools/sil-opt/SILOpt.cpp
@@ -427,10 +427,10 @@
       llvm::errs() << EC.message() << '\n';
       return 1;
     }
-    CI.getSILModule()->setOptRecordStream(
-        llvm::make_unique<llvm::yaml::Output>(*OptRecordFile,
-                                              &CI.getSourceMgr()),
-        std::move(OptRecordFile));
+    auto Stream = llvm::make_unique<llvm::yaml::Output>(*OptRecordFile,
+                                                        &CI.getSourceMgr());
+    CI.getSILModule()->setOptRecordStream(std::move(Stream),
+                                          std::move(OptRecordFile));
   }
 
   if (OptimizationGroup == OptGroup::Diagnostics) {
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index be88c8e..426ce52 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -10,6 +10,7 @@
     DESTINATION bin)
 
 # We install LLVM's FileCheck, if requested.
+file(TO_CMAKE_PATH "${SWIFT_PATH_TO_LLVM_BUILD}/bin/FileCheck${CMAKE_EXECUTABLE_SUFFIX}" _SWIFT_UTILS_FILECHECK)
 swift_install_in_component(toolchain-dev-tools
-    FILES "${SWIFT_PATH_TO_LLVM_BUILD}/bin/FileCheck"
-    DESTINATION bin)
+  FILES "${_SWIFT_UTILS_FILECHECK}"
+  DESTINATION bin)
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index 512664e..248669f 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -806,6 +806,13 @@
 android-icu-i18n-include=%(arm_dir)s/icu/source/i18n
 android-icu-data=%(arm_dir)s/libicudataswift.so
 
+[preset: buildbot_linux_crosscompile_android,tools=RA,stdlib=RD,build,aarch64]
+mixin-preset=buildbot_linux_crosscompile_android,tools=RA,stdlib=RD,build
+
+dash-dash
+
+android-arch=aarch64
+
 # Ubuntu 18.04 preset for backwards compat and future customizations.
 [preset: buildbot_linux_1804]
 mixin-preset=buildbot_linux
diff --git a/utils/build-toolchain b/utils/build-toolchain
index 68284db..4edcc95 100755
--- a/utils/build-toolchain
+++ b/utils/build-toolchain
@@ -41,9 +41,11 @@
 case $(uname -s) in
   Darwin)
     SWIFT_PACKAGE=buildbot_osx_package,no_test
+    OS_SUFFIX=osx
   ;;
   Linux)
     SWIFT_PACKAGE=buildbot_linux,no_test
+    OS_SUFFIX=linux
   ;;
   *)
     echo "Unrecognised platform $(uname -s)"
@@ -98,8 +100,8 @@
 DAY=$(date +"%d")
 TOOLCHAIN_VERSION="swift-LOCAL-${YEAR}-${MONTH}-${DAY}-a"
 DARWIN_TOOLCHAIN_VERSION="0.0.${YEAR}${MONTH}${DAY}"
-ARCHIVE="${TOOLCHAIN_VERSION}-osx.tar.gz"
-SYM_ARCHIVE="${TOOLCHAIN_VERSION}-osx-symbols.tar.gz"
+ARCHIVE="${TOOLCHAIN_VERSION}-${OS_SUFFIX}.tar.gz"
+SYM_ARCHIVE="${TOOLCHAIN_VERSION}-${OS_SUFFIX}-symbols.tar.gz"
 BUNDLE_PREFIX=${BUNDLE_PREFIX:?Please specify a bundle prefix}
 BUNDLE_IDENTIFIER="${BUNDLE_PREFIX}.${YEAR}${MONTH}${DAY}"
 DISPLAY_NAME_SHORT="Local Swift Development Snapshot"
diff --git a/utils/vim/syntax/swift.vim b/utils/vim/syntax/swift.vim
index 2654c53..57da585 100644
--- a/utils/vim/syntax/swift.vim
+++ b/utils/vim/syntax/swift.vim
@@ -42,6 +42,7 @@
       \ nonmutating
       \ open
       \ override
+      \ prefix
       \ private
       \ public
       \ required
diff --git a/validation-test/compiler_crashers_2_fixed/0187-rdar46678653.swift b/validation-test/compiler_crashers_2_fixed/0187-rdar46678653.swift
new file mode 100644
index 0000000..0cb046d
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0187-rdar46678653.swift
@@ -0,0 +1,15 @@
+// RUN: not %target-swift-frontend -typecheck %s
+
+protocol P: class { }
+
+protocol Q {
+  func g()
+}
+
+protocol P { }
+
+struct S : Q {
+  @_implements(P, g())
+  func h() {}
+}
+
diff --git a/validation-test/compiler_crashers_2_fixed/0188-sr9496.swift b/validation-test/compiler_crashers_2_fixed/0188-sr9496.swift
new file mode 100644
index 0000000..73f5bd4
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0188-sr9496.swift
@@ -0,0 +1,23 @@
+// RUN: %target-swift-frontend -typecheck %s
+
+protocol P1 {
+    associatedtype A1
+}
+
+protocol P2 {
+    associatedtype A2
+}
+
+struct S1<G1: P1, G2: P1>: P1 where G1.A1 == G2.A1 {
+    typealias A1 = G1.A1
+}
+
+struct S2<G1: P1, G2: P2>: P2 where G1.A1 == G2.A2 {
+    typealias A2 = G2.A2
+}
+
+struct S3<G1: P1, G2: P2> where G1.A1 == G2.A2 {
+    func f<G: P1>(_: G) -> S3<S1<G, G1>, S2<G, G2>> {
+        fatalError()
+    }
+}
diff --git a/validation-test/stdlib/Dictionary.swift b/validation-test/stdlib/Dictionary.swift
index 7659d65..2555100 100644
--- a/validation-test/stdlib/Dictionary.swift
+++ b/validation-test/stdlib/Dictionary.swift
@@ -2383,6 +2383,9 @@
 }
 
 DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.ImmutableDictionaryIsCopied") {
+  //some bridged NSDictionary operations on non-standard NSDictionary subclasses
+  //autorelease keys and values. Make sure the leak checker isn't confused
+  autoreleasepool {
   let nsd: NSDictionary = CustomImmutableNSDictionary(_privateInit: ())
 
   CustomImmutableNSDictionary.timesCopyWithZoneWasCalled = 0
@@ -2406,6 +2409,7 @@
   _fixLifetime(nsd)
   _fixLifetime(d)
   _fixLifetime(bridgedBack)
+  }
 }
 
 
@@ -3243,9 +3247,9 @@
 }
 
 DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.Generate_ParallelArray") {
-autoreleasepoolIfUnoptimizedReturnAutoreleased {
-  // Add an autorelease pool because ParallelArrayDictionary autoreleases
-  // values in objectForKey.
+  //some bridged NSDictionary operations on non-standard NSDictionary subclasses
+  //autorelease keys and values. Make sure the leak checker isn't confused
+autoreleasepool {
 
   let d = getParallelArrayBridgedNonverbatimDictionary()
   let identity1 = d._rawIdentifier()
@@ -5691,6 +5695,62 @@
   d.remove(at: i)
 }
 
+DictionaryTestSuite.test("BulkLoadingInitializer.Unique") {
+  for c in [0, 1, 2, 3, 5, 10, 25, 150] {
+    let d1 = Dictionary<TestKeyTy, TestEquatableValueTy>(
+      _unsafeUninitializedCapacity: c,
+      allowingDuplicates: false
+    ) { keys, values, count in
+      let k = keys.baseAddress!
+      let v = values.baseAddress!
+      for i in 0 ..< c {
+        (k + i).initialize(to: TestKeyTy(i))
+        (v + i).initialize(to: TestEquatableValueTy(i))
+        count += 1
+      }
+    }
+
+    let d2 = Dictionary(
+      uniqueKeysWithValues: (0..<c).map {
+        (TestKeyTy($0), TestEquatableValueTy($0))
+      })
+
+    for i in 0 ..< c {
+      expectEqual(TestEquatableValueTy(i), d1[TestKeyTy(i)])
+    }
+    expectEqual(d2, d1)
+  }
+}
+
+DictionaryTestSuite.test("BulkLoadingInitializer.Nonunique") {
+  for c in [0, 1, 2, 3, 5, 10, 25, 150] {
+    let d1 = Dictionary<TestKeyTy, TestEquatableValueTy>(
+      _unsafeUninitializedCapacity: c,
+      allowingDuplicates: true
+    ) { keys, values, count in
+      let k = keys.baseAddress!
+      let v = values.baseAddress!
+      for i in 0 ..< c {
+        (k + i).initialize(to: TestKeyTy(i / 2))
+        (v + i).initialize(to: TestEquatableValueTy(i / 2))
+        count += 1
+      }
+    }
+
+    let d2 = Dictionary(
+      (0 ..< c).map {
+        (TestKeyTy($0 / 2), TestEquatableValueTy($0 / 2))
+      },
+      uniquingKeysWith: { a, b in a })
+
+    expectEqual(d1.count, d2.count)
+    for i in 0 ..< c / 2 {
+      expectEqual(TestEquatableValueTy(i), d1[TestKeyTy(i)])
+    }
+    expectEqual(d2, d1)
+  }
+}
+
 DictionaryTestSuite.setUp {
 #if _runtime(_ObjC)
   // Exercise ARC's autoreleased return value optimization in Foundation.