Merge pull request #6863 from matthewcarroll/SR-3600-Better-recovery-for-naming-an-initializer-deinitializer-or-subscript

[DiagnosticsQoI] SR-3600: Better recovery for trying to name an initializer, deinitializer, or subscript
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f81317..fddee49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,17 @@
 Swift 3.1
 ---------
 
+* [SE-0080][]:
+
+  Adds a new family of conversion initializers to all numeric types that
+  either complete successfully without loss of information or return nil.
+
+* Swift will now warn when an `NSObject` subclass attempts to override the
+  class `initialize` method. Swift doesn't guarantee that references to class
+  names trigger Objective-C class realization if they have no other
+  side effects, leading to bugs when Swift code attempted to override
+  `initialize`.
+
 * [SR-2394](https://bugs.swift.org/browse/SR-2394)
 
   C functions that "return twice" are no longer imported into Swift. Instead,
@@ -38,7 +49,7 @@
   the compiler will prevent them from being used in the first place.
 
 * Indirect fields from C structures and unions are now always imported, while
-  they previously weren't imported if they belonged to an union. This is done by
+  they previously weren't imported if they belonged to a union. This is done by
   naming anonymous fields. For example:
 
   ```c
@@ -72,7 +83,7 @@
 
 * The `withoutActuallyEscaping` function from [SE-0103][] has been implemented.
   To pass off a non-escaping closure to an API that formally takes an
-  `@escaping` closure, but which is used in a way that will not in fact 
+  `@escaping` closure, but which is used in a way that will not in fact
   escape it in practice, use `withoutActuallyEscaping` to get an escapable
   copy of the closure and delimit its expected lifetime. For example:
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 70823a5..d66418c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -288,6 +288,58 @@
 # End of user-configurable options.
 #
 
+# Look for either a program in execute_process()'s path or for a hardcoded path.
+# Find a program's version and set it in the parent scope.
+# Replace newlines with spaces so it prints on one line.
+function(find_version cmd flag find_in_path)
+  if(find_in_path)
+    message(STATUS "Finding installed version for: ${cmd}")
+  else()
+    message(STATUS "Finding version for: ${cmd}")
+  endif()
+  execute_process(
+    COMMAND ${cmd} ${flag}
+    OUTPUT_VARIABLE out
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+  if(NOT out)
+    if(find_in_path)
+      message(STATUS "tried to find version for ${cmd}, but ${cmd} not found in path, continuing")
+    else()
+      message(FATAL_ERROR "tried to find version for ${cmd}, but ${cmd} not found")
+    endif()
+  else()
+    string(REPLACE "\n" " " out2 ${out})
+    message(STATUS "Found version: ${out2}")
+  endif()
+  message(STATUS "")
+endfunction()
+
+# Print out path and version of any installed commands.
+# We migth be using the wrong version of a command, so record them all.
+function(print_versions)
+  find_version("cmake" "--version" TRUE)
+  find_version(${CMAKE_COMMAND} "--version" FALSE)
+
+  if(CMAKE_MAKE_PROGRAM MATCHES "ninja")
+    find_version("ninja" "--version" TRUE)
+    find_version(${CMAKE_MAKE_PROGRAM} "--version" FALSE)
+  elseif(CMAKE_MAKE_PROGRAM MATCHES "make")
+    find_version("make" "--version" TRUE)
+    find_version(${CMAKE_MAKE_PROGRAM} "--version" FALSE)
+  endif()
+
+  if(${SWIFT_PATH_TO_CMARK_BUILD})
+    find_version("cmark" "--version" TRUE)
+    find_version("${SWIFT_PATH_TO_CMARK_BUILD}/src/cmark" "--version" FALSE)
+  endif()
+
+  find_version(${CMAKE_C_COMPILER} "--version" FALSE)
+  find_version(${CMAKE_CXX_COMPILER} "--version" FALSE)
+endfunction()
+
+print_versions()
+
+
 set(SWIFT_BUILT_STANDALONE FALSE)
 if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
   set(SWIFT_BUILT_STANDALONE TRUE)
@@ -589,10 +641,10 @@
 elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "CYGWIN")
 
   # set(CMAKE_EXECUTABLE_FORMAT "ELF")
-  set(SWIFT_HOST_VARIANT "windows" CACHE STRING
-      "Deployment OS for Swift host tools (the compiler) [windows].")
+  set(SWIFT_HOST_VARIANT "cygwin" CACHE STRING
+      "Deployment OS for Swift host tools (the compiler) [cygwin].")
 
-  configure_sdk_unix(CYGWIN "Cygwin" "windows" "cygwin" "windows" "x86_64-unknown-windows-cygnus" "/")
+  configure_sdk_unix(CYGWIN "Cygwin" "cygwin" "cygwin" "x86_64" "x86_64-unknown-windows-cygnus" "/")
   set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
   set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
 
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index c26431e..db5acfc 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -31,6 +31,8 @@
     single-source/ByteSwap
     single-source/Calculator
     single-source/CaptureProp
+    single-source/CharacterLiteralsLarge
+    single-source/CharacterLiteralsSmall
     single-source/Chars
     single-source/ClassArrayGetter
     single-source/DeadArray
diff --git a/benchmark/single-source/CharacterLiteralsLarge.swift b/benchmark/single-source/CharacterLiteralsLarge.swift
new file mode 100644
index 0000000..fd94a4b
--- /dev/null
+++ b/benchmark/single-source/CharacterLiteralsLarge.swift
@@ -0,0 +1,45 @@
+//===--- CharacterLiteralsLarge.swift -------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+// This test tests the performance of Characters initialized from literals
+// which don't fit into the small (63-bit) representation and need to allocate
+// and retain a StringBuffer.
+import TestsUtils
+
+@inline(never)
+func makeCharacter_UTF8Length9() -> Character {
+  return "a\u{0300}\u{0301}\u{0302}\u{0303}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length10() -> Character {
+  return "\u{00a9}\u{0300}\u{0301}\u{0302}\u{0303}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length11() -> Character {
+  return "a\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length12() -> Character {
+  return "\u{00a9}\u{0300}\u{0301}\u{0302}\u{0303}\u{0304}"
+}
+
+public func run_CharacterLiteralsLarge(_ N: Int) {
+  for _ in 0...10000 * N {
+    _ = makeCharacter_UTF8Length9()
+    _ = makeCharacter_UTF8Length10()
+    _ = makeCharacter_UTF8Length11()
+    _ = makeCharacter_UTF8Length12()
+  }
+}
diff --git a/benchmark/single-source/CharacterLiteralsSmall.swift b/benchmark/single-source/CharacterLiteralsSmall.swift
new file mode 100644
index 0000000..b04daff
--- /dev/null
+++ b/benchmark/single-source/CharacterLiteralsSmall.swift
@@ -0,0 +1,69 @@
+//===--- CharacterLiteralsSmall.swift -------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+// This test tests the performance of Characters initialized from literals that
+// fit within the small (63 bits or fewer) representation and can be
+// represented as a packed integer.
+import TestsUtils
+
+@inline(never)
+func makeCharacter_UTF8Length1() -> Character {
+  return "a"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length2() -> Character {
+  return "\u{00a9}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length3() -> Character {
+  return "a\u{0300}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length4() -> Character {
+  return "\u{00a9}\u{0300}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length5() -> Character {
+  return "a\u{0300}\u{0301}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length6() -> Character {
+  return "\u{00a9}\u{0300}\u{0301}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length7() -> Character {
+  return "a\u{0300}\u{0301}\u{0302}"
+}
+
+@inline(never)
+func makeCharacter_UTF8Length8() -> Character {
+  return "\u{00a9}\u{0300}\u{0301}\u{0302}"
+}
+
+public func run_CharacterLiteralsSmall(_ N: Int) {
+  for _ in 0...10000 * N {
+    _ = makeCharacter_UTF8Length1()
+    _ = makeCharacter_UTF8Length2()
+    _ = makeCharacter_UTF8Length3()
+    _ = makeCharacter_UTF8Length4()
+    _ = makeCharacter_UTF8Length5()
+    _ = makeCharacter_UTF8Length6()
+    _ = makeCharacter_UTF8Length7()
+    _ = makeCharacter_UTF8Length8()
+  }
+}
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index 95866cc..ea4c169 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -36,6 +36,8 @@
 import ByteSwap
 import Calculator
 import CaptureProp
+import CharacterLiteralsLarge
+import CharacterLiteralsSmall
 import Chars
 import ClassArrayGetter
 import DeadArray
@@ -139,6 +141,8 @@
   "ByteSwap": run_ByteSwap,
   "Calculator": run_Calculator,
   "CaptureProp": run_CaptureProp,
+  "CharacterLiteralsLarge": run_CharacterLiteralsLarge,
+  "CharacterLiteralsSmall": run_CharacterLiteralsSmall,
   "Chars": run_Chars,
   "ClassArrayGetter": run_ClassArrayGetter,
   "DeadArray": run_DeadArray,
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 6490233..60b5b57 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -125,17 +125,6 @@
       "-B" "${SWIFT_ANDROID_PREBUILT_PATH}/arm-linux-androideabi/bin/")
   endif()
 
-  if("${CFLAGS_SDK}" STREQUAL "WINDOWS")
-    list(APPEND result "-DLLVM_ON_WIN32")
-    list(APPEND result "-D_CRT_SECURE_NO_WARNINGS")
-    list(APPEND result "-D_CRT_NONSTDC_NO_WARNINGS")
-    # TODO(compnerd) permit building for different families
-    list(APPEND result "-D_CRT_USE_WINAPI_FAMILY_DESKTOP_APP")
-    # TODO(compnerd) handle /MT
-    list(APPEND result "-D_DLL")
-    list(APPEND result "-fms-compatibility-version=1900")
-  endif()
-
   if(IS_DARWIN)
     # Check if there's a specific OS deployment version needed for this invocation
     if("${CFLAGS_SDK}" STREQUAL "OSX")
@@ -233,6 +222,17 @@
     list(APPEND result -fno-pic)
   endif()
 
+  if("${CFLAGS_SDK}" STREQUAL "WINDOWS")
+    list(APPEND result "-DLLVM_ON_WIN32")
+    list(APPEND result "-D_CRT_SECURE_NO_WARNINGS")
+    list(APPEND result "-D_CRT_NONSTDC_NO_WARNINGS")
+    # TODO(compnerd) permit building for different families
+    list(APPEND result "-D_CRT_USE_WINAPI_FAMILY_DESKTOP_APP")
+    # TODO(compnerd) handle /MT
+    list(APPEND result "-D_DLL")
+    list(APPEND result "-fms-compatibility-version=1900")
+  endif()
+
   if(CFLAGS_ENABLE_ASSERTIONS)
     list(APPEND result "-UNDEBUG")
   else()
@@ -886,7 +886,7 @@
   elseif("${SWIFTLIB_SINGLE_SDK}" STREQUAL "CYGWIN")
     set_target_properties("${target}"
       PROPERTIES
-      INSTALL_RPATH "$ORIGIN:/usr/lib/swift/windows")
+      INSTALL_RPATH "$ORIGIN:/usr/lib/swift/cygwin")
   endif()
 
   set_target_properties("${target}" PROPERTIES BUILD_WITH_INSTALL_RPATH YES)
@@ -1256,6 +1256,9 @@
 # SWIFT_MODULE_DEPENDS_LINUX
 #   Swift modules this library depends on when built for Linux.
 #
+# SWIFT_MODULE_DEPENDS_CYGWIN
+#   Swift modules this library depends on when built for Cygwin.
+#
 # FRAMEWORK_DEPENDS
 #   System frameworks this library depends on.
 #
@@ -1329,7 +1332,7 @@
   cmake_parse_arguments(SWIFTLIB
     "${SWIFTLIB_options}"
     "INSTALL_IN_COMPONENT;DEPLOYMENT_VERSION_OSX;DEPLOYMENT_VERSION_IOS;DEPLOYMENT_VERSION_TVOS;DEPLOYMENT_VERSION_WATCHOS"
-    "DEPENDS;LINK_LIBRARIES;SWIFT_MODULE_DEPENDS;SWIFT_MODULE_DEPENDS_OSX;SWIFT_MODULE_DEPENDS_IOS;SWIFT_MODULE_DEPENDS_TVOS;SWIFT_MODULE_DEPENDS_WATCHOS;SWIFT_MODULE_DEPENDS_FREEBSD;SWIFT_MODULE_DEPENDS_LINUX;FRAMEWORK_DEPENDS;FRAMEWORK_DEPENDS_WEAK;FRAMEWORK_DEPENDS_OSX;FRAMEWORK_DEPENDS_IOS_TVOS;LLVM_COMPONENT_DEPENDS;FILE_DEPENDS;TARGET_SDKS;C_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS_OSX;SWIFT_COMPILE_FLAGS_IOS;SWIFT_COMPILE_FLAGS_TVOS;SWIFT_COMPILE_FLAGS_WATCHOS;LINK_FLAGS;PRIVATE_LINK_LIBRARIES;INTERFACE_LINK_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY"
+    "DEPENDS;LINK_LIBRARIES;SWIFT_MODULE_DEPENDS;SWIFT_MODULE_DEPENDS_OSX;SWIFT_MODULE_DEPENDS_IOS;SWIFT_MODULE_DEPENDS_TVOS;SWIFT_MODULE_DEPENDS_WATCHOS;SWIFT_MODULE_DEPENDS_FREEBSD;SWIFT_MODULE_DEPENDS_LINUX;SWIFT_MODULE_DEPENDS_CYGWIN;FRAMEWORK_DEPENDS;FRAMEWORK_DEPENDS_WEAK;FRAMEWORK_DEPENDS_OSX;FRAMEWORK_DEPENDS_IOS_TVOS;LLVM_COMPONENT_DEPENDS;FILE_DEPENDS;TARGET_SDKS;C_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS;SWIFT_COMPILE_FLAGS_OSX;SWIFT_COMPILE_FLAGS_IOS;SWIFT_COMPILE_FLAGS_TVOS;SWIFT_COMPILE_FLAGS_WATCHOS;LINK_FLAGS;PRIVATE_LINK_LIBRARIES;INTERFACE_LINK_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES;INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY"
     ${ARGN})
   set(SWIFTLIB_SOURCES ${SWIFTLIB_UNPARSED_ARGUMENTS})
 
@@ -1462,6 +1465,9 @@
         elseif("${sdk}" STREQUAL "LINUX" OR "${sdk}" STREQUAL "ANDROID")
           list(APPEND swiftlib_module_depends_flattened
               ${SWIFTLIB_SWIFT_MODULE_DEPENDS_LINUX})
+        elseif("${sdk}" STREQUAL "CYGWIN")
+          list(APPEND swiftlib_module_depends_flattened
+               ${SWIFTLIB_SWIFT_MODULE_DEPENDS_CYGWIN})
         endif()
 
         # Swift compiles depend on swift modules, while links depend on
@@ -1858,7 +1864,7 @@
       dependency_target
       unused_module_dependency_target
       unused_sib_dependency_target
-      unusged_sibopt_dependency_target
+      unused_sibopt_dependency_target
       unused_sibgen_dependency_target
       SWIFTEXE_SINGLE_SOURCES SWIFTEXE_SINGLE_EXTERNAL_SOURCES ${name}
       DEPENDS
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index fd91d64..982da5b 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -284,6 +284,11 @@
   # Check for '-fapplication-extension'.  On OS X/iOS we wish to link all
   # dynamic libraries with this flag.
   check_cxx_compiler_flag("-fapplication-extension" CXX_SUPPORTS_FAPPLICATION_EXTENSION)
+
+  # Disable C4068: unknown pragma. This means that MSVC doesn't report hundreds of warnings across
+  # the repository for IDE features such as #pragma mark "Title".
+  check_cxx_compiler_flag("/wd4068" CXX_SUPPORTS_UNKNOWN_PRAGMA_FLAG)
+  append_if(CXX_SUPPORTS_UNKNOWN_PRAGMA_FLAG "/wd4068" CMAKE_CXX_FLAGS)
 endmacro()
 
 # Like 'llvm_config()', but uses libraries from the selected build
diff --git a/docs/DriverParseableOutput.rst b/docs/DriverParseableOutput.rst
index 79d41ba..d4554f3 100644
--- a/docs/DriverParseableOutput.rst
+++ b/docs/DriverParseableOutput.rst
@@ -104,7 +104,8 @@
 key. It may include an error message describing the signal under the
 "error-message" key. As with the "finished" message, it may include the
 stdout/stderr of the task under the "output" key; if this key is missing, no
-output was generated by the task.
+output was generated by the task. It may include the "signal" key,
+the terminating signal number. (This may not be available on all platforms.)
 
 Example::
 
@@ -112,7 +113,8 @@
      "kind": "signalled",
      "name": "compile",
      "pid": 12345,
-     "error-message": "Segmentation fault: 11"
+     "error-message": "Segmentation fault: 11",
+     "signal": 4
      // "output" key omitted because there was no stdout/stderr.
    }
 
diff --git a/docs/GenericsManifesto.md b/docs/GenericsManifesto.md
index 613b88d..0332edb 100644
--- a/docs/GenericsManifesto.md
+++ b/docs/GenericsManifesto.md
@@ -2,7 +2,7 @@
 
 ## Introduction
 
-The "Complete Generics" goal for Swift 3 has been fairly ill-defined thus fair, with just this short blurb in the list of goals:
+The "Complete Generics" goal for Swift 3 has been fairly ill-defined thus far, with just this short blurb in the list of goals:
 
 > *Complete generics*: Generics are used pervasively in a number of Swift libraries, especially the standard library. However, there are a number of generics features the standard library requires to fully realize its vision, including recursive protocol constraints, the ability to make a constrained extension conform to a new protocol (i.e., an array of Equatable elements is Equatable), and so on. Swift 3.0 should provide those generics features needed by the standard library, because they affect the standard library's ABI.
 
diff --git a/docs/SIL.rst b/docs/SIL.rst
index ccc4fff..e49e44b 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -3236,6 +3236,23 @@
 and more efficient to reason about aggregate copies than it is to
 reason about copies of the subobjects.
 
+unmanaged_retain_value
+``````````````````````
+
+::
+
+  sil-instruction ::= 'unmanaged_retain_value' sil-value
+
+  unmanaged_retain_value %0 : $A
+
+This instruction has the same local semantics as ``retain_value`` but:
+
+* Is valid in ownership qualified SIL.
+* Is not intended to be statically paired at compile time by the compiler.
+
+The intention is that this instruction is used to implement unmanaged
+constructs.
+
 copy_value
 ``````````
 
@@ -3285,6 +3302,23 @@
 and more efficient to reason about aggregate destroys than it is to
 reason about destroys of the subobjects.
 
+unmanaged_release_value
+```````````````````````
+
+::
+
+  sil-instruction ::= 'unmanaged_release_value' sil-value
+
+  unmanaged_release_value %0 : $A
+
+This instruction has the same local semantics as ``release_value`` but:
+
+* Is valid in ownership qualified SIL.
+* Is not intended to be statically paired at compile time by the compiler.
+
+The intention is that this instruction is used to implement unmanaged
+constructs.
+
 destroy_value
 `````````````
 
diff --git a/docs/StringManifesto.md b/docs/StringManifesto.md
new file mode 100644
index 0000000..8e88572
--- /dev/null
+++ b/docs/StringManifesto.md
@@ -0,0 +1,1281 @@
+# String Processing For Swift 4
+
+* Authors: [Dave Abrahams](https://github.com/dabrahams), [Ben Cohen](https://github.com/airspeedswift)
+
+The goal of re-evaluating Strings for Swift 4 has been fairly ill-defined thus
+far, with just this short blurb in the
+[list of goals](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160725/025676.html):
+
+> **String re-evaluation**: String is one of the most important fundamental
+> types in the language.  The standard library leads have numerous ideas of how
+> to improve the programming model for it, without jeopardizing the goals of
+> providing a unicode-correct-by-default model.  Our goal is to be better at
+> string processing than Perl!
+   
+For Swift 4 and beyond we want to improve three dimensions of text processing:
+
+  1. Ergonomics
+  2. Correctness
+  3. Performance
+
+This document is meant to both provide a sense of the long-term vision 
+(including undecided issues and possible approaches), and to define the scope of
+work that could be done in the Swift 4 timeframe.
+
+## General Principles
+
+### Ergonomics
+
+It's worth noting that ergonomics and correctness are mutually-reinforcing.  An
+API that is easy to use--but incorrectly--cannot be considered an ergonomic
+success.  Conversely, an API that's simply hard to use is also hard to use
+correctly.  Achieving optimal performance without compromising ergonomics or
+correctness is a greater challenge.
+
+Consistency with the Swift language and idioms is also important for
+ergonomics. There are several places both in the standard library and in the
+Foundation additions to `String` where patterns and practices found elsewhere
+could be applied to improve usability and familiarity.
+
+### API Surface Area
+
+Primary data types such as `String` should have APIs that are easily understood
+given a signature and a one-line summary.  Today, `String` fails that test.  As
+you can see, the Standard Library and Foundation both contribute significantly to
+its overall complexity.
+
+**Method Arity** | **Standard Library** | **Foundation**
+---|:---:|:---:
+0: `f()` | 5 | 7
+1: `f(:)` | 19 | 48
+2: `f(::)` | 13 | 19
+3: `f(:::)` | 5 | 11
+4: `f(::::)` | 1 | 7
+5: `f(:::::)` | - | 2
+6: `f(::::::)` | - | 1
+
+**API Kind** | **Standard Library** | **Foundation**
+---|:---:|:---:
+`init` | 41 | 18
+`func` | 42 | 55
+`subscript` | 9 | 0
+`var` | 26 | 14
+
+**Total: 205 APIs**
+
+By contrast, `Int` has 80 APIs, none with more than two parameters.  <sup
+id="a0">[0](#f0)</sup> String processing is complex enough; users shouldn't have
+to press through physical API sprawl just to get started.
+
+Many of the choices detailed below contribute to solving this problem,
+including:
+
+  * [Restoring `Collection` conformance](#L-code-string--code--should-be-a--code-collection--code--of--code-character--code-s-again) and
+    dropping the `.characters` view.
+  * Providing a more
+    general, [composable slicing syntax](#unification-of-slicing-operations).
+  * [Altering `Comparable`](#syntax) so that parameterized
+    (e.g. case-insensitive) comparison fits smoothly into the basic syntax.
+  * [Clearly separating](#internationalization-and-the-default-behavior-of--code-string--code-) language-dependent
+    operations on text produced by and for humans from language-independent
+    operations on text produced by and for machine processing.
+  * Relocating APIs that fall outside the domain of basic string processing and
+    discouraging the proliferation of ad-hoc extensions.
+
+
+### Batteries Included
+
+While `String` is available to all programs out-of-the-box, crucial APIs for
+basic string processing tasks are still inaccessible until `Foundation` is
+imported.  While it makes sense that `Foundation` is needed for domain-specific
+jobs such as
+[linguistic tagging](https://developer.apple.com/reference/foundation/nslinguistictagger),
+one should not need to import anything to, for example, do case-insensitive
+comparison.
+
+### Unicode Compliance and Platform Support
+
+The Unicode standard provides a crucial objective reference point for what
+constitutes correct behavior in an extremely complex domain, so
+Unicode-correctness is, and will remain, a fundamental design principle behind
+Swift's `String`.  That said, the Unicode standard is an evolving document, so
+this objective reference-point is not fixed.  <sup id="a1">[1](#f1)</sup> While
+many of the most important operations--e.g. string hashing, equality, and
+non-localized comparison--[will be stable](#collation-semantics), the semantics
+of others, such as grapheme breaking and localized comparison and case
+conversion, are expected to change as platforms are updated, so programs should
+be written so their correctness does not depend on precise stability of these
+semantics across OS versions or platforms.  Although it may be possible to
+imagine static and/or dynamic analysis tools that will help users find such
+errors, the only sure way to deal with this fact of life is to educate users.
+
+## Design Points
+
+### Internationalization
+
+There is strong evidence that developers cannot determine how to use
+internationalization APIs correctly.  Although documentation could and should be
+improved, the sheer size, complexity, and diversity of these APIs is a major
+contributor to the problem, causing novices to tune out, and more experienced
+programmers to make avoidable mistakes.
+
+The first step in improving this situation is to regularize all localized
+operations as invocations of normal string operations with extra
+parameters. Among other things, this means:
+
+1. Doing away with `localizedXXX` methods.
+2. Providing a terse way to name the current locale as a parameter.
+3. Automatically [adjusting defaults](#operations-with-options) for options such
+   as case sensitivity based on whether the operation is localized.
+4. Removing correctness traps like `localizedCaseInsensitiveCompare` (see
+    guidance in the
+    [Internationalization and Localization Guide](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPInternational/InternationalizingYourCode/InternationalizingYourCode.html).
+
+Along with appropriate documentation updates, these changes will make localized
+operations more teachable, comprehensible, and approachable, thereby lowering a
+barrier that currently leads some developers to ignore localization issues
+altogether.
+
+####  The Default Behavior of `String`
+
+Although this isn't well-known, the most accessible form of many operations on
+Swift `String` (and `NSString`) are really only appropriate for text that is
+intended to be processed for, and consumed by, machines.  The semantics of the
+operations with the simplest spellings are always non-localized and
+language-agnostic.
+
+Two major factors play into this design choice:
+
+1. Machine processing of text is important, so we should have first-class,
+   accessible functions appropriate to that use case.
+   
+2. The most general localized operations require a locale parameter not required
+   by their un-localized counterparts.  This naturally skews complexity towards
+   localized operations.
+
+Reaffirming that `String`'s simplest APIs have
+language-independent/machine-processed semantics has the benefit of clarifying
+the proper default behavior of operations such as comparison, and allows us to
+make [significant optimizations](#collation-semantics) that were previously
+thought to conflict with Unicode.
+
+#### Future Directions
+
+One of the most common internationalization errors is the unintentional
+presentation to users of text that has not been localized, but regularizing APIs
+and improving documentation can go only so far in preventing this error.
+Combined with the fact that `String` operations are non-localized by default,
+the environment for processing human-readable text may still be somewhat
+error-prone in Swift 4.
+
+For an audience of mostly non-experts, it is especially important that naïve
+code is very likely to be correct if it compiles, and that more sophisticated
+issues can be revealed progressively.  For this reason, we intend to
+specifically and separately target localization and internationalization
+problems in the Swift 5 timeframe.
+
+### Operations With Options
+
+There are three categories of common string operation that commonly need to be
+tuned in various dimensions:
+
+**Operation**|**Applicable Options**
+---|---
+sort ordering | locale, case/diacritic/width-insensitivity
+case conversion | locale
+pattern matching | locale, case/diacritic/width-insensitivity
+
+The defaults for case-, diacritic-, and width-insensitivity are sometimes different for
+localized operations than for non-localized operations, so for example a
+localized search should be case-insensitive by default, and a non-localized search
+should be case-sensitive by default.  We propose a standard "language" of
+defaulted parameters to be used for these purposes, with usage roughly like this:
+
+```swift
+  x.compared(to: y, case: .sensitive, in: swissGerman)
+  
+  x.lowercased(in: .currentLocale)
+  
+  x.allMatches(
+    somePattern, case: .insensitive, diacritic: .insensitive)
+```
+
+This usage might be supported by code like this:
+
+```swift
+enum StringSensitivity {
+case sensitive
+case insensitive
+}
+
+extension Locale {
+  static var currentLocale: Locale { ... }
+}
+
+extension Unicode {
+  // An example of the option language in declaration context,
+  // with nil defaults indicating unspecified, so defaults can be
+  // driven by the presence/absence of a specific Locale
+  func frobnicated(
+    case caseSensitivity: StringSensitivity? = nil,
+    diacritic diacriticSensitivity: StringSensitivity? = nil,
+    width widthSensitivity: StringSensitivity? = nil,
+    in locale: Locale? = nil
+  ) -> Self { ... }
+}
+```
+
+### Comparing and Hashing Strings
+
+#### Collation Semantics
+
+What Unicode says about collation--which is used in `<`, `==`, and hashing-- turns
+out to be quite interesting, once you pick it apart.  The full Unicode Collation
+Algorithm (UCA) works like this:
+
+1. Fully normalize both strings.
+2. Convert each string to a sequence of numeric triples to form a collation key.
+3. "Flatten" the key by concatenating the sequence of first elements to the
+   sequence of second elements to the sequence of third elements.
+4. Lexicographically compare the flattened keys.
+
+While step 1 can usually
+be [done quickly](http://unicode.org/reports/tr15/#Description_Norm) and
+incrementally, step 2 uses a collation table that maps matching *sequences* of
+Unicode scalars in the normalized string to *sequences* of triples, which get
+accumulated into a collation key.  Predictably, this is where the real costs
+lie.
+
+*However*, there are some bright spots to this story.  First, as it turns out,
+string sorting (localized or not) should be done down to what's called
+the
+["identical" level](http://unicode.org/reports/tr10/#Multi_Level_Comparison),
+which adds a step 3a: append the string's normalized form to the flattened
+collation key.  At first blush this just adds work, but consider what it does
+for equality: two strings that normalize the same, naturally, will collate the
+same.  But also, *strings that normalize differently will always collate
+differently*.  In other words, for equality, it is sufficient to compare the
+strings' normalized forms and see if they are the same.  We can therefore
+entirely skip the expensive part of collation for equality comparison.
+
+Next, naturally, anything that applies to equality also applies to hashing: it
+is sufficient to hash the string's normalized form, bypassing collation keys.
+This should provide significant speedups over the current implementation.
+Perhaps more importantly, since comparison down to the "identical" level applies
+even to localized strings, it means that hashing and equality can be implemented
+exactly the same way for localized and non-localized text, and hash tables with
+localized keys will remain valid across current-locale changes.
+
+Finally, once it is agreed that the *default* role for `String` is to handle
+machine-generated and machine-readable text, the default ordering of `String`s
+need no longer use the UCA at all.  It is sufficient to order them in any way
+that's consistent with equality, so `String` ordering can simply be a
+lexicographical comparison of normalized forms, <sup id="a4">[4](#f4)</sup>
+(which is equivalent to lexicographically comparing the sequences of grapheme
+clusters), again bypassing step 2 and offering another speedup.
+
+This leaves us executing the full UCA *only* for localized sorting, and ICU's
+implementation has apparently been very well optimized.
+
+Following this scheme everywhere would also allow us to make sorting behavior
+consistent across platforms.  Currently, we sort `String` according to the UCA,
+except that--*only on Apple platforms*--pairs of ASCII characters are ordered by
+unicode scalar value.
+
+#### Syntax
+
+Because the current `Comparable` protocol expresses all comparisons with binary
+operators, string comparisons--which may require
+additional [options](#operations-with-options)--do not fit smoothly into the
+existing syntax.  At the same time, we'd like to solve other problems with
+comparison, as outlined
+in
+[this proposal](https://gist.github.com/CodaFi/f0347bd37f1c407bf7ea0c429ead380e)
+(implemented by changes at the head
+of
+[this branch](https://github.com/CodaFi/swift/commits/space-the-final-frontier)).
+We should adopt a modification of that proposal that uses a method rather than
+an operator `<=>`:
+
+```swift
+enum SortOrder { case before, same, after }
+
+protocol Comparable : Equatable {
+ func compared(to: Self) -> SortOrder
+ ...
+}
+```
+
+This change will give us a syntactic platform on which to implement methods with
+additional, defaulted arguments, thereby unifying and regularizing comparison
+across the library.
+
+```swift
+extension String {
+ func compared(to: Self) -> SortOrder
+
+}
+```
+
+**Note:** `SortOrder` should bridge to `NSComparisonResult`.  It's also possible
+that the standard library simply adopts Foundation's `ComparisonResult` as is,
+but we believe the community should at least consider alternate naming before
+that happens.  There will be an opportunity to discuss the choices in detail
+when the modified
+[Comparison Proposal](https://gist.github.com/CodaFi/f0347bd37f1c407bf7ea0c429ead380e) comes
+up for review.
+
+### `String` should be a `Collection` of `Character`s Again
+
+In Swift 2.0, `String`'s `Collection` conformance was dropped, because we
+convinced ourselves that its semantics differed from those of `Collection` too
+significantly.
+
+It was always well understood that if strings were treated as sequences of
+`UnicodeScalar`s, algorithms such as `lexicographicalCompare`, `elementsEqual`,
+and `reversed` would produce nonsense results. Thus, in Swift 1.0, `String` was
+a collection of `Character` (extended grapheme clusters). During 2.0
+development, though, we realized that correct string concatenation could
+occasionally merge distinct grapheme clusters at the start and end of combined
+strings.
+
+This quirk aside, every aspect of strings-as-collections-of-graphemes appears to
+comport perfectly with Unicode. We think the concatenation problem is tolerable,
+because the cases where it occurs all represent partially-formed constructs. The
+largest class--isolated combining characters such as ◌́ (U+0301 COMBINING ACUTE
+ACCENT)--are explicitly called out in the Unicode standard as
+"[degenerate](http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)" or
+"[defective](http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf)". The other
+cases--such as a string ending in a zero-width joiner or half of a regional
+indicator--appear to be equally transient and unlikely outside of a text editor.
+
+Admitting these cases encourages exploration of grapheme composition and is
+consistent with what appears to be an overall Unicode philosophy that "no
+special provisions are made to get marginally better behavior for... cases that
+never occur in practice." <sup id="a2">[2](#f2)</sup> Furthermore, it seems
+unlikely to disturb the semantics of any plausible algorithms. We can handle
+these cases by documenting them, explicitly stating that the elements of a
+`String` are an emergent property based on Unicode rules.
+
+The benefits of restoring `Collection` conformance are substantial: 
+
+  * Collection-like operations encourage experimentation with strings to
+    investigate and understand their behavior. This is useful for teaching new
+    programmers, but also good for experienced programmers who want to
+    understand more about strings/unicode.
+    
+  * Extended grapheme clusters form a natural element boundary for Unicode
+    strings.  For example, searching and matching operations will always produce
+    results that line up on grapheme cluster boundaries.
+    
+  * Character-by-character processing is a legitimate thing to do in many real
+    use-cases, including parsing, pattern matching, and language-specific
+    transformations such as transliteration.
+    
+  * `Collection` conformance makes a wide variety of powerful operations
+    available that are appropriate to `String`'s default role as the vehicle for
+    machine processed text.
+    
+    The methods `String` would inherit from `Collection`, where similar to
+    higher-level string algorithms, have the right semantics.  For example,
+    grapheme-wise `lexicographicalCompare`, `elementsEqual`, and application of
+    `flatMap` with case-conversion, produce the same results one would expect
+    from whole-string ordering comparison, equality comparison, and
+    case-conversion, respectively.  `reverse` operates correctly on graphemes,
+    keeping diacritics moored to their base characters and leaving emoji intact.
+    Other methods such as `index(of:)` and `contains` make obvious sense. A few
+    `Collection` methods, like `min` and `max`, may not be particularly useful
+    on `String`, but we don't consider that to be a problem worth solving, in
+    the same way that we wouldn't try to suppress `min` and `max` on a
+    `Set([UInt8])` that was used to store IP addresses.
+    
+  * Many of the higher-level operations that we want to provide for `String`s,
+    such as parsing and pattern matching, should apply to any `Collection`, and
+    many of the benefits we want for `Collections`, such
+    as [unified slicing](#unification-of-slicing-operations), should accrue
+    equally to `String`.  Making `String` part of the same protocol hierarchy
+    allows us to write these operations once and not worry about keeping the
+    benefits in sync.
+    
+  * Slicing strings into substrings is a crucial part of the vocabulary of
+    string processing, and all other sliceable things are `Collection`s.
+    Because of its collection-like behavior, users naturally think of `String`
+    in collection terms, but run into frustrating limitations where it fails to
+    conform and are left to wonder where all the differences lie.  Many simply
+    "correct" this limitation by declaring a trivial conformance:
+    
+    ```swift
+  extension String : BidirectionalCollection {}
+    ```
+    
+    Even if we removed indexing-by-element from `String`, users could still do
+    this:
+    
+    ```swift
+    extension String : BidirectionalCollection {
+      subscript(i: Index) -> Character { return characters[i] }
+    }
+    ```
+    
+    It would be much better to legitimize the conformance to `Collection` and
+    simply document the oddity of any concatenation corner-cases, than to deny
+    users the benefits on the grounds that a few cases are confusing.
+
+Note that the fact that `String` is a collection of graphemes does *not* mean
+that string operations will necessarily have to do grapheme boundary
+recognition.  See [this section](#the--code-unicode--code--protocol) for details.
+
+### `Character` and `CharacterSet`
+
+`Character`, which represents a
+Unicode
+[extended grapheme cluster](http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries),
+is a bit of a black box, requiring conversion to `String` in order to
+do any introspection, including interoperation with ASCII.  To fix this, we should:
+
+ - Add a `unicodeScalars` view much like `String`'s, so that the sub-structure
+   of grapheme clusters is discoverable.
+ - Add a failable `init` from sequences of scalars (returning nil for sequences
+   that contain 0 or 2+ graphemes).
+ - (Lower priority) expose some operations, such as `func uppercase() ->
+   String`, `var isASCII: Bool`, and, to the extent they can be sensibly
+   generalized, queries of Unicode properties that should also be exposed on
+   `UnicodeScalar` such as `isAlphabetic` and `isGraphemeBase`.
+
+Despite its name, `CharacterSet` currently operates on the Swift `UnicodeScalar`
+type. This means it is usable on `String`, but only by going through the unicode
+scalar view. To deal with this clash in the short term, `CharacterSet` should be
+renamed to `UnicodeScalarSet`.  In the longer term, it may be appropriate to
+introduce a `CharacterSet` that provides similar functionality for extended
+grapheme clusters. <sup id="a5">[5](#f5)</sup>
+
+### Unification of Slicing Operations
+
+Creating substrings is a basic part of string processing, but the slicing
+operations that we have in Swift are inconsistent in both their spelling and
+their naming:
+
+  * Slices with two explicit endpoints are done with subscript, and support
+    in-place mutation:
+    
+    ```swift
+    s[i..<j].mutate()
+    ```
+
+  * Slicing from an index to the end, or from the start to an index, is done
+    with a method and does not support in-place mutation:
+    ```swift
+    s.prefix(upTo: i).readOnly()
+    ```
+
+Prefix and suffix operations should be migrated to be subscripting operations
+with one-sided ranges i.e. `s.prefix(upTo: i)` should become `s[..<i]`, as
+in
+[this proposal](https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0132-sequence-end-ops.md).
+With generic subscripting in the language, that will allow us to collapse a wide
+variety of methods and subscript overloads into a single implementation, and
+give users an easy-to-use and composable way to describe subranges.
+
+Further extending this EDSL to integrate use-cases like `s.prefix(maxLength: 5)`
+is an ongoing research project that can be considered part of the potential
+long-term vision of text (and collection) processing.
+
+### Substrings
+
+When implementing substring slicing, languages are faced with three options:
+
+1. Make the substrings the same type as string, and share storage.
+2. Make the substrings the same type as string, and copy storage when making the substring.
+3. Make substrings a different type, with a storage copy on conversion to string.
+
+We think number 3 is the best choice. A walk-through of the tradeoffs follows.
+
+#### Same type, shared storage
+
+In Swift 3.0, slicing a `String` produces a new `String` that is a view into a
+subrange of the original `String`'s storage. This is why `String` is 3 words in
+size (the start, length and buffer owner), unlike the similar `Array` type
+which is only one.
+
+This is a simple model with big efficiency gains when chopping up strings into
+multiple smaller strings. But it does mean that a stored substring keeps the
+entire original string buffer alive even after it would normally have been
+released.
+
+This arrangement has proven to be problematic in other programming languages,
+because applications sometimes extract small strings from large ones and keep
+those small strings long-term. That is considered a memory leak and was enough
+of a problem in Java that they changed from substrings sharing storage to
+making a copy in 1.7.
+
+#### Same type, copied storage
+
+Copying of substrings is also the choice made in C#, and in the default
+`NSString` implementation. This approach avoids the memory leak issue, but has
+obvious performance overhead in performing the copies.
+
+This in turn encourages trafficking in string/range pairs instead of in
+substrings, for performance reasons, leading to API challenges. For example:
+
+```swift
+foo.compare(bar, range: start..<end)
+```
+
+Here, it is not clear whether `range` applies to `foo` or `bar`. This
+relationship is better expressed in Swift as a slicing operation:
+
+```swift
+foo[start..<end].compare(bar)
+```
+
+Not only does this clarify to which string the range applies, it also brings
+this sub-range capability to any API that operates on `String` "for free". So
+these other combinations also work equally well:
+
+```swift
+// apply range on argument rather than target
+foo.compare(bar[start..<end])
+// apply range on both
+foo[start..<end].compare(bar[start1..<end1])
+// compare two strings ignoring first character
+foo.dropFirst().compare(bar.dropFirst())
+```
+
+In all three cases, an explicit range argument need not appear on the `compare`
+method itself. The implementation of `compare` does not need to know anything
+about ranges. Methods need only take range arguments when that was an
+integral part of their purpose (for example, setting the start and end of a
+user's current selection in a text box).
+
+#### Different type, shared storage
+
+The desire to share underlying storage while preventing accidental memory leaks
+occurs with slices of `Array`. For this reason we have an `ArraySlice` type.
+The inconvenience of a separate type is mitigated by most operations used on
+`Array` from the standard library being generic over `Sequence` or `Collection`.
+
+We should apply the same approach for `String` by introducing a distinct
+`SubSequence` type, `Substring`. Similar advice given for `ArraySlice` would apply to `Substring`:
+
+> Important: Long-term storage of `Substring` instances is discouraged. A
+> substring holds a reference to the entire storage of a larger string, not
+> just to the portion it presents, even after the original string's lifetime
+> ends. Long-term storage of a `Substring` may therefore prolong the lifetime
+> of large strings that are no longer otherwise accessible, which can appear
+> to be memory leakage.
+
+When assigning a `Substring` to a longer-lived variable (usually a stored
+property) explicitly of type `String`, a type conversion will be performed, and
+at this point the substring buffer is copied and the original string's storage
+can be released.
+
+A `String` that was not its own `Substring` could be one word--a single tagged
+pointer--without requiring additional allocations. `Substring`s would be a view
+onto a `String`, so are 3 words - pointer to owner, pointer to start, and a
+length. The small string optimization for `Substring` would take advantage of
+the larger size, probably with a less compressed encoding for speed.
+
+The downside of having two types is the inconvenience of sometimes having a
+`Substring` when you need a `String`, and vice-versa. It is likely this would
+be a significantly bigger problem than with `Array` and `ArraySlice`, as
+slicing of `String` is such a common operation. It is especially relevant to
+existing code that assumes `String` is the currency type. To ease the pain of
+type mismatches, `Substring` should be a subtype of `String` in the same way
+that `Int` is a subtype of `Optional<Int>`. This would give users an implicit
+conversion from `Substring` to `String`, as well as the usual implicit
+conversions such as `[Substring]` to `[String]` that other subtype
+relationships receive.
+
+In most cases, type inference combined with the subtype relationship should
+make the type difference a non-issue and users will not care which type they
+are using. For flexibility and optimizability, most operations from the
+standard library will traffic in generic models of
+[`Unicode`](#the--code-unicode--code--protocol).
+
+##### Guidance for API Designers
+
+In this model, **if a user is unsure about which type to use, `String` is always
+a reasonable default**. A `Substring` passed where `String` is expected will be
+implicitly copied. When compared to the "same type, copied storage" model, we
+have effectively deferred the cost of copying from the point where a substring
+is created until it must be converted to `String` for use with an API.
+
+A user who needs to optimize away copies altogether should use this guideline:
+if for performance reasons you are tempted to add a `Range` argument to your
+method as well as a `String` to avoid unnecessary copies, you should instead
+use `Substring`.
+
+##### The "Empty Subscript"
+
+To make it easy to call such an optimized API when you only have a `String` (or
+to call any API that takes a `Collection`'s `SubSequence` when all you have is
+the `Collection`), we propose the following "empty subscript" operation,
+
+```swift
+extension Collection {
+  subscript() -> SubSequence { 
+    return self[startIndex..<endIndex] 
+  }
+}
+```
+
+which allows the following usage:
+
+```swift
+funcThatIsJustLooking(at: person.name[]) // pass person.name as Substring
+```
+
+The `[]` syntax can be offered as a fixit when needed, similar to `&` for an
+`inout` argument. While it doesn't help a user to convert `[String]` to
+`[Substring]`, the need for such conversions is extremely rare, can be done with
+a simple `map` (which could also be offered by a fixit):
+
+```swift
+takesAnArrayOfSubstring(arrayOfString.map { $0[] })
+```
+
+#### Other Options Considered
+
+As we have seen, all three options above have downsides, but it's possible
+these downsides could be eliminated/mitigated by the compiler. We are proposing
+one such mitigation--implicit conversion--as part of the the "different type,
+shared storage" option, to help avoid the cognitive load on developers of
+having to deal with a separate `Substring` type.
+
+To avoid the memory leak issues of a "same type, shared storage" substring
+option, we considered whether the compiler could perform an implicit copy of
+the underlying storage when it detects the string is being "stored" for long
+term usage, say when it is assigned to a stored property. The trouble with this
+approach is it is very difficult for the compiler to distinguish between
+long-term storage versus short-term in the case of abstractions that rely on
+stored properties. For example, should the storing of a substring inside an
+`Optional` be considered long-term? Or the storing of multiple substrings
+inside an array? The latter would not work well in the case of a
+`components(separatedBy:)` implementation that intended to return an array of
+substrings. It would also be difficult to distinguish intentional medium-term
+storage of substrings, say by a lexer. There does not appear to be an effective
+consistent rule that could be applied in the general case for detecting when a
+substring is truly being stored long-term.
+
+To avoid the cost of copying substrings under "same type, copied storage", the
+optimizer could be enhanced to reduce the impact of some of those copies.
+For example, this code could be optimized to pull the invariant substring out
+of the loop:
+
+```swift
+for _ in 0..<lots { 
+  someFunc(takingString: bigString[bigRange]) 
+}
+```
+
+It's worth noting that a similar optimization is needed to avoid an equivalent
+problem with implicit conversion in the "different type, shared storage" case:
+
+```swift
+let substring = bigString[bigRange]
+for _ in 0..<lots { someFunc(takingString: substring) }
+```
+
+However, in the case of "same type, copied storage" there are many use cases
+that cannot be optimized as easily. Consider the following simple definition of
+a recursive `contains` algorithm, which when substring slicing is linear makes
+the overall algorithm quadratic:
+
+```swift
+extension String {
+    func containsChar(_ x: Character) -> Bool {
+        return !isEmpty && (first == x || dropFirst().containsChar(x))
+    }
+}
+```
+
+For the optimizer to eliminate this problem is unrealistic, forcing the user to
+remember to optimize the code to not use string slicing if they want it to be
+efficient (assuming they remember):
+
+```swift
+extension String {
+    // add optional argument tracking progress through the string
+    func containsCharacter(_ x: Character, atOrAfter idx: Index? = nil) -> Bool {
+        let idx = idx ?? startIndex
+        return idx != endIndex
+            && (self[idx] == x || containsCharacter(x, atOrAfter: index(after: idx)))
+    }
+}
+```
+
+#### Substrings, Ranges and Objective-C Interop
+
+The pattern of passing a string/range pair is common in several Objective-C
+APIs, and is made especially awkward in Swift by the non-interchangeability of
+`Range<String.Index>` and `NSRange`.  
+
+```swift
+s2.find(s2, sourceRange: NSRange(j..<s2.endIndex, in: s2))
+```
+
+In general, however, the Swift idiom for operating on a sub-range of a
+`Collection` is to *slice* the collection and operate on that:
+
+```swift
+s2.find(s2[j..<s2.endIndex])
+```
+
+Therefore, APIs that operate on an `NSString`/`NSRange` pair should be imported
+without the `NSRange` argument.  The Objective-C importer should be changed to
+give these APIs special treatment so that when a `Substring` is passed, instead
+of being converted to a `String`, the full `NSString` and range are passed to
+the Objective-C method, thereby avoiding a copy.
+
+As a result, you would never need to pass an `NSRange` to these APIs, which
+solves the impedance problem by eliminating the argument, resulting in more
+idiomatic Swift code while retaining the performance benefit.  To help users
+manually handle any cases that remain, Foundation should be augmented to allow
+the following syntax for converting to and from `NSRange`:
+
+```swift
+let nsr = NSRange(i..<j, in: s) // An NSRange corresponding to s[i..<j]
+let iToJ = Range(nsr, in: s)    // Equivalent to i..<j
+```
+
+### The `Unicode` protocol
+
+With `Substring` and `String` being distinct types and sharing almost all
+interface and semantics, and with the highest-performance string processing
+requiring knowledge of encoding and layout that the currency types can't
+provide, it becomes important to capture the common "string API" in a protocol.
+Since Unicode conformance is a key feature of string processing in Swift, we
+call that protocol `Unicode`:
+
+**Note:** The following assumes several features that are planned but not yet implemented in
+  Swift, and should be considered a sketch rather than a final design.
+  
+```swift
+protocol Unicode 
+  : Comparable, BidirectionalCollection where Element == Character {
+  
+  associatedtype Encoding : UnicodeEncoding
+  var encoding: Encoding { get }
+  
+  associatedtype CodeUnits 
+    : RandomAccessCollection where Element == Encoding.CodeUnit
+  var codeUnits: CodeUnits { get }
+  
+  associatedtype UnicodeScalars 
+    : BidirectionalCollection where Element == UnicodeScalar
+  var unicodeScalars: UnicodeScalars { get }
+
+  associatedtype ExtendedASCII 
+    : BidirectionalCollection where Element == UInt32
+  var extendedASCII: ExtendedASCII { get }
+
+  var unicodeScalars: UnicodeScalars { get }
+}
+
+extension Unicode {
+  // ... define high-level non-mutating string operations, e.g. search ...
+
+  func compared<Other: Unicode>(
+    to rhs: Other,
+    case caseSensitivity: StringSensitivity? = nil,
+    diacritic diacriticSensitivity: StringSensitivity? = nil,
+    width widthSensitivity: StringSensitivity? = nil,
+    in locale: Locale? = nil
+  ) -> SortOrder { ... }
+}
+
+extension Unicode : RangeReplaceableCollection where CodeUnits :
+  RangeReplaceableCollection {
+    // Satisfy protocol requirement
+    mutating func replaceSubrange<C : Collection>(_: Range<Index>, with: C) 
+      where C.Element == Element
+  
+  // ... define high-level mutating string operations, e.g. replace ...
+}
+
+```
+
+The goal is that `Unicode` exposes the underlying encoding and code units in
+such a way that for types with a known representation (e.g. a high-performance
+`UTF8String`) that information can be known at compile-time and can be used to
+generate a single path, while still allowing types like `String` that admit
+multiple representations to use runtime queries and branches to fast path
+specializations.
+
+**Note:** `Unicode` would make a fantastic namespace for much of
+what's in this proposal if we could get the ability to nest types and
+protocols in protocols.
+
+
+### Scanning, Matching, and Tokenization
+
+#### Low-Level Textual Analysis
+
+We should provide convenient APIs for processing strings by character.  For example,
+it should be easy to cleanly express, "if this string starts with `"f"`, process
+the rest of the string as follows..."  Swift is well-suited to expressing this
+common pattern beautifully, but we need to add the APIs.  Here are two examples
+of the sort of code that might be possible given such APIs:
+
+```swift
+if let firstLetter = input.dropPrefix(alphabeticCharacter) {
+  somethingWith(input) // process the rest of input
+}
+
+if let (number, restOfInput) = input.parsingPrefix(Int.self) {
+   ...
+}
+```
+
+The specific spelling and functionality of APIs like this are TBD.  The larger
+point is to make sure matching-and-consuming jobs are well-supported.
+
+#### Unified Pattern Matcher Protocol
+
+Many of the current methods that do matching are overloaded to do the same
+logical operations in different ways, with the following axes:
+
+- Logical Operation: `find`, `split`, `replace`, match at start.
+- Kind of pattern: `CharacterSet`, `String`, a regex, a closure.
+- Options, e.g. case/diacritic sensitivity, locale.  Sometimes a part of
+  the method name, and sometimes an argument.
+- Whole string or subrange.
+
+We should represent these aspects as orthogonal, composable components,
+abstracting pattern matchers into a protocol like
+[this one](https://github.com/apple/swift/blob/master/test/Prototypes/PatternMatching.swift#L33),
+that can allow us to define logical operations once, without introducing
+overloads, and massively reducing API surface area.
+
+For example, using the strawman prefix `%` syntax to turn string literals into
+patterns, the following pairs would all invoke the same generic methods:
+
+```swift
+if let found = s.firstMatch(%"searchString") { ... }
+if let found = s.firstMatch(someRegex) { ... }
+
+for m in s.allMatches((%"searchString"), case: .insensitive) { ... }
+for m in s.allMatches(someRegex) { ... }
+
+let items = s.split(separatedBy: ", ")
+let tokens = s.split(separatedBy: CharacterSet.whitespace)
+```
+
+Note that, because Swift requires the indices of a slice to match the indices of
+the range from which it was sliced, operations like `firstMatch` can return a
+`Substring?` in lieu of a `Range<String.Index>?`: the indices of the match in
+the string being searched, if needed, can easily be recovered as the
+`startIndex` and `endIndex` of the `Substring`.
+
+Note also that matching operations are useful for collections in general, and
+would fall out of this proposal:
+
+```
+// replace subsequences of contiguous NaNs with zero
+forces.replace(oneOrMore([Float.nan]), [0.0])
+```
+
+#### Regular Expressions
+
+Addressing regular expressions is out of scope for this proposal.
+That said, it is important to note that the pattern matching protocol mentioned
+above provides a suitable foundation for regular expressions, and types such as
+`NSRegularExpression` can easily be retrofitted to conform to it.  In the
+future, support for regular expression literals in the compiler could allow for
+compile-time syntax checking and optimization.
+
+### String Indices
+
+`String` currently has four views--`characters`, `unicodeScalars`, `utf8`, and
+`utf16`--each with its own opaque index type.  The APIs used to translate indices
+between views add needless complexity, and the opacity of indices makes them
+difficult to serialize.
+
+The index translation problem has two aspects:
+
+  1. `String` views cannot consume one anothers' indices without a cumbersome
+    conversion step.  An index into a `String`'s `characters` must be translated
+    before it can be used as a position in its `unicodeScalars`.  Although these
+    translations are rarely needed, they add conceptual and API complexity.
+  2. Many APIs in the core libraries and other frameworks still expose `String`
+    positions as `Int`s and regions as `NSRange`s, which can only reference a
+    `utf16` view and interoperate poorly with `String` itself.
+
+#### Index Interchange Among Views
+
+String's need for flexible backing storage and reasonably-efficient indexing
+(i.e. without dynamically allocating and reference-counting the indices
+themselves) means indices need an efficient underlying storage type.  Although
+we do not wish to expose `String`'s indices *as* integers, `Int` offsets into
+underlying code unit storage makes a good underlying storage type, provided
+`String`'s underlying storage supports random-access.  We think random-access
+*code-unit storage* is a reasonable requirement to impose on all `String`
+instances.
+
+Making these `Int` code unit offsets conveniently accessible and constructible
+solves the serialization problem:
+
+```swift
+clipboard.write(s.endIndex.codeUnitOffset)
+let offset = clipboard.read(Int.self)
+let i = String.Index(codeUnitOffset: offset)
+```
+
+Index interchange between `String` and its `unicodeScalars`, `codeUnits`,
+and [`extendedASCII`](#parsing-ascii-structure) views can be made entirely
+seamless by having them share an index type (semantics of indexing a `String`
+between grapheme cluster boundaries are TBD--it can either trap or be forgiving).
+Having a common index allows easy traversal into the interior of graphemes,
+something that is often needed, without making it likely that someone will do it
+by accident.
+
+ - `String.index(after:)` should advance to the next grapheme, even when the
+   index points partway through a grapheme.
+   
+ - `String.index(before:)` should move to the start of the grapheme before
+   the current position.
+
+Seamless index interchange between `String` and its UTF-8 or UTF-16 views is not
+crucial, as the specifics of encoding should not be a concern for most use
+cases, and would impose needless costs on the indices of other views.  That
+said, we can make translation much more straightforward by exposing simple
+bidirectional converting `init`s on both index types:
+
+```swift
+let u8Position = String.UTF8.Index(someStringIndex)
+let originalPosition = String.Index(u8Position)
+```
+
+#### Index Interchange with Cocoa
+
+We intend to address `NSRange`s that denote substrings in Cocoa APIs as
+described [later in this document](#substrings--ranges-and-objective-c-interop).
+That leaves the interchange of bare indices with Cocoa APIs trafficking in
+`Int`.  Hopefully such APIs will be rare, but when needed, the following
+extension, which would be useful for all `Collections`, can help:
+
+```swift
+extension Collection {
+  func index(offset: IndexDistance) -> Index {
+    return index(startIndex, offsetBy: offset)
+  }
+  func offset(of i: Index) -> IndexDistance {
+    return distance(from: startIndex, to: i)
+  }
+}
+```
+
+Then integers can easily be translated into offsets into a `String`'s `utf16`
+view for consumption by Cocoa:
+
+```swift
+let cocoaIndex = s.utf16.offset(of: String.UTF16Index(i))
+let swiftIndex = s.utf16.index(offset: cocoaIndex)
+```
+
+### Formatting
+
+A full treatment of formatting is out of scope of this proposal, but
+we believe it's crucial for completing the text processing picture.  This
+section details some of the existing issues and thinking that may guide future
+development.
+
+#### Printf-Style Formatting
+
+`String(format:)` is designed on the `printf` model: it takes a format string with
+textual placeholders for substitution, and an arbitrary list of other arguments.
+The syntax and meaning of these placeholders has a long history in
+C, but for anyone who doesn't use them regularly they are cryptic and complex,
+as the `printf (3)` man page attests.
+
+Aside from complexity, this style of API has two major problems: First, the
+spelling of these placeholders must match up to the types of the arguments, in
+the right order, or the behavior is undefined.  Some limited support for
+compile-time checking of this correspondence could be implemented, but only for
+the cases where the format string is a literal. Second, there's no reasonable
+way to extend the formatting vocabulary to cover the needs of new types: you are
+stuck with what's in the box.
+
+#### Foundation Formatters
+
+The formatters supplied by Foundation are highly capable and versatile, offering
+both formatting and parsing services.  When used for formatting, though, the
+design pattern demands more from users than it should:
+
+  * Matching the type of data being formatted to a formatter type
+  * Creating an instance of that type
+  * Setting stateful options (`currency`, `dateStyle`) on the type.  Note: the
+    need for this step prevents the instance from being used and discarded in
+    the same expression where it is created.
+  * Overall, introduction of needless verbosity into source
+
+These may seem like small issues, but the experience of Apple localization
+experts is that the total drag of these factors on programmers is such that they
+tend to reach for `String(format:)` instead.
+
+#### String Interpolation
+
+Swift string interpolation provides a user-friendly alternative to printf's
+domain-specific language (just write ordinary swift code!) and its type safety
+problems (put the data right where it belongs!) but the following issues prevent
+it from being useful for localized formatting (among other jobs):
+
+  * [SR-2303](https://bugs.swift.org/browse/SR-2303) We are unable to restrict
+    types used in string interpolation.
+  * [SR-1260](https://bugs.swift.org/browse/SR-1260) String interpolation can't
+    distinguish (fragments of) the base string from the string substitutions.
+
+In the long run, we should improve Swift string interpolation to the point where
+it can participate in most any formatting job.  Mostly this centers around
+fixing the interpolation protocols per the previous item, and supporting
+localization.
+
+To be able to use formatting effectively inside interpolations, it needs to be
+both lightweight (because it all happens in-situ) and discoverable.  One 
+approach would be to standardize on `format` methods, e.g.:
+
+```swift
+"Column 1: \(n.format(radix:16, width:8)) *** \(message)"
+
+"Something with leading zeroes: \(x.format(fill: zero, width:8))"
+```
+
+### C String Interop
+
+Our support for interoperation with nul-terminated C strings is scattered and
+incoherent, with 6 ways to transform a C string into a `String` and four ways to
+do the inverse.  These APIs should be replaced with the following
+
+```swift
+extension String {
+  /// Constructs a `String` having the same contents as `nulTerminatedUTF8`.
+  ///
+  /// - Parameter nulTerminatedUTF8: a sequence of contiguous UTF-8 encoded 
+  ///   bytes ending just before the first zero byte (NUL character).
+  init(cString nulTerminatedUTF8: UnsafePointer<CChar>)
+  
+  /// Constructs a `String` having the same contents as `nulTerminatedCodeUnits`.
+  ///
+  /// - Parameter nulTerminatedCodeUnits: a sequence of contiguous code units in
+  ///   the given `encoding`, ending just before the first zero code unit.
+  /// - Parameter encoding: describes the encoding in which the code units
+  ///   should be interpreted.
+  init<Encoding: UnicodeEncoding>(
+    cString nulTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>,
+    encoding: Encoding)
+    
+  /// Invokes the given closure on the contents of the string, represented as a
+  /// pointer to a null-terminated sequence of UTF-8 code units.
+  func withCString<Result>(
+    _ body: (UnsafePointer<CChar>) throws -> Result) rethrows -> Result
+}
+```
+
+In both of the construction APIs, any invalid encoding sequence detected will
+have its longest valid prefix replaced by U+FFFD, the Unicode replacement
+character, per Unicode specification.  This covers the common case.  The
+replacement is done *physically* in the underlying storage and the validity of
+the result is recorded in the `String`'s `encoding` such that future accesses
+need not be slowed down by possible error repair separately.
+
+Construction that is aborted when encoding errors are detected can be
+accomplished using APIs on the `encoding`.  String types that retain their
+physical encoding even in the presence of errors and are repaired on-the-fly can
+be built as different instances of the `Unicode` protocol.
+
+### Unicode 9 Conformance
+
+Unicode 9 (and MacOS 10.11) brought us support for family emoji, which changes
+the process of properly identifying `Character` boundaries.  We need to update
+`String` to account for this change.
+
+### High-Performance String Processing
+
+Many strings are short enough to store in 64 bits, many can be stored using only
+8 bits per unicode scalar, others are best encoded in UTF-16, and some come to
+us already in some other encoding, such as UTF-8, that would be costly to
+translate.  Supporting these formats while maintaining usability for
+general-purpose APIs demands that a single `String` type can be backed by many
+different representations.
+
+That said, the highest performance code always requires static knowledge of the
+data structures on which it operates, and for this code, dynamic selection of
+representation comes at too high a cost.  Heavy-duty text processing demands a
+way to opt out of dynamism and directly use known encodings.  Having this
+ability can also make it easy to cleanly specialize code that handles dynamic
+cases for maximal efficiency on the most common representations.
+
+To address this need, we can build models of the `Unicode` protocol that encode
+representation information into the type, such as `NFCNormalizedUTF16String`.
+
+### Parsing ASCII Structure
+
+Although many machine-readable formats support the inclusion of arbitrary
+Unicode text, it is also common that their fundamental structure lies entirely
+within the ASCII subset (JSON, YAML, many XML formats).  These formats are often
+processed most efficiently by recognizing ASCII structural elements as ASCII,
+and capturing the arbitrary sections between them in more-general strings.  The
+current String API offers no way to efficiently recognize ASCII and skip past
+everything else without the overhead of full decoding into unicode scalars.
+
+For these purposes, strings should supply an `extendedASCII` view that is a
+collection of `UInt32`, where values less than `0x80` represent the
+corresponding ASCII character, and other values represent data that is specific
+to the underlying encoding of the string.
+
+## Language Support
+
+This proposal depends on two new features in the Swift language:
+
+1. **Generic subscripts**, to
+   enable [unified slicing syntax](#unification-of-slicing-operations).
+
+2. **A [subtype relationship](#different-type-shared-storage)** between
+   `Substring` and `String`, enabling framework APIs to traffic solely in
+   `String` while still making it possible to avoid copies by handling
+   `Substring`s where necessary.
+
+Additionally, **the ability to nest types and protocols inside
+protocols** could significantly shrink the footprint of this proposal
+on the top-level Swift namespace.
+
+
+## Open Questions
+
+### Must `String` be limited to storing UTF-16 subset encodings?
+
+- The ability to handle `UTF-8`-encoded strings (models of `Unicode`) is not in
+  question here; this is about what encodings must be storable, without
+  transcoding, in the common currency type called "`String`".
+- ASCII, Latin-1, UCS-2, and UTF-16 are UTF-16 subsets.  UTF-8 is not.
+- If we have a way to get at a `String`'s code units, we need a concrete type in
+  which to express them in the API of `String`, which is a concrete type
+- If String needs to be able to represent UTF-32, presumably the code units need
+  to be `UInt32`.
+- Not supporting UTF-32-encoded text seems like one reasonable design choice.
+- Maybe we can allow UTF-8 storage in `String` and expose its code units as
+  `UInt16`, just as we would for Latin-1.
+- Supporting only UTF-16-subset encodings would imply that `String` indices can
+  be serialized without recording the `String`'s underlying encoding.
+
+### Do we need a type-erasable base protocol for UnicodeEncoding?
+
+UnicodeEncoding has an associated type, but it may be important to be able to
+traffic in completely dynamic encoding values, e.g. for "tell me the most
+efficient encoding for this string."
+
+### Should there be a string "facade?"
+
+One possible design alternative makes `Unicode` a vehicle for expressing
+the storage and encoding of code units, but does not attempt to give it an API
+appropriate for `String`.  Instead, string APIs would be provided by a generic
+wrapper around an instance of `Unicode`:
+
+```swift
+struct StringFacade<U: Unicode> : BidirectionalCollection {
+
+  // ...APIs for high-level string processing here...
+  
+  var unicode: U // access to lower-level unicode details
+}
+
+typealias String = StringFacade<StringStorage>
+typealias Substring = StringFacade<StringStorage.SubSequence>
+```
+
+This design would allow us to de-emphasize lower-level `String` APIs such as
+access to the specific encoding, by putting them behind a `.unicode` property.
+A similar effect in a facade-less design would require a new top-level
+`StringProtocol` playing the role of the facade with an an `associatedtype
+Storage : Unicode`.
+
+An interesting variation on this design is possible if defaulted generic
+parameters are introduced to the language:
+
+```swift
+struct String<U: Unicode = StringStorage> 
+  : BidirectionalCollection {
+
+  // ...APIs for high-level string processing here...
+  
+  var unicode: U // access to lower-level unicode details
+}
+
+typealias Substring = String<StringStorage.SubSequence>
+```
+
+One advantage of such a design is that naïve users will always extend "the right
+type" (`String`) without thinking, and the new APIs will show up on `Substring`,
+`MyUTF8String`, etc.  That said, it also has downsides that should not be
+overlooked, not least of which is the confusability of the meaning of the word
+"string."  Is it referring to the generic or the concrete type?
+
+### `TextOutputStream` and `TextOutputStreamable`
+
+`TextOutputStreamable` is intended to provide a vehicle for
+efficiently transporting formatted representations to an output stream
+without forcing the allocation of storage.  Its use of `String`, a
+type with multiple representations, at the lowest-level unit of
+communication, conflicts with this goal.  It might be sufficient to
+change `TextOutputStream` and `TextOutputStreamable` to traffic in an
+associated type conforming to `Unicode`, but that is not yet clear.
+This area will require some design work.
+
+### `description` and `debugDescription`
+
+* Should these be creating localized or non-localized representations?
+* Is returning a `String` efficient enough?
+* Is `debugDescription` pulling the weight of the API surface area it adds?
+
+### `StaticString`
+
+`StaticString` was added as a byproduct of standard library development and kept
+around because it seemed useful, but it was never truly *designed* for client
+programmers.  We need to decide what happens with it.  Presumably *something*
+should fill its role, and that should conform to `Unicode`.
+
+## Footnotes
+
+<b id="f0">0</b> The integers rewrite currently underway is expected to
+    substantially reduce the scope of `Int`'s API by using more
+    generics. [↩](#a0)
+
+<b id="f1">1</b> In practice, these semantics will usually be tied to the
+version of the installed [ICU](http://icu-project.org) library, which
+programmatically encodes the most complex rules of the Unicode Standard and its
+de-facto extension, CLDR.[↩](#a1)
+
+<b id="f2">2</b>
+See
+[http://unicode.org/reports/tr29/#Notation](http://unicode.org/reports/tr29/#Notation). Note
+that inserting Unicode scalar values to prevent merging of grapheme clusters would
+also constitute a kind of misbehavior (one of the clusters at the boundary would
+not be found in the result), so would be relatively costly to implement, with
+little benefit. [↩](#a2)
+
+<b id="f4">4</b> The use of non-UCA-compliant ordering is fully sanctioned by
+  the Unicode standard for this purpose.  In fact there's
+  a [whole chapter](http://www.unicode.org/versions/Unicode9.0.0/ch05.pdf)
+  dedicated to it.  In particular, §5.17 says:
+
+  > When comparing text that is visible to end users, a correct linguistic sort
+  > should be used, as described in _Section 5.16, Sorting and
+  > Searching_. However, in many circumstances the only requirement is for a
+  > fast, well-defined ordering. In such cases, a binary ordering can be used.
+
+  [↩](#a4)
+
+
+<b id="f5">5</b> The queries supported by `NSCharacterSet` map directly onto
+properties in a table that's indexed by unicode scalar value.  This table is
+part of the Unicode standard.  Some of these queries (e.g., "is this an
+uppercase character?") may have fairly obvious generalizations to grapheme
+clusters, but exactly how to do it is a research topic and *ideally* we'd either
+establish the existing practice that the Unicode committee would standardize, or
+the Unicode committee would do the research and we'd implement their
+result.[↩](#a5)
+
+<!-- Local Variables: -->
+<!-- eval: (buffer-face-mode 1) -->
+<!-- auto-fill-inhibit-regexp: ".*|.*" -->
+<!-- End: -->
diff --git a/docs/Windows.md b/docs/Windows.md
index aff99dd..f6dfb38 100644
--- a/docs/Windows.md
+++ b/docs/Windows.md
@@ -174,7 +174,7 @@
 ### 4. Upgrade CMake
 Install the latest version of CMake - Swift uses new CMake features such as `IN_LIST` and won't build without these features.
 ```bash
-wget http://www.cmake.org/files/v3.5/cmake-3.6.2.tar.gz
+wget http://www.cmake.org/files/v3.6/cmake-3.6.2.tar.gz
 tar xf cmake-3.6.2.tar.gz
 cd cmake-3.6.2
 ./configure
diff --git a/docs/proposals/Concurrency.rst b/docs/proposals/Concurrency.rst
index d22d5bf..0e34b05 100644
--- a/docs/proposals/Concurrency.rst
+++ b/docs/proposals/Concurrency.rst
@@ -370,7 +370,7 @@
 
 Stream utilities
 ----------------
-The Swift library can to implement a few utilities that will allow users and
+The Swift library can implement a few utilities that will allow users and
 library designers to build cool things:
 
 *  The ``Funnel`` class accepts multiple incoming streams and weaves them into a
diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h
index f916ad9..09b8838 100644
--- a/include/swift/AST/ASTContext.h
+++ b/include/swift/AST/ASTContext.h
@@ -20,7 +20,6 @@
 #include "llvm/Support/DataTypes.h"
 #include "swift/AST/ClangModuleLoader.h"
 #include "swift/AST/Identifier.h"
-#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/SearchPathOptions.h"
 #include "swift/AST/Type.h"
 #include "swift/AST/TypeAlignments.h"
@@ -43,6 +42,7 @@
 namespace clang {
   class Decl;
   class MacroInfo;
+  class Module;
   class ObjCInterfaceDecl;
 }
 
@@ -58,11 +58,16 @@
   class ForeignRepresentationInfo;
   class FuncDecl;
   class InFlightDiagnostic;
+  class IterableDeclContext;
   class LazyAbstractFunctionData;
+  class LazyGenericTypeData;
+  class LazyContextData;
+  class LazyMemberLoader;
   class LazyIterableDeclContextData;
   class LazyResolver;
   class PatternBindingDecl;
   class PatternBindingInitializer;
+  class SourceFile;
   class SourceLoc;
   class Type;
   class TypeVariableType;
@@ -75,6 +80,12 @@
   class ModuleDecl;
   class ModuleLoader;
   class NominalTypeDecl;
+  class NormalProtocolConformance;
+  class InheritedProtocolConformance;
+  class SpecializedProtocolConformance;
+  enum class ProtocolConformanceState;
+  class Pattern;
+  enum PointerTypeKind : unsigned;
   class PrecedenceGroupDecl;
   class TupleTypeElt;
   class EnumElementDecl;
@@ -86,8 +97,11 @@
   class DiagnosticEngine;
   class Substitution;
   class TypeCheckerDebugConsumer;
+  struct RawComment;
   class DocComment;
   class SILBoxType;
+  class TypeAliasDecl;
+  class VarDecl;
 
   enum class KnownProtocolKind : uint8_t;
 
diff --git a/include/swift/AST/ArchetypeBuilder.h b/include/swift/AST/ArchetypeBuilder.h
index 5404485..9914458 100644
--- a/include/swift/AST/ArchetypeBuilder.h
+++ b/include/swift/AST/ArchetypeBuilder.h
@@ -574,6 +574,9 @@
   PotentialArchetype *getNestedType(Identifier Name,
                                     ArchetypeBuilder &builder);
 
+  /// \brief Retrieve (or create) a nested type with a known associated type.
+  PotentialArchetype *getNestedType(AssociatedTypeDecl *assocType,
+                                    ArchetypeBuilder &builder);
 
   /// \brief Retrieve (or build) the type corresponding to the potential
   /// archetype within the given generic environment.
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index 1a040e7..2e7739e 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -28,6 +28,7 @@
 #include "swift/AST/KnownProtocols.h"
 #include "swift/AST/Ownership.h"
 #include "swift/AST/PlatformKind.h"
+#include "swift/AST/Requirement.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -40,6 +41,8 @@
 struct PrintOptions;
 class Decl;
 class ClassDecl;
+class GenericFunctionType;
+class TrailingWhereClause;
 struct TypeLoc;
 
 /// TypeAttributes - These are attributes that may be applied to types.
@@ -310,7 +313,8 @@
 
   /// Prints this attribute (if applicable), returning `true` if anything was
   /// printed.
-  bool printImpl(ASTPrinter &Printer, const PrintOptions &Options) const;
+  bool printImpl(ASTPrinter &Printer, const PrintOptions &Options,
+                 const Decl *D = nullptr) const;
 
 public:
   DeclAttrKind getKind() const {
@@ -340,10 +344,11 @@
   }
 
   /// Print the attribute to the provided ASTPrinter.
-  void print(ASTPrinter &Printer, const PrintOptions &Options) const;
+  void print(ASTPrinter &Printer, const PrintOptions &Options,
+             const Decl *D = nullptr) const;
 
   /// Print the attribute to the provided stream.
-  void print(llvm::raw_ostream &OS) const;
+  void print(llvm::raw_ostream &OS, const Decl *D = nullptr) const;
 
   /// Returns true if this attribute can appear on the specified decl.  This is
   /// controlled by the flags in Attr.def.
@@ -584,15 +589,18 @@
                    PlatformKind Platform,
                    StringRef Message, StringRef Rename,
                    const clang::VersionTuple &Introduced,
+                   SourceRange IntroducedRange,
                    const clang::VersionTuple &Deprecated,
+                   SourceRange DeprecatedRange,
                    const clang::VersionTuple &Obsoleted,
+                   SourceRange ObsoletedRange,
                    PlatformAgnosticAvailabilityKind PlatformAgnostic,
                    bool Implicit)
     : DeclAttribute(DAK_Available, AtLoc, Range, Implicit),
       Message(Message), Rename(Rename),
-      INIT_VER_TUPLE(Introduced),
-      INIT_VER_TUPLE(Deprecated),
-      INIT_VER_TUPLE(Obsoleted),
+      INIT_VER_TUPLE(Introduced), IntroducedRange(IntroducedRange),
+      INIT_VER_TUPLE(Deprecated), DeprecatedRange(DeprecatedRange),
+      INIT_VER_TUPLE(Obsoleted), ObsoletedRange(ObsoletedRange),
       PlatformAgnostic(PlatformAgnostic),
       Platform(Platform)
   {}
@@ -613,12 +621,21 @@
   /// Indicates when the symbol was introduced.
   const Optional<clang::VersionTuple> Introduced;
 
+  /// Indicates where the Introduced version was specified.
+  const SourceRange IntroducedRange;
+
   /// Indicates when the symbol was deprecated.
   const Optional<clang::VersionTuple> Deprecated;
 
+  /// Indicates where the Deprecated version was specified.
+  const SourceRange DeprecatedRange;
+
   /// Indicates when the symbol was obsoleted.
   const Optional<clang::VersionTuple> Obsoleted;
 
+  /// Indicates where the Obsoleted version was specified.
+  const SourceRange ObsoletedRange;
+
   /// Indicates if the declaration has platform-agnostic availability.
   const PlatformAgnosticAvailabilityKind PlatformAgnostic;
 
@@ -1027,27 +1044,66 @@
 /// The @_specialize attribute, which forces specialization on the specified
 /// type list.
 class SpecializeAttr : public DeclAttribute {
-  unsigned numTypes;
-  ConcreteDeclRef specializedDecl;
+public:
+  enum class SpecializationKind {
+    Full,
+    Partial
+  };
 
-  TypeLoc *getTypeLocData() {
-    return reinterpret_cast<TypeLoc *>(this + 1);
+private:
+  unsigned numRequirements;
+  TrailingWhereClause *trailingWhereClause;
+  SpecializationKind kind;
+  bool exported;
+
+  Requirement *getRequirementsData() {
+    return reinterpret_cast<Requirement *>(this+1);
   }
 
   SpecializeAttr(SourceLoc atLoc, SourceRange Range,
-                 ArrayRef<TypeLoc> typeLocs);
+                 TrailingWhereClause *clause, bool exported,
+                 SpecializationKind kind);
+
+  SpecializeAttr(SourceLoc atLoc, SourceRange Range,
+                 ArrayRef<Requirement> requirements,
+                 bool exported,
+                 SpecializationKind kind);
 
 public:
   static SpecializeAttr *create(ASTContext &Ctx, SourceLoc atLoc,
-                                SourceRange Range, ArrayRef<TypeLoc> typeLocs);
+                                SourceRange Range, TrailingWhereClause *clause,
+                                bool exported, SpecializationKind kind);
 
-  ArrayRef<TypeLoc> getTypeLocs() const;
+  static SpecializeAttr *create(ASTContext &Ctx, SourceLoc atLoc,
+                                SourceRange Range,
+                                ArrayRef<Requirement> requirement,
+                                bool exported, SpecializationKind kind);
 
-  MutableArrayRef<TypeLoc> getTypeLocs();
+  TrailingWhereClause *getTrailingWhereClause() const;
 
-  ConcreteDeclRef getConcreteDecl() const { return specializedDecl; }
+  ArrayRef<Requirement> getRequirements() const;
 
-  void setConcreteDecl(ConcreteDeclRef ref) { specializedDecl = ref; }
+  MutableArrayRef<Requirement> getRequirements() {
+    return { getRequirementsData(), numRequirements };
+  }
+
+  void setRequirements(ASTContext &Ctx, ArrayRef<Requirement> requirements);
+
+  bool isExported() const {
+    return exported;
+  }
+
+  SpecializationKind getSpecializationKind() const {
+    return kind;
+  }
+
+  bool isFullSpecialization() const {
+    return kind == SpecializationKind::Full;
+  }
+
+  bool isPartialSpecialization() const {
+    return kind == SpecializationKind::Partial;
+  }
 
   static bool classof(const DeclAttribute *DA) {
     return DA->getKind() == DAK_Specialize;
@@ -1101,8 +1157,9 @@
   /// a declaration is deprecated on all deployment targets, or null otherwise.
   const AvailableAttr *getDeprecated(const ASTContext &ctx) const;
 
-  void dump() const;
-  void print(ASTPrinter &Printer, const PrintOptions &Options) const;
+  void dump(const Decl *D = nullptr) const;
+  void print(ASTPrinter &Printer, const PrintOptions &Options,
+             const Decl *D = nullptr) const;
 
   template <typename T, typename DERIVED>
   class iterator_base : public std::iterator<std::forward_iterator_tag, T *> {
diff --git a/include/swift/AST/Builtins.h b/include/swift/AST/Builtins.h
index bfc31ae..5380db2 100644
--- a/include/swift/AST/Builtins.h
+++ b/include/swift/AST/Builtins.h
@@ -82,7 +82,7 @@
 /// Given an LLVM IR intrinsic name with argument types remove (e.g. like
 /// "bswap") return the LLVM IR IntrinsicID for the intrinsic or 0 if the
 /// intrinsic name doesn't match anything.
-unsigned getLLVMIntrinsicID(StringRef Name, bool HasArgTypes);
+unsigned getLLVMIntrinsicID(StringRef Name);
 
 /// Get the LLVM intrinsic ID that corresponds to the given builtin with
 /// overflow.
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 24d01b7..3ce71bb 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -237,8 +237,12 @@
 
     /// \brief Whether this declaration is currently being validated.
     unsigned BeingValidated : 1;
+
+    /// \brief Whether this declaration was added to the surrounding
+    /// DeclContext of an active #if config clause.
+    unsigned EscapedFromIfConfig : 1;
   };
-  enum { NumDeclBits = 11 };
+  enum { NumDeclBits = 12 };
   static_assert(NumDeclBits <= 32, "fits in an unsigned");
 
   class PatternBindingDeclBitfields {
@@ -649,6 +653,7 @@
     DeclBits.FromClang = false;
     DeclBits.EarlyAttrValidation = false;
     DeclBits.BeingValidated = false;
+    DeclBits.EscapedFromIfConfig = false;
   }
 
   ClangNode getClangNodeImpl() const {
@@ -806,6 +811,14 @@
     DeclBits.BeingValidated = ibv;
   }
 
+  bool escapedFromIfConfig() const {
+    return DeclBits.EscapedFromIfConfig;
+  }
+
+  void setEscapedFromIfConfig(bool Escaped) {
+    DeclBits.EscapedFromIfConfig = Escaped;
+  }
+
   /// \returns the unparsed comment attached to this declaration.
   RawComment getRawComment() const;
 
@@ -982,7 +995,7 @@
   /// \brief Construct a new layout-constraint requirement.
   ///
   /// \param Subject The type that must conform to the given layout 
-  /// requirment.
+  /// requirement.
   /// \param ColonLoc The location of the ':', or an invalid location if
   /// this requirement was implied.
   /// \param Layout The layout requirement to which the
@@ -5387,9 +5400,6 @@
   /// object by delegating to another initializer (eventually reaching a
   /// designated initializer).
   ///
-  /// A convenience initializer is written with a return type of "Self" in
-  /// source code.
-  ///
   /// Convenience initializers are inherited into subclasses that override
   /// all of their superclass's designated initializers.
   Convenience,
diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def
index f1adcb7..65d061a 100644
--- a/include/swift/AST/DiagnosticsDriver.def
+++ b/include/swift/AST/DiagnosticsDriver.def
@@ -44,8 +44,10 @@
 
 ERROR(error_unable_to_execute_command,none,
       "unable to execute command: %0", (StringRef))
-ERROR(error_command_signalled,none,
+ERROR(error_command_signalled_without_signal_number,none,
       "%0 command failed due to signal (use -v to see invocation)", (StringRef))
+ERROR(error_command_signalled,none,
+      "%0 command failed due to signal %1 (use -v to see invocation)", (StringRef, int))
 ERROR(error_command_failed,none,
       "%0 command failed with exit code %1 (use -v to see invocation)",
       (StringRef, int))
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 1d9583f..3cc5824 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -699,6 +699,19 @@
       "expected '>' to complete SIL box generic argument list", ())
 
 //------------------------------------------------------------------------------
+// Layout constraint diagnostics
+//------------------------------------------------------------------------------
+
+ERROR(layout_size_should_be_positive,none,
+      "expected non-negative size to be specified in layout constraint", ())
+ERROR(layout_alignment_should_be_positive,none,
+      "expected non-negative alignment to be specified in layout constraint", ())
+ERROR(expected_rparen_layout_constraint,none,
+      "expected ')' to complete layout constraint", ())
+ERROR(layout_constraints_only_inside_specialize_attr,none,
+      "layout constraints are only allowed inside '_specialize' attributes", ())
+
+//------------------------------------------------------------------------------
 // Pattern parsing diagnostics
 //------------------------------------------------------------------------------
 
@@ -1305,6 +1318,28 @@
 ERROR(attr_escaping_conflicts_noescape,none,
       "@escaping conflicts with @noescape", ())
 
+// _specialize
+ERROR(attr_specialize_missing_colon,none,
+      "missing ':' after %0 in '_specialize' attribute", (StringRef))
+
+ERROR(attr_specialize_missing_comma,none,
+      "missing ',' in '_specialize' attribute", ())
+
+ERROR(attr_specialize_unknown_parameter_name,none,
+      "unknown parameter %0 in '_specialize attribute'", (StringRef))
+
+ERROR(attr_specialize_expected_bool_value,none,
+      "expected a boolean true or false value in '_specialize' attribute", ())
+
+ERROR(attr_specialize_missing_parameter_label_or_where_clause,none,
+      "expected a parameter label or a where clause in '_specialize' attribute", ())
+
+ERROR(attr_specialize_parameter_already_defined,none,
+      "parameter '%0' was already defined in '_specialize' attribute", (StringRef))
+
+ERROR(attr_specialize_expected_partial_or_full,none,
+      "expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute", ())
+
 //------------------------------------------------------------------------------
 // Generics parsing diagnostics
 //------------------------------------------------------------------------------
@@ -1363,6 +1398,9 @@
       ())
 ERROR(unsupported_conditional_compilation_expression_type,none,
       "invalid conditional compilation expression", ())
+WARNING(swift3_unsupported_conditional_compilation_expression_type,none,
+        "ignoring invalid conditional compilation expression, "
+        "which will be rejected in future version of Swift", ())
 ERROR(unsupported_conditional_compilation_integer,none,
       "'%0' is not a valid conditional compilation expression, use '%1'",
       (StringRef, StringRef))
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 4ff67ad..e9de472 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1576,7 +1576,7 @@
       "superclass constraint %0 is recursive", (Type))
 ERROR(requires_same_type_conflict,none,
       "generic parameter %0 cannot be equal to both %1 and %2",
-      (Identifier, Type, Type))
+      (StringRef, Type, Type))
 ERROR(requires_generic_param_same_type_does_not_conform,none,
       "same-type constraint type %0 does not conform to required protocol %1",
       (Type, Identifier))
@@ -1707,6 +1707,12 @@
       "cannot override %select{strong|weak|unowned|unowned(unsafe)}0 property "
       "with %select{strong|weak|unowned|unowned(unsafe)}1 property",
       (/*Ownership*/unsigned, /*Ownership*/unsigned))
+ERROR(override_class_declaration_in_extension,none,
+      "cannot override a non-dynamic class declaration from an extension", 
+      ())
+WARNING(override_class_declaration_in_extension_warning,none,
+      "cannot override a non-dynamic class declaration from an extension",
+      ())
 ERROR(override_throws,none,
       "cannot override non-throwing %select{method|initializer}0 with "
       "throwing %select{method|initializer}0", (bool))
@@ -2342,8 +2348,6 @@
       "reference to generic type %0 requires arguments in <...>", (Type))
 NOTE(generic_type_declared_here,none,
      "generic type %0 declared here", (Identifier))
-ERROR(cannot_partially_specialize_generic_function,none,
-     "cannot partially specialize a generic function", ())
 
 WARNING(use_of_void_pointer,none,
 "Unsafe%0Pointer<Void> has been replaced by Unsafe%0RawPointer", (StringRef))
@@ -3137,6 +3141,11 @@
       OBJC_DIAG_SELECT " defines Objective-C class method %2, which is "
       "not permitted by Swift", (unsigned, DeclName, ObjCSelector))
 
+WARNING(objc_class_method_not_permitted_swift3_compat_warning,none,
+      OBJC_DIAG_SELECT " defines Objective-C class method %2, which is "
+      "not guaranteed to be invoked by Swift and will be disallowed in future "
+      "versions", (unsigned, DeclName, ObjCSelector))
+
 ERROR(objc_witness_selector_mismatch,none,
       "Objective-C method %2 provided by " OBJC_DIAG_SELECT
       " does not match the requirement's selector (%3)",
@@ -3316,11 +3325,20 @@
 // Resilience diagnostics
 //------------------------------------------------------------------------------
 
+ERROR(fixed_layout_attr_on_internal_type,
+      none, "'@_fixed_layout' attribute can only be applied to '@_versioned' "
+      "or public declarations, but %0 is "
+      "%select{private|fileprivate|internal|%error|%error}1",
+      (Identifier, Accessibility))
+
 ERROR(versioned_attr_with_explicit_accessibility,
       none, "'@_versioned' attribute can only be applied to internal "
       "declarations, but %0 is %select{private|fileprivate|%error|public|open}1",
       (Identifier, Accessibility))
 
+ERROR(versioned_attr_in_protocol,none,
+      "'@_versioned' attribute cannot be used in protocols", ())
+
 #define FRAGILE_FUNC_KIND \
   "%select{a '@_transparent' function|" \
   "an '@inline(__always)' function|" \
@@ -3336,10 +3354,48 @@
       "cannot be referenced from " FRAGILE_FUNC_KIND "3",
       (DescriptiveDeclKind, DeclName, Accessibility, unsigned))
 
+#undef FRAGILE_FUNC_KIND
+
 NOTE(resilience_decl_declared_here,
      none, "%0 %1 is not '@_versioned' or public", (DescriptiveDeclKind, DeclName))
 
-#undef FRAGILE_FUNC_KIND
+ERROR(designated_init_in_extension_resilient,none,
+      "initializer declared in an extension of "
+      "non-'@_fixed_layout' type %0 must delegate to another initializer", (Type))
+
+ERROR(designated_init_inlineable_resilient,none,
+      "initializer of non-'@_fixed_layout' type %0 is "
+      "'%select{@_transparent|@inline(__always)|@_inlineable|%error}1' and must "
+      "delegate to another initializer", (Type, unsigned))
+
+//------------------------------------------------------------------------------
+// @_specialize diagnostics
+//------------------------------------------------------------------------------
+
+ERROR(specialize_attr_nongeneric_trailing_where,none,
+      "trailing 'where' clause in '_specialize' attribute of non-generic function %0", (Identifier))
+ERROR(specialize_missing_where_clause,none,
+      "missing 'where' clause in '_specialize' attribute", ())
+ERROR(specialize_empty_where_clause,none,
+      "empty 'where' clause in '_specialize' attribute", ())
+ERROR(specialize_attr_non_concrete_same_type_req,none,
+      "Only concrete type same-type requirements are supported by '_specialize' attribute", ())
+ERROR(specialize_attr_only_generic_param_req,none,
+      "Only requirements on generic parameters are supported by '_specialize' attribute", ())
+ERROR(specialize_attr_only_one_concrete_same_type_req,none,
+      "Only one concrete type should be used in the same-type requirement in '_specialize' attribute", ())
+ERROR(specialize_attr_non_nominal_type_constraint_req,none,
+      "Only conformances to nominal types are supported by '_specialize' attribute", ())
+ERROR(specialize_attr_non_protocol_type_constraint_req,none,
+      "Only conformances to protocol types are supported by '_specialize' attribute", ())
+ERROR(specialize_attr_type_parameter_count_mismatch,none,
+      "%select{too many|too few}2 type parameters are specified "
+      "in '_specialize' attribute (got %1, but expected %0)",
+      (unsigned, unsigned, bool))
+ERROR(specialize_attr_missing_constraint,none,
+      "Missing constraint for %0 in '_specialize' attribute", (DeclName))
+ERROR(specialize_attr_unsupported_kind_of_req,none,
+      "Only same-type and layout requirements are supported by '_specialize' attribute", ())
 
 //------------------------------------------------------------------------------
 // Variable usage diagnostics
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index 7785788..1edf677 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -25,6 +25,7 @@
 #include "swift/AST/TypeAlignments.h"
 #include "swift/AST/TypeLoc.h"
 #include "swift/AST/Availability.h"
+#include "swift/Basic/Compiler.h"
 #include "llvm/Support/TrailingObjects.h"
 
 namespace llvm {
@@ -671,30 +672,15 @@
     return *static_cast<const Derived *>(this);
   }
 
-  // Work around MSVC bug: can't infer llvm::trailing_objects_internal,
-  // even though we granted friend access to it.
   size_t numTrailingObjects(
-#if defined(_MSC_VER) && !defined(__clang__)
-      llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken<
-      Identifier>) const {
-#else
-      typename TrailingObjects::template OverloadToken<Identifier>) const {
-#endif
+      SWIFT_TRAILING_OBJECTS_OVERLOAD_TOKEN(Identifier)) const {
     return asDerived().getNumArguments();
   }
 
-  // Work around MSVC bug: can't infer llvm::trailing_objects_internal,
-  // even though we granted friend access to it.
   size_t numTrailingObjects(
-#if defined(_MSC_VER) && !defined(__clang__)
-      llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken<
-      SourceLoc>) const {
-#else
-      typename TrailingObjects::template OverloadToken<SourceLoc>) const {
-#endif
-    return asDerived().hasArgumentLabelLocs()
-             ? asDerived().getNumArguments()
-             : 0;
+      SWIFT_TRAILING_OBJECTS_OVERLOAD_TOKEN(SourceLoc)) const {
+    return asDerived().hasArgumentLabelLocs() ? asDerived().getNumArguments()
+                                              : 0;
   }
 
   /// Retrieve the buffer containing the argument labels.
diff --git a/include/swift/AST/ExprNodes.def b/include/swift/AST/ExprNodes.def
index f48e69d..caa4eee 100644
--- a/include/swift/AST/ExprNodes.def
+++ b/include/swift/AST/ExprNodes.def
@@ -40,7 +40,7 @@
 #define UNCHECKED_EXPR(Id, Parent) EXPR(Id, Parent)
 #endif
 
-/// An literal expression node represents a literal value, such as a number,
+/// A literal expression node represents a literal value, such as a number,
 /// boolean, string, etc.
 ///
 /// By default, these are treated like any other expression.
diff --git a/include/swift/AST/GenericEnvironment.h b/include/swift/AST/GenericEnvironment.h
index 15db6ad..d6b1ad6 100644
--- a/include/swift/AST/GenericEnvironment.h
+++ b/include/swift/AST/GenericEnvironment.h
@@ -224,6 +224,10 @@
   /// Get the sugared form of a generic parameter type.
   GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const;
 
+  /// Get the sugared form of a type by substituting any
+  /// generic parameter types by their sugared form.
+  Type getSugaredType(Type type) const;
+
   /// Derive a contextual type substitution map from a substitution array.
   /// This is just like GenericSignature::getSubstitutionMap(), except
   /// with contextual types instead of interface types.
diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def
index c6fc040..46e21dc 100644
--- a/include/swift/AST/KnownIdentifiers.def
+++ b/include/swift/AST/KnownIdentifiers.def
@@ -43,6 +43,7 @@
 IDENTIFIER(fromRaw)
 IDENTIFIER(hashValue)
 IDENTIFIER(init)
+IDENTIFIER(initialize)
 IDENTIFIER(initStorage)
 IDENTIFIER(initialValue)
 IDENTIFIER(Key)
diff --git a/include/swift/AST/LayoutConstraint.h b/include/swift/AST/LayoutConstraint.h
index 1595967..9fa8753 100644
--- a/include/swift/AST/LayoutConstraint.h
+++ b/include/swift/AST/LayoutConstraint.h
@@ -5,8 +5,8 @@
 // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
-// See http://swift.org/LICENSE.txt for license information
-// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
 //
@@ -48,7 +48,7 @@
 /// This is a class representing the layout constraint.
 class LayoutConstraintInfo {
   // Alignment of the layout in bytes.
-  unsigned Alignment;
+  unsigned Alignment : 16;
   // Size of the layout in bits.
   unsigned SizeInBits : 24;
   // Kind of the layout.
@@ -223,7 +223,7 @@
 }
 
 /// LayoutConstraintLoc - Provides source location information for a
-/// parsed layout constaint.
+/// parsed layout constraint.
 struct LayoutConstraintLoc {
 private:
   LayoutConstraint Layout;
@@ -258,7 +258,7 @@
 /// Checks if ID is a name of a layout constraint and returns this
 /// constraint. If ID does not match any known layout constraint names,
 /// returns UnknownLayout.
-LayoutConstraintInfo getLayoutConstraintInfo(Identifier ID);
+LayoutConstraintInfo getLayoutConstraintInfo(Identifier ID, ASTContext &Ctx);
 
 } // end namespace swift
 
diff --git a/include/swift/AST/ProtocolConformance.h b/include/swift/AST/ProtocolConformance.h
index 1c2c247..4069fcb 100644
--- a/include/swift/AST/ProtocolConformance.h
+++ b/include/swift/AST/ProtocolConformance.h
@@ -612,7 +612,7 @@
     // some crazy cases that also require major diagnostic work, where the
     // substitutions involve conformances of the same type to the same
     // protocol drawn from different imported modules.
-    ID.AddPointer(type->getCanonicalType().getPointer());
+    ID.AddPointer(type.getPointer());
     ID.AddPointer(genericConformance);
   }
 
diff --git a/include/swift/AST/SubstitutionMap.h b/include/swift/AST/SubstitutionMap.h
index 637206e..971d2f6 100644
--- a/include/swift/AST/SubstitutionMap.h
+++ b/include/swift/AST/SubstitutionMap.h
@@ -43,7 +43,7 @@
   using ParentType = std::pair<CanType, AssociatedTypeDecl *>;
 
   llvm::DenseMap<SubstitutableType *, Type> subMap;
-  llvm::DenseMap<TypeBase *, ArrayRef<ProtocolConformanceRef>> conformanceMap;
+  llvm::DenseMap<TypeBase *, SmallVector<ProtocolConformanceRef, 1>> conformanceMap;
   llvm::DenseMap<TypeBase *, SmallVector<ParentType, 1>> parentMap;
 
   Optional<ProtocolConformanceRef>
@@ -66,7 +66,7 @@
 
   void addSubstitution(CanSubstitutableType type, Type replacement);
 
-  void addConformances(CanType type, ArrayRef<ProtocolConformanceRef> conformances);
+  void addConformance(CanType type, ProtocolConformanceRef conformance);
 
   void addParent(CanType type, CanType parent,
                  AssociatedTypeDecl *assocType);
diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h
index dd4f4d1..16c0015 100644
--- a/include/swift/AST/Type.h
+++ b/include/swift/AST/Type.h
@@ -228,7 +228,7 @@
   /// If at any time the function returns a null type, the null will be
   /// propagated out.
   ///
-  /// If the the function returns \c None, the transform operation will
+  /// If the function returns \c None, the transform operation will
   ///
   /// \param fn A function object with the signature
   /// \c Optional<Type>(TypeBase *), which accepts a type pointer and returns a
diff --git a/include/swift/AST/TypeAlignments.h b/include/swift/AST/TypeAlignments.h
index f1daf65..f2ff1ed 100644
--- a/include/swift/AST/TypeAlignments.h
+++ b/include/swift/AST/TypeAlignments.h
@@ -22,7 +22,7 @@
 #ifndef SWIFT_TYPEALIGNMENTS_H
 #define SWIFT_TYPEALIGNMENTS_H
 
-#include "llvm/Support/AlignOf.h"
+#include <cstddef>
 
 namespace swift {
   class AbstractStorageDecl;
@@ -101,7 +101,6 @@
 LLVM_DECLARE_TYPE_ALIGNMENT(swift::GenericEnvironment,
                             swift::DeclAlignInBits)
 
-static_assert(llvm::AlignOf<void*>::Alignment >= 2,
-              "pointer alignment is too small");
+static_assert(alignof(void*) >= 2, "pointer alignment is too small");
 
 #endif
diff --git a/include/swift/AST/TypeRefinementContext.h b/include/swift/AST/TypeRefinementContext.h
index 3300b14..9239ac1 100644
--- a/include/swift/AST/TypeRefinementContext.h
+++ b/include/swift/AST/TypeRefinementContext.h
@@ -225,7 +225,16 @@
   /// or an invalid location if the context reflects the minimum deployment
   // target.
   SourceLoc getIntroductionLoc() const;
-  
+
+  /// Returns the source range covering a _single_ decl-attribute or statement
+  /// condition that introduced the refinement context for a given platform
+  /// version; if zero or multiple such responsible attributes or statements
+  /// exist, returns an invalid SourceRange.
+  SourceRange
+  getAvailabilityConditionVersionSourceRange(
+      PlatformKind Platform,
+      const clang::VersionTuple &Version) const;
+
   /// Returns the source range on which this context refines types.
   SourceRange getSourceRange() const { return SrcRange; }
 
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 3a59b46e..a28a10e 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -2936,7 +2936,9 @@
     return out;
   }
 
-  ValueOwnershipKind getOwnershipKind(SILModule &) const; // in SILType.cpp
+  ValueOwnershipKind
+  getOwnershipKind(SILModule &,
+                   CanGenericSignature sig = nullptr) const; // in SILType.cpp
 
   bool operator==(SILResultInfo rhs) const {
     return TypeAndConvention == rhs.TypeAndConvention;
diff --git a/include/swift/Basic/Compiler.h b/include/swift/Basic/Compiler.h
index 74a8df9..5772025 100644
--- a/include/swift/Basic/Compiler.h
+++ b/include/swift/Basic/Compiler.h
@@ -22,10 +22,19 @@
 #if SWIFT_COMPILER_IS_MSVC
 // Work around MSVC bug: attempting to reference a deleted function
 // https://connect.microsoft.com/VisualStudio/feedback/details/3116505
-#define SWIFT_DELETE_OPERATOR_DELETED                                                \
+#define SWIFT_DELETE_OPERATOR_DELETED                                          \
   { llvm_unreachable("Delete operator should not be called."); }
+
+// Work around MSVC bug: can't infer llvm::trailing_objects_internal,
+// even though we granted friend access to it.
+// https://connect.microsoft.com/VisualStudio/feedback/details/3116517
+#define SWIFT_TRAILING_OBJECTS_OVERLOAD_TOKEN(TokenType)                       \
+  llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken<TokenType>
 #else
 #define SWIFT_DELETE_OPERATOR_DELETED = delete;
+
+#define SWIFT_TRAILING_OBJECTS_OVERLOAD_TOKEN(TokenType)                       \
+  typename TrailingObjects::template OverloadToken<TokenType>
 #endif
 
 #endif // SWIFT_BASIC_COMPILER_H
diff --git a/include/swift/Basic/SourceManager.h b/include/swift/Basic/SourceManager.h
index 098f5df..7ad26d6 100644
--- a/include/swift/Basic/SourceManager.h
+++ b/include/swift/Basic/SourceManager.h
@@ -134,7 +134,7 @@
   /// Returns the identifier for the buffer with the given ID.
   ///
   /// \p BufferID must be a valid buffer ID.
-  const char *getIdentifierForBuffer(unsigned BufferID) const;
+  StringRef getIdentifierForBuffer(unsigned BufferID) const;
 
   /// \brief Returns a SourceRange covering the entire specified buffer.
   ///
@@ -167,9 +167,9 @@
   /// location.
   ///
   /// This respects #line directives.
-  const char *getBufferIdentifierForLoc(SourceLoc Loc) const {
+  StringRef getBufferIdentifierForLoc(SourceLoc Loc) const {
     if (auto VFile = getVirtualFile(Loc))
-      return VFile->Name.c_str();
+      return VFile->Name;
     else
       return getIdentifierForBuffer(findBufferContainingLoc(Loc));
   }
diff --git a/include/swift/Basic/TaskQueue.h b/include/swift/Basic/TaskQueue.h
index bd54711..9773db7 100644
--- a/include/swift/Basic/TaskQueue.h
+++ b/include/swift/Basic/TaskQueue.h
@@ -95,11 +95,15 @@
   /// available and SeparateErrors was true.  (This may not be available on all
   /// platforms.)
   /// \param Context the context which was passed when the task was added
+  /// \param Signal the terminating signal number, if available.
+  /// This may not be available on all platforms. If it is ever provided,
+  /// it should not be removed in future versions of the compiler.
   ///
   /// \returns a TaskFinishedResponse indicating whether or not execution
   /// should proceed
   typedef std::function<TaskFinishedResponse(ProcessId Pid, StringRef ErrorMsg,
-                                             StringRef Output, StringRef Errors, void *Context)>
+                                             StringRef Output, StringRef Errors,
+                                             void *Context, Optional<int> Signal)>
     TaskSignalledCallback;
 #pragma clang diagnostic pop
 
diff --git a/include/swift/Basic/Timer.h b/include/swift/Basic/Timer.h
index 1810efc..8558cd2 100644
--- a/include/swift/Basic/Timer.h
+++ b/include/swift/Basic/Timer.h
@@ -33,7 +33,8 @@
   public:
     explicit SharedTimer(StringRef name) {
       if (CompilationTimersEnabled == State::Enabled)
-        Timer.emplace(name, StringRef("Swift compilation"));
+        Timer.emplace(name, StringRef("Swift compilation"), StringRef("swift"),
+                      StringRef("swift related timers"));
       else
         CompilationTimersEnabled = State::Skipped;
     }
diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h
index 8ad9321..2a4f867 100644
--- a/include/swift/ClangImporter/ClangImporter.h
+++ b/include/swift/ClangImporter/ClangImporter.h
@@ -202,7 +202,7 @@
   /// \param trackParsedSymbols If true, tracks decls and macros that were
   ///        parsed from the bridging header.
   /// \param implicitImport If true, indicates that this import was implicit
-  ///        from a reference in a module file (deprecated behaviour).
+  ///        from a reference in a module file (deprecated behavior).
   ///
   /// \returns true if there was an error importing the header.
   ///
diff --git a/include/swift/Driver/Action.h b/include/swift/Driver/Action.h
index 95f3b7f..a4efd34 100644
--- a/include/swift/Driver/Action.h
+++ b/include/swift/Driver/Action.h
@@ -19,7 +19,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/Chrono.h"
 
 namespace llvm {
 namespace opt {
@@ -138,14 +138,14 @@
       NewlyAdded
     };
     Status status = UpToDate;
-    llvm::sys::TimeValue previousModTime;
+    llvm::sys::TimePoint<> previousModTime;
 
     InputInfo() = default;
-    InputInfo(Status stat, llvm::sys::TimeValue time)
+    InputInfo(Status stat, llvm::sys::TimePoint<> time)
         : status(stat), previousModTime(time) {}
 
     static InputInfo makeNewlyAdded() {
-      return InputInfo(Status::NewlyAdded, llvm::sys::TimeValue::MaxTime());
+      return InputInfo(Status::NewlyAdded, llvm::sys::TimePoint<>::max());
     }
   };
 
diff --git a/include/swift/Driver/Compilation.h b/include/swift/Driver/Compilation.h
index d03ba34..ef4db3e 100644
--- a/include/swift/Driver/Compilation.h
+++ b/include/swift/Driver/Compilation.h
@@ -23,7 +23,7 @@
 #include "swift/Basic/LLVM.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/Chrono.h"
 
 #include <memory>
 #include <vector>
@@ -99,12 +99,12 @@
   ///
   /// This should be as close as possible to when the driver was invoked, since
   /// it's used as a lower bound.
-  llvm::sys::TimeValue BuildStartTime;
+  llvm::sys::TimePoint<> BuildStartTime;
 
   /// The time of the last build.
   ///
   /// If unknown, this will be some time in the past.
-  llvm::sys::TimeValue LastBuildTime = llvm::sys::TimeValue::MinTime();
+  llvm::sys::TimePoint<> LastBuildTime = llvm::sys::TimePoint<>::min();
 
   /// The number of commands which this compilation should attempt to run in
   /// parallel.
@@ -145,7 +145,7 @@
               std::unique_ptr<llvm::opt::InputArgList> InputArgs,
               std::unique_ptr<llvm::opt::DerivedArgList> TranslatedArgs,
               InputFileList InputsWithTypes,
-              StringRef ArgsHash, llvm::sys::TimeValue StartTime,
+              StringRef ArgsHash, llvm::sys::TimePoint<> StartTime,
               unsigned NumberOfParallelCommands = 1,
               bool EnableIncrementalBuild = false,
               bool SkipTaskExecution = false,
@@ -199,7 +199,7 @@
     CompilationRecordPath = path;
   }
 
-  void setLastBuildTime(llvm::sys::TimeValue time) {
+  void setLastBuildTime(llvm::sys::TimePoint<> time) {
     LastBuildTime = time;
   }
 
diff --git a/include/swift/Driver/Job.h b/include/swift/Driver/Job.h
index db99907..6963f2a 100644
--- a/include/swift/Driver/Job.h
+++ b/include/swift/Driver/Job.h
@@ -23,7 +23,7 @@
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/Chrono.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <memory>
@@ -118,7 +118,7 @@
   FilelistInfo FilelistFileInfo;
 
   /// The modification time of the main input file, if any.
-  llvm::sys::TimeValue InputModTime = llvm::sys::TimeValue::MaxTime();
+  llvm::sys::TimePoint<> InputModTime = llvm::sys::TimePoint<>::max();
 
 public:
   Job(const JobAction &Source,
@@ -152,11 +152,11 @@
     SourceAndCondition.setInt(Cond);
   }
 
-  void setInputModTime(llvm::sys::TimeValue time) {
+  void setInputModTime(llvm::sys::TimePoint<> time) {
     InputModTime = time;
   }
 
-  llvm::sys::TimeValue getInputModTime() const {
+  llvm::sys::TimePoint<> getInputModTime() const {
     return InputModTime;
   }
 
diff --git a/include/swift/Driver/ParseableOutput.h b/include/swift/Driver/ParseableOutput.h
index d7904f2..d25b167 100644
--- a/include/swift/Driver/ParseableOutput.h
+++ b/include/swift/Driver/ParseableOutput.h
@@ -39,7 +39,7 @@
 
 /// \brief Emits a "signalled" message to the given stream.
 void emitSignalledMessage(raw_ostream &os, const Job &Cmd, ProcessId Pid,
-                          StringRef ErrorMsg, StringRef Output);
+                          StringRef ErrorMsg, StringRef Output, Optional<int> Signal);
 
 /// \brief Emits a "skipped" message to the given stream.
 void emitSkippedMessage(raw_ostream &os, const Job &Cmd);
diff --git a/include/swift/IDE/CodeCompletion.h b/include/swift/IDE/CodeCompletion.h
index b790215..0ad03c2 100644
--- a/include/swift/IDE/CodeCompletion.h
+++ b/include/swift/IDE/CodeCompletion.h
@@ -18,7 +18,6 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
-#include "llvm/Support/TimeValue.h"
 #include "llvm/Support/TrailingObjects.h"
 #include <functional>
 #include <memory>
diff --git a/include/swift/IDE/CodeCompletionCache.h b/include/swift/IDE/CodeCompletionCache.h
index 8187d61..f0b1d13 100644
--- a/include/swift/IDE/CodeCompletionCache.h
+++ b/include/swift/IDE/CodeCompletionCache.h
@@ -16,6 +16,7 @@
 #include "swift/IDE/CodeCompletion.h"
 #include "swift/Basic/ThreadSafeRefCounted.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/Chrono.h"
 #include <system_error>
 
 namespace swift {
@@ -53,7 +54,7 @@
   };
 
   struct Value : public llvm::ThreadSafeRefCountedBase<Value> {
-    llvm::sys::TimeValue ModuleModificationTime;
+    llvm::sys::TimePoint<> ModuleModificationTime;
     CodeCompletionResultSink Sink;
   };
   using ValueRefCntPtr = llvm::IntrusiveRefCntPtr<Value>;
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index eb773f4..22a72df 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -18,6 +18,7 @@
 #define SWIFT_PARSER_H
 
 #include "swift/AST/AST.h"
+#include "swift/AST/LayoutConstraint.h"
 #include "swift/AST/DiagnosticsParse.h"
 #include "swift/Basic/Fallthrough.h"
 #include "swift/Basic/OptionSet.h"
@@ -603,9 +604,8 @@
   bool parseMatchingToken(tok K, SourceLoc &TokLoc, Diag<> ErrorDiag,
                           SourceLoc OtherLoc);
 
-  /// \brief Parse the list of statements, expressions, or declarations.
+  /// \brief Parse a comma separated list of some elements.
   ParserStatus parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
-                         tok SeparatorK, bool OptionalSep,
                          bool AllowSepAfterLast, Diag<> ErrorDiag,
                          std::function<ParserStatus()> callback);
 
@@ -675,8 +675,8 @@
     return AlreadyHandledDecls.erase(D);
   }
 
-  ParserStatus parseDecl(ParseDeclOptions Flags,
-                         llvm::function_ref<void(Decl*)> Handler);
+  ParserResult<Decl> parseDecl(ParseDeclOptions Flags,
+                               llvm::function_ref<void(Decl*)> Handler);
 
   void parseDeclDelayed();
 
@@ -697,6 +697,12 @@
   bool parseDeclAttributeList(DeclAttributes &Attributes,
                               bool &FoundCodeCompletionToken);
 
+  /// Parse the @_specialize attribute.
+  /// \p closingBrace is the expected closing brace, which can be either ) or ]
+  /// \p Attr is where to store the parsed attribute
+  bool parseSpecializeAttribute(swift::tok ClosingBrace, SourceLoc AtLoc,
+                                SourceLoc Loc, SpecializeAttr *&Attr);
+
   /// Parse a specific attribute.
   bool parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc);
 
@@ -723,25 +729,27 @@
                                            DeclAttributes &Attributes);
   ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
                                 SourceLoc *classRequirementLoc);
+  bool parseDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
+                     Diag<> ErrorDiag, ParseDeclOptions Options,
+                     llvm::function_ref<void(Decl*)> handler);
   ParserResult<ExtensionDecl> parseDeclExtension(ParseDeclOptions Flags,
                                                  DeclAttributes &Attributes);
   ParserResult<EnumDecl> parseDeclEnum(ParseDeclOptions Flags,
                                        DeclAttributes &Attributes);
-  ParserStatus parseDeclEnumCase(ParseDeclOptions Flags, DeclAttributes &Attributes,
-                                 SmallVectorImpl<Decl *> &decls);
-  bool parseNominalDeclMembers(SourceLoc LBLoc, SourceLoc &RBLoc,
-                               Diag<> ErrorDiag, ParseDeclOptions flags,
-                               llvm::function_ref<void(Decl*)> handler);
+  ParserResult<EnumCaseDecl>
+  parseDeclEnumCase(ParseDeclOptions Flags, DeclAttributes &Attributes,
+                    SmallVectorImpl<Decl *> &decls);
   ParserResult<StructDecl>
   parseDeclStruct(ParseDeclOptions Flags, DeclAttributes &Attributes);
   ParserResult<ClassDecl>
   parseDeclClass(SourceLoc ClassLoc,
                  ParseDeclOptions Flags, DeclAttributes &Attributes);
-  ParserStatus parseDeclVar(ParseDeclOptions Flags, DeclAttributes &Attributes,
-                            SmallVectorImpl<Decl *> &Decls,
-                            SourceLoc StaticLoc,
-                            StaticSpellingKind StaticSpelling,
-                            SourceLoc TryLoc);
+  ParserResult<PatternBindingDecl>
+  parseDeclVar(ParseDeclOptions Flags, DeclAttributes &Attributes,
+               SmallVectorImpl<Decl *> &Decls,
+               SourceLoc StaticLoc,
+               StaticSpellingKind StaticSpelling,
+               SourceLoc TryLoc);
 
   void consumeGetSetBody(AbstractFunctionDecl *AFD, SourceLoc LBLoc);
 
@@ -790,9 +798,9 @@
   ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
                                                DeclAttributes &Attributes);
 
-  ParserStatus parseDeclSubscript(ParseDeclOptions Flags,
-                                  DeclAttributes &Attributes,
-                                  SmallVectorImpl<Decl *> &Decls);
+  ParserResult<SubscriptDecl>
+  parseDeclSubscript(ParseDeclOptions Flags, DeclAttributes &Attributes,
+                     SmallVectorImpl<Decl *> &Decls);
 
   ParserResult<ConstructorDecl>
   parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes);
@@ -854,6 +862,10 @@
   ParserResult<TypeRepr> parseTypeSimple();
   ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID,
                                          bool HandleCodeCompletion = true);
+
+  /// \brief Parse layout constraint.
+  LayoutConstraintInfo parseLayoutConstraint(Identifier LayoutConstraintID);
+
   bool parseGenericArguments(SmallVectorImpl<TypeRepr*> &Args,
                              SourceLoc &LAngleLoc,
                              SourceLoc &RAngleLoc);
@@ -1251,12 +1263,10 @@
   ParserStatus
   parseFreestandingGenericWhereClause(GenericParamList *&GPList,
                              WhereClauseKind kind=WhereClauseKind::Declaration);
-  
-  ParserStatus parseGenericWhereClause(SourceLoc &WhereLoc,
-                               SmallVectorImpl<RequirementRepr> &Requirements,
-                                       bool &FirstTypeInComplete);
-  
 
+  ParserStatus parseGenericWhereClause(
+      SourceLoc &WhereLoc, SmallVectorImpl<RequirementRepr> &Requirements,
+      bool &FirstTypeInComplete, bool AllowLayoutConstraints = false);
 
   //===--------------------------------------------------------------------===//
   // Availability Specification Parsing
diff --git a/include/swift/Runtime/Concurrent.h b/include/swift/Runtime/Concurrent.h
index fe369dd..48e37ab 100644
--- a/include/swift/Runtime/Concurrent.h
+++ b/include/swift/Runtime/Concurrent.h
@@ -17,7 +17,7 @@
 #include <stdint.h>
 #include "llvm/Support/Allocator.h"
 
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__CYGWIN__)
 #include <stdio.h>
 #endif
 
diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h
index b9ac02f..7bbc6a6 100644
--- a/include/swift/Runtime/Debug.h
+++ b/include/swift/Runtime/Debug.h
@@ -19,12 +19,12 @@
 
 #include <llvm/Support/Compiler.h>
 #include <stdint.h>
+#include "swift/Basic/Unreachable.h"
 #include "swift/Runtime/Config.h"
 #include "swift/Runtime/Metadata.h"
 
 #ifdef SWIFT_HAVE_CRASHREPORTERCLIENT
 
-#define CRASH_REPORTER_CLIENT_HIDDEN __attribute__((visibility("hidden")))
 #define CRASHREPORTER_ANNOTATIONS_VERSION 5
 #define CRASHREPORTER_ANNOTATIONS_SECTION "__crash_info"
 
@@ -40,7 +40,7 @@
 };
 
 extern "C" {
-CRASH_REPORTER_CLIENT_HIDDEN
+LLVM_LIBRARY_VISIBILITY
 extern struct crashreporter_annotations_t gCRAnnotations;
 }
 
@@ -70,13 +70,9 @@
 LLVM_ATTRIBUTE_ALWAYS_INLINE // Minimize trashed registers
 static inline void crash(const char *message) {
   CRSetCrashLogMessage(message);
-  // __builtin_trap() doesn't always do the right thing due to GCC compatibility
-#if defined(__i386__) || defined(__x86_64__)
-  asm("int3");
-#else
-  __builtin_trap();
-#endif
-  __builtin_unreachable();
+
+  LLVM_BUILTIN_TRAP;
+  swift_unreachable("Expected compiler to crash.");
 }
 
 /// Report a corrupted type object.
diff --git a/include/swift/SIL/CFG.h b/include/swift/SIL/CFG.h
index afaab30..79b2c5c 100644
--- a/include/swift/SIL/CFG.h
+++ b/include/swift/SIL/CFG.h
@@ -27,8 +27,7 @@
 // GraphTraits for SILBasicBlock
 //===----------------------------------------------------------------------===//
 template <> struct GraphTraits<swift::SILBasicBlock*> {
-  typedef swift::SILBasicBlock NodeType;
-  typedef NodeType::SuccessorListTy::iterator ChildIteratorType;
+  typedef swift::SILBasicBlock::SuccessorListTy::iterator ChildIteratorType;
   typedef swift::SILBasicBlock *NodeRef;
 
   static NodeRef getEntryNode(NodeRef BB) { return BB; }
@@ -42,8 +41,7 @@
 };
 
 template <> struct GraphTraits<const swift::SILBasicBlock*> {
-  typedef const swift::SILBasicBlock NodeType;
-  typedef NodeType::ConstSuccessorListTy::iterator ChildIteratorType;
+  typedef swift::SILBasicBlock::ConstSuccessorListTy::iterator ChildIteratorType;
   typedef const swift::SILBasicBlock *NodeRef;
 
   static NodeRef getEntryNode(NodeRef BB) { return BB; }
@@ -57,8 +55,7 @@
 };
 
 template <> struct GraphTraits<Inverse<swift::SILBasicBlock*> > {
-  typedef swift::SILBasicBlock NodeType;
-  typedef NodeType::pred_iterator ChildIteratorType;
+  typedef swift::SILBasicBlock::pred_iterator ChildIteratorType;
   typedef swift::SILBasicBlock *NodeRef;
 
   static NodeRef getEntryNode(Inverse<swift::SILBasicBlock *> G) {
@@ -73,8 +70,7 @@
 };
 
 template <> struct GraphTraits<Inverse<const swift::SILBasicBlock*> > {
-  typedef const swift::SILBasicBlock NodeType;
-  typedef NodeType::pred_iterator ChildIteratorType;
+  typedef swift::SILBasicBlock::pred_iterator ChildIteratorType;
   typedef const swift::SILBasicBlock *NodeRef;
 
   static NodeRef getEntryNode(Inverse<const swift::SILBasicBlock *> G) {
@@ -95,9 +91,13 @@
 
   static NodeRef getEntryNode(GraphType F) { return &F->front(); }
 
-  typedef swift::SILFunction::iterator nodes_iterator;
-  static nodes_iterator nodes_begin(GraphType F) { return F->begin(); }
-  static nodes_iterator nodes_end(GraphType F) { return F->end(); }
+  typedef pointer_iterator<swift::SILFunction::iterator> nodes_iterator;
+  static nodes_iterator nodes_begin(GraphType F) {
+    return nodes_iterator(F->begin());
+  }
+  static nodes_iterator nodes_end(GraphType F) {
+    return nodes_iterator(F->end());
+  }
   static unsigned size(GraphType F) { return F->size(); }
 };
 
@@ -108,9 +108,13 @@
 
   static NodeRef getEntryNode(GraphType F) { return &F.Graph->front(); }
 
-  typedef swift::SILFunction::iterator nodes_iterator;
-  static nodes_iterator nodes_begin(GraphType F) { return F.Graph->begin(); }
-  static nodes_iterator nodes_end(GraphType F) { return F.Graph->end(); }
+  typedef pointer_iterator<swift::SILFunction::iterator> nodes_iterator;
+  static nodes_iterator nodes_begin(GraphType F) {
+    return nodes_iterator(F.Graph->begin());
+  }
+  static nodes_iterator nodes_end(GraphType F) {
+    return nodes_iterator(F.Graph->end());
+  }
   static unsigned size(GraphType F) { return F.Graph->size(); }
 };
 
diff --git a/include/swift/SIL/Dominance.h b/include/swift/SIL/Dominance.h
index 5ee02c2..9d1fd41 100644
--- a/include/swift/SIL/Dominance.h
+++ b/include/swift/SIL/Dominance.h
@@ -171,8 +171,7 @@
 /// DominatorTree GraphTraits specialization so the DominatorTree can be
 /// iterable by generic graph iterators.
 template <> struct GraphTraits<swift::DominanceInfoNode *> {
-  using NodeType = swift::DominanceInfoNode;
-  using ChildIteratorType = NodeType::iterator;
+  using ChildIteratorType = swift::DominanceInfoNode::iterator;
   typedef swift::DominanceInfoNode *NodeRef;
 
   static NodeRef getEntryNode(NodeRef N) { return N; }
@@ -181,8 +180,7 @@
 };
 
 template <> struct GraphTraits<const swift::DominanceInfoNode *> {
-  using NodeType = const swift::DominanceInfoNode;
-  using ChildIteratorType = NodeType::const_iterator;
+  using ChildIteratorType = swift::DominanceInfoNode::const_iterator;
   typedef const swift::DominanceInfoNode *NodeRef;
 
   static NodeRef getEntryNode(NodeRef N) { return N; }
diff --git a/include/swift/SIL/InstructionUtils.h b/include/swift/SIL/InstructionUtils.h
index 64f8a12..a12ee73 100644
--- a/include/swift/SIL/InstructionUtils.h
+++ b/include/swift/SIL/InstructionUtils.h
@@ -14,9 +14,13 @@
 #define SWIFT_SIL_INSTRUCTIONUTILS_H
 
 #include "swift/SIL/SILInstruction.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
 
 namespace swift {
 
+class SILWitnessTable;
+
 /// Strip off casts/indexing insts/address projections from V until there is
 /// nothing left to strip.
 SILValue getUnderlyingObject(SILValue V);
@@ -73,6 +77,92 @@
 /// intrinsic call.
 SILValue stripExpectIntrinsic(SILValue V);
 
+/// Collects conformances which are used by instructions or inside witness
+/// tables.
+///
+/// It also collects "escaping" metatypes. If a metatype can escape to a not
+/// visible function (outside the compilation unit), all it's conformances have
+/// to be alive, because an opaque type can be tested at runtime if it conforms
+/// to a protocol.
+class ConformanceCollector {
+  /// The used conformances.
+  llvm::SmallVector<const ProtocolConformance *, 8> Conformances;
+
+  /// Types of which metatypes are escaping.
+  llvm::SmallVector<const NominalTypeDecl *, 8> EscapingMetaTypes;
+
+  /// Conformances and types which have been handled.
+  llvm::SmallPtrSet<const void *, 8> Visited;
+
+  SILModule &M;
+
+  void scanType(Type type);
+  void scanSubsts(ArrayRef<Substitution> substs);
+
+  template <typename T> void scanFuncParams(ArrayRef<T> OrigParams,
+                                            ArrayRef<T> SubstParams) {
+    size_t NumParams = OrigParams.size();
+    assert(NumParams == SubstParams.size());
+    for (size_t Idx = 0; Idx < NumParams; ++Idx) {
+      if (OrigParams[Idx].getType()->hasTypeParameter()) {
+        scanType(SubstParams[Idx].getType());
+      }
+    }
+  }
+
+  void scanConformance(ProtocolConformance *C);
+
+  void scanConformance(ProtocolConformanceRef CRef) {
+    if (CRef.isConcrete())
+      scanConformance(CRef.getConcrete());
+  }
+
+  void scanConformances(ArrayRef<ProtocolConformanceRef> CRefs);
+
+public:
+
+  ConformanceCollector(SILModule &M) : M(M) { }
+
+  /// Collect all used conformances of an instruction.
+  ///
+  /// If the instruction can escape a metatype, also record this metatype.
+  void collect(SILInstruction *I);
+
+  /// Collect all used conformances and metatypes of a witness table.
+  void collect(SILWitnessTable *WT);
+
+  /// Clears all information about used conformances and metatypes.
+  void clear() {
+    Conformances.clear();
+    EscapingMetaTypes.clear();
+    Visited.clear();
+  }
+
+  /// For debug purposes.
+  void dump();
+
+  /// Returns the list of collected used conformances.
+  ArrayRef<const ProtocolConformance *> getUsedConformances() {
+    return Conformances;
+  }
+
+  /// Returns the list of collected escaping metatypes.
+  ArrayRef<const NominalTypeDecl *> getEscapingMetaTypes() {
+    return EscapingMetaTypes;
+  }
+
+  /// Returns true if \p Conf is in the list of used conformances.
+  bool isUsed(const ProtocolConformance *Conf) {
+    return Visited.count(Conf) != 0;
+  }
+
+  /// Returns true if the metatype of \p NT is in the list of escaping
+  /// metatypes.
+  bool isMetaTypeEscaping(const NominalTypeDecl *NT) {
+    return Visited.count(NT) != 0;
+  }
+};
+
 /// A utility class for evaluating whether a newly parsed or deserialized
 /// function has qualified or unqualified ownership.
 ///
diff --git a/include/swift/SIL/LoopInfo.h b/include/swift/SIL/LoopInfo.h
index 8c500e8..4bcdc47 100644
--- a/include/swift/SIL/LoopInfo.h
+++ b/include/swift/SIL/LoopInfo.h
@@ -63,6 +63,7 @@
   using SILLoopInfoBase = llvm::LoopInfoBase<SILBasicBlock, SILLoop>;
 
   SILLoopInfoBase LI;
+  DominanceInfo *Dominance;
 
   void operator=(const SILLoopInfo &) = delete;
   SILLoopInfo(const SILLoopInfo &) = delete;
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 6a8ffb1..544e6cd 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -13,6 +13,7 @@
 #ifndef SWIFT_SIL_SILBUILDER_H
 #define SWIFT_SIL_SILBUILDER_H
 
+#include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILDebugScope.h"
 #include "swift/SIL/SILFunction.h"
 #include "swift/SIL/SILModule.h"
@@ -514,10 +515,16 @@
     return lowering.emitStore(*this, Loc, Src, DestAddr, Qualifier);
   }
 
-  EndBorrowInst *createEndBorrow(SILLocation Loc, SILValue Src,
-                                 SILValue DestAddr) {
-    return insert(new (F.getModule())
-                      EndBorrowInst(getSILDebugLocation(Loc), Src, DestAddr));
+  EndBorrowInst *createEndBorrow(SILLocation Loc, SILValue BorrowedValue,
+                                 SILValue OriginalValue) {
+    return insert(new (F.getModule()) EndBorrowInst(
+        getSILDebugLocation(Loc), BorrowedValue, OriginalValue));
+  }
+
+  EndBorrowArgumentInst *createEndBorrowArgument(SILLocation Loc,
+                                                 SILValue Arg) {
+    return insert(new (F.getModule()) EndBorrowArgumentInst(
+        getSILDebugLocation(Loc), cast<SILArgument>(Arg)));
   }
 
   AssignInst *createAssign(SILLocation Loc, SILValue Src, SILValue DestAddr) {
@@ -803,6 +810,20 @@
                                                        operand, atomicity));
   }
 
+  UnmanagedRetainValueInst *createUnmanagedRetainValue(SILLocation Loc,
+                                                       SILValue operand) {
+    assert(F.hasQualifiedOwnership());
+    return insert(new (F.getModule()) UnmanagedRetainValueInst(
+        getSILDebugLocation(Loc), operand));
+  }
+
+  UnmanagedReleaseValueInst *createUnmanagedReleaseValue(SILLocation Loc,
+                                                         SILValue operand) {
+    assert(F.hasQualifiedOwnership());
+    return insert(new (F.getModule()) UnmanagedReleaseValueInst(
+        getSILDebugLocation(Loc), operand));
+  }
+
   CopyValueInst *createCopyValue(SILLocation Loc, SILValue operand) {
     return insert(new (F.getModule())
                       CopyValueInst(getSILDebugLocation(Loc), operand));
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 4765c86..72608e8 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -698,10 +698,19 @@
 template <typename ImplClass>
 void SILCloner<ImplClass>::visitEndBorrowInst(EndBorrowInst *Inst) {
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
-  doPostProcess(Inst,
-                getBuilder().createEndBorrow(getOpLocation(Inst->getLoc()),
-                                             getOpValue(Inst->getSrc()),
-                                             getOpValue(Inst->getDest())));
+  doPostProcess(
+      Inst, getBuilder().createEndBorrow(getOpLocation(Inst->getLoc()),
+                                         getOpValue(Inst->getBorrowedValue()),
+                                         getOpValue(Inst->getOriginalValue())));
+}
+
+template <typename ImplClass>
+void SILCloner<ImplClass>::visitEndBorrowArgumentInst(
+    EndBorrowArgumentInst *Inst) {
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  doPostProcess(
+      Inst, getBuilder().createEndBorrowArgument(
+                getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
 }
 
 template <typename ImplClass>
@@ -1145,6 +1154,15 @@
 }
 
 template <typename ImplClass>
+void SILCloner<ImplClass>::visitUnmanagedRetainValueInst(
+    UnmanagedRetainValueInst *Inst) {
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  doPostProcess(
+      Inst, getBuilder().createUnmanagedRetainValue(
+                getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
+}
+
+template <typename ImplClass>
 void SILCloner<ImplClass>::visitCopyValueInst(CopyValueInst *Inst) {
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
   doPostProcess(Inst,
@@ -1171,6 +1189,15 @@
 }
 
 template <typename ImplClass>
+void SILCloner<ImplClass>::visitUnmanagedReleaseValueInst(
+    UnmanagedReleaseValueInst *Inst) {
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  doPostProcess(
+      Inst, getBuilder().createUnmanagedReleaseValue(
+                getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
+}
+
+template <typename ImplClass>
 void SILCloner<ImplClass>::visitDestroyValueInst(DestroyValueInst *Inst) {
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
   doPostProcess(
diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h
index 5816fc0..7b23467 100644
--- a/include/swift/SIL/SILFunction.h
+++ b/include/swift/SIL/SILFunction.h
@@ -38,22 +38,54 @@
 enum Inline_t { InlineDefault, NoInline, AlwaysInline };
 enum IsThunk_t { IsNotThunk, IsThunk, IsReabstractionThunk };
 
-class SILSpecializeAttr final :
-    private llvm::TrailingObjects<SILSpecializeAttr, Substitution> {
-  friend TrailingObjects;
-
-  unsigned numSubs;
-  
-  SILSpecializeAttr(ArrayRef<Substitution> subs);
-
+class SILSpecializeAttr final {
+  friend SILFunction;
 public:
-  static SILSpecializeAttr *create(SILModule &M, ArrayRef<Substitution> subs);
+  enum class SpecializationKind {
+    Full,
+    Partial
+  };
 
-  ArrayRef<Substitution> getSubstitutions() const {
-    return { getTrailingObjects<Substitution>(), numSubs };
+  static SILSpecializeAttr *create(SILModule &M,
+                                   ArrayRef<Requirement> requirements,
+                                   bool exported, SpecializationKind kind);
+
+  ArrayRef<Requirement> getRequirements() const;
+
+  bool isExported() const {
+    return exported;
   }
-  
+
+  bool isFullSpecialization() const {
+    return kind == SpecializationKind::Full;
+  }
+
+  bool isPartialSpecialization() const {
+    return kind == SpecializationKind::Partial;
+  }
+
+  SpecializationKind getSpecializationKind() const {
+    return kind;
+  }
+
+  SILFunction *getFunction() const {
+    return F;
+  }
+
   void print(llvm::raw_ostream &OS) const;
+
+private:
+  unsigned numRequirements;
+  SpecializationKind kind;
+  bool exported;
+  SILFunction *F;
+
+  SILSpecializeAttr(ArrayRef<Requirement> requirements, bool exported,
+                    SpecializationKind kind);
+
+  Requirement *getRequirementsData() {
+    return reinterpret_cast<Requirement *>(this+1);
+  }
 };
 
 /// SILFunction - A function body that has been lowered to SIL. This consists of
@@ -452,9 +484,7 @@
   /// Removes all specialize attributes from this function.
   void clearSpecializeAttrs() { SpecializeAttrSet.clear(); }
 
-  void addSpecializeAttr(SILSpecializeAttr *attr) {
-    SpecializeAttrSet.push_back(attr);
-  }
+  void addSpecializeAttr(SILSpecializeAttr *Attr);
 
   /// \returns True if the function is optimizable (i.e. not marked as no-opt),
   ///          or is raw SIL (so that the mandatory passes still run).
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 9883473..a97cf51 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -443,9 +443,9 @@
   friend llvm::TrailingObjects<DERIVED, Operand, TRAILING_TYPES...>;
 
   typedef llvm::TrailingObjects<DERIVED, Operand, TRAILING_TYPES...>
-      TrailingBase;
+      TrailingObjects;
 
-  using TrailingBase::totalSizeToAlloc;
+  using TrailingObjects::totalSizeToAlloc;
 
   // Total number of operands of this instruction.
   // It is number of type dependent operands + 1.
@@ -460,15 +460,8 @@
     }
   }
 
-  // Work around MSVC bug: can't infer llvm::trailing_objects_internal,
-  // even though we granted friend access to it.
-  size_t numTrailingObjects(
-#if defined(_MSC_VER) && !defined(__clang__)
-      llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken<
-      Operand>) const {
-#else
-      typename TrailingBase::template OverloadToken<Operand>) const {
-#endif
+  size_t
+      numTrailingObjects(SWIFT_TRAILING_OBJECTS_OVERLOAD_TOKEN(Operand)) const {
     return NumOperands;
   }
 
@@ -520,12 +513,12 @@
   getType() const { return ValueBase::getType(); }
 
   ArrayRef<Operand> getAllOperands() const {
-    return {TrailingBase::template getTrailingObjects<Operand>(),
+    return {TrailingObjects::template getTrailingObjects<Operand>(),
             static_cast<size_t>(NumOperands)};
   }
 
   MutableArrayRef<Operand> getAllOperands() {
-    return {TrailingBase::template getTrailingObjects<Operand>(),
+    return {TrailingObjects::template getTrailingObjects<Operand>(),
             static_cast<size_t>(NumOperands)};
   }
 
@@ -1818,20 +1811,21 @@
 
 public:
   enum {
-    /// The source of the value being borrowed.
-    Src,
-    /// The destination of the borrowed value.
-    Dest
+    /// The borrowed value.
+    BorrowedValue,
+    /// The original value that was borrowed from.
+    OriginalValue
   };
 
 private:
   FixedOperandList<2> Operands;
-  EndBorrowInst(SILDebugLocation DebugLoc, SILValue Src, SILValue Dest);
+  EndBorrowInst(SILDebugLocation DebugLoc, SILValue BorrowedValue,
+                SILValue OriginalValue);
 
 public:
-  SILValue getSrc() const { return Operands[Src].get(); }
+  SILValue getBorrowedValue() const { return Operands[BorrowedValue].get(); }
 
-  SILValue getDest() const { return Operands[Dest].get(); }
+  SILValue getOriginalValue() const { return Operands[OriginalValue].get(); }
 
   ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
   MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
@@ -1841,6 +1835,17 @@
   }
 };
 
+/// Represents the end of a borrow scope for an argument. The reason why this is
+/// seperate from end_borrow is that an argument is not borrowed from a
+/// specific SSA value. Instead it is borrowed from potentially many different
+/// incoming values.
+class EndBorrowArgumentInst
+    : public UnaryInstructionBase<ValueKind::EndBorrowArgumentInst> {
+  friend class SILBuilder;
+
+  EndBorrowArgumentInst(SILDebugLocation DebugLoc, SILArgument *Arg);
+};
+
 /// AssignInst - Represents an abstract assignment to a memory location, which
 /// may either be an initialization or a store sequence.  This is only valid in
 /// Raw SIL.
@@ -2273,9 +2278,9 @@
     public SILInstruction,
     protected llvm::TrailingObjects<BindMemoryInst, Operand> {
 
-  typedef llvm::TrailingObjects<BindMemoryInst, Operand> TrailingBase;
-  friend TrailingBase;
-  using TrailingBase::totalSizeToAlloc;
+  typedef llvm::TrailingObjects<BindMemoryInst, Operand> TrailingObjects;
+  friend TrailingObjects;
+  using TrailingObjects::totalSizeToAlloc;
 
   friend SILBuilder;
 
@@ -2310,26 +2315,18 @@
   SILType getBoundType() const { return BoundType ; }
 
   // Implement llvm::TrailingObjects.
-
-  // Work around MSVC bug: can't infer llvm::trailing_objects_internal,
-  // even though we granted friend access to it.
-  size_t numTrailingObjects(
-#if defined(_MSC_VER) && !defined(__clang__)
-      llvm::trailing_objects_internal::TrailingObjectsBase::OverloadToken<
-      Operand>) const {
-#else
-      typename TrailingBase::template OverloadToken<Operand>) const {
-#endif
+  size_t
+      numTrailingObjects(SWIFT_TRAILING_OBJECTS_OVERLOAD_TOKEN(Operand)) const {
     return NumOperands;
   }
 
   ArrayRef<Operand> getAllOperands() const {
-    return {TrailingBase::template getTrailingObjects<Operand>(),
+    return {TrailingObjects::template getTrailingObjects<Operand>(),
             static_cast<size_t>(NumOperands)};
   }
 
   MutableArrayRef<Operand> getAllOperands() {
-    return {TrailingBase::template getTrailingObjects<Operand>(),
+    return {TrailingObjects::template getTrailingObjects<Operand>(),
             static_cast<size_t>(NumOperands)};
   }
 
@@ -3010,6 +3007,32 @@
   }
 };
 
+/// Copies a loadable value in an unmanaged, unbalanced way. Only meant for use
+/// in ownership qualified SIL. Please do not use this EVER unless you are
+/// implementing a part of the stdlib called Unmanaged.
+class UnmanagedRetainValueInst
+    : public UnaryInstructionBase<ValueKind::UnmanagedRetainValueInst,
+                                  RefCountingInst,
+                                  /*HasValue*/ false> {
+  friend SILBuilder;
+
+  UnmanagedRetainValueInst(SILDebugLocation DebugLoc, SILValue operand)
+      : UnaryInstructionBase(DebugLoc, operand) {}
+};
+
+/// Destroys a loadable value in an unmanaged, unbalanced way. Only meant for
+/// use in ownership qualified SIL. Please do not use this EVER unless you are
+/// implementing a part of the stdlib called Unmanaged.
+class UnmanagedReleaseValueInst
+    : public UnaryInstructionBase<ValueKind::UnmanagedReleaseValueInst,
+                                  RefCountingInst,
+                                  /*HasValue*/ false> {
+  friend SILBuilder;
+
+  UnmanagedReleaseValueInst(SILDebugLocation DebugLoc, SILValue operand)
+      : UnaryInstructionBase(DebugLoc, operand) {}
+};
+
 /// Transfers ownership of a loadable value to the current autorelease pool.
 class AutoreleaseValueInst
                   : public UnaryInstructionBase<ValueKind::AutoreleaseValueInst,
@@ -4844,6 +4867,36 @@
   ArrayRef<Operand> getFalseOperands() const;
   MutableArrayRef<Operand> getFalseOperands();
 
+  bool isConditionOperandIndex(unsigned OpIndex) const {
+    assert(OpIndex < getNumOperands() &&
+           "OpIndex must be an index for an actual operand");
+    return OpIndex == ConditionIdx;
+  }
+
+  /// Is \p OpIndex an operand associated with the true case?
+  bool isTrueOperandIndex(unsigned OpIndex) const {
+    assert(OpIndex < getNumOperands() &&
+           "OpIndex must be an index for an actual operand");
+    if (NumTrueArgs == 0)
+      return false;
+
+    auto Operands = getTrueOperands();
+    return Operands.front().getOperandNumber() <= OpIndex &&
+           Operands.back().getOperandNumber() <= OpIndex;
+  }
+
+  /// Is \p OpIndex an operand associated with the false case?
+  bool isFalseOperandIndex(unsigned OpIndex) const {
+    assert(OpIndex < getNumOperands() &&
+           "OpIndex must be an index for an actual operand");
+    if (NumFalseArgs == 0)
+      return false;
+
+    auto Operands = getFalseOperands();
+    return Operands.front().getOperandNumber() <= OpIndex &&
+           Operands.back().getOperandNumber() <= OpIndex;
+  }
+
   /// Returns the argument on the cond_br terminator that will be passed to
   /// DestBB in A.
   SILValue getArgForDestBB(const SILBasicBlock *DestBB,
diff --git a/include/swift/SIL/SILLocation.h b/include/swift/SIL/SILLocation.h
index b3804ce..aaacab2 100644
--- a/include/swift/SIL/SILLocation.h
+++ b/include/swift/SIL/SILLocation.h
@@ -87,15 +87,15 @@
   struct DebugLoc {
     unsigned Line;
     unsigned Column;
-    const char *Filename;
+    StringRef Filename;
 
     DebugLoc(unsigned Line = 0, unsigned Column = 0,
-             const char *Filename = nullptr)
+             StringRef Filename = StringRef())
         : Line(Line), Column(Column), Filename(Filename) {}
 
     inline bool operator==(const DebugLoc &R) const {
       return Line == R.Line && Column == R.Column &&
-             StringRef(Filename).equals(R.Filename);
+             Filename.equals(R.Filename);
     }
   };
 
@@ -265,7 +265,7 @@
   bool isNull() const {
     switch (getStorageKind()) {
     case ASTNodeKind:   return Loc.ASTNode.Primary.isNull();
-    case DebugInfoKind: return Loc.DebugInfoLoc.Filename;
+    case DebugInfoKind: return Loc.DebugInfoLoc.Filename.empty();
     case SILFileKind:   return Loc.SILFileLoc.isInvalid();
     default:            return true;
     }
@@ -410,7 +410,7 @@
   }
 
   /// Fingerprint a DebugLoc for use in a DenseMap.
-  typedef std::pair<std::pair<unsigned, unsigned>, const void *> DebugLocKey;
+  typedef std::pair<std::pair<unsigned, unsigned>, StringRef> DebugLocKey;
   struct DebugLocHash : public DebugLocKey {
     DebugLocHash(DebugLoc L) : DebugLocKey({{L.Line, L.Column}, L.Filename}) {}
   };
diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h
index f034414..1b1e4e0 100644
--- a/include/swift/SIL/SILModule.h
+++ b/include/swift/SIL/SILModule.h
@@ -535,6 +535,9 @@
   createDefaultWitnessTableDeclaration(const ProtocolDecl *Protocol,
                                        SILLinkage Linkage);
 
+  /// Deletes a dead witness table.
+  void deleteWitnessTable(SILWitnessTable *Wt);
+
   /// \brief Return the stage of processing this module is at.
   SILStage getStage() const { return Stage; }
 
diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def
index ce0b917..cdf5f37 100644
--- a/include/swift/SIL/SILNodes.def
+++ b/include/swift/SIL/SILNodes.def
@@ -107,6 +107,7 @@
   INST(LoadBorrowInst, SILInstruction, load_borrow, MayRead, DoesNotRelease)
   INST(BeginBorrowInst, SILInstruction, begin_borrow, MayHaveSideEffects, DoesNotRelease)
   INST(EndBorrowInst, SILInstruction, end_borrow, MayHaveSideEffects, DoesNotRelease)
+  INST(EndBorrowArgumentInst, SILInstruction, end_borrow_argument, MayHaveSideEffects, DoesNotRelease)
   INST(LoadUnownedInst, SILInstruction, load_unowned, MayRead, DoesNotRelease)
   INST(LoadWeakInst, SILInstruction, load_weak, MayRead, DoesNotRelease)
   INST(StoreInst, SILInstruction, store, MayWrite, DoesNotRelease)
@@ -158,6 +159,8 @@
   INST(MarkDependenceInst, SILInstruction, mark_dependence, None, DoesNotRelease)
   INST(CopyBlockInst, SILInstruction, copy_block, MayHaveSideEffects, DoesNotRelease)
   INST(CopyValueInst, SILInstruction, copy_value, MayHaveSideEffects, DoesNotRelease)
+  INST(UnmanagedRetainValueInst, RefCountingInst, unmanaged_retain_value, MayHaveSideEffects, DoesNotRelease)
+  INST(UnmanagedReleaseValueInst, RefCountingInst, unmanaged_release_value, MayHaveSideEffects, MayRelease)
   INST(CopyUnownedValueInst, SILInstruction, copy_unowned_value, MayHaveSideEffects, DoesNotRelease)
   INST(DestroyValueInst, SILInstruction, destroy_value, MayHaveSideEffects, MayRelease)
 
diff --git a/include/swift/SIL/SILVTable.h b/include/swift/SIL/SILVTable.h
index 6e70195..68e4c6a 100644
--- a/include/swift/SIL/SILVTable.h
+++ b/include/swift/SIL/SILVTable.h
@@ -58,7 +58,7 @@
 
     /// The linkage of the implementing function.
     ///
-    /// This is usuallly the same as
+    /// This is usually the same as
     ///   stripExternalFromLinkage(Implementation->getLinkage())
     /// except if Implementation is a thunk (which has private or shared
     /// linkage).
diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h
index d069068..5ded6fa 100644
--- a/include/swift/SIL/SILWitnessTable.h
+++ b/include/swift/SIL/SILWitnessTable.h
@@ -247,7 +247,7 @@
     for (Entry &entry : Entries) {
       if (entry.getKind() == WitnessKind::Method) {
         const MethodWitness &MW = entry.getMethodWitness();
-        if (predicate(MW)) {
+        if (MW.Witness && predicate(MW)) {
           entry.removeWitnessMethod();
         }
       }
diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h
index ec33ad2..7ec29b9 100644
--- a/include/swift/SIL/TypeSubstCloner.h
+++ b/include/swift/SIL/TypeSubstCloner.h
@@ -19,6 +19,7 @@
 #define SWIFT_SIL_TYPESUBSTCLONER_H
 
 #include "swift/AST/GenericEnvironment.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Type.h"
 #include "swift/SIL/SILCloner.h"
 #include "swift/SIL/DynamicCasts.h"
diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def
index 4d64080..fb7538e 100644
--- a/include/swift/Serialization/DeclTypeRecordNodes.def
+++ b/include/swift/Serialization/DeclTypeRecordNodes.def
@@ -163,8 +163,9 @@
 OTHER(GENERIC_PARAM_LIST, 240)
 TRAILING_INFO(GENERIC_PARAM)
 TRAILING_INFO(GENERIC_REQUIREMENT)
-OTHER(GENERIC_ENVIRONMENT, 243)
-OTHER(SIL_GENERIC_ENVIRONMENT, 244)
+TRAILING_INFO(LAYOUT_REQUIREMENT)
+OTHER(GENERIC_ENVIRONMENT, 244)
+OTHER(SIL_GENERIC_ENVIRONMENT, 245)
 
 OTHER(LOCAL_DISCRIMINATOR, 248)
 OTHER(PRIVATE_DISCRIMINATOR, 249)
diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h
index f8471de..0f8b184 100644
--- a/include/swift/Serialization/ModuleFile.h
+++ b/include/swift/Serialization/ModuleFile.h
@@ -13,7 +13,6 @@
 #ifndef SWIFT_SERIALIZATION_MODULEFILE_H
 #define SWIFT_SERIALIZATION_MODULEFILE_H
 
-#include "swift/AST/Decl.h"
 #include "swift/AST/Identifier.h"
 #include "swift/AST/LazyResolver.h"
 #include "swift/AST/LinkLibrary.h"
@@ -37,6 +36,9 @@
 }
 
 namespace swift {
+class Decl;
+class FileUnit;
+class ModuleDecl;
 class Pattern;
 class ProtocolConformance;
 
@@ -56,12 +58,6 @@
   std::unique_ptr<llvm::MemoryBuffer> ModuleInputBuffer;
   std::unique_ptr<llvm::MemoryBuffer> ModuleDocInputBuffer;
 
-  /// The reader attached to \c ModuleInputBuffer.
-  llvm::BitstreamReader ModuleInputReader;
-
-  /// The reader attached to \c ModuleDocInputBuffer.
-  llvm::BitstreamReader ModuleDocInputReader;
-
   /// The cursor used to lazily load things from the file.
   llvm::BitstreamCursor DeclTypeCursor;
 
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index e0036bc..f90cad8 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -254,6 +254,18 @@
 
 // These IDs must \em not be renumbered or reordered without incrementing
 // VERSION_MAJOR.
+enum LayoutRequirementKind : uint8_t {
+  UnknownLayout = 0,
+  TrivialOfExactSize = 1,
+  TrivialOfAtMostSize = 2,
+  Trivial = 3,
+  RefCountedObject = 4,
+  NativeRefCountedObject = 5,
+};
+using LayoutRequirementKindField = BCFixed<3>;
+
+// These IDs must \em not be renumbered or reordered without incrementing
+// VERSION_MAJOR.
 enum Associativity : uint8_t {
   NonAssociative = 0,
   LeftAssociative,
@@ -1102,6 +1114,14 @@
     TypeIDField                  // same-type; one for value witness marker)
   >;
 
+  using LayoutRequirementLayout = BCRecordLayout<
+    LAYOUT_REQUIREMENT,
+    LayoutRequirementKindField,  // requirement kind
+    TypeIDField,                 // type being constrained
+    BCFixed<24>,                 // size
+    BCFixed<32>                  // alignment
+  >;
+
   /// Specifies the private discriminator string for a private declaration. This
   /// identifies the declaration's original source file in some opaque way.
   using PrivateDiscriminatorLayout = BCRecordLayout<
@@ -1351,7 +1371,8 @@
 
   using SpecializeDeclAttrLayout = BCRecordLayout<
     Specialize_DECL_ATTR,
-    BCArray<TypeIDField> // concrete types
+    BCFixed<1>, // exported flag
+    BCFixed<1> // specialization kind
   >;
 
 #define SIMPLE_DECL_ATTR(X, CLASS, ...) \
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index f9b1399..453a961 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -22,6 +22,7 @@
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Initializer.h"
 #include "swift/AST/ParameterList.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeVisitor.h"
 #include "swift/Basic/STLExtras.h"
 #include "llvm/ADT/APFloat.h"
@@ -408,6 +409,9 @@
 
       if (D->isImplicit())
         PrintWithColorRAII(OS, DeclModifierColor) << " implicit";
+
+      if (D->TrailingSemiLoc.isValid())
+        PrintWithColorRAII(OS, DeclModifierColor) << " trailing_semi";
     }
 
     void printInherited(ArrayRef<TypeLoc> Inherited) {
@@ -1296,6 +1300,20 @@
     }
   }
 
+  raw_ostream &printCommon(Stmt *S, const char *Name) {
+    OS.indent(Indent);
+    PrintWithColorRAII(OS, ParenthesisColor) << '(';
+    PrintWithColorRAII(OS, StmtColor) << Name;
+
+    if (S->isImplicit())
+      OS << " implicit";
+
+    if (S->TrailingSemiLoc.isValid())
+      OS << " trailing_semi";
+
+    return OS;
+  }
+
   void visitBraceStmt(BraceStmt *S) {
     printASTNodes(S->getElements(), "brace_stmt");
   }
@@ -1317,9 +1335,7 @@
   }
 
   void visitReturnStmt(ReturnStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "return_stmt";
+    printCommon(S, "return_stmt");
     if (S->hasResult()) {
       OS << '\n';
       printRec(S->getResult());
@@ -1328,9 +1344,7 @@
   }
 
   void visitDeferStmt(DeferStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "defer_stmt\n";
+    printCommon(S, "defer_stmt") << '\n';
     printRec(S->getTempDecl());
     OS << '\n';
     printRec(S->getCallExpr());
@@ -1338,9 +1352,7 @@
   }
 
   void visitIfStmt(IfStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "if_stmt\n";
+    printCommon(S, "if_stmt") << '\n';
     for (auto elt : S->getCond())
       printRec(elt);
     OS << '\n';
@@ -1353,9 +1365,7 @@
   }
 
   void visitGuardStmt(GuardStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "guard_stmt\n";
+    printCommon(S, "guard_stmt") << '\n';
     for (auto elt : S->getCond())
       printRec(elt);
     OS << '\n';
@@ -1364,11 +1374,10 @@
   }
 
   void visitIfConfigStmt(IfConfigStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "#if_stmt\n";
+    printCommon(S, "#if_stmt");
     Indent += 2;
     for (auto &Clause : S->getClauses()) {
+      OS << '\n';
       OS.indent(Indent);
       if (Clause.Cond) {
         PrintWithColorRAII(OS, ParenthesisColor) << '(';
@@ -1389,17 +1398,13 @@
   }
 
   void visitDoStmt(DoStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "do_stmt\n";
+    printCommon(S, "do_stmt") << '\n';
     printRec(S->getBody());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
   void visitWhileStmt(WhileStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "while_stmt\n";
+    printCommon(S, "while_stmt") << '\n';
     for (auto elt : S->getCond())
       printRec(elt);
     OS << '\n';
@@ -1408,18 +1413,14 @@
   }
 
   void visitRepeatWhileStmt(RepeatWhileStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "do_while_stmt\n";
+    printCommon(S, "repeat_while_stmt") << '\n';
     printRec(S->getBody());
     OS << '\n';
     printRec(S->getCond());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitForStmt(ForStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "for_stmt\n";
+    printCommon(S, "for_stmt") << '\n';
     if (!S->getInitializerVarDecls().empty()) {
       for (auto D : S->getInitializerVarDecls()) {
         printRec(D);
@@ -1448,9 +1449,7 @@
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitForEachStmt(ForEachStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    OS << "for_each_stmt\n";
+    printCommon(S, "for_each_stmt") << '\n';
     printRec(S->getPattern());
     OS << '\n';
     if (S->getWhere()) {
@@ -1476,27 +1475,19 @@
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitBreakStmt(BreakStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "break_stmt";
+    printCommon(S, "break_stmt");
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitContinueStmt(ContinueStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "continue_stmt";
+    printCommon(S, "continue_stmt");
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitFallthroughStmt(FallthroughStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "fallthrough_stmt";
+    printCommon(S, "fallthrough_stmt");
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitSwitchStmt(SwitchStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "switch_stmt\n";
+    printCommon(S, "switch_stmt") << '\n';
     printRec(S->getSubjectExpr());
     for (CaseStmt *C : S->getCases()) {
       OS << '\n';
@@ -1505,9 +1496,7 @@
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitCaseStmt(CaseStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "case_stmt";
+    printCommon(S, "case_stmt");
     for (const auto &LabelItem : S->getCaseLabelItems()) {
       OS << '\n';
       OS.indent(Indent + 2);
@@ -1528,24 +1517,18 @@
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitFailStmt(FailStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "fail_stmt";
+    printCommon(S, "fail_stmt");
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
   void visitThrowStmt(ThrowStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "throw_stmt\n";
+    printCommon(S, "throw_stmt") << '\n';
     printRec(S->getSubExpr());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
   void visitDoCatchStmt(DoCatchStmt *S) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "do_catch_stmt\n";
+    printCommon(S, "do_catch_stmt") << '\n';
     printRec(S->getBody());
     OS << '\n';
     Indent += 2;
@@ -1559,9 +1542,7 @@
     }
   }
   void visitCatchStmt(CatchStmt *clause) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << '(';
-    PrintWithColorRAII(OS, StmtColor) << "catch\n";
+    printCommon(clause, "catch") << '\n';
     printRec(clause->getErrorPattern());
     if (auto guard = clause->getGuardExpr()) {
       OS << '\n';
@@ -1669,6 +1650,9 @@
       }
     }
 
+    if (E->TrailingSemiLoc.isValid())
+      OS << " trailing_semi";
+
     return OS;
   }
 
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 77e3a12..2deee3c 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -39,23 +39,21 @@
 using namespace swift::NewMangling;
 
 std::string NewMangling::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
-  if (useNewMangling()) {
-    ASTMangler NewMangler(/* DWARF */ true);
-    return NewMangler.mangleTypeForDebugger(Ty, DC);
-  }
   Mangle::Mangler OldMangler(/* DWARF */ true);
   OldMangler.mangleTypeForDebugger(Ty, DC);
-  return OldMangler.finalize();
+  std::string Old = OldMangler.finalize();
+  ASTMangler NewMangler(/* DWARF */ true);
+  std::string New = NewMangler.mangleTypeForDebugger(Ty, DC);
+  return selectMangling(Old, New);
 }
 
 std::string NewMangling::mangleTypeAsUSR(Type Ty) {
-  if (useNewMangling()) {
-    ASTMangler NewMangler;
-    return NewMangler.mangleTypeAsUSR(Ty);
-  }
   Mangle::Mangler OldMangler;
   OldMangler.mangleType(Ty, /*uncurry*/ 0);
-  return OldMangler.finalize();
+  std::string Old = OldMangler.finalize();
+  ASTMangler NewMangler;
+  std::string New = NewMangler.mangleTypeAsUSR(Ty);
+  return selectMangling(Old, New);
 }
 
 
@@ -593,8 +591,6 @@
       auto GTPT = DC->mapTypeOutOfContext(archetype)
           ->castTo<GenericTypeParamType>();
 
-      Buffer << 'q' << Index(GTPT->getIndex());
-
       // The DWARF output created by Swift is intentionally flat,
       // therefore archetypes are emitted with their DeclContext if
       // they appear at the top level of a type.
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 986864e..45b3ae0 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -25,6 +25,7 @@
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/PrintOptions.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Stmt.h"
 #include "swift/AST/TypeVisitor.h"
 #include "swift/AST/TypeWalker.h"
@@ -476,17 +477,17 @@
 std::string ASTPrinter::sanitizeUtf8(StringRef Text) {
   llvm::SmallString<256> Builder;
   Builder.reserve(Text.size());
-  const UTF8* Data = reinterpret_cast<const UTF8*>(Text.begin());
-  const UTF8* End = reinterpret_cast<const UTF8*>(Text.end());
+  const llvm::UTF8* Data = reinterpret_cast<const llvm::UTF8*>(Text.begin());
+  const llvm::UTF8* End = reinterpret_cast<const llvm::UTF8*>(Text.end());
   StringRef Replacement = u8"\ufffd";
   while (Data < End) {
-    auto Step = getNumBytesForUTF8(*Data);
+    auto Step = llvm::getNumBytesForUTF8(*Data);
     if (Data + Step > End) {
       Builder.append(Replacement);
       break;
     }
 
-    if (isLegalUTF8Sequence(Data, Data + Step)) {
+    if (llvm::isLegalUTF8Sequence(Data, Data + Step)) {
       Builder.append(Data, Data + Step);
     } else {
 
@@ -1068,7 +1069,7 @@
     Options.ExcludeAttrList.push_back(DAK_Final);
   }
 
-  D->getAttrs().print(Printer, Options);
+  D->getAttrs().print(Printer, Options, D);
 
   Options.ExcludeAttrList.resize(originalExcludeAttrCount);
 }
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 254fedd..1a86a68 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -24,6 +24,7 @@
 #include "swift/AST/Initializer.h"
 #include "swift/AST/Mangle.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/SourceManager.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallString.h"
@@ -1992,9 +1993,15 @@
         if (auto *FD = dyn_cast<FuncDecl>(member))
           if (FD->isAccessor())
             continue;
-        
+
+
         if (auto req = dyn_cast<ValueDecl>(member)) {
           if (!normal->hasWitness(req)) {
+            if (req->getAttrs().isUnavailable(Ctx) &&
+                proto->isObjC()) {
+              continue;
+            }
+
             dumpRef(decl);
             Out << " is missing witness for "
                 << conformance->getProtocol()->getName().str() 
diff --git a/lib/AST/ArchetypeBuilder.cpp b/lib/AST/ArchetypeBuilder.cpp
index 88f6238..4d6e0d0 100644
--- a/lib/AST/ArchetypeBuilder.cpp
+++ b/lib/AST/ArchetypeBuilder.cpp
@@ -402,35 +402,46 @@
       if (int compareProtocols
             = ProtocolType::compareProtocols(&protoa, &protob))
         return compareProtocols;
+
+      // Error case: if we have two associated types with the same name in the
+      // same protocol, just tie-break based on address.
+      if (aa != ab)
+        return aa < ab ? -1 : +1;
     } else {
       // A resolved archetype is always ordered before an unresolved one.
       return -1;
     }
+  } else {
+    // A resolved archetype is always ordered before an unresolved one.
+    if (b->getResolvedAssociatedType())
+      return +1;
   }
 
-  // A resolved archetype is always ordered before an unresolved one.
-  if (b->getResolvedAssociatedType())
-    return +1;
-
   // Make sure typealiases are properly ordered, to avoid crashers.
   // FIXME: Ideally we would eliminate typealiases earlier.
   if (auto *aa = a->getTypeAliasDecl()) {
     if (auto *ab = b->getTypeAliasDecl()) {
       // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
-      auto protoa = aa->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
-      auto protob = ab->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
+      auto protoa =
+        aa->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
+      auto protob =
+        ab->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
+
       if (int compareProtocols
             = ProtocolType::compareProtocols(&protoa, &protob))
         return compareProtocols;
+
+      // FIXME: Arbitrarily break the result here.
+      if (aa != ab)
+        return aa < ab ? -1 : +1;
+    } else {
+      // A resolved archetype is always ordered before an unresolved one.
+      return -1;
     }
-
+  } else if (b->getTypeAliasDecl()) {
     // A resolved archetype is always ordered before an unresolved one.
-    return -1;
-  }
-
-  // A resolved archetype is always ordered before an unresolved one.
-  if (b->getTypeAliasDecl())
     return +1;
+  }
 
   // Along the error path where one or both of the potential archetypes was
   // renamed due to typo correction,
@@ -569,6 +580,12 @@
   return nested.front();
 }
 
+auto ArchetypeBuilder::PotentialArchetype::getNestedType(
+                            AssociatedTypeDecl *assocType,
+                            ArchetypeBuilder &builder) -> PotentialArchetype * {
+  return getNestedType(assocType->getName(), builder);
+}
+
 Type ArchetypeBuilder::PotentialArchetype::getTypeInContext(
                                                ArchetypeBuilder &builder,
                                                GenericEnvironment *genericEnv) {
@@ -913,6 +930,9 @@
     if (!base)
       return nullptr;
 
+    if (auto assocType = dependentMember->getAssocType())
+      return base->getNestedType(assocType, *this);
+
     return base->getNestedType(dependentMember->getName(), *this);
   }
 
@@ -1003,7 +1023,7 @@
   for (auto Member : Proto->getMembers()) {
     if (auto AssocType = dyn_cast<AssociatedTypeDecl>(Member)) {
       // Add requirements placed directly on this associated type.
-      auto AssocPA = T->getNestedType(AssocType->getName(), *this);
+      auto AssocPA = T->getNestedType(AssocType, *this);
       if (AssocPA != T) {
         if (addAbstractTypeParamRequirements(AssocType, AssocPA,
                                              RequirementSource::Protocol,
@@ -1173,8 +1193,9 @@
   
   if (concrete1 && concrete2) {
     if (!concrete1->isEqual(concrete2)) {
+      StringRef Name = T1->getFullName();
       Diags.diagnose(Source.getLoc(), diag::requires_same_type_conflict,
-                     T1->getName(), concrete1, concrete2);
+                     Name, concrete1, concrete2);
       return true;
       
     }
@@ -1245,8 +1266,9 @@
   // problem.
   if (auto oldConcrete = T->getConcreteType()) {
     if (!oldConcrete->isEqual(Concrete)) {
+      StringRef Name = T->getFullName();
       Diags.diagnose(Source.getLoc(), diag::requires_same_type_conflict,
-                     T->getName(), oldConcrete, Concrete);
+                     Name, oldConcrete, Concrete);
       return true;
     }
     return false;
diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp
index a2e0bb4..263e758 100644
--- a/lib/AST/Attr.cpp
+++ b/lib/AST/Attr.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTPrinter.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/Defer.h"
@@ -180,10 +181,10 @@
   return conditional;
 }
 
-void DeclAttributes::dump() const {
+void DeclAttributes::dump(const Decl *D) const {
   StreamPrinter P(llvm::errs());
   PrintOptions PO = PrintOptions::printEverything();
-  print(P, PO);
+  print(P, PO, D);
 }
 
 /// Returns true if the attribute can be presented as a short form available
@@ -249,8 +250,8 @@
   Printer.printNewline();
 }
 
-void DeclAttributes::print(ASTPrinter &Printer,
-                           const PrintOptions &Options) const {
+void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
+                           const Decl *D) const {
   if (!DeclAttrs)
     return;
 
@@ -285,11 +286,11 @@
   }
 
   for (auto DA : longAttributes)
-    DA->print(Printer, Options);
+    DA->print(Printer, Options, D);
   for (auto DA : attributes)
-    DA->print(Printer, Options);
+    DA->print(Printer, Options, D);
   for (auto DA : modifiers)
-    DA->print(Printer, Options);
+    DA->print(Printer, Options, D);
 }
 
 SourceLoc DeclAttributes::getStartLoc(bool forModifiers) const {
@@ -306,7 +307,8 @@
   return lastAttr ? lastAttr->getRangeWithAt().Start : SourceLoc();
 }
 
-bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options) const {
+bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
+                              const Decl *D) const {
 
   // Handle any attributes that are not printed at all before we make printer
   // callbacks.
@@ -440,9 +442,43 @@
   case DAK_Specialize: {
     Printer << "@" << getAttrName() << "(";
     auto *attr = cast<SpecializeAttr>(this);
-    interleave(attr->getTypeLocs(),
-               [&](TypeLoc tyLoc){ tyLoc.getType().print(Printer, Options); },
-               [&]{ Printer << ", "; });
+    auto exported = attr->isExported() ? "true" : "false";
+    auto kind = attr->isPartialSpecialization() ? "partial" : "full";
+
+    Printer << "exported: "<<  exported << ", ";
+    Printer << "kind: " << kind << ", ";
+
+    if (!attr->getRequirements().empty()) {
+      Printer << "where ";
+    }
+    std::function<Type(Type)> GetInterfaceType;
+    auto *FnDecl = dyn_cast_or_null<AbstractFunctionDecl>(D);
+    if (!FnDecl || !FnDecl->getGenericEnvironment())
+      GetInterfaceType = [](Type Ty) -> Type { return Ty; };
+    else {
+      // Use GenericEnvironment to produce user-friendly
+      // names instead of something like t_0_0.
+      auto *GenericEnv = FnDecl->getGenericEnvironment();
+      assert(GenericEnv);
+      GetInterfaceType = [=](Type Ty) -> Type {
+        return GenericEnv->getSugaredType(Ty);
+      };
+    }
+    interleave(attr->getRequirements(),
+               [&](Requirement req) {
+                 auto FirstTy = GetInterfaceType(req.getFirstType());
+                 if (req.getKind() != RequirementKind::Layout) {
+                   auto SecondTy = GetInterfaceType(req.getSecondType());
+                   Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
+                   ReqWithDecls.print(Printer, Options);
+                 } else {
+                   Requirement ReqWithDecls(req.getKind(), FirstTy,
+                                            req.getLayoutConstraint());
+                   ReqWithDecls.print(Printer, Options);
+                 }
+               },
+               [&] { Printer << ", "; });
+
     Printer << ")";
     break;
   }
@@ -457,10 +493,10 @@
   return true;
 }
 
-void DeclAttribute::print(ASTPrinter &Printer,
-                          const PrintOptions &Options) const {
+void DeclAttribute::print(ASTPrinter &Printer, const PrintOptions &Options,
+                          const Decl *D) const {
 
-  if (!printImpl(Printer, Options))
+  if (!printImpl(Printer, Options, D))
     return; // Nothing printed.
 
   if (isLongAttribute() && Options.PrintLongAttrsOnSeparateLines)
@@ -469,9 +505,9 @@
     Printer << " ";
 }
 
-void DeclAttribute::print(llvm::raw_ostream &OS) const {
+void DeclAttribute::print(llvm::raw_ostream &OS, const Decl *D) const {
   StreamPrinter P(OS);
-  print(P, PrintOptions());
+  print(P, PrintOptions(), D);
 }
 
 unsigned DeclAttribute::getOptions(DeclAttrKind DK) {
@@ -679,7 +715,10 @@
   }
   return new (C) AvailableAttr(
     SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename,
-    NoVersion, NoVersion, Obsoleted, Kind, /* isImplicit */ false);
+    NoVersion, SourceRange(),
+    NoVersion, SourceRange(),
+    Obsoleted, SourceRange(),
+    Kind, /* isImplicit */ false);
 }
 
 bool AvailableAttr::isActivePlatform(const ASTContext &ctx) const {
@@ -768,25 +807,65 @@
 }
 
 SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
-                               ArrayRef<TypeLoc> typeLocs)
+                               TrailingWhereClause *clause,
+                               bool exported,
+                               SpecializationKind kind)
     : DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false),
-      numTypes(typeLocs.size())
-{
-  std::copy(typeLocs.begin(), typeLocs.end(), getTypeLocData());
+      numRequirements(0), trailingWhereClause(clause),
+      kind(kind), exported(exported) {
 }
 
-ArrayRef<TypeLoc> SpecializeAttr::getTypeLocs() const {
-  return const_cast<SpecializeAttr*>(this)->getTypeLocs();
+SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
+                               ArrayRef<Requirement> requirements,
+                               bool exported,
+                               SpecializationKind kind)
+    : DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false),
+      numRequirements(0), kind(kind), exported(exported) {
+  numRequirements = requirements.size();
+  std::copy(requirements.begin(), requirements.end(), getRequirementsData());
 }
 
-MutableArrayRef<TypeLoc> SpecializeAttr::getTypeLocs() {
-  return { this->getTypeLocData(), numTypes };
+void SpecializeAttr::setRequirements(ASTContext &Ctx,
+                                     ArrayRef<Requirement> requirements) {
+  unsigned numClauseRequirements =
+      (trailingWhereClause) ? trailingWhereClause->getRequirements().size() : 0;
+  assert(requirements.size() <= numClauseRequirements);
+  if (!numClauseRequirements)
+    return;
+  numRequirements = requirements.size();
+  std::copy(requirements.begin(), requirements.end(), getRequirementsData());
+}
+
+ArrayRef<Requirement> SpecializeAttr::getRequirements() const {
+  return const_cast<SpecializeAttr*>(this)->getRequirements();
+}
+
+TrailingWhereClause *SpecializeAttr::getTrailingWhereClause() const {
+  return trailingWhereClause;
 }
 
 SpecializeAttr *SpecializeAttr::create(ASTContext &Ctx, SourceLoc atLoc,
                                        SourceRange range,
-                                       ArrayRef<TypeLoc> typeLocs) {
-  unsigned size = sizeof(SpecializeAttr) + (typeLocs.size() * sizeof(TypeLoc));
+                                       TrailingWhereClause *clause,
+                                       bool exported,
+                                       SpecializationKind kind) {
+  unsigned numRequirements = (clause) ? clause->getRequirements().size() : 0;
+  unsigned size =
+      sizeof(SpecializeAttr) + (numRequirements * sizeof(Requirement));
   void *mem = Ctx.Allocate(size, alignof(SpecializeAttr));
-  return new (mem) SpecializeAttr(atLoc, range, typeLocs);
+  return new (mem)
+      SpecializeAttr(atLoc, range, clause, exported, kind);
+}
+
+SpecializeAttr *SpecializeAttr::create(ASTContext &Ctx, SourceLoc atLoc,
+                                       SourceRange range,
+                                       ArrayRef<Requirement> requirements,
+                                       bool exported,
+                                       SpecializationKind kind) {
+  unsigned numRequirements = requirements.size();
+  unsigned size =
+      sizeof(SpecializeAttr) + (numRequirements * sizeof(Requirement));
+  void *mem = Ctx.Allocate(size, alignof(SpecializeAttr));
+  return new (mem)
+      SpecializeAttr(atLoc, range, requirements, exported, kind);
 }
diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp
index e8c2e71..684faeb 100644
--- a/lib/AST/Availability.cpp
+++ b/lib/AST/Availability.cpp
@@ -91,7 +91,10 @@
   return new (Context) AvailableAttr(
       SourceLoc(), SourceRange(), Platform,
       /*Message=*/StringRef(),
-      /*Rename=*/StringRef(), Introduced, Deprecated, Obsoleted,
+      /*Rename=*/StringRef(),
+        Introduced, /*IntroducedRange=*/SourceRange(),
+        Deprecated, /*DeprecatedRange=*/SourceRange(),
+        Obsoleted, /*ObsoletedRange=*/SourceRange(),
       Inferred.PlatformAgnostic, /*Implicit=*/true);
 }
 
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 4693cff..4f8902a 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -1138,7 +1138,7 @@
 /// getLLVMIntrinsicID - Given an LLVM IR intrinsic name with argument types
 /// removed (e.g. like "bswap") return the LLVM IR IntrinsicID for the intrinsic
 /// or 0 if the intrinsic name doesn't match anything.
-unsigned swift::getLLVMIntrinsicID(StringRef InName, bool hasArgTypes) {
+unsigned swift::getLLVMIntrinsicID(StringRef InName) {
   using namespace llvm;
 
   // Swift intrinsic names start with int_.
@@ -1151,9 +1151,7 @@
   NameS.append("llvm.");
   for (char C : InName)
     NameS.push_back(C == '_' ? '.' : C);
-  if (hasArgTypes)
-    NameS.push_back('.');
-  
+
   const char *Name = NameS.c_str();
   ArrayRef<const char *> NameTable(&IntrinsicNameTable[1],
                                    TargetInfos[1].Offset);
@@ -1348,7 +1346,7 @@
 
   // If this is the name of an LLVM intrinsic, cons up a swift function with a
   // type that matches the IR types.
-  if (unsigned ID = getLLVMIntrinsicID(OperationName, !Types.empty())) {
+  if (unsigned ID = getLLVMIntrinsicID(OperationName)) {
     SmallVector<Type, 8> ArgElts;
     Type ResultTy;
     FunctionType::ExtInfo Info;
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 6e8ff39..2f9d8df 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -76,7 +76,7 @@
     clangBasic
 
   LLVM_COMPONENT_DEPENDS
-    bitreader bitwriter coverage irreader debuginfoDWARF
+    bitreader bitwriter coroutines coverage irreader debuginfoDWARF
     profiledata instrumentation object objcarcopts mc mcparser
     bitreader bitwriter lto ipo option core support ${LLVM_TARGETS_TO_BUILD}
   )
diff --git a/lib/AST/ConcreteDeclRef.cpp b/lib/AST/ConcreteDeclRef.cpp
index eb2dbad..58b2444 100644
--- a/lib/AST/ConcreteDeclRef.cpp
+++ b/lib/AST/ConcreteDeclRef.cpp
@@ -17,6 +17,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ConcreteDeclRef.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Types.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace swift;
diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp
index fdf0b67..537db39 100644
--- a/lib/AST/ConformanceLookupTable.cpp
+++ b/lib/AST/ConformanceLookupTable.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "llvm/Support/SaveAndRestore.h"
 
 using namespace swift;
@@ -1041,7 +1042,7 @@
         }
 
         // Otherwise, order by buffer identifier.
-        return StringRef(ctx.SourceMgr.getIdentifierForBuffer(lhsBuffer))
+        return ctx.SourceMgr.getIdentifierForBuffer(lhsBuffer)
                  .compare(ctx.SourceMgr.getIdentifierForBuffer(rhsBuffer));
       }
     }
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 462fcd5..dd7c2e8 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -28,6 +28,7 @@
 #include "swift/AST/LazyResolver.h"
 #include "swift/AST/Mangle.h"
 #include "swift/AST/ParameterList.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/ResilienceExpansion.h"
 #include "swift/AST/TypeLoc.h"
 #include "clang/Lex/MacroInfo.h"
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index c99e410..cd344f0 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1411,6 +1411,8 @@
                              ArrayRef<SourceLoc> ElementNameLocs,
                              SourceLoc RParenLoc, bool HasTrailingClosure, 
                              bool Implicit, Type Ty) {
+  assert(!Ty || isa<TupleType>(Ty.getPointer()));
+
   size_t size =
       totalSizeToAlloc<Expr *, Identifier, SourceLoc>(SubExprs.size(),
                                                       ElementNames.size(),
diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp
index 13d5ea3..f5409d3 100644
--- a/lib/AST/GenericEnvironment.cpp
+++ b/lib/AST/GenericEnvironment.cpp
@@ -318,6 +318,18 @@
   llvm_unreachable("missing generic parameter");
 }
 
+Type GenericEnvironment::getSugaredType(Type type) const {
+  if (!type->hasTypeParameter())
+    return type;
+
+  return type.transform([this](Type Ty) -> Type {
+    if (auto GP = dyn_cast<GenericTypeParamType>(Ty.getPointer())) {
+      return Type(getSugaredType(GP));
+    }
+    return Ty;
+  });
+}
+
 ArrayRef<Substitution>
 GenericEnvironment::getForwardingSubstitutions() const {
   auto lookupConformanceFn =
@@ -357,7 +369,8 @@
     // Record the replacement type and its conformances.
     if (auto *archetype = contextTy->getAs<ArchetypeType>()) {
       result.addSubstitution(CanArchetypeType(archetype), sub.getReplacement());
-      result.addConformances(CanType(archetype), sub.getConformances());
+      for (auto conformance : sub.getConformances())
+        result.addConformance(CanType(archetype), conformance);
       continue;
     }
 
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 1540519..3e1c6f9 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -313,11 +313,11 @@
     subs = subs.slice(1);
 
     auto canTy = depTy->getCanonicalType();
-    if (isa<SubstitutableType>(canTy)) {
+    if (isa<SubstitutableType>(canTy))
       result.addSubstitution(cast<SubstitutableType>(canTy),
                              sub.getReplacement());
-    }
-    result.addConformances(canTy, sub.getConformances());
+    for (auto conformance : sub.getConformances())
+      result.addConformance(canTy, conformance);
   }
 
   for (auto reqt : getRequirements()) {
@@ -369,8 +369,6 @@
                  GenericSignature::LookupConformanceFn lookupConformance,
                  SmallVectorImpl<Substitution> &result) const {
 
-  ArchetypeBuilder builder(getASTContext(), lookupConformance);
-
   // Enumerate all of the requirements that require substitution.
   enumeratePairedRequirements([&](Type depTy, ArrayRef<Requirement> reqs) {
     auto &ctx = getASTContext();
@@ -380,19 +378,21 @@
     if (!currentReplacement)
       currentReplacement = ErrorType::get(depTy);
 
-    // Canonicalize the current replacement in context.
-    currentReplacement = const_cast<GenericSignature *>(this)
-        ->getCanonicalTypeInContext(currentReplacement, builder);
-
     // Collect the conformances.
     SmallVector<ProtocolConformanceRef, 4> currentConformances;
     for (auto req: reqs) {
       assert(req.getKind() == RequirementKind::Conformance);
       auto protoType = req.getSecondType()->castTo<ProtocolType>();
-      // TODO: Error handling for failed conformance lookup.
-      currentConformances.push_back(
-        *lookupConformance(depTy->getCanonicalType(), currentReplacement,
-                           protoType));
+      if (auto conformance = lookupConformance(depTy->getCanonicalType(),
+                                               currentReplacement,
+                                               protoType)) {
+        currentConformances.push_back(*conformance);
+      } else {
+        if (!currentReplacement->hasError())
+          currentReplacement = ErrorType::get(currentReplacement);
+        currentConformances.push_back(
+                                  ProtocolConformanceRef(protoType->getDecl()));
+      }
     }
 
     // Add it to the final substitution list.
@@ -605,21 +605,22 @@
     return CanType(type);
 
   // Replace non-canonical type parameters.
-  type = type.transform([&](Type component) -> Type {
-    if (!component->isTypeParameter()) return component;
+  type = type.transformRec([&](TypeBase *component) -> Optional<Type> {
+    if (!isa<GenericTypeParamType>(component) &&
+        !isa<DependentMemberType>(component))
+      return None;
 
     // Resolve the potential archetype.  This can be null in nested generic
     // types, which we can't immediately canonicalize.
-    auto pa = builder.resolveArchetype(component);
-    if (!pa) return component;
+    auto pa = builder.resolveArchetype(Type(component));
+    if (!pa) return None;
 
     auto rep = pa->getArchetypeAnchor();
     if (rep->isConcreteType()) {
       return getCanonicalTypeInContext(rep->getConcreteType(), builder);
-    } else {
-      return rep->getDependentType(getGenericParams(),
-                                   /*allowUnresolved*/ false);
     }
+
+    return rep->getDependentType(getGenericParams(), /*allowUnresolved*/ false);
   });
   
   auto result = type->getCanonicalType();
diff --git a/lib/AST/Identifier.cpp b/lib/AST/Identifier.cpp
index 3ddf7ce..2ecdd4a 100644
--- a/lib/AST/Identifier.cpp
+++ b/lib/AST/Identifier.cpp
@@ -56,12 +56,12 @@
 
 bool Identifier::isOperatorSlow() const {
   StringRef data = str();
-  auto *s = reinterpret_cast<UTF8 const *>(data.begin()),
-  *end = reinterpret_cast<UTF8 const *>(data.end());
-  UTF32 codePoint;
-  ConversionResult res = llvm::convertUTF8Sequence(&s, end, &codePoint,
-                                                   strictConversion);
-  assert(res == conversionOK && "invalid UTF-8 in identifier?!");
+  auto *s = reinterpret_cast<llvm::UTF8 const *>(data.begin()),
+  *end = reinterpret_cast<llvm::UTF8 const *>(data.end());
+  llvm::UTF32 codePoint;
+  llvm::ConversionResult res =
+    llvm::convertUTF8Sequence(&s, end, &codePoint, llvm::strictConversion);
+  assert(res == llvm::conversionOK && "invalid UTF-8 in identifier?!");
   (void)res;
   return !empty() && isOperatorStartCodePoint(codePoint);
 }
diff --git a/lib/AST/LayoutConstraint.cpp b/lib/AST/LayoutConstraint.cpp
index ef09efc..176a017 100644
--- a/lib/AST/LayoutConstraint.cpp
+++ b/lib/AST/LayoutConstraint.cpp
@@ -1,12 +1,12 @@
-//===- LayoutConstraint.cpp - Layout constraints types and APIs -*- C++ -*-===//
+//===--- LayoutConstraint.cpp - Layout constraints types and APIs ---------===//
 //
 // This source file is part of the Swift.org open source project
 //
 // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
-// See http://swift.org/LICENSE.txt for license information
-// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/lib/AST/LookupVisibleDecls.cpp b/lib/AST/LookupVisibleDecls.cpp
index 0d6e824..7341714 100644
--- a/lib/AST/LookupVisibleDecls.cpp
+++ b/lib/AST/LookupVisibleDecls.cpp
@@ -17,8 +17,9 @@
 
 #include "NameLookupImpl.h"
 #include "swift/AST/AST.h"
-#include "swift/AST/NameLookup.h"
 #include "swift/AST/Initializer.h"
+#include "swift/AST/NameLookup.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Basic/STLExtras.h"
 #include "swift/Sema/IDETypeChecking.h"
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index f0c8c81..4c65ea9 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -29,6 +29,7 @@
 #include "swift/AST/ReferencedNameTracker.h"
 #include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/PrintOptions.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Compiler.h"
 #include "swift/Basic/SourceManager.h"
 #include "clang/Basic/Module.h"
@@ -842,10 +843,10 @@
 
   template <typename T>
   struct OperatorLookup {
-    // TODO: this assertion fails in MSVC, but not clang-cl.
-#if !SWIFT_COMPILER_IS_MSVC
-    static_assert(static_cast<T*>(nullptr), "Only usable with operators");
-#endif
+    // Don't fold this into the static_assert: this would trigger an MSVC bug
+    // that causes the assertion to fail.
+    static constexpr T* ptr = static_cast<T*>(nullptr);
+    static_assert(ptr, "Only usable with operators");
   };
 
   template <>
diff --git a/lib/AST/Parameter.cpp b/lib/AST/Parameter.cpp
index 8657add..46c5ba5 100644
--- a/lib/AST/Parameter.cpp
+++ b/lib/AST/Parameter.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/Expr.h"
+#include "swift/AST/Types.h"
 using namespace swift;
 
 /// TODO: unique and reuse the () parameter list in ASTContext, it is common to
diff --git a/lib/AST/RawComment.cpp b/lib/AST/RawComment.cpp
index 7583c62..4295b49 100644
--- a/lib/AST/RawComment.cpp
+++ b/lib/AST/RawComment.cpp
@@ -21,6 +21,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/Types.h"
 #include "swift/Basic/PrimitiveParsing.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Markup/Markup.h"
diff --git a/lib/AST/SILLayout.cpp b/lib/AST/SILLayout.cpp
index 62783eb..e02e1a6 100644
--- a/lib/AST/SILLayout.cpp
+++ b/lib/AST/SILLayout.cpp
@@ -27,6 +27,8 @@
 
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/SILLayout.h"
+#include "swift/AST/Types.h"
+#include "swift/Basic/Range.h"
 
 using namespace swift;
 
diff --git a/lib/AST/Substitution.cpp b/lib/AST/Substitution.cpp
index 9e0844c..3a38772 100644
--- a/lib/AST/Substitution.cpp
+++ b/lib/AST/Substitution.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/SubstitutionMap.h"
 #include "swift/AST/Types.h"
 #include "llvm/ADT/DenseMap.h"
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index 9a5e48c..3c33e17 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -97,15 +97,8 @@
 }
 
 void SubstitutionMap::
-addConformances(CanType type, ArrayRef<ProtocolConformanceRef> conformances) {
-  if (conformances.empty())
-    return;
-
-  auto result = conformanceMap.insert(
-      std::make_pair(type.getPointer(), conformances));
-  assert(result.second ||
-         result.first->getSecond().size() == conformances.size());
-  (void) result;
+addConformance(CanType type, ProtocolConformanceRef conformance) {
+  conformanceMap[type.getPointer()].push_back(conformance);
 }
 
 ArrayRef<ProtocolConformanceRef> SubstitutionMap::
@@ -172,8 +165,6 @@
 
   // Map the innermost generic parameters of the derived function to
   // the base.
-  auto &ctx = baseClass->getASTContext();
-
   auto baseParams = baseSig->getInnermostGenericParams();
   if (baseParams.back()->getDepth() >= minDepth) {
     assert(derivedSig);
@@ -203,21 +194,17 @@
         auto canTy = t->getCanonicalType();
 
         if (isRootedInInnermostParameter(t)) {
-          auto conformances =
-              ctx.AllocateUninitialized<ProtocolConformanceRef>(
-                  reqs.size());
           for (unsigned i = 0, e = reqs.size(); i < e; i++) {
             auto reqt = reqs[i];
             assert(reqt.getKind() == RequirementKind::Conformance);
             auto *proto = reqt.getSecondType()
                 ->castTo<ProtocolType>()->getDecl();
             if (derivedSubs)
-              conformances[i] = *derivedSubs->lookupConformance(canTy, proto);
+              subMap.addConformance(canTy, *derivedSubs->lookupConformance(
+                                                                 canTy, proto));
             else
-              conformances[i] = ProtocolConformanceRef(proto);
+              subMap.addConformance(canTy, ProtocolConformanceRef(proto));
           }
-
-          subMap.addConformances(canTy, conformances);
         }
 
         return false;
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index dbf0534..6a777d0 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1446,12 +1446,12 @@
 
 const llvm::fltSemantics &BuiltinFloatType::getAPFloatSemantics() const {
   switch (getFPKind()) {
-  case BuiltinFloatType::IEEE16:  return APFloat::IEEEhalf;
-  case BuiltinFloatType::IEEE32:  return APFloat::IEEEsingle;
-  case BuiltinFloatType::IEEE64:  return APFloat::IEEEdouble;
-  case BuiltinFloatType::IEEE80:  return APFloat::x87DoubleExtended;
-  case BuiltinFloatType::IEEE128: return APFloat::IEEEquad;
-  case BuiltinFloatType::PPC128:  return APFloat::PPCDoubleDouble;
+  case BuiltinFloatType::IEEE16:  return APFloat::IEEEhalf();
+  case BuiltinFloatType::IEEE32:  return APFloat::IEEEsingle();
+  case BuiltinFloatType::IEEE64:  return APFloat::IEEEdouble();
+  case BuiltinFloatType::IEEE80:  return APFloat::x87DoubleExtended();
+  case BuiltinFloatType::IEEE128: return APFloat::IEEEquad();
+  case BuiltinFloatType::PPC128:  return APFloat::PPCDoubleDouble();
   }
   llvm::report_fatal_error("Unknown FP semantics");
 }
diff --git a/lib/AST/TypeJoinMeet.cpp b/lib/AST/TypeJoinMeet.cpp
index 8626647..eebe691 100644
--- a/lib/AST/TypeJoinMeet.cpp
+++ b/lib/AST/TypeJoinMeet.cpp
@@ -15,6 +15,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "swift/AST/ASTContext.h"
+#include "swift/AST/Decl.h"
 #include "swift/AST/Type.h"
 #include "swift/AST/Types.h"
 #include "llvm/ADT/SmallPtrSet.h"
diff --git a/lib/AST/TypeRefinementContext.cpp b/lib/AST/TypeRefinementContext.cpp
index 61017d3..c1eb173 100644
--- a/lib/AST/TypeRefinementContext.cpp
+++ b/lib/AST/TypeRefinementContext.cpp
@@ -194,6 +194,99 @@
   llvm_unreachable("Unhandled Reason in switch.");
 }
 
+static SourceRange
+getAvailabilityConditionVersionSourceRange(const PoundAvailableInfo *PAI,
+                                           PlatformKind Platform,
+                                           const clang::VersionTuple &Version) {
+  SourceRange Range;
+  for (auto *S : PAI->getQueries()) {
+    if (auto *V = dyn_cast<PlatformVersionConstraintAvailabilitySpec>(S)) {
+      if (V->getPlatform() == Platform && V->getVersion() == Version) {
+        // More than one: return invalid range, no unique choice.
+        if (Range.isValid())
+          return SourceRange();
+        else
+          Range = V->getVersionSrcRange();
+      }
+    }
+  }
+  return Range;
+}
+
+static SourceRange
+getAvailabilityConditionVersionSourceRange(
+    const MutableArrayRef<StmtConditionElement> &Conds,
+    PlatformKind Platform,
+    const clang::VersionTuple &Version) {
+  SourceRange Range;
+  for (auto const& C : Conds) {
+    if (C.getKind() == StmtConditionElement::CK_Availability) {
+      SourceRange R = getAvailabilityConditionVersionSourceRange(
+        C.getAvailability(), Platform, Version);
+      // More than one: return invalid range.
+      if (Range.isValid())
+        return SourceRange();
+      else
+        Range = R;
+    }
+  }
+  return Range;
+}
+
+static SourceRange
+getAvailabilityConditionVersionSourceRange(const DeclAttributes &DeclAttrs,
+                                           PlatformKind Platform,
+                                           const clang::VersionTuple &Version) {
+  SourceRange Range;
+  for (auto *Attr : DeclAttrs) {
+    if (auto *AA = dyn_cast<AvailableAttr>(Attr)) {
+      if (AA->Introduced.hasValue() &&
+          AA->Introduced.getValue() == Version &&
+          AA->Platform == Platform) {
+
+        // More than one: return invalid range.
+        if (Range.isValid())
+          return SourceRange();
+        else
+          Range = AA->IntroducedRange;
+      }
+    }
+  }
+  return Range;
+}
+
+SourceRange
+TypeRefinementContext::getAvailabilityConditionVersionSourceRange(
+    PlatformKind Platform,
+    const clang::VersionTuple &Version) const {
+  switch (getReason()) {
+  case Reason::Decl:
+    return ::getAvailabilityConditionVersionSourceRange(
+      Node.getAsDecl()->getAttrs(), Platform, Version);
+
+  case Reason::IfStmtThenBranch:
+  case Reason::IfStmtElseBranch:
+    return ::getAvailabilityConditionVersionSourceRange(
+      Node.getAsIfStmt()->getCond(), Platform, Version);
+
+  case Reason::ConditionFollowingAvailabilityQuery:
+    return ::getAvailabilityConditionVersionSourceRange(
+      Node.getAsPoundAvailableInfo(), Platform, Version);
+
+  case Reason::GuardStmtFallthrough:
+  case Reason::GuardStmtElseBranch:
+    return ::getAvailabilityConditionVersionSourceRange(
+      Node.getAsGuardStmt()->getCond(), Platform, Version);
+
+  case Reason::WhileStmtBody:
+    return ::getAvailabilityConditionVersionSourceRange(
+      Node.getAsWhileStmt()->getCond(), Platform, Version);
+
+  case Reason::Root:
+    return SourceRange();
+  }
+}
+
 void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr,
                                   unsigned Indent) const {
   OS.indent(Indent);
diff --git a/lib/Basic/Default/TaskQueue.inc b/lib/Basic/Default/TaskQueue.inc
index 9dcdeac..629c6b5 100644
--- a/lib/Basic/Default/TaskQueue.inc
+++ b/lib/Basic/Default/TaskQueue.inc
@@ -68,7 +68,11 @@
 }
 
 void TaskQueue::addTask(const char *ExecPath, ArrayRef<const char *> Args,
-                        ArrayRef<const char *> Env, void *Context) {
+                        ArrayRef<const char *> Env, void *Context,
+                        bool SeparateErrors) {
+  // This implementation of TaskQueue ignores SeparateErrors.
+  // We need to reference SeparateErrors to avoid warnings, though.
+  (void)SeparateErrors;
   std::unique_ptr<Task> T(new Task(ExecPath, Args, Env, Context));
   QueuedTasks.push(std::move(T));
 }
@@ -113,7 +117,7 @@
       // a signal during execution.
       if (Signalled) {
         TaskFinishedResponse Response =
-            Signalled(PI.Pid, ErrMsg, StringRef(), StringRef(), T->Context);
+            Signalled(PI.Pid, ErrMsg, StringRef(), StringRef(), T->Context, None);
         ContinueExecution = Response != TaskFinishedResponse::StopExecution;
       } else {
         // If we don't have a Signalled callback, unconditionally stop.
diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp
index f39cbe3..c30d6b8 100644
--- a/lib/Basic/Platform.cpp
+++ b/lib/Basic/Platform.cpp
@@ -119,7 +119,17 @@
   case llvm::Triple::FreeBSD:
     return "freebsd";
   case llvm::Triple::Win32:
-    return "windows";
+    switch (triple.getEnvironment()) {
+    case llvm::Triple::Cygnus:
+      return "cygwin";
+    case llvm::Triple::GNU:
+      return "mingw";
+    case llvm::Triple::MSVC:
+    case llvm::Triple::Itanium:
+      return "windows";
+    default:
+      llvm_unreachable("unsupported Windows environment");
+    }
   case llvm::Triple::PS4:
     return "ps4";
   }
diff --git a/lib/Basic/SourceLoc.cpp b/lib/Basic/SourceLoc.cpp
index 8c5736e..be77b46 100644
--- a/lib/Basic/SourceLoc.cpp
+++ b/lib/Basic/SourceLoc.cpp
@@ -137,7 +137,7 @@
   return It->second;
 }
 
-const char *SourceManager::getIdentifierForBuffer(unsigned bufferID) const {
+StringRef SourceManager::getIdentifierForBuffer(unsigned bufferID) const {
   auto *buffer = LLVMSourceMgr.getMemoryBuffer(bufferID);
   assert(buffer && "invalid buffer ID");
   return buffer->getBufferIdentifier();
diff --git a/lib/Basic/Unicode.cpp b/lib/Basic/Unicode.cpp
index 1fe3902..6e33133 100644
--- a/lib/Basic/Unicode.cpp
+++ b/lib/Basic/Unicode.cpp
@@ -22,14 +22,15 @@
   if (S.empty())
     return StringRef();
 
-  const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+  const llvm::UTF8 *SourceStart =
+    reinterpret_cast<const llvm::UTF8 *>(S.data());
 
-  const UTF8 *SourceNext = SourceStart;
-  UTF32 C[2];
-  UTF32 *TargetStart = C;
+  const llvm::UTF8 *SourceNext = SourceStart;
+  llvm::UTF32 C[2];
+  llvm::UTF32 *TargetStart = C;
 
   ConvertUTF8toUTF32(&SourceNext, SourceStart + S.size(), &TargetStart, C + 1,
-                     lenientConversion);
+                     llvm::lenientConversion);
   if (TargetStart == C) {
     // The source string contains an ill-formed subsequence at the end.
     return S;
@@ -42,7 +43,7 @@
 
     size_t C1Offset = SourceNext - SourceStart;
     ConvertUTF8toUTF32(&SourceNext, SourceStart + S.size(), &TargetStart, C + 2,
-                       lenientConversion);
+                       llvm::lenientConversion);
 
     if (TargetStart == C + 1) {
       // End of source string or the source string contains an ill-formed
@@ -65,14 +66,15 @@
   if (S.empty())
     return false;
 
-  const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+  const llvm::UTF8 *SourceStart =
+    reinterpret_cast<const llvm::UTF8 *>(S.data());
 
-  const UTF8 *SourceNext = SourceStart;
-  UTF32 C;
-  UTF32 *TargetStart = &C;
+  const llvm::UTF8 *SourceNext = SourceStart;
+  llvm::UTF32 C;
+  llvm::UTF32 *TargetStart = &C;
 
   ConvertUTF8toUTF32(&SourceNext, SourceStart + S.size(), &TargetStart,
-                     TargetStart + 1, lenientConversion);
+                     TargetStart + 1, llvm::lenientConversion);
   if (TargetStart == &C) {
     // The source string contains an ill-formed subsequence at the end.
     return false;
@@ -98,13 +100,14 @@
 uint64_t swift::unicode::getUTF16Length(StringRef Str) {
   uint64_t Length;
   // Transcode the string to UTF-16 to get its length.
-  SmallVector<UTF16, 128> buffer(Str.size() + 1); // +1 for ending nulls.
-  const UTF8 *fromPtr = (const UTF8 *) Str.data();
-  UTF16 *toPtr = &buffer[0];
-  ConversionResult Result = ConvertUTF8toUTF16(&fromPtr, fromPtr + Str.size(),
-                                               &toPtr, toPtr + Str.size(),
-                                               strictConversion);
-  assert(Result == conversionOK &&
+  SmallVector<llvm::UTF16, 128> buffer(Str.size() + 1); // +1 for ending nulls.
+  const llvm::UTF8 *fromPtr = (const llvm::UTF8 *) Str.data();
+  llvm::UTF16 *toPtr = &buffer[0];
+  llvm::ConversionResult Result =
+    ConvertUTF8toUTF16(&fromPtr, fromPtr + Str.size(),
+                       &toPtr, toPtr + Str.size(),
+                       llvm::strictConversion);
+  assert(Result == llvm::conversionOK &&
          "UTF-8 encoded string cannot be converted into UTF-16 encoding");
   (void)Result;
 
diff --git a/lib/Basic/Unix/TaskQueue.inc b/lib/Basic/Unix/TaskQueue.inc
index dabb35b..28e78d1 100644
--- a/lib/Basic/Unix/TaskQueue.inc
+++ b/lib/Basic/Unix/TaskQueue.inc
@@ -341,7 +341,7 @@
       }
 
       PollFds.push_back({ T->getPipe(), POLLIN | POLLPRI | POLLHUP, 0 });
-      // We should also poll T->getErrorPipe(), but this intrroduces timing
+      // We should also poll T->getErrorPipe(), but this introduces timing
       // issues with shutting down the task after reading getPipe().
       ExecutingTasks[Pid] = std::move(T);
     }
@@ -419,7 +419,7 @@
             if (Signalled) {
               TaskFinishedResponse Response =
                   Signalled(T.getPid(), ErrorMsg, T.getOutput(), T.getErrors(),
-                            T.getContext());
+                            T.getContext(), Signal);
               if (Response == TaskFinishedResponse::StopExecution)
                 // If we have a TaskCrashedCallback, only set SubtaskFailed to
                 // true if the callback returns StopExecution.
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index da36b42..20c5c97 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -199,8 +199,8 @@
            /*null-terminated=*/true);
     }
 
-    const char *getBufferIdentifier() const override {
-      return name.c_str();
+    StringRef getBufferIdentifier() const override {
+      return name;
     }
 
     BufferKind getBufferKind() const override {
@@ -690,12 +690,10 @@
                                                         diagClient.release());
 
   // Create a new Clang compiler invocation.
-  llvm::IntrusiveRefCntPtr<CompilerInvocation> invocation{
-    clang::createInvocationFromCommandLine(invocationArgs, clangDiags)
-  };
-  if (!invocation)
+  importer->Impl.Invocation =
+      clang::createInvocationFromCommandLine(invocationArgs, clangDiags);
+  if (!importer->Impl.Invocation)
     return nullptr;
-  importer->Impl.Invocation = invocation;
 
   // Don't stop emitting messages if we ever can't load a module.
   // FIXME: This is actually a general problem: any "fatal" error could mess up
@@ -711,17 +709,18 @@
   auto sourceBuffer = llvm::MemoryBuffer::getMemBuffer(
     "extern int __swift __attribute__((unavailable));",
     Implementation::moduleImportBufferName);
-  clang::PreprocessorOptions &ppOpts = invocation->getPreprocessorOpts();
+  clang::PreprocessorOptions &ppOpts =
+      importer->Impl.Invocation->getPreprocessorOpts();
   ppOpts.addRemappedFile(Implementation::moduleImportBufferName,
                          sourceBuffer.release());
 
   // Install a Clang module file extension to build Swift name lookup tables.
-  invocation->getFrontendOpts().ModuleFileExtensions.push_back(
-      new SwiftNameLookupExtension(importer->Impl.BridgingHeaderLookupTable,
-                                   importer->Impl.LookupTables,
-                                   importer->Impl.SwiftContext,
-                                   importer->Impl.platformAvailability,
-                                   importer->Impl.InferImportAsMember));
+  importer->Impl.Invocation->getFrontendOpts().ModuleFileExtensions.push_back(
+      std::make_shared<SwiftNameLookupExtension>(
+          importer->Impl.BridgingHeaderLookupTable,
+          importer->Impl.LookupTables, importer->Impl.SwiftContext,
+          importer->Impl.platformAvailability,
+          importer->Impl.InferImportAsMember));
 
   // Create a compiler instance.
   auto PCHContainerOperations =
@@ -733,7 +732,7 @@
   importer->Impl.Instance.reset(new CompilerInstance(PCHContainerOperations));
   auto &instance = *importer->Impl.Instance;
   instance.setDiagnostics(&*clangDiags);
-  instance.setInvocation(&*invocation);
+  instance.setInvocation(importer->Impl.Invocation);
 
   // Create the associated action.
   importer->Impl.Action.reset(new ParsingAction(ctx, *importer,
@@ -1035,9 +1034,9 @@
 std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
                                                      off_t &fileSize,
                                                      time_t &fileModTime) {
-  llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation{
-    new clang::CompilerInvocation(*Impl.Invocation)
-  };
+  auto invocation =
+      std::make_shared<clang::CompilerInvocation>(*Impl.Invocation);
+
   invocation->getFrontendOpts().DisableFree = false;
   invocation->getFrontendOpts().Inputs.clear();
   invocation->getFrontendOpts().Inputs.push_back(
@@ -1047,7 +1046,7 @@
 
   clang::CompilerInstance rewriteInstance(
     Impl.Instance->getPCHContainerOperations());
-  rewriteInstance.setInvocation(&*invocation);
+  rewriteInstance.setInvocation(invocation);
   rewriteInstance.createDiagnostics(new clang::IgnoringDiagConsumer);
 
   clang::FileManager &fileManager = Impl.Instance->getFileManager();
@@ -1082,9 +1081,8 @@
 bool
 ClangImporter::emitBridgingPCH(StringRef headerPath,
                                StringRef outputPCHPath) {
-  llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> invocation{
-    new clang::CompilerInvocation(*Impl.Invocation)
-  };
+  auto invocation = std::make_shared<clang::CompilerInvocation>
+    (clang::CompilerInvocation(*Impl.Invocation));
   invocation->getFrontendOpts().DisableFree = false;
   invocation->getFrontendOpts().Inputs.clear();
   invocation->getFrontendOpts().Inputs.push_back(
@@ -1094,7 +1092,7 @@
 
   clang::CompilerInstance emitInstance(
     Impl.Instance->getPCHContainerOperations());
-  emitInstance.setInvocation(&*invocation);
+  emitInstance.setInvocation(std::move(invocation));
   emitInstance.createDiagnostics(&Impl.Instance->getDiagnosticClient(),
                                  false);
 
@@ -2351,7 +2349,7 @@
   if (!clangModule)
     return "<imports>";
   if (const clang::FileEntry *F = clangModule->getASTFile())
-    if (F->getName())
+    if (!F->getName().empty())
       return F->getName();
   return StringRef();
 }
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 62b6d6a..7941489 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -30,6 +30,7 @@
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/Pattern.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Stmt.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/Fallthrough.h"
@@ -245,19 +246,19 @@
     switch(CTypeKind) {
     case MappedCTypeKind::FloatIEEEsingle:
       assert(Bitwidth == 32 && "FloatIEEEsingle should be 32 bits wide");
-      if (&Sem != &APFloat::IEEEsingle)
+      if (&Sem != &APFloat::IEEEsingle())
         return std::make_pair(Type(), "");
       break;
 
     case MappedCTypeKind::FloatIEEEdouble:
       assert(Bitwidth == 64 && "FloatIEEEdouble should be 64 bits wide");
-      if (&Sem != &APFloat::IEEEdouble)
+      if (&Sem != &APFloat::IEEEdouble())
         return std::make_pair(Type(), "");
       break;
 
     case MappedCTypeKind::FloatX87DoubleExtended:
       assert(Bitwidth == 80 && "FloatX87DoubleExtended should be 80 bits wide");
-      if (&Sem != &APFloat::x87DoubleExtended)
+      if (&Sem != &APFloat::x87DoubleExtended())
         return std::make_pair(Type(), "");
       break;
 
@@ -642,7 +643,7 @@
 
   // Reverse scan of the members because indirect field are generated just
   // after the corresponding anonymous type, so a reverse scan allows
-  // swiftching from O(n) to O(1) here.
+  // switching from O(n) to O(1) here.
   for (auto decl : reverse(members)) {
     if (decl->getClangDecl() == containingField) {
       anonymousFieldDecl = cast<VarDecl>(decl);
@@ -1556,8 +1557,11 @@
                                       /*Message=*/StringRef(),
                                       /*Rename=*/StringRef(),
                                       info.getOSVersion().getLowerEndpoint(),
+                                      /*IntroducedRange*/SourceRange(),
                                       /*Deprecated=*/noVersion,
+                                      /*DeprecatedRange*/SourceRange(),
                                       /*Obsoleted=*/noVersion,
+                                      /*ObsoletedRange*/SourceRange(),
                                       PlatformAgnosticAvailabilityKind::None,
                                       /*Implicit=*/false);
 
@@ -3457,10 +3461,21 @@
       Optional<ForeignErrorConvention> errorConvention;
       bodyParams.push_back(nullptr);
       Type type;
+
+      // If we have a property accessor, find the corresponding property
+      // declaration.
+      const clang::ObjCPropertyDecl *prop = nullptr;
       if (decl->isPropertyAccessor()) {
-        const clang::ObjCPropertyDecl *prop = decl->findPropertyDecl();
-        if (!prop)
-          return nullptr;
+        prop = decl->findPropertyDecl();
+        if (!prop) return nullptr;
+
+        // If we're importing just the accessors (not the property), ignore
+        // the property.
+        if (shouldImportPropertyAsAccessors(prop))
+          prop = nullptr;
+      }
+
+      if (prop) {
         // If the matching property is in a superclass, or if the getter and
         // setter are redeclared in a potentially incompatible way, bail out.
         if (prop->getGetterMethodDecl() != decl &&
@@ -6560,7 +6575,12 @@
       auto AvAttr = new (C) AvailableAttr(SourceLoc(), SourceRange(),
                                           platformK.getValue(),
                                           message, swiftReplacement,
-                                          introduced, deprecated, obsoleted,
+                                          introduced,
+                                          /*IntroducedRange=*/SourceRange(),
+                                          deprecated,
+                                          /*DeprecatedRange=*/SourceRange(),
+                                          obsoleted,
+                                          /*ObsoletedRange=*/SourceRange(),
                                           PlatformAgnostic, /*Implicit=*/false);
 
       MappedDecl->getAttrs().add(AvAttr);
diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp
index 6fe856b..68a8e65 100644
--- a/lib/ClangImporter/ImportName.cpp
+++ b/lib/ClangImporter/ImportName.cpp
@@ -572,10 +572,6 @@
       return FactoryAsInitKind::AsClassMethod;
   }
 
-  if (method->hasAttr<clang::SwiftSuppressFactoryAsInitAttr>()) {
-    return FactoryAsInitKind::AsClassMethod;
-  }
-
   return FactoryAsInitKind::Infer;
 }
 
diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h
index 81a7f90..fdb1c6c 100644
--- a/lib/ClangImporter/ImporterImpl.h
+++ b/lib/ClangImporter/ImporterImpl.h
@@ -302,7 +302,7 @@
   unsigned VerifiedImportCounter = 0;
 
   /// \brief Clang compiler invocation.
-  llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> Invocation;
+  std::shared_ptr<clang::CompilerInvocation> Invocation;
 
   /// \brief Clang compiler instance, which is used to actually load Clang
   /// modules.
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index ee3ef8a..b80e325 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -30,6 +30,7 @@
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/Support/Chrono.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
@@ -47,7 +48,7 @@
                          std::unique_ptr<InputArgList> InputArgs,
                          std::unique_ptr<DerivedArgList> TranslatedArgs,
                          InputFileList InputsWithTypes,
-                         StringRef ArgsHash, llvm::sys::TimeValue StartTime,
+                         StringRef ArgsHash, llvm::sys::TimePoint<> StartTime,
                          unsigned NumberOfParallelCommands,
                          bool EnableIncrementalBuild,
                          bool SkipTaskExecution,
@@ -162,7 +163,7 @@
                                     const InputInfoMap &inputs) {
   for (const auto &inputPair : inputs) {
     auto recordedModTime = inputPair.second.previousModTime;
-    if (recordedModTime == llvm::sys::TimeValue::MaxTime())
+    if (recordedModTime == llvm::sys::TimePoint<>::max())
       continue;
 
     const char *input = inputPair.first->getValue();
@@ -182,7 +183,7 @@
 }
 
 static void writeCompilationRecord(StringRef path, StringRef argsHash,
-                                   llvm::sys::TimeValue buildTime,
+                                   llvm::sys::TimePoint<> buildTime,
                                    const InputInfoMap &inputs) {
   // Before writing to the dependencies file path, preserve any previous file
   // that may have been there. No error handling -- this is just a nicety, it
@@ -197,8 +198,13 @@
     return;
   }
 
-  auto writeTimeValue = [](llvm::raw_ostream &out, llvm::sys::TimeValue time) {
-    out << "[" << time.seconds() << ", " << time.nanoseconds() << "]";
+  auto writeTimeValue = [](llvm::raw_ostream &out,
+                           llvm::sys::TimePoint<> time) {
+    using namespace std::chrono;
+    auto secs = time_point_cast<seconds>(time);
+    time -= secs.time_since_epoch(); // remainder in nanoseconds
+    out << "[" << secs.time_since_epoch().count()
+        << ", " << time.time_since_epoch().count() << "]";
   };
 
   using compilation_record::TopLevelKey;
@@ -436,7 +442,7 @@
   }
 
   int Result = EXIT_SUCCESS;
-  llvm::TimerGroup DriverTimerGroup("Driver Time Compilation");
+  llvm::TimerGroup DriverTimerGroup("driver", "Driver Compilation Time");
   llvm::SmallDenseMap<const Job *, std::unique_ptr<llvm::Timer>, 16>
     DriverTimers;
 
@@ -468,7 +474,7 @@
       DriverTimers.insert({
         BeganCmd,
         std::unique_ptr<llvm::Timer>(
-          new llvm::Timer(OS.str(), DriverTimerGroup))
+          new llvm::Timer("task", OS.str(), DriverTimerGroup))
       });
       DriverTimers[BeganCmd]->startTimer();
     }
@@ -619,7 +625,7 @@
 
   auto taskSignalled = [&](ProcessId Pid, StringRef ErrorMsg, StringRef Output,
                            StringRef Errors,
-                           void *Context) -> TaskFinishedResponse {
+                           void *Context, Optional<int> Signal) -> TaskFinishedResponse {
     const Job *SignalledCmd = (const Job *)Context;
 
     if (ShowDriverTimeCompilation) {
@@ -629,7 +635,7 @@
     if (Level == OutputLevel::Parseable) {
       // Parseable output was requested.
       parseable_output::emitSignalledMessage(llvm::errs(), *SignalledCmd, Pid,
-                                             ErrorMsg, Output);
+                                             ErrorMsg, Output, Signal);
     } else {
       // Otherwise, send the buffered output to stderr, though only if we
       // support getting buffered output.
@@ -640,9 +646,14 @@
     if (!ErrorMsg.empty())
       Diags.diagnose(SourceLoc(), diag::error_unable_to_execute_command,
                      ErrorMsg);
-
-    Diags.diagnose(SourceLoc(), diag::error_command_signalled,
-                   SignalledCmd->getSource().getClassName());
+    
+    if (Signal.hasValue()) {
+      Diags.diagnose(SourceLoc(), diag::error_command_signalled,
+                     SignalledCmd->getSource().getClassName(), Signal.getValue());
+    } else {
+      Diags.diagnose(SourceLoc(), diag::error_command_signalled_without_signal_number,
+                     SignalledCmd->getSource().getClassName());
+    }
 
     // Since the task signalled, unconditionally set result to -2.
     Result = -2;
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 8d2986c..3afa943 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -270,7 +270,7 @@
   bool optionsMatch = true;
 
   auto readTimeValue = [&scratch](yaml::Node *node,
-                                  llvm::sys::TimeValue &timeValue) -> bool {
+                                  llvm::sys::TimePoint<> &timeValue) -> bool {
     auto *seq = dyn_cast<yaml::SequenceNode>(node);
     if (!seq)
       return true;
@@ -282,7 +282,7 @@
     auto *secondsRaw = dyn_cast<yaml::ScalarNode>(&*seqI);
     if (!secondsRaw)
       return true;
-    llvm::sys::TimeValue::SecondsType parsedSeconds;
+    std::time_t parsedSeconds;
     if (secondsRaw->getValue(scratch).getAsInteger(10, parsedSeconds))
       return true;
 
@@ -293,7 +293,7 @@
     auto *nanosecondsRaw = dyn_cast<yaml::ScalarNode>(&*seqI);
     if (!nanosecondsRaw)
       return true;
-    llvm::sys::TimeValue::NanoSecondsType parsedNanoseconds;
+    std::chrono::system_clock::rep parsedNanoseconds;
     if (nanosecondsRaw->getValue(scratch).getAsInteger(10, parsedNanoseconds))
       return true;
 
@@ -301,8 +301,8 @@
     if (seqI != seqE)
       return true;
 
-    timeValue.seconds(parsedSeconds);
-    timeValue.nanoseconds(parsedNanoseconds);
+    timeValue = llvm::sys::TimePoint<>(std::chrono::seconds(parsedSeconds));
+    timeValue += std::chrono::nanoseconds(parsedNanoseconds);
     return false;
   };
 
@@ -346,7 +346,7 @@
         return failedToReadOutOfDateMap(ShowIncrementalBuildDecisions,
                                         buildRecordPath, reason);
       }
-      llvm::sys::TimeValue timeVal;
+      llvm::sys::TimePoint<> timeVal;
       if (readTimeValue(i->getValue(), timeVal))
         return true;
       map[nullptr] = { InputInfo::NeedsCascadingBuild, timeVal };
@@ -377,7 +377,7 @@
         if (!previousBuildState)
           return true;
 
-        llvm::sys::TimeValue timeValue;
+        llvm::sys::TimePoint<> timeValue;
         if (readTimeValue(value, timeValue))
           return true;
 
@@ -453,7 +453,7 @@
     ArrayRef<const char *> Args) {
   llvm::PrettyStackTraceString CrashInfo("Compilation construction");
 
-  llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now();
+  llvm::sys::TimePoint<> StartTime = std::chrono::system_clock::now();
 
   std::unique_ptr<InputArgList> ArgList(parseArgStrings(Args.slice(1)));
   if (Diags.hadAnyError())
@@ -1305,7 +1305,7 @@
 
         CompileJobAction::InputInfo previousBuildState = {
           CompileJobAction::InputInfo::NeedsCascadingBuild,
-          llvm::sys::TimeValue::MinTime()
+          llvm::sys::TimePoint<>::min()
         };
         if (OutOfDateMap)
           previousBuildState = OutOfDateMap->lookup(InputArg);
diff --git a/lib/Driver/ParseableOutput.cpp b/lib/Driver/ParseableOutput.cpp
index c2eecc1..89696ad 100644
--- a/lib/Driver/ParseableOutput.cpp
+++ b/lib/Driver/ParseableOutput.cpp
@@ -201,15 +201,17 @@
 
 class SignalledMessage : public TaskOutputMessage {
   std::string ErrorMsg;
+  Optional<int> Signal;
 public:
   SignalledMessage(const Job &Cmd, ProcessId Pid, StringRef Output,
-                   StringRef ErrorMsg) : TaskOutputMessage("signalled", Cmd,
-                                                           Pid, Output),
-                                         ErrorMsg(ErrorMsg) {}
+                   StringRef ErrorMsg, Optional<int> Signal) :
+      TaskOutputMessage("signalled", Cmd, Pid, Output), ErrorMsg(ErrorMsg),
+      Signal(Signal) {}
 
   void provideMapping(swift::json::Output &out) override {
     TaskOutputMessage::provideMapping(out);
     out.mapOptional("error-message", ErrorMsg, std::string());
+    out.mapOptional("signal", Signal);
   }
 };
 
@@ -260,8 +262,9 @@
 void parseable_output::emitSignalledMessage(raw_ostream &os,
                                             const Job &Cmd, ProcessId Pid,
                                             StringRef ErrorMsg,
-                                            StringRef Output) {
-  SignalledMessage msg(Cmd, Pid, Output, ErrorMsg);
+                                            StringRef Output,
+                                            Optional<int> Signal) {
+  SignalledMessage msg(Cmd, Pid, Output, ErrorMsg, Signal);
   emitMessage(os, msg);
 }
 
diff --git a/lib/Frontend/PrintingDiagnosticConsumer.cpp b/lib/Frontend/PrintingDiagnosticConsumer.cpp
index 983ff70..7a95c55 100644
--- a/lib/Frontend/PrintingDiagnosticConsumer.cpp
+++ b/lib/Frontend/PrintingDiagnosticConsumer.cpp
@@ -117,7 +117,7 @@
   // location to pull out the source line.
   SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
   std::pair<unsigned, unsigned> LineAndCol;
-  const char *BufferID = "<unknown>";
+  StringRef BufferID = "<unknown>";
   std::string LineStr;
 
   if (Loc.isValid()) {
diff --git a/lib/Frontend/SerializedDiagnosticConsumer.cpp b/lib/Frontend/SerializedDiagnosticConsumer.cpp
index be6bf78..fe00841 100644
--- a/lib/Frontend/SerializedDiagnosticConsumer.cpp
+++ b/lib/Frontend/SerializedDiagnosticConsumer.cpp
@@ -329,7 +329,8 @@
 }
 
 /// \brief Emit bitcode for abbreviation for source locations.
-static void addSourceLocationAbbrev(llvm::BitCodeAbbrev *Abbrev) {
+static void
+addSourceLocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> Abbrev) {
   using namespace llvm;
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // File ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Line.
@@ -338,13 +339,14 @@
 }
 
 /// \brief Emit bitcode for abbreviation for source ranges.
-static void addRangeLocationAbbrev(llvm::BitCodeAbbrev *Abbrev) {
+static void
+addRangeLocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> Abbrev) {
   addSourceLocationAbbrev(Abbrev);
   addSourceLocationAbbrev(Abbrev);
 }
 
 void SerializedDiagnosticConsumer::emitBlockInfoBlock() {
-  State->Stream.EnterBlockInfoBlock(3);
+  State->Stream.EnterBlockInfoBlock();
 
   using namespace llvm;
   llvm::BitstreamWriter &Stream = State->Stream;
@@ -357,7 +359,7 @@
 
   emitBlockID(BLOCK_META, "Meta", Stream, Record);
   emitRecordID(RECORD_VERSION, "Version", Stream, Record);
-  BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_VERSION));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
   Abbrevs.set(RECORD_VERSION, Stream.EmitBlockInfoAbbrev(BLOCK_META, Abbrev));
@@ -375,7 +377,7 @@
   emitRecordID(RECORD_FIXIT, "FixIt", Stream, Record);
 
   // Emit abbreviation for RECORD_DIAG.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_DIAG));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));  // Diag level.
   addSourceLocationAbbrev(Abbrev);
@@ -386,7 +388,7 @@
   Abbrevs.set(RECORD_DIAG, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
 
   // Emit abbreviation for RECORD_CATEGORY.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_CATEGORY));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Category ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));  // Text size.
@@ -394,14 +396,14 @@
   Abbrevs.set(RECORD_CATEGORY, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
 
   // Emit abbreviation for RECORD_SOURCE_RANGE.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_SOURCE_RANGE));
   addRangeLocationAbbrev(Abbrev);
   Abbrevs.set(RECORD_SOURCE_RANGE,
               Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
 
   // Emit the abbreviation for RECORD_DIAG_FLAG.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_DIAG_FLAG));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped Diag ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
@@ -410,7 +412,7 @@
                                                            Abbrev));
 
   // Emit the abbreviation for RECORD_FILENAME.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_FILENAME));
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped file ID.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Size.
@@ -421,7 +423,7 @@
                                                           Abbrev));
 
   // Emit the abbreviation for RECORD_FIXIT.
-  Abbrev = new BitCodeAbbrev();
+  Abbrev = std::make_shared<BitCodeAbbrev>();
   Abbrev->Add(BitCodeAbbrevOp(RECORD_FIXIT));
   addRangeLocationAbbrev(Abbrev);
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 5c997ba..659f9f3 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/Initializer.h"
 #include "swift/AST/LazyResolver.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/USRGeneration.h"
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/Fallthrough.h"
diff --git a/lib/IDE/CodeCompletionCache.cpp b/lib/IDE/CodeCompletionCache.cpp
index c30adc5..c1958d2 100644
--- a/lib/IDE/CodeCompletionCache.cpp
+++ b/lib/IDE/CodeCompletionCache.cpp
@@ -77,7 +77,7 @@
 
     llvm::sys::fs::file_status ModuleStatus;
     if (llvm::sys::fs::status(K.ModuleFilename, ModuleStatus)) {
-      V->ModuleModificationTime = llvm::sys::TimeValue::now();
+      V->ModuleModificationTime = std::chrono::system_clock::now();
       return;
     } else {
       V->ModuleModificationTime = ModuleStatus.getLastModificationTime();
@@ -153,7 +153,8 @@
     if (!allowOutOfDate) {
       llvm::sys::fs::file_status status;
       if (llvm::sys::fs::status(K.ModuleFilename, status) ||
-          status.getLastModificationTime().toEpochTime() != mtime) {
+          status.getLastModificationTime().time_since_epoch().count() !=
+          std::chrono::nanoseconds(mtime).count()) {
         return false; // Out of date, or doesn't exist.
       }
     }
@@ -293,7 +294,8 @@
   // HEADER
   // Metadata required for reading the completions.
   LE.write(onDiskCompletionCacheVersion);           // Version
-  LE.write(V.ModuleModificationTime.toEpochTime()); // Mtime for module file
+  auto mtime = V.ModuleModificationTime.time_since_epoch().count();
+  LE.write(mtime);                                  // Mtime for module file
 
   // KEY
   // We don't need the stored key to load the results, but it is useful if we
diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp
index 0a68bbb..6f0700d 100644
--- a/lib/IDE/Utils.cpp
+++ b/lib/IDE/Utils.cpp
@@ -246,9 +246,8 @@
   ClangArgList.insert(ClangArgList.end(), ArgList.begin(), ArgList.end());
 
   // Create a new Clang compiler invocation.
-  llvm::IntrusiveRefCntPtr<clang::CompilerInvocation> ClangInvok{
-    clang::createInvocationFromCommandLine(ClangArgList, ClangDiags)
-  };
+  std::unique_ptr<clang::CompilerInvocation> ClangInvok =
+      clang::createInvocationFromCommandLine(ClangArgList, ClangDiags);
   if (!ClangInvok || ClangDiags->hasErrorOccurred()) {
     for (auto I = DiagBuf.err_begin(), E = DiagBuf.err_end(); I != E; ++I) {
       Error += I->second;
@@ -342,7 +341,7 @@
     CCArgs.push_back(Entry);
   }
 
-  if (!ClangInvok->getLangOpts()->CompilingModule) {
+  if (!ClangInvok->getLangOpts()->isCompilingModule()) {
     CCArgs.push_back("-Xclang");
     llvm::SmallString<64> Str;
     Str += "-fmodule-name=";
diff --git a/lib/IRGen/GenBuiltin.cpp b/lib/IRGen/GenBuiltin.cpp
index ec335c8..e864d6e 100644
--- a/lib/IRGen/GenBuiltin.cpp
+++ b/lib/IRGen/GenBuiltin.cpp
@@ -125,7 +125,7 @@
   if (Builtin.ID == BuiltinValueKind::UnsafeGuaranteedEnd) {
     // Just consume the incoming argument.
     assert(args.size() == 1 && "Expecting one incoming argument");
-    args.claimAll();
+    (void)args.claimAll();
     return;
   }
 
@@ -146,7 +146,7 @@
 
   // These builtins don't care about their argument:
   if (Builtin.ID == BuiltinValueKind::Sizeof) {
-    args.claimAll();
+    (void)args.claimAll();
     auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM,
                                              substitutions[0].getReplacement());
     out.add(valueTy.second.getSize(IGF, valueTy.first));
@@ -154,7 +154,7 @@
   }
 
   if (Builtin.ID == BuiltinValueKind::Strideof) {
-    args.claimAll();
+    (void)args.claimAll();
     auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM,
                                              substitutions[0].getReplacement());
     out.add(valueTy.second.getStride(IGF, valueTy.first));
@@ -162,7 +162,7 @@
   }
 
   if (Builtin.ID == BuiltinValueKind::Alignof) {
-    args.claimAll();
+    (void)args.claimAll();
     auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM,
                                              substitutions[0].getReplacement());
     // The alignof value is one greater than the alignment mask.
@@ -173,7 +173,7 @@
   }
 
   if (Builtin.ID == BuiltinValueKind::IsPOD) {
-    args.claimAll();
+    (void)args.claimAll();
     auto valueTy = getLoweredTypeAndTypeInfo(IGF.IGM,
                                              substitutions[0].getReplacement());
     out.add(valueTy.second.getIsPOD(IGF, valueTy.first));
@@ -832,7 +832,7 @@
   }
   
   if (Builtin.ID == BuiltinValueKind::GetObjCTypeEncoding) {
-    args.claimAll();
+    (void)args.claimAll();
     Type valueTy = substitutions[0].getReplacement();
     // Get the type encoding for the associated clang type.
     auto clangTy = IGF.IGM.getClangType(valueTy->getCanonicalType());
diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp
index d55cc1b..450380b 100644
--- a/lib/IRGen/GenCall.cpp
+++ b/lib/IRGen/GenCall.cpp
@@ -552,17 +552,17 @@
     }
 
     llvm::Type *convertFloatingType(const llvm::fltSemantics &format) {
-      if (&format == &llvm::APFloat::IEEEhalf)
+      if (&format == &llvm::APFloat::IEEEhalf())
         return llvm::Type::getHalfTy(IGM.getLLVMContext());
-      if (&format == &llvm::APFloat::IEEEsingle)
+      if (&format == &llvm::APFloat::IEEEsingle())
         return llvm::Type::getFloatTy(IGM.getLLVMContext());
-      if (&format == &llvm::APFloat::IEEEdouble)
+      if (&format == &llvm::APFloat::IEEEdouble())
         return llvm::Type::getDoubleTy(IGM.getLLVMContext());
-      if (&format == &llvm::APFloat::IEEEquad)
+      if (&format == &llvm::APFloat::IEEEquad())
         return llvm::Type::getFP128Ty(IGM.getLLVMContext());
-      if (&format == &llvm::APFloat::PPCDoubleDouble)
+      if (&format == &llvm::APFloat::PPCDoubleDouble())
         return llvm::Type::getPPC_FP128Ty(IGM.getLLVMContext());
-      if (&format == &llvm::APFloat::x87DoubleExtended)
+      if (&format == &llvm::APFloat::x87DoubleExtended())
         return llvm::Type::getX86_FP80Ty(IGM.getLLVMContext());
       llvm_unreachable("bad float format");
     }
diff --git a/lib/IRGen/GenCast.cpp b/lib/IRGen/GenCast.cpp
index 762eee9..061afd4 100644
--- a/lib/IRGen/GenCast.cpp
+++ b/lib/IRGen/GenCast.cpp
@@ -759,7 +759,7 @@
     // value, which we don't need.
     // TODO: In existential-to-existential casts, we should carry over common
     // witness tables from the source to the destination.
-    value.claimAll();
+    (void)value.claimAll();
 
     SmallVector<ProtocolDecl*, 1> protocols;
 
diff --git a/lib/IRGen/GenClangDecl.cpp b/lib/IRGen/GenClangDecl.cpp
index 191a9cf..00b5a0e 100644
--- a/lib/IRGen/GenClangDecl.cpp
+++ b/lib/IRGen/GenClangDecl.cpp
@@ -50,9 +50,18 @@
   stack.push_back(decl);
 
   ClangDeclRefFinder refFinder([&](const clang::DeclRefExpr *DRE) {
-    const clang::ValueDecl *D = DRE->getDecl();
-    if (!D->hasLinkage() || D->isExternallyVisible())
-      return;
+    const clang::Decl *D = DRE->getDecl();
+    // Check that this is a file-level declaration and not inside a function.
+    // If it's a member of a file-level decl, like a C++ static member variable,
+    // we want to add the entire file-level declaration because Clang doesn't
+    // expect to see members directly here.
+    for (auto *DC = D->getDeclContext();; DC = DC->getParent()) {
+      if (DC->isFunctionOrMethod())
+        return;
+      if (DC->isFileContext())
+        break;
+      D = cast<const clang::Decl>(DC);
+    }
     if (!GlobalClangDecls.insert(D->getCanonicalDecl()).second)
       return;
     stack.push_back(D);
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 67da31e..072de50 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -23,6 +23,7 @@
 #include "swift/AST/Module.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/Pattern.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeMemberVisitor.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/Fallthrough.h"
@@ -824,7 +825,17 @@
   // Emit witness tables.
   for (SILWitnessTable &wt : PrimaryIGM->getSILModule().getWitnessTableList()) {
     CurrentIGMPtr IGM = getGenModule(wt.getConformance()->getDeclContext());
+#ifndef NDEBUG
+    IGM->EligibleConfs.collect(&wt);
+    IGM->CurrentWitnessTable = &wt;
+#endif
+
     IGM->emitSILWitnessTable(&wt);
+
+#ifndef NDEBUG
+    IGM->EligibleConfs.clear();
+    IGM->CurrentWitnessTable = nullptr;
+#endif
   }
   
   for (auto Iter : *this) {
@@ -937,7 +948,7 @@
     // For each eliminated method symbol create an alias to the stub.
     auto *alias = llvm::GlobalAlias::create(llvm::GlobalValue::ExternalLinkage,
                                             F.getName(), stub);
-    if (Triple.isOSBinFormatCOFF())
+    if (useDllStorage())
       alias->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
   }
 }
@@ -1049,7 +1060,8 @@
 
 static SILLinkage getConformanceLinkage(IRGenModule &IGM,
                                         const ProtocolConformance *conf) {
-  if (auto wt = IGM.getSILModule().lookUpWitnessTable(conf)) {
+  if (auto wt = IGM.getSILModule().lookUpWitnessTable(conf,
+                                               /*deserializeLazily*/ false)) {
     return wt->getLinkage();
   } else {
     return SILLinkage::PublicExternal;
@@ -1232,18 +1244,25 @@
     case Kind::SILGlobalVariable:
       return getSILGlobalVariable()->isFragile();
       
-    case Kind::DirectProtocolWitnessTable: {
-      if (auto wt = IGM.getSILModule().lookUpWitnessTable(
-              getProtocolConformance())) {
-        return wt->isFragile();
-      } else {
-        return false;
-      }
-    }
-      
+    case Kind::ReflectionAssociatedTypeDescriptor:
+    case Kind::ReflectionSuperclassDescriptor:
+      return false;
+
     default:
       break;
   }
+  if (isProtocolConformanceKind(getKind())) {
+    if (SILWitnessTable *wt = IGM.getSILModule().lookUpWitnessTable(
+                                            getProtocolConformance(), false)) {
+      SILLinkage L = wt->getLinkage();
+      // We don't deserialize the fragile attribute correctly. But we know that
+      // if the witness table was deserialized (= available externally) and it's
+      // not public, it must be fragile.
+      if (swift::isAvailableExternally(L) && !hasPublicVisibility(L))
+        return true;
+      return wt->isFragile();
+    }
+  }
   return false;
 }
 
@@ -1260,7 +1279,7 @@
 
   const auto ObjFormat = IGM.TargetInfo.OutputObjectFormat;
   bool IsELFObject = ObjFormat == llvm::Triple::ELF;
-  bool IsCOFFObject = ObjFormat == llvm::Triple::COFF;
+  bool UseDLLStorage = IGM.useDllStorage();
 
   // Use protected visibility for public symbols we define on ELF.  ld.so
   // doesn't support relative relocations at load time, which interferes with
@@ -1270,11 +1289,11 @@
       IsELFObject ? llvm::GlobalValue::ProtectedVisibility
                   : llvm::GlobalValue::DefaultVisibility;
   llvm::GlobalValue::DLLStorageClassTypes ExportedStorage =
-      IsCOFFObject ? llvm::GlobalValue::DLLExportStorageClass
-                   : llvm::GlobalValue::DefaultStorageClass;
+      UseDLLStorage ? llvm::GlobalValue::DLLExportStorageClass
+                    : llvm::GlobalValue::DefaultStorageClass;
   llvm::GlobalValue::DLLStorageClassTypes ImportedStorage =
-      IsCOFFObject ? llvm::GlobalValue::DLLImportStorageClass
-                   : llvm::GlobalValue::DefaultStorageClass;
+      UseDLLStorage ? llvm::GlobalValue::DLLImportStorageClass
+                    : llvm::GlobalValue::DefaultStorageClass;
 
   if (isFragile) {
     // Fragile functions/globals must be visible from outside, regardless of
@@ -1835,6 +1854,77 @@
   llvm_unreachable("bad reference kind");
 }
 
+void IRGenModule::checkEligibleConf(const ProtocolConformance *Conf) {
+#ifndef NDEBUG
+  if (EligibleConfs.isUsed(Conf))
+    return;
+
+  if (CurrentInst) {
+    llvm::errs() << "## Conformance: ";
+    Conf->dump();
+    llvm::errs() << "## Inst: ";
+    CurrentInst->dump();
+    llvm_unreachable(
+                "ConformanceCollector is missing a conformance in instruction");
+  }
+  if (CurrentWitnessTable) {
+    llvm_unreachable(
+              "ConformanceCollector is missing a conformance in witness table");
+  }
+#endif
+}
+
+void IRGenModule::checkEligibleMetaType(NominalTypeDecl *NT) {
+#ifndef NDEBUG
+  if (!NT || EligibleConfs.isMetaTypeEscaping(NT))
+    return;
+
+  if (CurrentInst) {
+    // Ignore instructions which may use a metatype but do not let escape it.
+    switch (CurrentInst->getKind()) {
+      case ValueKind::DestroyAddrInst:
+      case ValueKind::StructElementAddrInst:
+      case ValueKind::TupleElementAddrInst:
+      case ValueKind::InjectEnumAddrInst:
+      case ValueKind::SwitchEnumAddrInst:
+      case ValueKind::SelectEnumAddrInst:
+      case ValueKind::IndexAddrInst:
+      case ValueKind::RefElementAddrInst:
+      case ValueKind::RefTailAddrInst:
+      case ValueKind::TailAddrInst:
+      case ValueKind::AllocValueBufferInst:
+      case ValueKind::ProjectValueBufferInst:
+      case ValueKind::ProjectBoxInst:
+      case ValueKind::CopyAddrInst:
+      case ValueKind::UncheckedRefCastAddrInst:
+      case ValueKind::AllocStackInst:
+      case ValueKind::SuperMethodInst:
+      case ValueKind::WitnessMethodInst:
+      case ValueKind::DeallocRefInst:
+      case ValueKind::AllocGlobalInst:
+        return;
+      case ValueKind::ApplyInst:
+      case ValueKind::TryApplyInst:
+      case ValueKind::PartialApplyInst:
+        // It's not trivial to find the non-escaping vs. escaping meta-
+        // types of an apply. Therefore we just trust the ConformanceCollector
+        // that it does the right job.
+        return;
+      default:
+        break;
+    }
+    llvm::errs() << "## NominalType: " << NT->getName() << "\n## Inst: ";
+    CurrentInst->dump();
+    llvm_unreachable(
+                  "ConformanceCollector is missing a metatype in instruction");
+  }
+  if (CurrentWitnessTable) {
+    llvm_unreachable(
+                "ConformanceCollector is missing a metatype in witness table");
+  }
+#endif
+}
+
 /// A convenient wrapper around getAddrOfLLVMVariable which uses the
 /// default type as the definition type.
 llvm::Constant *
@@ -2368,6 +2458,7 @@
 IRGenModule::getAddrOfTypeMetadataAccessFunction(CanType type,
                                               ForDefinition_t forDefinition) {
   assert(!type->hasArchetype() && !type->hasTypeParameter());
+  checkEligibleMetaType(type->getNominalOrBoundGenericNominal());
   LinkEntity entity = LinkEntity::forTypeMetadataAccessFunction(type);
   llvm::Function *&entry = GlobalFuncs[entity];
   if (entry) {
@@ -2389,6 +2480,7 @@
                                            ForDefinition_t forDefinition) {
   assert(!genericArgs.empty());
   assert(nominal->isGenericContext());
+  checkEligibleMetaType(nominal);
 
   auto type = nominal->getDeclaredType()->getCanonicalType();
   assert(type->hasUnboundGenericType());
@@ -2411,6 +2503,7 @@
 IRGenModule::getAddrOfTypeMetadataLazyCacheVariable(CanType type,
                                               ForDefinition_t forDefinition) {
   assert(!type->hasArchetype() && !type->hasTypeParameter());
+  checkEligibleMetaType(type->getNominalOrBoundGenericNominal());
   LinkEntity entity = LinkEntity::forTypeMetadataLazyCacheVariable(type);
   return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
                                TypeMetadataPtrTy, DebugTypeInfo());
@@ -2570,6 +2663,7 @@
                                                SymbolReferenceKind refKind) {
   assert(isPattern || !isa<UnboundGenericType>(concreteType));
 
+  checkEligibleMetaType(concreteType->getNominalOrBoundGenericNominal());
   llvm::Type *defaultVarTy;
   unsigned adjustmentIndex;
   Alignment alignment = getPointerAlignment();
@@ -2664,6 +2758,7 @@
 llvm::Constant *IRGenModule::getAddrOfNominalTypeDescriptor(NominalTypeDecl *D,
                                                   llvm::Type *definitionType) {
   assert(definitionType && "not defining nominal type descriptor?");
+  checkEligibleMetaType(D);
   auto entity = LinkEntity::forNominalTypeDescriptor(D);
   return getAddrOfLLVMVariable(entity, getPointerAlignment(),
                                definitionType, definitionType,
@@ -2960,19 +3055,19 @@
   if (entry) return entry;
 
   // If not, first transcode it to UTF16.
-  SmallVector<UTF16, 128> buffer(utf8.size() + 1); // +1 for ending nulls.
-  const UTF8 *fromPtr = (const UTF8 *) utf8.data();
-  UTF16 *toPtr = &buffer[0];
+  SmallVector<llvm::UTF16, 128> buffer(utf8.size() + 1); // +1 for ending nulls.
+  const llvm::UTF8 *fromPtr = (const llvm::UTF8 *) utf8.data();
+  llvm::UTF16 *toPtr = &buffer[0];
   (void) ConvertUTF8toUTF16(&fromPtr, fromPtr + utf8.size(),
                             &toPtr, toPtr + utf8.size(),
-                            strictConversion);
+                            llvm::strictConversion);
 
   // The length of the transcoded string in UTF-8 code points.
   size_t utf16Length = toPtr - &buffer[0];
 
   // Null-terminate the UTF-16 string.
   *toPtr = 0;
-  ArrayRef<UTF16> utf16(&buffer[0], utf16Length + 1);
+  ArrayRef<llvm::UTF16> utf16(&buffer[0], utf16Length + 1);
 
   auto init = llvm::ConstantDataArray::get(LLVMContext, utf16);
   auto global = new llvm::GlobalVariable(Module, init->getType(), true,
@@ -3040,6 +3135,7 @@
 llvm::Constant *IRGenModule::
 getAddrOfGenericWitnessTableCache(const NormalProtocolConformance *conf,
                                   ForDefinition_t forDefinition) {
+  checkEligibleConf(conf);
   auto entity = LinkEntity::forGenericProtocolWitnessTableCache(conf);
   auto expectedTy = getGenericWitnessTableCacheTy();
   auto storageTy = (forDefinition ? expectedTy : nullptr);
@@ -3050,6 +3146,7 @@
 llvm::Function *
 IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
                                       const NormalProtocolConformance *conf) {
+  checkEligibleConf(conf);
   auto forDefinition = ForDefinition;
 
   LinkEntity entity =
@@ -3096,6 +3193,7 @@
 IRGenModule::getAddrOfWitnessTableAccessFunction(
                                       const NormalProtocolConformance *conf,
                                               ForDefinition_t forDefinition) {
+  checkEligibleConf(conf);
   LinkEntity entity = LinkEntity::forProtocolWitnessTableAccessFunction(conf);
   llvm::Function *&entry = GlobalFuncs[entity];
   if (entry) {
@@ -3122,6 +3220,7 @@
                                       const NormalProtocolConformance *conf,
                                               CanType conformingType,
                                               ForDefinition_t forDefinition) {
+  checkEligibleConf(conf);
   LinkEntity entity =
     LinkEntity::forProtocolWitnessTableLazyAccessFunction(conf, conformingType);
   llvm::Function *&entry = GlobalFuncs[entity];
@@ -3146,6 +3245,7 @@
                                               CanType conformingType,
                                               ForDefinition_t forDefinition) {
   assert(!conformingType->hasArchetype());
+  checkEligibleConf(conf);
   LinkEntity entity =
     LinkEntity::forProtocolWitnessTableLazyCacheVariable(conf, conformingType);
   return getAddrOfLLVMVariable(entity, getPointerAlignment(),
@@ -3162,6 +3262,7 @@
 llvm::Constant*
 IRGenModule::getAddrOfWitnessTable(const NormalProtocolConformance *conf,
                                    llvm::Type *storageTy) {
+  checkEligibleConf(conf);
   auto entity = LinkEntity::forDirectProtocolWitnessTable(conf);
   return getAddrOfLLVMVariable(entity, getPointerAlignment(), storageTy,
                                WitnessTableTy, DebugTypeInfo());
@@ -3171,6 +3272,7 @@
 IRGenModule::getAddrOfAssociatedTypeMetadataAccessFunction(
                                   const NormalProtocolConformance *conformance,
                                   AssociatedTypeDecl *associate) {
+  checkEligibleConf(conformance);
   auto forDefinition = ForDefinition;
 
   LinkEntity entity =
@@ -3192,6 +3294,7 @@
                                   const NormalProtocolConformance *conformance,
                                   AssociatedTypeDecl *associate,
                                   ProtocolDecl *associateProtocol) {
+  checkEligibleConf(conformance);
   auto forDefinition = ForDefinition;
 
   assert(conformance->getProtocol() == associate->getProtocol());
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index c9ab9c3..5a69a6b 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -304,7 +304,7 @@
     emitValueCaseTest(IRGenFunction &IGF,
                       Explosion &value,
                       EnumElementDecl *Case) const override {
-      value.claim(getExplosionSize());
+      (void)value.claim(getExplosionSize());
       return IGF.Builder.getInt1(true);
     }
     llvm::Value *
@@ -330,7 +330,7 @@
                          ArrayRef<std::pair<EnumElementDecl*,
                                             llvm::BasicBlock*>> dests,
                          llvm::BasicBlock *defaultDest) const override {
-      value.claim(getExplosionSize());
+      (void)value.claim(getExplosionSize());
       emitSingletonSwitch(IGF, dests, defaultDest);
     }
 
@@ -788,7 +788,7 @@
                           EnumElementDecl *elt,
                           Explosion &out) const override {
       // All of the cases project an empty explosion.
-      in.claim(getExplosionSize());
+      (void)in.claim(getExplosionSize());
     }
 
     void emitValueInjection(IRGenFunction &IGF,
@@ -1498,7 +1498,7 @@
         auto &loadableTI = getLoadablePayloadTypeInfo();
         loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
         loadableTI.copy(IGF, payloadValue, payloadCopy, Atomicity::Atomic);
-        payloadCopy.claimAll(); // FIXME: repack if not bit-identical
+        (void)payloadCopy.claimAll(); // FIXME: repack if not bit-identical
       }
 
       IGF.Builder.CreateBr(endBB);
@@ -2003,7 +2003,7 @@
       // Only the payload case has anything to project. The other cases are
       // empty.
       if (theCase != getPayloadElement()) {
-        inEnum.claim(getExplosionSize());
+        (void)inEnum.claim(getExplosionSize());
         return;
       }
 
@@ -2286,7 +2286,7 @@
 
       switch (CopyDestroyKind) {
       case POD:
-        src.claim(getExplosionSize());
+        (void)src.claim(getExplosionSize());
         return;
 
       case Normal: {
@@ -2316,7 +2316,7 @@
 
       switch (CopyDestroyKind) {
       case POD:
-        src.claim(getExplosionSize());
+        (void)src.claim(getExplosionSize());
         return;
 
       case Normal: {
@@ -2912,7 +2912,7 @@
 
         Explosion tmp;
         lti.copy(IGF, value, tmp, Atomicity::Atomic);
-        tmp.claimAll(); // FIXME: repack if not bit-identical
+        (void)tmp.claimAll(); // FIXME: repack if not bit-identical
       });
 
       IGF.Builder.CreateRetVoid();
@@ -3659,7 +3659,7 @@
 
       // Non-payload cases project to an empty explosion.
       if (foundPayload == ElementsWithPayload.end()) {
-        inValue.claim(getExplosionSize());
+        (void)inValue.claim(getExplosionSize());
         return;
       }
 
@@ -3964,7 +3964,7 @@
       assert(TIK >= Loadable);
       switch (CopyDestroyKind) {
       case POD:
-        src.claim(getExplosionSize());
+        (void)src.claim(getExplosionSize());
         return;
 
       case BitwiseTakable:
@@ -3997,7 +3997,7 @@
 
       switch (CopyDestroyKind) {
       case POD:
-        src.claim(getExplosionSize());
+        (void)src.claim(getExplosionSize());
         return;
 
       case BitwiseTakable:
diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp
index 370e1fc..cc16f51 100644
--- a/lib/IRGen/GenExistential.cpp
+++ b/lib/IRGen/GenExistential.cpp
@@ -17,8 +17,9 @@
 #include "GenExistential.h"
 
 #include "swift/AST/ASTContext.h"
-#include "swift/AST/Types.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/ProtocolConformance.h"
+#include "swift/AST/Types.h"
 #include "swift/SIL/SILValue.h"
 #include "swift/SIL/TypeLowering.h"
 #include "llvm/ADT/SmallString.h"
@@ -741,7 +742,7 @@
   /// Given an existential object, returns the payload value.
   llvm::Value *getValue(IRGenFunction &IGF, Explosion &container) const {
     llvm::Value *instance = container.claimNext();
-    container.claim(getNumStoredProtocols());
+    (void)container.claim(getNumStoredProtocols());
     return instance;
   }
 
@@ -806,7 +807,7 @@
     asDerived().emitValueRelease(IGF, value, atomicity);
 
     // Throw out the witness table pointers.
-    src.claim(getNumStoredProtocols());
+    (void)src.claim(getNumStoredProtocols());
   }
 
   void fixLifetime(IRGenFunction &IGF, Explosion &src) const override {
@@ -815,7 +816,7 @@
     asDerived().emitValueFixLifetime(IGF, value);
 
     // Throw out the witness table pointers.
-    src.claim(getNumStoredProtocols());
+    (void)src.claim(getNumStoredProtocols());
   }
 
   void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {
@@ -1067,34 +1068,34 @@
   void strongRetain(IRGenFunction &IGF, Explosion &e,
                     Atomicity atomicity) const override {
     IGF.emitStrongRetain(e.claimNext(), Refcounting, atomicity);
-    e.claim(getNumStoredProtocols());
+    (void)e.claim(getNumStoredProtocols());
   }
 
   void strongRelease(IRGenFunction &IGF, Explosion &e,
                      Atomicity atomicity) const override {
     IGF.emitStrongRelease(e.claimNext(), Refcounting, atomicity);
-    e.claim(getNumStoredProtocols());
+    (void)e.claim(getNumStoredProtocols());
   }
 
   void strongRetainUnowned(IRGenFunction &IGF, Explosion &e) const override {
     IGF.emitStrongRetainUnowned(e.claimNext(), Refcounting);
-    e.claim(getNumStoredProtocols());
+    (void)e.claim(getNumStoredProtocols());
   }
 
   void strongRetainUnownedRelease(IRGenFunction &IGF,
                                   Explosion &e) const override {
     IGF.emitStrongRetainAndUnownedRelease(e.claimNext(), Refcounting);
-    e.claim(getNumStoredProtocols());
+    (void)e.claim(getNumStoredProtocols());
   }
 
   void unownedRetain(IRGenFunction &IGF, Explosion &e) const override {
     IGF.emitUnownedRetain(e.claimNext(), Refcounting);
-    e.claim(getNumStoredProtocols());
+    (void)e.claim(getNumStoredProtocols());
   }
 
   void unownedRelease(IRGenFunction &IGF, Explosion &e) const override {
     IGF.emitUnownedRelease(e.claimNext(), Refcounting);
-    e.claim(getNumStoredProtocols());
+    (void)e.claim(getNumStoredProtocols());
   }
 
   void unownedLoadStrong(IRGenFunction &IGF, Address existential,
diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp
index 4523a40..46bf437 100644
--- a/lib/IRGen/GenFunc.cpp
+++ b/lib/IRGen/GenFunc.cpp
@@ -1511,7 +1511,7 @@
   auto NSConcreteStackBlock =
       IGF.IGM.getModule()->getOrInsertGlobal("_NSConcreteStackBlock",
                                              IGF.IGM.ObjCClassStructTy);
-  if (IGF.IGM.Triple.isOSBinFormatCOFF())
+  if (IGF.IGM.useDllStorage())
     cast<llvm::GlobalVariable>(NSConcreteStackBlock)
         ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index bcbc3ad..fb4a227 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -4035,7 +4035,7 @@
                                           metadata->getLinkage(),
                                           classSymbol.str(), metadata,
                                           IGM.getModule());
-  if (IGM.TargetInfo.OutputObjectFormat == llvm::Triple::COFF)
+  if (IGM.useDllStorage())
     alias->setDLLStorageClass(metadata->getDLLStorageClass());
 }
 
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index f57cc59..a8248e4 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -36,7 +36,7 @@
 #include "swift/SILOptimizer/PassManager/PassPipeline.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/CodeGen/BasicTTIImpl.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
@@ -61,6 +61,7 @@
 #include "llvm/Target/TargetSubtargetInfo.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Object/ObjectFile.h"
@@ -163,7 +164,7 @@
     PMBuilder.OptLevel = 0;
     if (!Opts.DisableLLVMOptzns)
       PMBuilder.Inliner =
-        llvm::createAlwaysInlinerPass(/*insertlifetime*/false);
+        llvm::createAlwaysInlinerLegacyPass(/*insertlifetime*/false);
   }
 
   // If the optimizer is enabled, we run the ARCOpt pass in the scalar optimizer
@@ -496,10 +497,13 @@
   }
 
   // Create a target machine.
-  llvm::TargetMachine *TargetMachine
-    = Target->createTargetMachine(Triple.str(), CPU,
-                                  targetFeatures, TargetOpts, Reloc::PIC_,
-                                  CodeModel::Default, OptLevel);
+  auto cmodel = CodeModel::Default;
+  if (Triple.isWindowsCygwinEnvironment())
+    cmodel = CodeModel::Large;
+
+  llvm::TargetMachine *TargetMachine =
+      Target->createTargetMachine(Triple.str(), CPU, targetFeatures, TargetOpts,
+                                  Reloc::PIC_, cmodel, OptLevel);
   if (!TargetMachine) {
     Ctx.Diags.diagnose(SourceLoc(), diag::no_llvm_target,
                        Triple.str(), "no LLVM target machine");
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index b312af6..8c86ecb 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -135,12 +135,12 @@
   // Note that File + Dir need not result in a valid path.
   // Clang is doing the same thing here.
   TheCU = DBuilder.createCompileUnit(
-      Lang, AbsMainFile, Opts.DebugCompilationDir, Producer, IsOptimized,
-      Flags, MajorRuntimeVersion, SplitName,
+      Lang, DBuilder.createFile(AbsMainFile, Opts.DebugCompilationDir),
+      Producer, IsOptimized, Flags, MajorRuntimeVersion, SplitName,
       Opts.DebugInfoKind > IRGenDebugInfoKind::LineTables
           ? llvm::DICompileUnit::FullDebug
           : llvm::DICompileUnit::LineTablesOnly);
-  MainFile = getOrCreateFile(BumpAllocatedString(AbsMainFile).data());
+  MainFile = getOrCreateFile(BumpAllocatedString(AbsMainFile));
 
   // Because the swift compiler relies on Clang to setup the Module,
   // the clang CU is always created first.  Several dwarf-reading
@@ -162,22 +162,15 @@
   DBuilder.createImportedModule(MainFile, MainModule, 1);
 }
 
-static const char *getFilenameFromDC(const DeclContext *DC) {
-  if (auto LF = dyn_cast<LoadedFile>(DC)) {
-    // FIXME: Today, the subclasses of LoadedFile happen to return StringRefs
-    // that are backed by null-terminated strings, but that's certainly not
-    // guaranteed in the future.
-    StringRef Fn = LF->getFilename();
-    assert(((Fn.size() == 0) ||
-            (Fn.data()[Fn.size()] == '\0')) && "not a C string");
-    return Fn.data();
-  }
+static StringRef getFilenameFromDC(const DeclContext *DC) {
+  if (auto LF = dyn_cast<LoadedFile>(DC))
+    return LF->getFilename();
   if (auto SF = dyn_cast<SourceFile>(DC))
-    return SF->getFilename().data();
+    return SF->getFilename();
   else if (auto M = dyn_cast<ModuleDecl>(DC))
-    return M->getModuleFilename().data();
+    return M->getModuleFilename();
   else
-    return nullptr;
+    return StringRef();
 }
 
 SILLocation::DebugLoc getDeserializedLoc(Pattern *) { return {}; }
@@ -186,7 +179,8 @@
 SILLocation::DebugLoc getDeserializedLoc(Decl *D) {
   SILLocation::DebugLoc L;
   const DeclContext *DC = D->getDeclContext()->getModuleScopeContext();
-  if (const char *Filename = getFilenameFromDC(DC))
+  StringRef Filename = getFilenameFromDC(DC);
+  if (!Filename.empty())
     L.Filename = Filename;
   return L;
 }
@@ -413,8 +407,8 @@
   return DScope;
 }
 
-llvm::DIFile *IRGenDebugInfo::getOrCreateFile(const char *Filename) {
-  if (!Filename)
+llvm::DIFile *IRGenDebugInfo::getOrCreateFile(StringRef Filename) {
+  if (Filename.empty())
     return MainFile;
 
   if (MainFile) {
@@ -678,7 +672,7 @@
 
   // We know that main always comes from MainFile.
   if (LinkageName == SWIFT_ENTRY_POINT_FUNCTION) {
-    if (!L.Filename)
+    if (L.Filename.empty())
       File = MainFile;
     Line = 1;
     Name = LinkageName;
@@ -696,7 +690,7 @@
   bool IsLocalToUnit = Fn ? Fn->hasInternalLinkage() : true;
   bool IsDefinition = true;
   bool IsOptimized = Opts.Optimize;
-  unsigned Flags = 0;
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
 
   // Mark everything that is not visible from the source code (i.e.,
   // does not have a Swift name) as artificial, so the debugger can
@@ -761,8 +755,7 @@
 
 llvm::DIModule *
 IRGenDebugInfo::getOrCreateModule(ModuleDecl::ImportedModule M) {
-  const char *fn = getFilenameFromDC(M.second);
-  StringRef Path(fn ? fn : "");
+  StringRef Path = getFilenameFromDC(M.second);
   if (M.first.empty()) {
     StringRef Name = M.second->getName().str();
     return getOrCreateModule(Name, TheCU, Name, Path);
@@ -908,7 +901,7 @@
   assert(DITy && "could not determine debug type of variable");
 
   unsigned Line = Loc.Line;
-  unsigned Flags = 0;
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (Artificial || DITy->isArtificial() || DITy == InternalType)
     Flags |= llvm::DINode::FlagArtificial;
 
@@ -1025,8 +1018,8 @@
 
   // Emit it as global variable of the current module.
   auto *Expr = Var ? nullptr : DBuilder.createConstantValueExpression(0);
-  auto *GV = DBuilder.createGlobalVariable(MainModule, Name, LinkageName, File,
-                                           L.Line, Ty, IsLocalToUnit, Expr);
+  auto *GV = DBuilder.createGlobalVariableExpression(
+      MainModule, Name, LinkageName, File, L.Line, Ty, IsLocalToUnit, Expr);
   if (Var)
     Var->addDebugInfo(GV);
 }
@@ -1043,7 +1036,8 @@
 llvm::DIDerivedType *
 IRGenDebugInfo::createMemberType(DebugTypeInfo DbgTy, StringRef Name,
                                  unsigned &OffsetInBits, llvm::DIScope *Scope,
-                                 llvm::DIFile *File, unsigned Flags) {
+                                 llvm::DIFile *File,
+                                 llvm::DINode::DIFlags Flags) {
   unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
   auto *Ty = getOrCreateType(DbgTy);
   auto *DITy = DBuilder.createMemberType(
@@ -1057,7 +1051,8 @@
 
 llvm::DINodeArray IRGenDebugInfo::getTupleElements(
     TupleType *TupleTy, llvm::DIScope *Scope, llvm::DIFile *File,
-    unsigned Flags, DeclContext *DeclContext, unsigned &SizeInBits) {
+    llvm::DINode::DIFlags Flags, DeclContext *DeclContext,
+    unsigned &SizeInBits) {
   SmallVector<llvm::Metadata *, 16> Elements;
   unsigned OffsetInBits = 0;
   auto genericSig = IGM.getSILTypes().getCurGenericContext();
@@ -1077,7 +1072,8 @@
 llvm::DINodeArray
 IRGenDebugInfo::getStructMembers(NominalTypeDecl *D, Type BaseTy,
                                  llvm::DIScope *Scope, llvm::DIFile *File,
-                                 unsigned Flags, unsigned &SizeInBits) {
+                                 llvm::DINode::DIFlags Flags,
+                                 unsigned &SizeInBits) {
   SmallVector<llvm::Metadata *, 16> Elements;
   unsigned OffsetInBits = 0;
   for (VarDecl *VD : D->getStoredProperties()) {
@@ -1099,7 +1095,7 @@
 llvm::DICompositeType *IRGenDebugInfo::createStructType(
     DebugTypeInfo DbgTy, NominalTypeDecl *Decl, Type BaseTy,
     llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
-    unsigned SizeInBits, unsigned AlignInBits, unsigned Flags,
+    unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
     llvm::DIType *DerivedFrom, unsigned RuntimeLang, StringRef UniqueID) {
   StringRef Name = Decl->getName().str();
 
@@ -1132,7 +1128,7 @@
                                                   EnumDecl *ED,
                                                   llvm::DIScope *Scope,
                                                   llvm::DIFile *File,
-                                                  unsigned Flags) {
+                                                  llvm::DINode::DIFlags Flags) {
   SmallVector<llvm::Metadata *, 16> Elements;
 
   for (auto *ElemDecl : ED->getAllElements()) {
@@ -1172,7 +1168,8 @@
 
 llvm::DICompositeType *IRGenDebugInfo::createEnumType(
     DebugTypeInfo DbgTy, EnumDecl *Decl, StringRef MangledName,
-    llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line, unsigned Flags) {
+    llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
+    llvm::DINode::DIFlags Flags) {
   unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
   unsigned SizeInBits = DbgTy.size.getValue() * SizeOfByte;
   unsigned AlignInBits = DbgTy.align.getValue() * SizeOfByte;
@@ -1222,7 +1219,7 @@
 
 llvm::DIType *IRGenDebugInfo::createPointerSizedStruct(
     llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
-    unsigned Flags, StringRef MangledName) {
+    llvm::DINode::DIFlags Flags, StringRef MangledName) {
   if (Opts.DebugInfoKind > IRGenDebugInfoKind::ASTTypes) {
     auto FwdDecl = DBuilder.createForwardDecl(
         llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
@@ -1239,7 +1236,8 @@
 
 llvm::DIType *IRGenDebugInfo::createPointerSizedStruct(
     llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
-    llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName) {
+    llvm::DIFile *File, unsigned Line, llvm::DINode::DIFlags Flags,
+    StringRef MangledName) {
   unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
   unsigned PtrAlign = CI.getTargetInfo().getPointerAlign(0);
   auto PtrTy = DBuilder.createPointerType(PointeeTy, PtrSize, PtrAlign);
@@ -1255,7 +1253,8 @@
 
 llvm::DIType *IRGenDebugInfo::createDoublePointerSizedStruct(
     llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
-    llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName) {
+    llvm::DIFile *File, unsigned Line, llvm::DINode::DIFlags Flags,
+    StringRef MangledName) {
   unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
   unsigned PtrAlign = CI.getTargetInfo().getPointerAlign(0);
   llvm::Metadata *Elements[] = {
@@ -1274,7 +1273,8 @@
 llvm::DIType *
 IRGenDebugInfo::createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                                       unsigned SizeInBits, unsigned AlignInBits,
-                                      unsigned Flags, StringRef MangledName) {
+                                      llvm::DINode::DIFlags Flags,
+                                      StringRef MangledName) {
   auto FwdDecl = llvm::TempDINode(DBuilder.createReplaceableCompositeType(
       llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, MainFile, 0,
       llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags, MangledName));
@@ -1322,7 +1322,8 @@
 llvm::DIType *IRGenDebugInfo::createTuple(DebugTypeInfo DbgTy,
                                           llvm::DIScope *Scope,
                                           unsigned SizeInBits,
-                                          unsigned AlignInBits, unsigned Flags,
+                                          unsigned AlignInBits,
+                                          llvm::DINode::DIFlags Flags,
                                           StringRef MangledName) {
   TypeBase *BaseTy = DbgTy.getType();
   auto *TupleTy = BaseTy->castTo<TupleType>();
@@ -1352,7 +1353,8 @@
 IRGenDebugInfo::createOpaqueStruct(llvm::DIScope *Scope, StringRef Name,
                                    llvm::DIFile *File, unsigned Line,
                                    unsigned SizeInBits, unsigned AlignInBits,
-                                   unsigned Flags, StringRef MangledName) {
+                                   llvm::DINode::DIFlags Flags,
+                                   StringRef MangledName) {
   return DBuilder.createStructType(
       Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
       /* DerivedFrom */ nullptr,
@@ -1373,7 +1375,7 @@
   uint64_t SizeInBits = DbgTy.size.getValue() * SizeOfByte;
   uint64_t AlignInBits = DbgTy.align.getValue() * SizeOfByte;
   unsigned Encoding = 0;
-  unsigned Flags = 0;
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
 
   TypeBase *BaseTy = DbgTy.getType();
 
@@ -1757,8 +1759,7 @@
           llvm::errs() << "\n");
     MangledName = "<unknown>";
   }
-  return DBuilder.createBasicType(MangledName, SizeInBits, AlignInBits,
-                                  Encoding);
+  return DBuilder.createBasicType(MangledName, SizeInBits, Encoding);
 }
 
 /// Determine if there exists a name mangling for the given type.
diff --git a/lib/IRGen/IRGenDebugInfo.h b/lib/IRGen/IRGenDebugInfo.h
index de0ed6f..3d645dd 100644
--- a/lib/IRGen/IRGenDebugInfo.h
+++ b/lib/IRGen/IRGenDebugInfo.h
@@ -63,7 +63,7 @@
 
   // Various caches.
   llvm::DenseMap<const SILDebugScope *, llvm::TrackingMDNodeRef> ScopeCache;
-  llvm::DenseMap<const char *, llvm::TrackingMDNodeRef> DIFileCache;
+  llvm::DenseMap<llvm::StringRef, llvm::TrackingMDNodeRef> DIFileCache;
   llvm::DenseMap<TypeBase *, llvm::TrackingMDNodeRef> DITypeCache;
   llvm::StringMap<llvm::TrackingMDNodeRef> DIModuleCache;
   TrackingDIRefMap DIRefMap;
@@ -243,7 +243,7 @@
   llvm::MDNode *createInlinedAt(const SILDebugScope *CallSite);
 
   /// Translate filenames into DIFiles.
-  llvm::DIFile *getOrCreateFile(const char *Filename);
+  llvm::DIFile *getOrCreateFile(StringRef Filename);
   /// Return a DIType for Ty reusing any DeclContext found in DbgTy.
   llvm::DIType *getOrCreateDesugaredType(Type Ty, DebugTypeInfo DbgTy);
 
@@ -266,7 +266,8 @@
                            SILType CanTy, DeclContext *DeclCtx);
   /// Return an array with the DITypes for each of a tuple's elements.
   llvm::DINodeArray getTupleElements(TupleType *TupleTy, llvm::DIScope *Scope,
-                                     llvm::DIFile *File, unsigned Flags,
+                                     llvm::DIFile *File,
+                                     llvm::DINode::DIFlags Flags,
                                      DeclContext *DeclContext,
                                      unsigned &SizeInBits);
   llvm::DIFile *getFile(llvm::DIScope *Scope);
@@ -278,13 +279,15 @@
   /// Return an array with the DITypes for each of a struct's elements.
   llvm::DINodeArray getStructMembers(NominalTypeDecl *D, Type BaseTy,
                                      llvm::DIScope *Scope, llvm::DIFile *File,
-                                     unsigned Flags, unsigned &SizeInBits);
+                                     llvm::DINode::DIFlags Flags,
+                                     unsigned &SizeInBits);
   /// Create a temporary forward declaration for a struct and add it to
   /// the type cache so we can safely build recursive types.
   llvm::DICompositeType *
   createStructType(DebugTypeInfo DbgTy, NominalTypeDecl *Decl, Type BaseTy,
                    llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
-                   unsigned SizeInBits, unsigned AlignInBits, unsigned Flags,
+                   unsigned SizeInBits, unsigned AlignInBits,
+                   llvm::DINode::DIFlags Flags,
                    llvm::DIType *DerivedFrom, unsigned RuntimeLang,
                    StringRef UniqueID);
 
@@ -292,49 +295,55 @@
   llvm::DIDerivedType *createMemberType(DebugTypeInfo DbgTy, StringRef Name,
                                         unsigned &OffsetInBits,
                                         llvm::DIScope *Scope,
-                                        llvm::DIFile *File, unsigned Flags);
+                                        llvm::DIFile *File,
+                                        llvm::DINode::DIFlags Flags);
   /// Return an array with the DITypes for each of an enum's elements.
   llvm::DINodeArray getEnumElements(DebugTypeInfo DbgTy, EnumDecl *D,
                                     llvm::DIScope *Scope, llvm::DIFile *File,
-                                    unsigned Flags);
+                                    llvm::DINode::DIFlags Flags);
   /// Create a temporary forward declaration for an enum and add it to
   /// the type cache so we can safely build recursive types.
   llvm::DICompositeType *createEnumType(DebugTypeInfo DbgTy, EnumDecl *Decl,
                                         StringRef MangledName,
                                         llvm::DIScope *Scope,
                                         llvm::DIFile *File, unsigned Line,
-                                        unsigned Flags);
+                                        llvm::DINode::DIFlags Flags);
   /// Convenience function that creates a forward declaration for PointeeTy.
   llvm::DIType *createPointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                          llvm::DIFile *File, unsigned Line,
-                                         unsigned Flags, StringRef MangledName);
+                                         llvm::DINode::DIFlags Flags,
+                                         StringRef MangledName);
   /// Create a pointer-sized struct with a mangled name and a single
   /// member of PointeeTy.
   llvm::DIType *createPointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                          llvm::DIType *PointeeTy,
                                          llvm::DIFile *File, unsigned Line,
-                                         unsigned Flags, StringRef MangledName);
+                                         llvm::DINode::DIFlags Flags,
+                                         StringRef MangledName);
   /// Create a 2*pointer-sized struct with a mangled name and a single
   /// member of PointeeTy.
   llvm::DIType *createDoublePointerSizedStruct(
       llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
-      llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName);
+      llvm::DIFile *File, unsigned Line, llvm::DINode::DIFlags Flags,
+      StringRef MangledName);
 
   /// Create DWARF debug info for a function pointer type.
   llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                                       unsigned SizeInBits, unsigned AlignInBits,
-                                      unsigned Flags, StringRef MangledName);
+                                      llvm::DINode::DIFlags Flags,
+                                      StringRef MangledName);
 
   /// Create DWARF debug info for a tuple type.
   llvm::DIType *createTuple(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                             unsigned SizeInBits, unsigned AlignInBits,
-                            unsigned Flags, StringRef MangledName);
+                            llvm::DINode::DIFlags Flags, StringRef MangledName);
 
   /// Create an opaque struct with a mangled name.
   llvm::DIType *createOpaqueStruct(llvm::DIScope *Scope, StringRef Name,
                                    llvm::DIFile *File, unsigned Line,
                                    unsigned SizeInBits, unsigned AlignInBits,
-                                   unsigned Flags, StringRef MangledName);
+                                   llvm::DINode::DIFlags Flags,
+                                   StringRef MangledName);
   uint64_t getSizeOfBasicType(DebugTypeInfo DbgTy);
   TypeAliasDecl *getMetadataType();
 };
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 8e22a64..a87e70f 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -117,6 +117,11 @@
   return ClangCodeGen;
 }
 
+/// A helper for determining if the triple uses the DLL storage
+static bool useDllStorage(const llvm::Triple &Triple) {
+  return Triple.isOSBinFormatCOFF() && !Triple.isOSCygMing();
+}
+
 IRGenModule::IRGenModule(IRGenerator &irgen,
                          std::unique_ptr<llvm::TargetMachine> &&target,
                          SourceFile *SF, llvm::LLVMContext &LLVMContext,
@@ -127,6 +132,9 @@
       Module(*ClangCodeGen->GetModule()), LLVMContext(Module.getContext()),
       DataLayout(target->createDataLayout()), Triple(Context.LangOpts.Target),
       TargetMachine(std::move(target)), OutputFilename(OutputFilename),
+#ifndef NDEBUG
+      EligibleConfs(getSILModule()),
+#endif
       TargetInfo(SwiftTargetInfo::get(*this)), DebugInfo(nullptr),
       ModuleHash(nullptr), ObjCInterop(Context.LangOpts.EnableObjCInterop),
       Types(*new TypeConverter(*this)) {
@@ -439,7 +447,7 @@
   if (auto fn = dyn_cast<llvm::Function>(cache)) {
     fn->setCallingConv(cc);
 
-    if (llvm::Triple(Module.getTargetTriple()).isOSBinFormatCOFF() &&
+    if (::useDllStorage(llvm::Triple(Module.getTargetTriple())) &&
         (fn->getLinkage() == llvm::GlobalValue::ExternalLinkage ||
          fn->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage))
       fn->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
@@ -519,7 +527,7 @@
     auto *globalFnPtr = new llvm::GlobalVariable(
         Module, fnPtrTy, false, llvm::GlobalValue::ExternalLinkage, nullptr,
         symbol);
-    if (llvm::Triple(Module.getTargetTriple()).isOSBinFormatCOFF())
+    if (::useDllStorage(llvm::Triple(Module.getTargetTriple())))
       globalFnPtr->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
 
     // Forward all arguments.
@@ -638,7 +646,7 @@
   EmptyTupleMetadata = Module.getOrInsertGlobal(
                           MANGLE_AS_STRING(METADATA_SYM(EMPTY_TUPLE_MANGLING)),
                           FullTypeMetadataStructTy);
-  if (Triple.isOSBinFormatCOFF())
+  if (useDllStorage())
     cast<llvm::GlobalVariable>(EmptyTupleMetadata)
         ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
   return EmptyTupleMetadata;
@@ -652,7 +660,7 @@
     // struct objc_cache _objc_empty_cache;
     ObjCEmptyCachePtr = Module.getOrInsertGlobal("_objc_empty_cache",
                                                  OpaquePtrTy->getElementType());
-    if (Triple.isOSBinFormatCOFF())
+    if (useDllStorage())
       cast<llvm::GlobalVariable>(ObjCEmptyCachePtr)
           ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
   } else {
@@ -685,7 +693,7 @@
   assert(TargetInfo.hasISAMasking());
   if (!ObjCISAMaskPtr) {
     ObjCISAMaskPtr = Module.getOrInsertGlobal("swift_isaMask", IntPtrTy);
-    if (Triple.isOSBinFormatCOFF())
+    if (useDllStorage())
       cast<llvm::GlobalVariable>(ObjCISAMaskPtr)
           ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
   }
@@ -851,7 +859,7 @@
     llvm::SmallString<64> buf;
     encodeForceLoadSymbolName(buf, linkLib.getName());
     auto symbolAddr = Module.getOrInsertGlobal(buf.str(), Int1Ty);
-    if (Triple.isOSBinFormatCOFF())
+    if (useDllStorage())
       cast<llvm::GlobalVariable>(symbolAddr)
           ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
 
@@ -916,9 +924,9 @@
                                        }),
                         AutolinkEntries.end());
 
-  if (TargetInfo.OutputObjectFormat == llvm::Triple::COFF ||
-      TargetInfo.OutputObjectFormat == llvm::Triple::MachO ||
-      Triple.isPS4()) {
+  if ((TargetInfo.OutputObjectFormat == llvm::Triple::COFF &&
+       !Triple.isOSCygMing()) ||
+      TargetInfo.OutputObjectFormat == llvm::Triple::MachO || Triple.isPS4()) {
     llvm::LLVMContext &ctx = Module.getContext();
 
     if (!LinkerOptions) {
@@ -935,8 +943,9 @@
       assert(FoundOldEntry && "Could not replace old linker options entry?");
     }
   } else {
-    assert(TargetInfo.OutputObjectFormat == llvm::Triple::ELF &&
-           "expected ELF output format");
+    assert((TargetInfo.OutputObjectFormat == llvm::Triple::ELF ||
+            Triple.isOSCygMing()) &&
+           "expected ELF output format or COFF format for Cygwin/MinGW");
 
     // Merge the entries into null-separated string.
     llvm::SmallString<64> EntriesString;
@@ -969,7 +978,7 @@
                                  llvm::GlobalValue::CommonLinkage,
                                  llvm::Constant::getNullValue(Int1Ty),
                                  buf.str());
-    if (Triple.isOSBinFormatCOFF())
+    if (useDllStorage())
       symbol->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
   }
 }
@@ -1072,6 +1081,8 @@
                          message.toStringRef(buffer));
 }
 
+bool IRGenModule::useDllStorage() { return ::useDllStorage(Triple); }
+
 void IRGenerator::addGenModule(SourceFile *SF, IRGenModule *IGM) {
   assert(GenModules.count(SF) == 0);
   GenModules[SF] = IGM;
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index bef4bba..52a274a 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -21,6 +21,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/Module.h"
 #include "swift/SIL/SILFunction.h"
+#include "swift/SIL/InstructionUtils.h"
 #include "swift/Basic/LLVM.h"
 #include "swift/Basic/ClusteredBitVector.h"
 #include "swift/Basic/SuccessorMap.h"
@@ -367,7 +368,14 @@
   Lowering::TypeConverter &getSILTypes() const;
   SILModule &getSILModule() const { return IRGen.SIL; }
   llvm::SmallString<128> OutputFilename;
-  
+
+#ifndef NDEBUG
+  // Used for testing ConformanceCollector.
+  ConformanceCollector EligibleConfs;
+  SILInstruction *CurrentInst = nullptr;
+  SILWitnessTable *CurrentWitnessTable = nullptr;
+#endif
+
   /// Order dependency -- TargetInfo must be initialized after Opts.
   const SwiftTargetInfo TargetInfo;
   /// Holds lexical scope info, etc. Is a nullptr if we compile without -g.
@@ -534,6 +542,8 @@
   void fatal_unimplemented(SourceLoc, StringRef Message);
   void error(SourceLoc loc, const Twine &message);
 
+  bool useDllStorage();
+
 private:
   Size PtrSize;
   llvm::Type *FixedBufferTy;          /// [N x i8], where N == 3 * sizeof(void*)
@@ -1001,6 +1011,9 @@
                                         DebugTypeInfo debugType,
                                         SymbolReferenceKind refKind);
 
+  void checkEligibleConf(const ProtocolConformance *Conf);
+  void checkEligibleMetaType(NominalTypeDecl *NT);
+
   void emitLazyPrivateDefinitions();
   void addRuntimeResolvableType(CanType type);
 
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 61ea01a..29e7bec 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -885,9 +885,18 @@
   void visitEndBorrowInst(EndBorrowInst *i) {
     llvm_unreachable("unimplemented");
   }
+  void visitEndBorrowArgumentInst(EndBorrowArgumentInst *i) {
+    llvm_unreachable("unimplemented");
+  }
   void visitStoreBorrowInst(StoreBorrowInst *i) {
     llvm_unreachable("unimplemented");
   }
+  void visitUnmanagedRetainValueInst(UnmanagedRetainValueInst *i) {
+    llvm_unreachable("unimplemented");
+  }
+  void visitUnmanagedReleaseValueInst(UnmanagedReleaseValueInst *i) {
+    llvm_unreachable("unimplemented");
+  }
   void visitMarkDependenceInst(MarkDependenceInst *i);
   void visitCopyBlockInst(CopyBlockInst *i);
   void visitStrongPinInst(StrongPinInst *i);
@@ -1538,6 +1547,10 @@
 
   for (auto InsnIter = BB->begin(); InsnIter != BB->end(); ++InsnIter) {
     auto &I = *InsnIter;
+#ifndef NDEBUG
+    IGM.EligibleConfs.collect(&I);
+    IGM.CurrentInst = &I;
+#endif
     if (IGM.DebugInfo) {
       // Set the debug info location for I, if applicable.
       SILLocation ILoc = I.getLoc();
@@ -1592,6 +1605,10 @@
     }
     visit(&I);
 
+#ifndef NDEBUG
+    IGM.EligibleConfs.clear();
+    IGM.CurrentInst = nullptr;
+#endif
   }
   
   assert(Builder.hasPostTerminatorIP() && "SIL bb did not terminate block?!");
@@ -2696,7 +2713,7 @@
   Explosion enumValue = IGF.getLoweredExplosion(inst->getEnumOperand());
   llvm::Value *result = EIS.emitExtractDiscriminator(IGF, enumValue);
   if (!result) {
-    enumValue.claimAll();
+    (void)enumValue.claimAll();
     return nullptr;
   }
 
@@ -2945,7 +2962,7 @@
   cast<LoadableTypeInfo>(getTypeInfo(i->getOperand()->getType()))
       .copy(*this, in, out, i->isAtomic() ? irgen::Atomicity::Atomic
                                           : irgen::Atomicity::NonAtomic);
-  out.claimAll();
+  (void)out.claimAll();
 }
 
 void IRGenSILFunction::visitCopyValueInst(swift::CopyValueInst *i) {
@@ -3078,7 +3095,7 @@
                                    fullTuple,
                                    i->getFieldNo(),
                                    output);
-  fullTuple.claimAll();
+  (void)fullTuple.claimAll();
   setLoweredExplosion(i, output);
 }
 
@@ -3103,7 +3120,7 @@
                                            i->getField(),
                                            lowered);
 
-  operand.claimAll();
+  (void)operand.claimAll();
   setLoweredExplosion(i, lowered);
 }
 
@@ -3803,7 +3820,7 @@
   llvm::Value *ptrValue = from.claimNext();
   // The input may have witness tables or other additional data, but the class
   // reference is always first.
-  from.claimAll();
+  (void)from.claimAll();
 
   auto schema = ti.getSchema();
   assert(schema.size() == 1
@@ -3879,7 +3896,7 @@
 
   llvm::BasicBlock *contBB = llvm::BasicBlock::Create(IGF.IGM.getLLVMContext());
   IGF.Builder.emitBlock(contBB);
-  in.claimAll();
+  (void)in.claimAll();
   for (auto schema : outTI.getSchema())
     out.add(llvm::UndefValue::get(schema.getScalarType()));
 }
@@ -4080,7 +4097,7 @@
   // can drop.
   Explosion from = getLoweredExplosion(i->getOperand());
   llvm::Value *value = from.claimNext();
-  from.claimAll();
+  (void)from.claimAll();
   value = Builder.CreateBitCast(value, IGM.UnknownRefCountedPtrTy);
   Explosion to;
   to.add(value);
diff --git a/lib/IRGen/Linking.h b/lib/IRGen/Linking.h
index 77ed0bd..9b802dc 100644
--- a/lib/IRGen/Linking.h
+++ b/lib/IRGen/Linking.h
@@ -21,6 +21,7 @@
 
 #include "swift/AST/Types.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/SILModule.h"
 #include "swift/SIL/SILFunction.h"
 #include "swift/SIL/SILGlobalVariable.h"
diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp
index c3acf70..e561536 100644
--- a/lib/IRGen/LocalTypeData.cpp
+++ b/lib/IRGen/LocalTypeData.cpp
@@ -23,6 +23,7 @@
 #include "IRGenFunction.h"
 #include "IRGenModule.h"
 #include "swift/AST/IRGenOptions.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/SILModule.h"
 
 using namespace swift;
diff --git a/lib/IRGen/TypeLayoutVerifier.cpp b/lib/IRGen/TypeLayoutVerifier.cpp
index 3f0f97f..1423ce6 100644
--- a/lib/IRGen/TypeLayoutVerifier.cpp
+++ b/lib/IRGen/TypeLayoutVerifier.cpp
@@ -43,7 +43,7 @@
                                               /*var arg*/ false);
   auto verifierFn = IGF.IGM.Module.getOrInsertFunction(
       "_swift_debug_verifyTypeLayoutAttribute", verifierFnTy);
-  if (IGF.IGM.Triple.isOSBinFormatCOFF())
+  if (IGF.IGM.useDllStorage()) 
     if (auto *F = dyn_cast<llvm::Function>(verifierFn))
       F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
 
diff --git a/lib/Immediate/REPL.cpp b/lib/Immediate/REPL.cpp
index 6d5b0ad..f4f9e23 100644
--- a/lib/Immediate/REPL.cpp
+++ b/lib/Immediate/REPL.cpp
@@ -75,56 +75,58 @@
 template<>
 class ConvertForWcharSize<2> {
 public:
-  static ConversionResult ConvertFromUTF8(const char** sourceStart,
-                                          const char* sourceEnd,
-                                          wchar_t** targetStart,
-                                          wchar_t* targetEnd,
-                                          ConversionFlags flags) {
-    return ConvertUTF8toUTF16(reinterpret_cast<const UTF8**>(sourceStart),
-                              reinterpret_cast<const UTF8*>(sourceEnd),
-                              reinterpret_cast<UTF16**>(targetStart),
-                              reinterpret_cast<UTF16*>(targetEnd),
+  static llvm::ConversionResult ConvertFromUTF8(const char** sourceStart,
+                                                const char* sourceEnd,
+                                                wchar_t** targetStart,
+                                                wchar_t* targetEnd,
+                                                llvm::ConversionFlags flags) {
+    return ConvertUTF8toUTF16(reinterpret_cast<const llvm::UTF8**>(sourceStart),
+                              reinterpret_cast<const llvm::UTF8*>(sourceEnd),
+                              reinterpret_cast<llvm::UTF16**>(targetStart),
+                              reinterpret_cast<llvm::UTF16*>(targetEnd),
                               flags);
   }
   
-  static ConversionResult ConvertToUTF8(const wchar_t** sourceStart,
-                                        const wchar_t* sourceEnd,
-                                        char** targetStart,
-                                        char* targetEnd,
-                                        ConversionFlags flags) {
-    return ConvertUTF16toUTF8(reinterpret_cast<const UTF16**>(sourceStart),
-                              reinterpret_cast<const UTF16*>(sourceEnd),
-                              reinterpret_cast<UTF8**>(targetStart),
-                              reinterpret_cast<UTF8*>(targetEnd),
-                              flags);
+  static llvm::ConversionResult ConvertToUTF8(const wchar_t** sourceStart,
+                                              const wchar_t* sourceEnd,
+                                              char** targetStart,
+                                              char* targetEnd,
+                                              llvm::ConversionFlags flags) {
+    return ConvertUTF16toUTF8(
+                             reinterpret_cast<const llvm::UTF16**>(sourceStart),
+                             reinterpret_cast<const llvm::UTF16*>(sourceEnd),
+                             reinterpret_cast<llvm::UTF8**>(targetStart),
+                             reinterpret_cast<llvm::UTF8*>(targetEnd),
+                             flags);
   }
 };
 
 template<>
 class ConvertForWcharSize<4> {
 public:
-  static ConversionResult ConvertFromUTF8(const char** sourceStart,
-                                          const char* sourceEnd,
-                                          wchar_t** targetStart,
-                                          wchar_t* targetEnd,
-                                          ConversionFlags flags) {
-    return ConvertUTF8toUTF32(reinterpret_cast<const UTF8**>(sourceStart),
-                              reinterpret_cast<const UTF8*>(sourceEnd),
-                              reinterpret_cast<UTF32**>(targetStart),
-                              reinterpret_cast<UTF32*>(targetEnd),
+  static llvm::ConversionResult ConvertFromUTF8(const char** sourceStart,
+                                                const char* sourceEnd,
+                                                wchar_t** targetStart,
+                                                wchar_t* targetEnd,
+                                                llvm::ConversionFlags flags) {
+    return ConvertUTF8toUTF32(reinterpret_cast<const llvm::UTF8**>(sourceStart),
+                              reinterpret_cast<const llvm::UTF8*>(sourceEnd),
+                              reinterpret_cast<llvm::UTF32**>(targetStart),
+                              reinterpret_cast<llvm::UTF32*>(targetEnd),
                               flags);
   }
   
-  static ConversionResult ConvertToUTF8(const wchar_t** sourceStart,
-                                        const wchar_t* sourceEnd,
-                                        char** targetStart,
-                                        char* targetEnd,
-                                        ConversionFlags flags) {
-    return ConvertUTF32toUTF8(reinterpret_cast<const UTF32**>(sourceStart),
-                              reinterpret_cast<const UTF32*>(sourceEnd),
-                              reinterpret_cast<UTF8**>(targetStart),
-                              reinterpret_cast<UTF8*>(targetEnd),
-                              flags);
+  static llvm::ConversionResult ConvertToUTF8(const wchar_t** sourceStart,
+                                              const wchar_t* sourceEnd,
+                                              char** targetStart,
+                                              char* targetEnd,
+                                              llvm::ConversionFlags flags) {
+    return ConvertUTF32toUTF8(
+                             reinterpret_cast<const llvm::UTF32**>(sourceStart),
+                             reinterpret_cast<const llvm::UTF32*>(sourceEnd),
+                             reinterpret_cast<llvm::UTF8**>(targetStart),
+                             reinterpret_cast<llvm::UTF8*>(targetEnd),
+                             flags);
   }
 };
 
@@ -139,8 +141,8 @@
   wchar_t *wide_begin = out.end();
   auto res = Convert::ConvertFromUTF8(&utf8_begin, utf8.end(),
                                       &wide_begin, out.data() + reserve,
-                                      lenientConversion);
-  assert(res == conversionOK && "utf8-to-wide conversion failed!");
+                                      llvm::lenientConversion);
+  assert(res == llvm::conversionOK && "utf8-to-wide conversion failed!");
   (void)res;
   out.set_size(wide_begin - out.begin());
 }
@@ -153,8 +155,8 @@
   char *utf8_begin = out.end();
   auto res = Convert::ConvertToUTF8(&wide_begin, wide.end(),
                                     &utf8_begin, out.data() + reserve,
-                                    lenientConversion);
-  assert(res == conversionOK && "wide-to-utf8 conversion failed!");
+                                    llvm::lenientConversion);
+  assert(res == llvm::conversionOK && "wide-to-utf8 conversion failed!");
   (void)res;
   out.set_size(utf8_begin - out.begin());
 }
diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp
index 11da76c..79f6b7e 100644
--- a/lib/Index/Index.cpp
+++ b/lib/Index/Index.cpp
@@ -1037,8 +1037,8 @@
   // Don't use inode because it can easily change when you update the repository
   // even though the file is supposed to be the same (same size/time).
   code = hash_combine(code, Filename);
-  return hash_combine(code, Status.getSize(),
-                      Status.getLastModificationTime().toEpochTime());
+  auto mtime = Status.getLastModificationTime().time_since_epoch().count();
+  return hash_combine(code, Status.getSize(), mtime);
 }
 
 llvm::hash_code IndexSwiftASTWalker::hashModule(llvm::hash_code code,
diff --git a/lib/LLVMPasses/ARCEntryPointBuilder.h b/lib/LLVMPasses/ARCEntryPointBuilder.h
index bfc10ff..144e92e 100644
--- a/lib/LLVMPasses/ARCEntryPointBuilder.h
+++ b/lib/LLVMPasses/ARCEntryPointBuilder.h
@@ -272,7 +272,8 @@
     CheckUnowned = M.getOrInsertFunction("swift_checkUnowned", AttrList,
                                          Type::getVoidTy(M.getContext()),
                                          ObjectPtrTy, nullptr);
-    if (llvm::Triple(M.getTargetTriple()).isOSBinFormatCOFF())
+    if (llvm::Triple(M.getTargetTriple()).isOSBinFormatCOFF() &&
+        !llvm::Triple(M.getTargetTriple()).isOSCygMing())
       if (auto *F = llvm::dyn_cast<llvm::Function>(CheckUnowned.get()))
         F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
     return CheckUnowned.get();
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 4c3ea95..a78a5a3 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -294,6 +294,149 @@
                                                  Segments.front().Length));
 }
 
+bool Parser::parseSpecializeAttribute(swift::tok ClosingBrace, SourceLoc AtLoc,
+                                      SourceLoc Loc, SpecializeAttr *&Attr) {
+  assert(ClosingBrace == tok::r_paren || ClosingBrace == tok::r_square);
+  SourceLoc lParenLoc = consumeToken();
+  bool DiscardAttribute = false;
+  StringRef AttrName = "_specialize";
+
+  Optional<bool> exported;
+  Optional<SpecializeAttr::SpecializationKind> kind;
+
+  // Parse optional "exported" and "kind" labeled parameters.
+  while (!Tok.is(tok::kw_where)) {
+    if (Tok.is(tok::identifier)) {
+      auto ParamLabel = Tok.getText();
+      if (ParamLabel != "exported" && ParamLabel != "kind") {
+        diagnose(Tok.getLoc(), diag::attr_specialize_unknown_parameter_name,
+                 ParamLabel);
+      }
+      consumeToken();
+      if (!consumeIf(tok::colon)) {
+        diagnose(Tok.getLoc(), diag::attr_specialize_missing_colon, ParamLabel);
+        skipUntil(tok::comma, tok::kw_where);
+        if (Tok.is(ClosingBrace))
+          break;
+        if (Tok.is(tok::kw_where)) {
+          continue;
+        }
+        if (Tok.is(tok::comma)) {
+          consumeToken();
+          continue;
+        }
+        DiscardAttribute = true;
+        return false;
+      }
+      if ((ParamLabel == "exported" && exported.hasValue()) ||
+          (ParamLabel == "kind" && kind.hasValue())) {
+        diagnose(Tok.getLoc(), diag::attr_specialize_parameter_already_defined,
+                 ParamLabel);
+      }
+      if (ParamLabel == "exported") {
+        bool isTrue = consumeIf(tok::kw_true);
+        bool isFalse = consumeIf(tok::kw_false);
+        if (!isTrue && !isFalse) {
+          diagnose(Tok.getLoc(), diag::attr_specialize_expected_bool_value);
+          skipUntil(tok::comma, tok::kw_where);
+          if (Tok.is(ClosingBrace))
+            break;
+          if (Tok.is(tok::kw_where)) {
+            continue;
+          }
+          if (Tok.is(tok::comma)) {
+            consumeToken();
+            continue;
+          }
+          DiscardAttribute = true;
+          return false;
+        }
+        if (ParamLabel == "exported") {
+          exported = isTrue ? true : false;
+        }
+      }
+      if (ParamLabel == "kind") {
+        SourceLoc paramValueLoc;
+        if (Tok.is(tok::identifier)) {
+          if (Tok.getText() == "partial") {
+            kind = SpecializeAttr::SpecializationKind::Partial;
+          } else if (Tok.getText() == "full") {
+            kind = SpecializeAttr::SpecializationKind::Full;
+          } else {
+            diagnose(Tok.getLoc(),
+                     diag::attr_specialize_expected_partial_or_full);
+          }
+          consumeToken();
+        } else if (consumeIf(tok::kw_true, paramValueLoc) ||
+                   consumeIf(tok::kw_false, paramValueLoc)) {
+          diagnose(paramValueLoc,
+                   diag::attr_specialize_expected_partial_or_full);
+        }
+      }
+      if (!consumeIf(tok::comma)) {
+        diagnose(Tok.getLoc(), diag::attr_specialize_missing_comma);
+        skipUntil(tok::comma, tok::kw_where);
+        if (Tok.is(ClosingBrace))
+          break;
+        if (Tok.is(tok::kw_where)) {
+          continue;
+        }
+        if (Tok.is(tok::comma)) {
+          consumeToken();
+          continue;
+        }
+        DiscardAttribute = true;
+        return false;
+      }
+      continue;
+    }
+    diagnose(Tok.getLoc(),
+             diag::attr_specialize_missing_parameter_label_or_where_clause);
+    DiscardAttribute = true;
+    return false;
+  };
+
+  // Parse the where clause.
+  TrailingWhereClause *trailingWhereClause = nullptr;
+  if (Tok.is(tok::kw_where)) {
+    SourceLoc whereLoc;
+    SmallVector<RequirementRepr, 4> requirements;
+    bool firstTypeInComplete;
+    parseGenericWhereClause(whereLoc, requirements, firstTypeInComplete,
+                            /* AllowLayoutConstraints */ true);
+    trailingWhereClause =
+      TrailingWhereClause::create(Context, whereLoc, requirements);
+  }
+
+  // Parse the closing ')' or ']'.
+  SourceLoc rParenLoc;
+  if (!consumeIf(ClosingBrace, rParenLoc)) {
+    if (ClosingBrace == tok::r_paren)
+      diagnose(lParenLoc, diag::attr_expected_rparen, AttrName,
+             /*DeclModifier=*/false);
+    else if (ClosingBrace == tok::r_square)
+      diagnose(lParenLoc, diag::attr_expected_rparen, AttrName,
+             /*DeclModifier=*/false);
+    return false;
+  }
+  // Not exported by default.
+  if (!exported.hasValue())
+    exported = false;
+  // Full specialization by default.
+  if (!kind.hasValue())
+    kind = SpecializeAttr::SpecializationKind::Full;
+
+  if (DiscardAttribute) {
+    Attr = nullptr;
+    return false;
+  }
+  // Store the attribute.
+  Attr = SpecializeAttr::create(Context, AtLoc, SourceRange(Loc, rParenLoc),
+                                trailingWhereClause, exported.getValue(),
+                                kind.getValue());
+  return true;
+}
+
 bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
                                    DeclAttrKind DK) {
   // Ok, it is a valid attribute, eat it, and then process it.
@@ -712,9 +855,9 @@
     //   identifier
     if (!Tok.is(tok::identifier) &&
         !(Tok.isAnyOperator() && Tok.getText() == "*")) {
-        if (Tok.is(tok::code_complete) && CodeCompletion) {
-          CodeCompletion->completeDeclAttrParam(DAK_Available, 0);
-          consumeToken(tok::code_complete);
+      if (Tok.is(tok::code_complete) && CodeCompletion) {
+        CodeCompletion->completeDeclAttrParam(DAK_Available, 0);
+        consumeToken(tok::code_complete);
       }
       diagnose(Tok.getLoc(), diag::attr_availability_platform, AttrName)
         .highlight(SourceRange(Tok.getLoc()));
@@ -754,18 +897,21 @@
       for (auto *Spec : Specs) {
         PlatformKind Platform;
         clang::VersionTuple Version;
+        SourceRange VersionRange;
         PlatformAgnosticAvailabilityKind PlatformAgnostic;
 
         if (auto *PlatformVersionSpec =
             dyn_cast<PlatformVersionConstraintAvailabilitySpec>(Spec)) {
           Platform = PlatformVersionSpec->getPlatform();
           Version = PlatformVersionSpec->getVersion();
+          VersionRange = PlatformVersionSpec->getVersionSrcRange();
           PlatformAgnostic = PlatformAgnosticAvailabilityKind::None;
 
         } else if (auto *LanguageVersionSpec =
                    dyn_cast<LanguageVersionConstraintAvailabilitySpec>(Spec)) {
           Platform = PlatformKind::none;
           Version = LanguageVersionSpec->getVersion();
+          VersionRange = LanguageVersionSpec->getVersionSrcRange();
           PlatformAgnostic =
             PlatformAgnosticAvailabilityKind::SwiftVersionSpecific;
 
@@ -779,8 +925,11 @@
                                      /*Message=*/StringRef(),
                                      /*Rename=*/StringRef(),
                                      /*Introduced=*/Version,
+                                     /*IntroducedRange=*/VersionRange,
                                      /*Deprecated=*/clang::VersionTuple(),
+                                     /*DeprecatedRange=*/SourceRange(),
                                      /*Obsoleted=*/clang::VersionTuple(),
+                                     /*ObsoletedRange=*/SourceRange(),
                                      PlatformAgnostic,
                                      /*Implicit=*/true));
       }
@@ -798,6 +947,7 @@
 
     StringRef Message, Renamed;
     clang::VersionTuple Introduced, Deprecated, Obsoleted;
+    SourceRange IntroducedRange, DeprecatedRange, ObsoletedRange;
     auto PlatformAgnostic = PlatformAgnosticAvailabilityKind::None;
     bool AnyAnnotations = false;
     int ParamIndex = 0;
@@ -917,8 +1067,10 @@
                            (ArgumentKind == IsDeprecated) ? Deprecated :
                                                             Obsoleted;
 
-        SourceRange VersionRange;
-        
+        auto &VersionRange = (ArgumentKind == IsIntroduced) ? IntroducedRange :
+                             (ArgumentKind == IsDeprecated) ? DeprecatedRange :
+                                                              ObsoletedRange;
+
         if (parseVersionTuple(
                 VersionArg, VersionRange,
                 Diagnostic(diag::attr_availability_expected_version,
@@ -984,9 +1136,9 @@
                        AvailableAttr(AtLoc, AttrRange,
                                         PlatformKind.getValue(),
                                         Message, Renamed,
-                                        Introduced,
-                                        Deprecated,
-                                        Obsoleted,
+                                        Introduced, IntroducedRange,
+                                        Deprecated, DeprecatedRange,
+                                        Obsoleted, ObsoletedRange,
                                         PlatformAgnostic,
                                         /*Implicit=*/false));
       } else {
@@ -1099,34 +1251,11 @@
                DeclAttribute::isDeclModifier(DK));
       return false;
     }
-
-    SourceLoc lParenLoc = consumeToken();
-
-    SmallVector<TypeLoc, 8> TypeList;
-    do {
-      // Parse the concrete nominal type.
-      ParserResult<TypeRepr> Ty = parseTypeIdentifier();
-      if (Ty.isNull()) {
-        skipUntil(tok::r_paren);
-        return false;
-      }  
-
-      // Record the type.
-      TypeList.push_back(Ty.get());
-  
-      // Check for a ',', which indicates that there are more protocols coming.
-    } while (consumeIf(tok::comma));
-
-    // Parse the closing ')'.
-    SourceLoc rParenLoc;
-    if (!consumeIf(tok::r_paren, rParenLoc)) {
-      diagnose(lParenLoc, diag::attr_expected_rparen, AttrName,
-               /*DeclModifier=*/false);
+    SpecializeAttr *Attr;
+    if (!parseSpecializeAttribute(tok::r_paren, AtLoc, Loc, Attr))
       return false;
-    }
-    Attributes.add(
-      SpecializeAttr::create(Context, AtLoc, SourceRange(Loc, rParenLoc),
-                             TypeList));
+
+    Attributes.add(Attr);
     break;
     }
   }
@@ -1891,10 +2020,15 @@
 ///     decl-import
 ///     decl-operator
 /// \endverbatim
-ParserStatus Parser::parseDecl(ParseDeclOptions Flags,
-                               llvm::function_ref<void(Decl*)> Handler) {
-  if (Tok.isAny(tok::pound_sourceLocation, tok::pound_line))
-    return parseLineDirective(Tok.is(tok::pound_line));
+ParserResult<Decl>
+Parser::parseDecl(ParseDeclOptions Flags,
+                  llvm::function_ref<void(Decl*)> Handler) {
+  if (Tok.isAny(tok::pound_sourceLocation, tok::pound_line)) {
+    auto LineDirectiveStatus = parseLineDirective(Tok.is(tok::pound_line));
+    if (LineDirectiveStatus.isError())
+      return LineDirectiveStatus;
+    // If success, go on. line directive never produce decls.
+  }
 
   if (Tok.is(tok::pound_if)) {
     auto IfConfigResult = parseDeclIfConfig(Flags);
@@ -1909,12 +2043,6 @@
     return IfConfigResult;
   }
 
-  Decl* LastDecl = nullptr;
-  auto InternalHandler  = [&](Decl *D) {
-    LastDecl = D;
-    Handler(D);
-  };
-
   ParserPosition BeginParserPosition;
   if (isCodeCompletionFirstPass())
     BeginParserPosition = getParserPosition();
@@ -1936,7 +2064,6 @@
   SourceLoc StaticLoc;
   StaticSpellingKind StaticSpelling = StaticSpellingKind::None;
   ParserResult<Decl> DeclResult;
-  ParserStatus Status;
 
   while (1) {
     // Save the original token, in case code-completion needs it.
@@ -1978,7 +2105,6 @@
 
       // Otherwise this is the start of a class declaration.
       DeclResult = parseDeclClass(ClassLoc, Flags, Attributes);
-      Status = DeclResult;
       break;
     }
 
@@ -2101,69 +2227,61 @@
     // Unambiguous top level decls.
     case tok::kw_import:
       DeclResult = parseDeclImport(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_extension:
       DeclResult = parseDeclExtension(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_let:
     case tok::kw_var: {
       llvm::SmallVector<Decl *, 4> Entries;
-      Status = parseDeclVar(Flags, Attributes, Entries, StaticLoc,
-                            StaticSpelling, tryLoc);
+      DeclResult = parseDeclVar(Flags, Attributes, Entries, StaticLoc,
+                                StaticSpelling, tryLoc);
       StaticLoc = SourceLoc();   // we handled static if present.
       MayNeedOverrideCompletion = true;
-      std::for_each(Entries.begin(), Entries.end(), InternalHandler);
+      std::for_each(Entries.begin(), Entries.end(), Handler);
+      if (auto *D = DeclResult.getPtrOrNull())
+        markWasHandled(D);
       break;
     }
     case tok::kw_typealias:
       DeclResult = parseDeclTypeAlias(Flags, Attributes);
-      Status = DeclResult;
       MayNeedOverrideCompletion = true;
       break;
     case tok::kw_associatedtype:
       DeclResult = parseDeclAssociatedType(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_enum:
       DeclResult = parseDeclEnum(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_case: {
       llvm::SmallVector<Decl *, 4> Entries;
-      Status = parseDeclEnumCase(Flags, Attributes, Entries);
-      std::for_each(Entries.begin(), Entries.end(), InternalHandler);
+      DeclResult = parseDeclEnumCase(Flags, Attributes, Entries);
+      std::for_each(Entries.begin(), Entries.end(), Handler);
+      if (auto *D = DeclResult.getPtrOrNull())
+        markWasHandled(D);
       break;
     }
     case tok::kw_struct:
       DeclResult = parseDeclStruct(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_init:
       DeclResult = parseDeclInit(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_deinit:
       DeclResult = parseDeclDeinit(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_operator:
       DeclResult = parseDeclOperator(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_precedencegroup:
       DeclResult = parseDeclPrecedenceGroup(Flags, Attributes);
-      Status = DeclResult;
       break;
     case tok::kw_protocol:
       DeclResult = parseDeclProtocol(Flags, Attributes);
-      Status = DeclResult;
       break;
 
     case tok::kw_func:
       DeclResult = parseDeclFunc(StaticLoc, StaticSpelling, Flags, Attributes);
-      Status = DeclResult;
       StaticLoc = SourceLoc();   // we handled static if present.
       MayNeedOverrideCompletion = true;
       break;
@@ -2175,22 +2293,24 @@
         StaticLoc = SourceLoc();
       }
       llvm::SmallVector<Decl *, 4> Entries;
-      Status = parseDeclSubscript(Flags, Attributes, Entries);
-      std::for_each(Entries.begin(), Entries.end(), InternalHandler);
+      DeclResult = parseDeclSubscript(Flags, Attributes, Entries);
+      std::for_each(Entries.begin(), Entries.end(), Handler);
       MayNeedOverrideCompletion = true;
+      if (auto *D = DeclResult.getPtrOrNull())
+        markWasHandled(D);
       break;
     }
 
     case tok::code_complete:
       MayNeedOverrideCompletion = true;
-      Status.setIsParseError();
+      DeclResult = makeParserError();
       // Handled below.
       break;
     }
 
-    if (Status.isError() && MayNeedOverrideCompletion &&
+    if (DeclResult.isParseError() && MayNeedOverrideCompletion &&
         Tok.is(tok::code_complete)) {
-      Status = makeParserCodeCompletionStatus();
+      DeclResult = makeParserCodeCompletionStatus();
       if (CodeCompletion) {
         // If we need to complete an override, collect the keywords already
         // specified so that we do not duplicate them in code completion
@@ -2234,41 +2354,34 @@
                                               false);
     } else {
       delayParseFromBeginningToHere(BeginParserPosition, Flags);
-      return makeParserSuccess();
+      return makeParserError();
     }
   }
 
-  if (Status.hasCodeCompletion() && isCodeCompletionFirstPass() &&
+  if (DeclResult.hasCodeCompletion() && isCodeCompletionFirstPass() &&
       !CurDeclContext->isModuleScopeContext()) {
     // Only consume non-toplevel decls.
     consumeDecl(BeginParserPosition, Flags, /*IsTopLevel=*/false);
 
-    // Pretend that there was no error.
-    return makeParserSuccess();
+    return makeParserError();
   }
 
   if (DeclResult.isNonNull()) {
     Decl *D = DeclResult.get();
     if (!declWasHandledAlready(D))
-      InternalHandler(DeclResult.get());
+      Handler(DeclResult.get());
   }
 
-  if (Tok.is(tok::semi)) {
-    SourceLoc TrailingSemiLoc = consumeToken(tok::semi);
-    if (Status.isSuccess())
-      LastDecl->TrailingSemiLoc = TrailingSemiLoc;
-  }
-
-  if (Status.isSuccess()) {
+  if (!DeclResult.isParseError()) {
     // If we parsed 'class' or 'static', but didn't handle it above, complain
     // about it.
     if (StaticLoc.isValid())
-      diagnose(LastDecl->getLoc(), diag::decl_not_static,
+      diagnose(DeclResult.get()->getLoc(), diag::decl_not_static,
                StaticSpelling)
           .fixItRemove(SourceRange(StaticLoc));
   }
 
-  return Status;
+  return DeclResult;
 }
 
 void Parser::parseDeclDelayed() {
@@ -2592,6 +2705,64 @@
                                  ResyncP1, Diagnostic(ID, Args...));
 }
 
+/// Parse a Decl item in decl list.
+static ParserStatus parseDeclItem(Parser &P,
+                                  bool &PreviousHadSemi,
+                                  Parser::ParseDeclOptions Options,
+                                  llvm::function_ref<void(Decl*)> handler) {
+  if (P.Tok.is(tok::semi)) {
+    // Consume ';' without preceding decl.
+    P.diagnose(P.Tok, diag::unexpected_separator, ";")
+      .fixItRemove(P.Tok.getLoc());
+    P.consumeToken();
+    // Return success because we already recovered.
+    return makeParserSuccess();
+  }
+
+  // If the previous declaration didn't have a semicolon and this new
+  // declaration doesn't start a line, complain.
+  if (!PreviousHadSemi && !P.Tok.isAtStartOfLine() && !P.Tok.is(tok::unknown)) {
+    auto endOfPrevious = P.getEndOfPreviousLoc();
+    P.diagnose(endOfPrevious, diag::declaration_same_line_without_semi)
+      .fixItInsert(endOfPrevious, ";");
+  }
+
+  auto Result = P.parseDecl(Options, handler);
+  if (Result.isParseError())
+    P.skipUntilDeclRBrace(tok::semi, tok::pound_endif);
+  SourceLoc SemiLoc;
+  PreviousHadSemi = P.consumeIf(tok::semi, SemiLoc);
+  if (PreviousHadSemi && Result.isNonNull())
+    Result.get()->TrailingSemiLoc = SemiLoc;
+  return Result;
+}
+
+/// \brief Parse the members in a struct/class/enum/protocol/extension.
+///
+/// \verbatim
+///    decl* '}'
+/// \endverbatim
+bool Parser::parseDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
+                           Diag<> ErrorDiag, ParseDeclOptions Options,
+                           llvm::function_ref<void(Decl*)> handler) {
+  ParserStatus Status;
+  bool PreviousHadSemi = true;
+  while (Tok.isNot(tok::r_brace)) {
+    Status |= parseDeclItem(*this, PreviousHadSemi, Options, handler);
+    if (Tok.isAny(tok::eof, tok::pound_endif, tok::pound_else,
+                  tok::pound_elseif)) {
+      IsInputIncomplete = true;
+      break;
+    }
+  }
+
+  parseMatchingToken(tok::r_brace, RBLoc, ErrorDiag, LBLoc);
+
+  // If we found the closing brace, then the caller should not care if there
+  // were errors while parsing inner decls, because we recovered.
+  return !RBLoc.isValid();
+}
+
 /// \brief Parse an 'extension' declaration.
 ///
 /// \verbatim
@@ -2651,20 +2822,15 @@
     ContextChange CC(*this, ext);
     Scope S(this, ScopeKind::Extension);
 
-    ParserStatus BodyStatus =
-        parseList(tok::r_brace, LBLoc, RBLoc, tok::semi, /*OptionalSep=*/true,
-                  /*AllowSepAfterLast=*/false, diag::expected_rbrace_extension,
-                  [&]() -> ParserStatus {
-      ParseDeclOptions Options(PD_HasContainerType |
-                               PD_InExtension);
+    ParseDeclOptions Options(PD_HasContainerType | PD_InExtension);
 
-      return parseDecl(Options, [&] (Decl *D) {ext->addMember(D);});
-    });
+    if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_extension,
+                      Options, [&] (Decl *D) {ext->addMember(D);}))
+      status.setIsParseError();
+
     // Don't propagate the code completion bit from members: we cannot help
     // code completion inside a member decl, and our callers cannot do
     // anything about it either.  But propagate the error bit.
-    if (BodyStatus.isError())
-      status.setIsParseError();
   }
 
   ext->setBraces({LBLoc, RBLoc});
@@ -2862,14 +3028,20 @@
     SmallVector<Decl*, 8> Decls;
     if (ConfigState.shouldParse()) {
       ParserStatus Status;
-      while (Tok.isNot(tok::pound_else) && Tok.isNot(tok::pound_endif) &&
-             Tok.isNot(tok::pound_elseif)) {
-        Status = parseDecl(Flags, [&](Decl *D) {Decls.push_back(D);});
-        if (Status.isError()) {
-          diagnose(Tok, diag::expected_close_to_if_directive);
+      bool PreviousHadSemi = true;
+      while (Tok.isNot(tok::pound_else, tok::pound_endif, tok::pound_elseif)) {
+        SourceLoc StartLoc = Tok.getLoc();
+        Status |= parseDeclItem(*this, PreviousHadSemi, Flags,
+                                [&](Decl *D) {Decls.push_back(D);});
+        if (StartLoc == Tok.getLoc()) {
+          assert(Status.isError() && "no progress without error?");
           skipUntilConditionalBlockClose();
           break;
         }
+        if (Tok.isAny(tok::eof)) {
+          diagnose(Tok, diag::expected_close_to_if_directive);
+          break;
+        }
       }
     } else {
       DiagnosticTransaction DT(Diags);
@@ -4042,12 +4214,13 @@
 
 
 /// \brief Parse a 'var' or 'let' declaration, doing no token skipping on error.
-ParserStatus Parser::parseDeclVar(ParseDeclOptions Flags,
-                                  DeclAttributes &Attributes,
-                                  SmallVectorImpl<Decl *> &Decls,
-                                  SourceLoc StaticLoc,
-                                  StaticSpellingKind StaticSpelling,
-                                  SourceLoc TryLoc) {
+ParserResult<PatternBindingDecl>
+Parser::parseDeclVar(ParseDeclOptions Flags,
+                     DeclAttributes &Attributes,
+                     SmallVectorImpl<Decl *> &Decls,
+                     SourceLoc StaticLoc,
+                     StaticSpellingKind StaticSpelling,
+                     SourceLoc TryLoc) {
   assert(StaticLoc.isInvalid() || StaticSpelling != StaticSpellingKind::None);
 
   if (StaticLoc.isValid()) {
@@ -4087,19 +4260,22 @@
   // In var/let decl with multiple patterns, accumulate them all in this list
   // so we can build our singular PatternBindingDecl at the end.
   SmallVector<PatternBindingEntry, 4> PBDEntries;
+  auto BaseContext = CurDeclContext;
 
   // No matter what error path we take, make sure the
   // PatternBindingDecl/TopLevel code block are added.
-  SWIFT_DEFER {
+  auto makeResult =
+    [&](ParserStatus Status) -> ParserResult<PatternBindingDecl> {
+
     // If we didn't parse any patterns, don't create the pattern binding decl.
     if (PBDEntries.empty())
-      return;
+      return Status;
     
     // Now that we've parsed all of our patterns, initializers and accessors, we
     // can finally create our PatternBindingDecl to represent the
     // pattern/initializer pairs.
     auto PBD = PatternBindingDecl::create(Context, StaticLoc, StaticSpelling,
-                                          VarLoc, PBDEntries, CurDeclContext);
+                                          VarLoc, PBDEntries, BaseContext);
 
     // Wire up any initializer contexts we needed.
     for (unsigned i : indices(PBDEntries)) {
@@ -4116,13 +4292,16 @@
       topLevelDecl->setBody(BraceStmt::create(Context, range.Start,
                                               ASTNode(PBD), range.End, true));
       Decls.insert(Decls.begin()+NumDeclsInResult, topLevelDecl);
-      return;
+      return makeParserResult(Status, PBD);
     }
 
     // Otherwise return the PBD in "Decls" to the caller.  We add it at a
     // specific spot to get it in before any accessors, which SILGen seems to
     // want.
     Decls.insert(Decls.begin()+NumDeclsInResult, PBD);
+
+    // Always return the result for PBD.
+    return makeParserResult(Status, PBD);
   };
   
   do {
@@ -4134,9 +4313,9 @@
 
       auto patternRes = parseTypedPattern();
       if (patternRes.hasCodeCompletion())
-        return makeParserCodeCompletionStatus();
+        return makeResult(makeParserCodeCompletionStatus());
       if (patternRes.isNull())
-        return makeParserError();
+        return makeResult(makeParserError());
 
       pattern = patternRes.get();
     }
@@ -4225,12 +4404,13 @@
       if (init.hasCodeCompletion() && isCodeCompletionFirstPass()) {
 
         // Register the end of the init as the end of the delayed parsing.
-        DelayedDeclEnd = init.getPtrOrNull() ? init.get()->getEndLoc() : SourceLoc();
-        return makeParserCodeCompletionStatus();
+        DelayedDeclEnd
+          = init.getPtrOrNull() ? init.get()->getEndLoc() : SourceLoc();
+        return makeResult(makeParserCodeCompletionStatus());
       }
 
       if (init.isNull())
-        return makeParserError();
+        return makeResult(makeParserError());
     }
     
     // Parse a behavior block if present.
@@ -4241,9 +4421,9 @@
       auto type = parseType(diag::expected_behavior_name,
                             /*handle completion*/ true);
       if (type.isParseError())
-        return makeParserError();
+        return makeResult(makeParserError());
       if (type.hasCodeCompletion())
-        return makeParserCodeCompletionStatus();
+        return makeResult(makeParserCodeCompletionStatus());
       
       // Parse a following trailing closure argument.
       // FIXME: Handle generalized parameters.
@@ -4285,9 +4465,9 @@
         PBDEntries.back().setInitContext(initContext);
 
         if (closure.isParseError())
-          return makeParserError();
+          return makeResult(makeParserError());
         if (closure.hasCodeCompletion())
-          return makeParserCodeCompletionStatus();
+          return makeResult(makeParserCodeCompletionStatus());
         paramExpr = closure.get();
       }
 
@@ -4367,10 +4547,7 @@
     }
   }
 
-  // NOTE: At this point, the DoAtScopeExit object is destroyed and the PBD
-  // is added to the program.
-  
-  return Status;
+  return makeResult(Status);
 }
 
 void Parser::consumeAbstractFunctionBody(AbstractFunctionDecl *AFD,
@@ -4773,9 +4950,8 @@
     ContextChange CC(*this, ED);
     Scope S(this, ScopeKind::ClassBody);
     ParseDeclOptions Options(PD_HasContainerType | PD_AllowEnumElement | PD_InEnum);
-    if (parseNominalDeclMembers(LBLoc, RBLoc,
-                                diag::expected_rbrace_enum,
-                                Options, [&] (Decl *D) { ED->addMember(D); }))
+    if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_enum,
+                      Options, [&] (Decl *D) { ED->addMember(D); }))
       Status.setIsParseError();
   }
 
@@ -4794,9 +4970,10 @@
 ///   decl-enum-element:
 ///      'case' attribute-list enum-case (',' enum-case)*
 /// \endverbatim
-ParserStatus Parser::parseDeclEnumCase(ParseDeclOptions Flags,
-                                       DeclAttributes &Attributes,
-                                       llvm::SmallVectorImpl<Decl *> &Decls) {
+ParserResult<EnumCaseDecl>
+Parser::parseDeclEnumCase(ParseDeclOptions Flags,
+                          DeclAttributes &Attributes,
+                          llvm::SmallVectorImpl<Decl *> &Decls) {
   ParserStatus Status;
   SourceLoc CaseLoc = consumeToken(tok::kw_case);
 
@@ -4953,48 +5130,7 @@
   
   // Insert the element decls.
   std::copy(Elements.begin(), Elements.end(), std::back_inserter(Decls));
-  return Status;
-}
-
-/// \brief Parse the members in a struct/class/enum/protocol definition.
-///
-/// \verbatim
-///    decl*
-/// \endverbatim
-bool Parser::parseNominalDeclMembers(SourceLoc LBLoc, SourceLoc &RBLoc,
-                                     Diag<> ErrorDiag, ParseDeclOptions flags,
-                                     llvm::function_ref<void(Decl*)> handler) {
-  Decl *lastDecl = nullptr;
-  auto internalHandler = [&](Decl *D) {
-    lastDecl = D;
-    handler(D);
-  };
-  bool previousHadSemi = true;
-  parseList(tok::r_brace, LBLoc, RBLoc, tok::semi, /*OptionalSep=*/true,
-            /*AllowSepAfterLast=*/false, ErrorDiag, [&]() -> ParserStatus {
-    // If the previous declaration didn't have a semicolon and this new
-    // declaration doesn't start a line, complain.
-    if (!previousHadSemi && !Tok.isAtStartOfLine() && !Tok.is(tok::unknown)) {
-      SourceLoc endOfPrevious = getEndOfPreviousLoc();
-      diagnose(endOfPrevious, diag::declaration_same_line_without_semi)
-        .fixItInsert(endOfPrevious, ";");
-      // FIXME: Add semicolon to the AST?
-    }
-
-    previousHadSemi = false;
-    if (parseDecl(flags, internalHandler).isError())
-      return makeParserError();
-
-    // Check whether the previous declaration had a semicolon after it.
-    if (lastDecl && lastDecl->TrailingSemiLoc.isValid())
-      previousHadSemi = true;
-
-    return makeParserSuccess();
-  });
-
-  // If we found the closing brace, then the caller should not care if there
-  // were errors while parsing inner decls, because we recovered.
-  return !RBLoc.isValid();
+  return makeParserResult(Status, TheCase);
 }
 
 /// \brief Parse a 'struct' declaration, returning true (and doing no token
@@ -5070,9 +5206,8 @@
     ContextChange CC(*this, SD);
     Scope S(this, ScopeKind::StructBody);
     ParseDeclOptions Options(PD_HasContainerType | PD_InStruct);
-    if (parseNominalDeclMembers(LBLoc, RBLoc,
-                                diag::expected_rbrace_struct,
-                                Options, [&](Decl *D) {SD->addMember(D);}))
+    if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_struct,
+                      Options, [&](Decl *D) {SD->addMember(D);}))
       Status.setIsParseError();
   }
 
@@ -5160,8 +5295,8 @@
       if (isa<DestructorDecl>(D))
         CD->setHasDestructor();
     };
-    if (parseNominalDeclMembers(LBLoc, RBLoc, diag::expected_rbrace_class,
-                                Options, Handler))
+    if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_class,
+                      Options, Handler))
       Status.setIsParseError();
   }
 
@@ -5259,9 +5394,8 @@
       ParseDeclOptions Options(PD_HasContainerType |
                                PD_DisallowInit |
                                PD_InProtocol);
-      if (parseNominalDeclMembers(LBraceLoc, RBraceLoc,
-                                  diag::expected_rbrace_protocol,
-                                  Options, [&](Decl *D) {Proto->addMember(D);}))
+      if (parseDeclList(LBraceLoc, RBraceLoc, diag::expected_rbrace_protocol,
+                        Options, [&](Decl *D) {Proto->addMember(D);}))
         Status.setIsParseError();
     }
 
@@ -5280,9 +5414,10 @@
 ///   subscript-head
 ///     'subscript' attribute-list parameter-clause '->' type
 /// \endverbatim
-ParserStatus Parser::parseDeclSubscript(ParseDeclOptions Flags,
-                                        DeclAttributes &Attributes,
-                                        SmallVectorImpl<Decl *> &Decls) {
+ParserResult<SubscriptDecl>
+Parser::parseDeclSubscript(ParseDeclOptions Flags,
+                           DeclAttributes &Attributes,
+                           SmallVectorImpl<Decl *> &Decls) {
   ParserStatus Status;
   SourceLoc SubscriptLoc = consumeToken(tok::kw_subscript);
 
@@ -5291,7 +5426,7 @@
     = parseSingleParameterClause(ParameterContextKind::Subscript,
                                  &argumentNames);
   if (Indices.isNull() || Indices.hasCodeCompletion())
-    return Indices;
+    return ParserStatus(Indices);
   
   // '->'
   if (!Tok.is(tok::arrow)) {
@@ -5304,7 +5439,7 @@
   // type
   ParserResult<TypeRepr> ElementTy = parseType(diag::expected_type_subscript);
   if (ElementTy.isNull() || ElementTy.hasCodeCompletion())
-    return ElementTy;
+    return ParserStatus(ElementTy);
 
   
   // Build an AST for the subscript declaration.
@@ -5354,7 +5489,7 @@
 
   // No need to setLocalDiscriminator because subscripts cannot
   // validly appear outside of type decls.
-  return Status;
+  return makeParserResult(Status, Subscript);
 }
 
 ParserResult<ConstructorDecl>
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 1411252..6f74c1e 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2528,8 +2528,7 @@
   StructureMarkerRAII ParsingExprList(*this, Tok);
 
   leftLoc = consumeToken(leftTok);
-  ParserStatus status = parseList(rightTok, leftLoc, rightLoc, tok::comma,
-                                  /*OptionalSep=*/false,
+  ParserStatus status = parseList(rightTok, leftLoc, rightLoc,
                                   /*AllowSepAfterLast=*/false,
                                   rightTok == tok::r_paren
                                     ? diag::expected_rparen_expr_list
@@ -2877,7 +2876,6 @@
   CommaLocs.push_back(CommaLoc);
 
   Status |= parseList(tok::r_square, LSquareLoc, RSquareLoc,
-                      tok::comma, /*OptionalSep=*/false,
                       /*AllowSepAfterLast=*/true,
                       diag::expected_rsquare_array_expr,
                       [&] () -> ParserStatus
@@ -2928,8 +2926,8 @@
   bool FirstPair = true;
 
   ParserStatus Status =
-      parseList(tok::r_square, LSquareLoc, RSquareLoc, tok::comma,
-                /*OptionalSep=*/false, /*AllowSepAfterLast=*/true,
+      parseList(tok::r_square, LSquareLoc, RSquareLoc,
+                /*AllowSepAfterLast=*/true,
                 diag::expected_rsquare_array_expr, [&]() -> ParserStatus {
     // Parse the next key.
     ParserResult<Expr> Key;
diff --git a/lib/Parse/ParseGeneric.cpp b/lib/Parse/ParseGeneric.cpp
index 9c485e5..52c1ac9 100644
--- a/lib/Parse/ParseGeneric.cpp
+++ b/lib/Parse/ParseGeneric.cpp
@@ -241,7 +241,8 @@
 ParserStatus Parser::parseGenericWhereClause(
                SourceLoc &WhereLoc,
                SmallVectorImpl<RequirementRepr> &Requirements,
-               bool &FirstTypeInComplete) {
+               bool &FirstTypeInComplete,
+               bool AllowLayoutConstraints) {
   ParserStatus Status;
   // Parse the 'where'.
   WhereLoc = consumeToken(tok::kw_where);
@@ -262,21 +263,44 @@
       // A conformance-requirement.
       SourceLoc ColonLoc = consumeToken();
 
-      // Parse the protocol or composition.
-      ParserResult<TypeRepr> Protocol = parseTypeForInheritance(
-          diag::expected_identifier_for_type,
-          diag::expected_ident_type_in_inheritance);
-      
-      if (Protocol.isNull()) {
-        Status.setIsParseError();
-        if (Protocol.hasCodeCompletion())
-          Status.setHasCodeCompletion();
-        break;
-      }
+      if (Tok.is(tok::identifier) &&
+          getLayoutConstraintInfo(Context.getIdentifier(Tok.getText()),
+                                  Context)) {
+        // Parse a layout constraint.
+        auto LayoutName = Context.getIdentifier(Tok.getText());
+        auto LayoutLoc = consumeToken();
+        auto LayoutInfo = parseLayoutConstraint(LayoutName);
+        if (!LayoutInfo.isKnownLayout()) {
+          // There was a bug in the layout constraint.
+          Status.setIsParseError();
+        }
+        auto Layout = LayoutConstraint(Context.AllocateObjectCopy(LayoutInfo));
+        if (!AllowLayoutConstraints) {
+          diagnose(LayoutLoc,
+                   diag::layout_constraints_only_inside_specialize_attr);
+        } else {
+          // Add the layout requirement.
+          Requirements.push_back(RequirementRepr::getLayoutConstraint(
+              FirstType.get(), ColonLoc,
+              LayoutConstraintLoc(Layout, LayoutLoc)));
+        }
+      } else {
+        // Parse the protocol or composition.
+        ParserResult<TypeRepr> Protocol =
+            parseTypeForInheritance(diag::expected_identifier_for_type,
+                                    diag::expected_ident_type_in_inheritance);
 
-      // Add the requirement.
-      Requirements.push_back(RequirementRepr::getTypeConstraint(FirstType.get(),
-                                                     ColonLoc, Protocol.get()));
+        if (Protocol.isNull()) {
+          Status.setIsParseError();
+          if (Protocol.hasCodeCompletion())
+            Status.setHasCodeCompletion();
+          break;
+        }
+
+        // Add the requirement.
+        Requirements.push_back(RequirementRepr::getTypeConstraint(
+            FirstType.get(), ColonLoc, Protocol.get()));
+      }
     } else if ((Tok.isAnyOperator() && Tok.getText() == "==") ||
                Tok.is(tok::equal)) {
       // A same-type-requirement
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index afab6ea..e896c97 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -159,8 +159,8 @@
 
   // Parse the parameter list.
   bool isClosure = paramContext == ParameterContextKind::Closure;
-  return parseList(tok::r_paren, leftParenLoc, rightParenLoc, tok::comma,
-                      /*OptionalSep=*/false, /*AllowSepAfterLast=*/false,
+  return parseList(tok::r_paren, leftParenLoc, rightParenLoc,
+                      /*AllowSepAfterLast=*/false,
                       diag::expected_rparen_parameter,
                       [&]() -> ParserStatus {
     ParsedParameter param;
@@ -880,7 +880,7 @@
   // Parse all the elements.
   SmallVector<TuplePatternElt, 8> elts;
   ParserStatus ListStatus =
-    parseList(tok::r_paren, LPLoc, RPLoc, tok::comma, /*OptionalSep=*/false,
+    parseList(tok::r_paren, LPLoc, RPLoc,
               /*AllowSepAfterLast=*/false,
               diag::expected_rparen_tuple_pattern_list,
               [&] () -> ParserStatus {
diff --git a/lib/Parse/ParseSIL.cpp b/lib/Parse/ParseSIL.cpp
index 2e320d0..1ce71f3 100644
--- a/lib/Parse/ParseSIL.cpp
+++ b/lib/Parse/ParseSIL.cpp
@@ -13,6 +13,7 @@
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/Fallthrough.h"
 #include "swift/Parse/Lexer.h"
@@ -93,7 +94,9 @@
   };
 
   struct ParsedSpecAttr {
-    SmallVector<ParsedSubstitution, 4> subs;
+    ArrayRef<RequirementRepr> requirements;
+    bool exported;
+    SILSpecializeAttr::SpecializationKind kind;
   };
 
   class SILParser {
@@ -122,9 +125,13 @@
     /// A callback to be invoked every time a type was deserialized.
     std::function<void(Type)> ParsedTypeCallback;
 
-
     bool performTypeLocChecking(TypeLoc &T, bool IsSILType,
-                                GenericEnvironment *GenericEnv=nullptr);
+                                GenericEnvironment *GenericEnv = nullptr,
+                                DeclContext *DC = nullptr);
+
+    void convertRequirements(SILFunction *F, ArrayRef<RequirementRepr> From,
+                             SmallVectorImpl<Requirement> &To);
+
     ProtocolConformance *
     parseProtocolConformanceHelper(ProtocolDecl *&proto,
                                    GenericEnvironment *GenericEnv,
@@ -220,6 +227,32 @@
       TypeLoc = P.Tok.getLoc();
       return parseASTType(result);
     }
+    bool parseSILOwnership(Optional<ValueOwnershipKind> &OwnershipKind) {
+      // We pare here @ <identifier>.
+      if (P.consumeIf(tok::at_sign) && P.Tok.isNot(tok::identifier)) {
+        // Add error here.
+        return true;
+      }
+
+      OwnershipKind =
+          llvm::StringSwitch<Optional<ValueOwnershipKind>>(P.Tok.getText())
+              .Case("trivial",
+                    Optional<ValueOwnershipKind>(ValueOwnershipKind::Trivial))
+              .Case("unowned",
+                    Optional<ValueOwnershipKind>(ValueOwnershipKind::Unowned))
+              .Case("owned",
+                    Optional<ValueOwnershipKind>(ValueOwnershipKind::Owned))
+              .Case("guaranteed", Optional<ValueOwnershipKind>(
+                                      ValueOwnershipKind::Guaranteed))
+              .Default(None);
+
+      if (OwnershipKind.hasValue()) {
+        P.consumeToken();
+        return false;
+      }
+
+      return true;
+    }
     bool parseSILType(SILType &Result,
                       GenericEnvironment *&genericEnv,
                       bool IsFuncDecl = false);
@@ -683,6 +716,79 @@
   return false;
 }
 
+namespace {
+  /// A helper class to perform lookup of IdentTypes in the
+  /// current parser scope.
+  class IdentTypeReprLookup : public ASTWalker {
+    Parser &P;
+  public:
+    IdentTypeReprLookup(Parser &P) : P(P) {}
+
+    bool walkToTypeReprPre(TypeRepr *Ty) {
+      auto *T = dyn_cast_or_null<IdentTypeRepr>(Ty);
+      auto Comp = T->getComponentRange().front();
+      if (auto Entry = P.lookupInScope(Comp->getIdentifier()))
+        if (isa<TypeDecl>(Entry)) {
+          Comp->setValue(Entry);
+          return false;
+        }
+      return true;
+    }
+  };
+} // end anonymous namespace
+
+/// Remap RequirementReps to Requirements.
+void SILParser::convertRequirements(SILFunction *F,
+                                    ArrayRef<RequirementRepr> From,
+                                    SmallVectorImpl<Requirement> &To) {
+  if (From.empty()) {
+    To.clear();
+    return;
+  }
+
+  auto *GenericEnv = F->getGenericEnvironment();
+  assert(GenericEnv);
+
+  IdentTypeReprLookup PerformLookup(P);
+  // Use parser lexical scopes to resolve references
+  // to the generic parameters.
+  auto ResolveToInterfaceType = [&](TypeLoc Ty) -> Type {
+    Ty.getTypeRepr()->walk(PerformLookup);
+    performTypeLocChecking(Ty, /* IsSIL */ false);
+    assert(Ty.getType());
+    return GenericEnv->mapTypeOutOfContext(Ty.getType()->getCanonicalType());
+  };
+
+  for (auto &Req : From) {
+    if (Req.getKind() == RequirementReprKind::SameType) {
+      auto FirstType = ResolveToInterfaceType(Req.getFirstTypeLoc());
+      auto SecondType = ResolveToInterfaceType(Req.getSecondTypeLoc());
+      Requirement ConvertedRequirement(RequirementKind::SameType, FirstType,
+                                       SecondType);
+      To.push_back(ConvertedRequirement);
+      continue;
+    }
+
+    if (Req.getKind() == RequirementReprKind::TypeConstraint) {
+      auto FirstType = ResolveToInterfaceType(Req.getFirstTypeLoc());
+      auto SecondType = ResolveToInterfaceType(Req.getSecondTypeLoc());
+      Requirement ConvertedRequirement(RequirementKind::Conformance, FirstType,
+                                       SecondType);
+      To.push_back(ConvertedRequirement);
+      continue;
+    }
+
+    if (Req.getKind() == RequirementReprKind::LayoutConstraint) {
+      auto Subject = ResolveToInterfaceType(Req.getSubjectLoc());
+      Requirement ConvertedRequirement(RequirementKind::Layout, Subject,
+                                       Req.getLayoutConstraint());
+      To.push_back(ConvertedRequirement);
+      continue;
+    }
+    llvm_unreachable("Unsupported requirement kind");
+  }
+}
+
 static bool parseDeclSILOptional(bool *isTransparent, bool *isFragile,
                                  IsThunk_t *isThunk, bool *isGlobalInit,
                                  Inline_t *inlineStrategy, bool *isLet,
@@ -736,19 +842,30 @@
       continue;
     }
     else if (SpecAttrs && SP.P.Tok.getText() == "_specialize") {
-      SP.P.consumeToken(tok::identifier);
+      SourceLoc AtLoc = SP.P.Tok.getLoc();
+      SourceLoc Loc(AtLoc);
 
-      /// Parse a specialized attributed, building a parsed substitution list
-      /// and pushing a new ParsedSpecAttr on the SpecAttrs list. Conformances
-      /// cannot be generated until the function declaration is fully parsed so
-      /// that the function's generic signature can be consulted.
+      // Parse a _specialized attribute, building a parsed substitution list
+      // and pushing a new ParsedSpecAttr on the SpecAttrs list. Conformances
+      // cannot be generated until the function declaration is fully parsed so
+      // that the function's generic signature can be consulted.
       ParsedSpecAttr SpecAttr;
-      if (SP.parseSubstitutions(SpecAttr.subs))
+      SpecAttr.requirements = {};
+      SpecAttr.exported = false;
+      SpecAttr.kind = SILSpecializeAttr::SpecializationKind::Full;
+      SpecializeAttr *Attr;
+
+      if (!SP.P.parseSpecializeAttribute(tok::r_square, AtLoc, Loc, Attr))
         return true;
 
+      // Convert SpecializeAttr into ParsedSpecAttr.
+      SpecAttr.requirements = Attr->getTrailingWhereClause()->getRequirements();
+      SpecAttr.kind = Attr->getSpecializationKind() ==
+                              swift::SpecializeAttr::SpecializationKind::Full
+                          ? SILSpecializeAttr::SpecializationKind::Full
+                          : SILSpecializeAttr::SpecializationKind::Partial;
+      SpecAttr.exported = Attr->isExported();
       SpecAttrs->emplace_back(SpecAttr);
-
-      SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
       continue;
     }
     else if (ClangDecl && SP.P.Tok.getText() == "clang") {
@@ -770,7 +887,8 @@
 }
 
 bool SILParser::performTypeLocChecking(TypeLoc &T, bool IsSILType,
-                                       GenericEnvironment *GenericEnv) {
+                                       GenericEnvironment *GenericEnv,
+                                       DeclContext *DC) {
   // Do some type checking / name binding for the parsed type.
   assert(P.SF.ASTStage == SourceFile::Parsing &&
          "Unexpected stage during parsing!");
@@ -778,9 +896,12 @@
   if (GenericEnv == nullptr)
     GenericEnv = this->GenericEnv;
 
+  if (!DC)
+    DC = &P.SF;
+
   return swift::performTypeLocChecking(P.Context, T,
                                        /*isSILMode=*/true, IsSILType,
-                                       GenericEnv, &P.SF);
+                                       GenericEnv, DC);
 }
 
 /// Find the top-level ValueDecl or Module given a name.
@@ -1233,7 +1354,6 @@
     SourceLoc RParenLoc;
 
     if (P.parseList(tok::r_paren, LParenLoc, RParenLoc,
-                    tok::comma, /*OptionalSep=*/false,
                     /*AllowSepAfterLast=*/false,
                     diag::sil_basicblock_arg_rparen,
                     [&]() -> ParserStatus {
@@ -1911,6 +2031,9 @@
     UNARY_INSTRUCTION(CopyUnownedValue)
     UNARY_INSTRUCTION(DestroyValue)
     UNARY_INSTRUCTION(CondFail)
+    UNARY_INSTRUCTION(EndBorrowArgument)
+    UNARY_INSTRUCTION(UnmanagedReleaseValue)
+    UNARY_INSTRUCTION(UnmanagedRetainValue)
     REFCOUNTING_INSTRUCTION(StrongPin)
     REFCOUNTING_INSTRUCTION(StrongRetain)
     REFCOUNTING_INSTRUCTION(StrongRelease)
@@ -2421,19 +2544,19 @@
   }
 
   case ValueKind::EndBorrowInst: {
-    UnresolvedValueName BorrowDestName, BorrowSourceName;
+    UnresolvedValueName BorrowedFromName, BorrowedValueName;
     SourceLoc ToLoc;
     Identifier ToToken;
-    SILType BorrowDestTy, BorrowSourceTy;
+    SILType BorrowedFromTy, BorrowedValueTy;
 
-    if (parseValueName(BorrowDestName) ||
+    if (parseValueName(BorrowedValueName) ||
         parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
                            "from") ||
-        parseValueName(BorrowSourceName) ||
+        parseValueName(BorrowedFromName) ||
         P.parseToken(tok::colon, diag::expected_sil_colon_value_ref) ||
-        parseSILType(BorrowDestTy) ||
+        parseSILType(BorrowedValueTy) ||
         P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
-        parseSILType(BorrowSourceTy) || parseSILDebugLocation(InstLoc, B))
+        parseSILType(BorrowedFromTy) || parseSILDebugLocation(InstLoc, B))
       return true;
 
     if (ToToken.str() != "from") {
@@ -2441,12 +2564,12 @@
       return true;
     }
 
-    SILValue BorrowDest =
-        getLocalValue(BorrowDestName, BorrowDestTy, InstLoc, B);
-    SILValue BorrowSource =
-        getLocalValue(BorrowSourceName, BorrowSourceTy, InstLoc, B);
+    SILValue BorrowedValue =
+        getLocalValue(BorrowedValueName, BorrowedValueTy, InstLoc, B);
+    SILValue BorrowedFrom =
+        getLocalValue(BorrowedFromName, BorrowedFromTy, InstLoc, B);
 
-    ResultVal = B.createEndBorrow(InstLoc, BorrowDest, BorrowSource);
+    ResultVal = B.createEndBorrow(InstLoc, BorrowedValue, BorrowedFrom);
     break;
   }
 
@@ -3952,18 +4075,34 @@
     if (P.consumeIf(tok::l_paren)) {
       do {
         SILType Ty;
+        Optional<ValueOwnershipKind> OwnershipKind;
         SourceLoc NameLoc;
         StringRef Name = P.Tok.getText();
         if (P.parseToken(tok::sil_local_name, NameLoc,
                          diag::expected_sil_value_name) ||
-            P.parseToken(tok::colon, diag::expected_sil_colon_value_ref) ||
-            parseSILType(Ty))
+            P.parseToken(tok::colon, diag::expected_sil_colon_value_ref))
           return true;
+
+        // If SILOwnership is enabled and we are not assuming that we are
+        // parsing unqualified SIL, look for printed value ownership kinds.
+        if (!F->getModule()
+                 .getOptions()
+                 .AssumeUnqualifiedOwnershipWhenParsing &&
+            F->getModule().getOptions().EnableSILOwnership &&
+            parseSILOwnership(OwnershipKind))
+          return true;
+
+        if (parseSILType(Ty))
+          return true;
+
         SILArgument *Arg;
-        if (IsEntry)
+        if (IsEntry) {
           Arg = BB->createFunctionArgument(Ty);
-        else
-          Arg = BB->createPHIArgument(Ty, ValueOwnershipKind::Any);
+        } else {
+          Arg = BB->createPHIArgument(
+              Ty, OwnershipKind.getValueOr(
+                      ValueOwnershipKind(ValueOwnershipKind::Any)));
+        }
         setLocalValue(Arg, Name, NameLoc);
       } while (P.consumeIf(tok::comma));
       
@@ -4071,23 +4210,25 @@
 
     bool isDefinition = false;
     SourceLoc LBraceLoc = Tok.getLoc();
+
     if (consumeIf(tok::l_brace)) {
       isDefinition = true;
-      
+
       FunctionState.GenericEnv = GenericEnv;
       FunctionState.F->setGenericEnvironment(GenericEnv);
 
-      // Resolve specialization attributes after setting GenericEnv.
-      for (auto &Attr : SpecAttrs) {
-        SmallVector<Substitution, 4> Subs;
-        if (getApplySubstitutionsFromParsed(FunctionState, GenericEnv,
-                                            Attr.subs, Subs)) {
-          return true;
+      if (GenericEnv && !SpecAttrs.empty()) {
+        for (auto &Attr : SpecAttrs) {
+          SmallVector<Requirement, 4> requirements;
+          // Resolve types and convert requirements.
+          FunctionState.convertRequirements(FunctionState.F,
+                                            Attr.requirements, requirements);
+          FunctionState.F->addSpecializeAttr(SILSpecializeAttr::create(
+              FunctionState.F->getModule(), requirements, Attr.exported,
+              Attr.kind));
         }
-        FunctionState.F->addSpecializeAttr(
-          SILSpecializeAttr::create(FunctionState.F->getModule(), Subs));
       }
-      
+
       // Parse the basic block list.
       FunctionState.OwnershipEvaluator.reset(FunctionState.F);
       SILOpenedArchetypesTracker OpenedArchetypesTracker(*FunctionState.F);
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index ab152e9..bb7267d 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -297,22 +297,21 @@
     PreviousHadSemi = false;
     if (isStartOfDecl()
         && Tok.isNot(tok::pound_if, tok::pound_sourceLocation)) {
-      ParseDeclOptions options = IsTopLevel ? PD_AllowTopLevel : PD_Default;
-      ParserStatus Status =
-        parseDecl(options, [&](Decl *D) { TmpDecls.push_back(D); });
-      if (Status.isError()) {
+      ParserResult<Decl> DeclResult = 
+          parseDecl(IsTopLevel ? PD_AllowTopLevel : PD_Default,
+                    [&](Decl *D) {TmpDecls.push_back(D);});
+      if (DeclResult.isParseError()) {
         NeedParseErrorRecovery = true;
-        if (Status.hasCodeCompletion() && IsTopLevel &&
+        if (DeclResult.hasCodeCompletion() && IsTopLevel &&
             isCodeCompletionFirstPass()) {
           consumeDecl(BeginParserPosition, None, IsTopLevel);
-          return Status;
+          return DeclResult;
         }
       }
+      Result = DeclResult.getPtrOrNull();
 
       for (Decl *D : TmpDecls)
         Entries.push_back(D);
-      if (!TmpDecls.empty())
-        PreviousHadSemi = TmpDecls.back()->TrailingSemiLoc.isValid();
       TmpDecls.clear();
     } else if (Tok.is(tok::pound_if)) {
       SourceLoc StartLoc = Tok.getLoc();
@@ -347,6 +346,9 @@
       IfConfigStmt *ICS = cast<IfConfigStmt>(Result.get<Stmt*>());
       for (auto &Entry : ICS->getActiveClauseElements()) {
         Entries.push_back(Entry);
+        if (Entry.is<Decl*>()) {
+          Entry.get<Decl*>()->setEscapedFromIfConfig(true);
+        }
       }
     } else if (Tok.is(tok::pound_line)) {
       ParserStatus Status = parseLineDirective(true);
@@ -414,15 +416,16 @@
         Entries.push_back(Result);
     }
 
-    if (!NeedParseErrorRecovery && !PreviousHadSemi && Tok.is(tok::semi)) {
-      if (Result) {
-        if (Result.is<Expr*>()) {
-          Result.get<Expr*>()->TrailingSemiLoc = consumeToken(tok::semi);
-        } else {
-          Result.get<Stmt*>()->TrailingSemiLoc = consumeToken(tok::semi);
-        }
-      }
+    if (!NeedParseErrorRecovery && Tok.is(tok::semi)) {
       PreviousHadSemi = true;
+      if (Expr *E = Result.dyn_cast<Expr*>())
+        E->TrailingSemiLoc = consumeToken(tok::semi);
+      else if (Stmt *S = Result.dyn_cast<Stmt*>())
+        S->TrailingSemiLoc = consumeToken(tok::semi);
+      else if (Decl *D = Result.dyn_cast<Decl*>())
+        D->TrailingSemiLoc = consumeToken(tok::semi);
+      else
+        assert(!Result && "Unsupported AST node");
     }
 
     if (NeedParseErrorRecovery) {
@@ -1570,10 +1573,27 @@
               break;
           }
         } else {
-          D.diagnose(SE->getLoc(),
-                     diag::unsupported_conditional_compilation_binary_expression);
+          D.diagnose(
+              SE->getLoc(),
+              diag::unsupported_conditional_compilation_binary_expression);
           return ConditionalCompilationExprState::error();
         }
+      } else {
+        // Swift3 didn't have this branch. the operator and the RHS are
+        // silently ignored.
+        if (!Context.isSwiftVersion3()) {
+          D.diagnose(
+              elements[iOperator]->getLoc(),
+              diag::unsupported_conditional_compilation_expression_type);
+          return ConditionalCompilationExprState::error();
+        } else {
+          SourceRange ignoredRange(elements[iOperator]->getLoc(),
+                                   elements[iOperand]->getEndLoc());
+          D.diagnose(
+              elements[iOperator]->getLoc(),
+              diag::swift3_unsupported_conditional_compilation_expression_type)
+            .highlight(ignoredRange);
+        }
       }
 
       iOperator += 2;
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index 2911f0c..5dfac08 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -59,6 +59,82 @@
   return ty;
 }
 
+LayoutConstraintInfo
+Parser::parseLayoutConstraint(Identifier LayoutConstraintID) {
+  LayoutConstraintInfo layoutConstraint =
+      getLayoutConstraintInfo(LayoutConstraintID, Context);
+  assert(layoutConstraint.isKnownLayout() &&
+         "Expected layout constraint definition");
+
+  if (!layoutConstraint.isTrivial())
+    return layoutConstraint;
+
+  SourceLoc LParenLoc;
+  if (!consumeIf(tok::l_paren, LParenLoc)) {
+    // It is a trivial without any size constraints.
+    return LayoutConstraintInfo(LayoutConstraintKind::Trivial);
+  }
+
+  int size = 0;
+  int alignment = 0;
+
+  auto ParseTrivialLayoutConstraintBody = [&] () -> bool {
+    // Parse the size and alignment.
+    if (Tok.is(tok::integer_literal)) {
+      if (Tok.getText().getAsInteger(10, size)) {
+        diagnose(Tok.getLoc(), diag::layout_size_should_be_positive);
+        return true;
+      }
+      consumeToken();
+      if (consumeIf(tok::comma)) {
+        // parse alignment.
+        if (Tok.is(tok::integer_literal)) {
+          if (Tok.getText().getAsInteger(10, alignment)) {
+            diagnose(Tok.getLoc(), diag::layout_alignment_should_be_positive);
+            return true;
+          }
+          consumeToken();
+        } else {
+          diagnose(Tok.getLoc(), diag::layout_alignment_should_be_positive);
+          return true;
+        }
+      }
+    } else {
+      diagnose(Tok.getLoc(), diag::layout_size_should_be_positive);
+      return true;
+    }
+    return false;
+  };
+
+  if (ParseTrivialLayoutConstraintBody()) {
+    // There was an error during parsing.
+    skipUntil(tok::r_paren);
+    consumeIf(tok::r_paren);
+    return LayoutConstraintInfo::getUnknownLayout();
+  }
+
+  if (!consumeIf(tok::r_paren)) {
+    // Expected a closing r_paren.
+    diagnose(Tok.getLoc(), diag::expected_rparen_layout_constraint);
+    consumeToken();
+    return LayoutConstraintInfo::getUnknownLayout();
+  }
+
+  if (size < 0) {
+    diagnose(Tok.getLoc(), diag::layout_size_should_be_positive);
+    return LayoutConstraintInfo::getUnknownLayout();
+  }
+
+  if (alignment < 0) {
+    diagnose(Tok.getLoc(), diag::layout_alignment_should_be_positive);
+    return LayoutConstraintInfo::getUnknownLayout();
+  }
+
+  // Otherwise it is a trivial layout constraint with
+  // provided size and alignment.
+  return LayoutConstraintInfo(layoutConstraint.getKind(), size, alignment);
+}
+
 ParserResult<TypeRepr> Parser::parseTypeSimple() {
   return parseTypeSimple(diag::expected_type);
 }
@@ -682,7 +758,6 @@
     Labels;
 
   ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
-                                  tok::comma, /*OptionalSep=*/false,
                                   /*AllowSepAfterLast=*/false,
                                   diag::expected_rparen_tuple_type_list,
                                   [&] () -> ParserStatus {
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index b7e241d..19bf5d5 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -658,9 +658,8 @@
 
 ParserStatus
 Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
-                  tok SeparatorK, bool OptionalSep, bool AllowSepAfterLast,
-                  Diag<> ErrorDiag, std::function<ParserStatus()> callback) {
-  assert(SeparatorK == tok::comma || SeparatorK == tok::semi);
+                  bool AllowSepAfterLast, Diag<> ErrorDiag,
+                  std::function<ParserStatus()> callback) {
 
   if (Tok.is(RightK)) {
     RightLoc = consumeToken(RightK);
@@ -669,9 +668,8 @@
 
   ParserStatus Status;
   while (true) {
-    while (Tok.is(SeparatorK)) {
-      diagnose(Tok, diag::unexpected_separator,
-               SeparatorK == tok::comma ? "," : ";")
+    while (Tok.is(tok::comma)) {
+      diagnose(Tok, diag::unexpected_separator, ",")
         .fixItRemove(SourceRange(Tok.getLoc()));
       consumeToken();
     }
@@ -689,23 +687,22 @@
     // If we haven't made progress, or seeing any error, skip ahead.
     if (Tok.getLoc() == StartLoc || Status.isError()) {
       assert(Status.isError() && "no progress without error");
-      skipUntilDeclRBrace(RightK, SeparatorK);
-      if (Tok.is(RightK) || (!OptionalSep && Tok.isNot(SeparatorK)))
+      skipUntilDeclRBrace(RightK, tok::comma);
+      if (Tok.is(RightK) || Tok.isNot(tok::comma))
         break;
     }
-    if (consumeIf(SeparatorK)) {
+    if (consumeIf(tok::comma)) {
       if (Tok.isNot(RightK))
         continue;
       if (!AllowSepAfterLast) {
-        diagnose(Tok, diag::unexpected_separator,
-                 SeparatorK == tok::comma ? "," : ";")
+        diagnose(Tok, diag::unexpected_separator, ",")
           .fixItRemove(SourceRange(PreviousLoc));
       }
       break;
     }
     // If we're in a comma-separated list, the next token is at the
     // beginning of a new line and can never start an element, break.
-    if (SeparatorK == tok::comma && Tok.isAtStartOfLine() &&
+    if (Tok.isAtStartOfLine() &&
         (Tok.is(tok::r_brace) || isStartOfDecl() || isStartOfStmt())) {
       break;
     }
@@ -714,12 +711,10 @@
       IsInputIncomplete = true;
       break;
     }
-    if (!OptionalSep) {
-      StringRef Separator = (SeparatorK == tok::comma ? "," : ";");
-      diagnose(Tok, diag::expected_separator, Separator)
-        .fixItInsertAfter(PreviousLoc, Separator);
-      Status.setIsParseError();
-    }
+
+    diagnose(Tok, diag::expected_separator, ",")
+      .fixItInsertAfter(PreviousLoc, ",");
+    Status.setIsParseError();
   }
 
   if (Status.isError()) {
diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp
index 626f439..ff1102b 100644
--- a/lib/PrintAsObjC/PrintAsObjC.cpp
+++ b/lib/PrintAsObjC/PrintAsObjC.cpp
@@ -17,6 +17,7 @@
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeVisitor.h"
 #include "swift/AST/Comment.h"
 #include "swift/Basic/StringExtras.h"
diff --git a/lib/SIL/Bridging.cpp b/lib/SIL/Bridging.cpp
index 7135dc5..1120aa1 100644
--- a/lib/SIL/Bridging.cpp
+++ b/lib/SIL/Bridging.cpp
@@ -20,6 +20,7 @@
 #include "swift/SIL/SILModule.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/DiagnosticsSIL.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Fallthrough.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/Support/Debug.h"
diff --git a/lib/SIL/InstructionUtils.cpp b/lib/SIL/InstructionUtils.cpp
index c75df27..24595ba 100644
--- a/lib/SIL/InstructionUtils.cpp
+++ b/lib/SIL/InstructionUtils.cpp
@@ -13,6 +13,8 @@
 #define DEBUG_TYPE "sil-inst-utils"
 #include "swift/SIL/InstructionUtils.h"
 #include "swift/Basic/NullablePtr.h"
+#include "swift/Basic/Fallthrough.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/Projection.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILBasicBlock.h"
@@ -224,6 +226,199 @@
   return BI->getArguments()[0];
 }
 
+void ConformanceCollector::scanType(Type type) {
+  type = type->getCanonicalType();
+  if (Visited.count(type.getPointer()) != 0)
+    return;
+
+  // Look for all possible metatypes and conformances which are used in type.
+  type.visit([this](Type SubType) {
+    if (NominalTypeDecl *NT = SubType->getNominalOrBoundGenericNominal()) {
+      if (Visited.count(SubType.getPointer()) == 0) {
+
+        if (Visited.count(NT) == 0) {
+          EscapingMetaTypes.push_back(NT);
+          Visited.insert(NT);
+        }
+
+        // Also inserts the type passed to scanType().
+        Visited.insert(SubType.getPointer());
+        auto substs = SubType->gatherAllSubstitutions(M.getSwiftModule(),
+                                                     nullptr);
+        scanSubsts(substs);
+      }
+    }
+  });
+}
+
+void ConformanceCollector::scanSubsts(ArrayRef<Substitution> substs) {
+  for (const Substitution &subst : substs) {
+    scanConformances(subst.getConformances());
+    scanType(subst.getReplacement());
+  }
+}
+
+void ConformanceCollector::scanConformance(ProtocolConformance *C) {
+  if (!C || Visited.count(C) != 0)
+    return;
+  Visited.insert(C);
+  Conformances.push_back(C);
+
+  switch (C->getKind()) {
+    case ProtocolConformanceKind::Normal:
+      break;
+    case ProtocolConformanceKind::Inherited:
+      scanConformance(cast<InheritedProtocolConformance>(C)->
+                        getInheritedConformance());
+      break;
+    case ProtocolConformanceKind::Specialized: {
+
+      auto *SpecC = cast<SpecializedProtocolConformance>(C);
+      scanConformance(SpecC->getGenericConformance());
+      scanSubsts(SpecC->getGenericSubstitutions());
+      break;
+    }
+  }
+
+  SILWitnessTable *WT = M.lookUpWitnessTable(C, /*deserializeLazily*/ false);
+  if (!WT)
+    return;
+
+  for (const SILWitnessTable::Entry &entry : WT->getEntries()) {
+    switch (entry.getKind()) {
+      case SILWitnessTable::AssociatedTypeProtocol:
+        scanConformance(entry.getAssociatedTypeProtocolWitness().Witness);
+        break;
+        
+      case SILWitnessTable::BaseProtocol:
+        scanConformance(entry.getBaseProtocolWitness().Witness);
+        break;
+        
+      case SILWitnessTable::AssociatedType:
+        scanType(entry.getAssociatedTypeWitness().Witness);
+        break;
+
+      case SILWitnessTable::Method:
+      case SILWitnessTable::Invalid:
+      case SILWitnessTable::MissingOptional:
+        break;
+    }
+  }
+}
+
+void ConformanceCollector::scanConformances(
+                                     ArrayRef<ProtocolConformanceRef> CRefs) {
+  for (ProtocolConformanceRef CRef : CRefs) {
+    scanConformance(CRef);
+  }
+}
+
+void ConformanceCollector::collect(swift::SILInstruction *I) {
+  switch (I->getKind()) {
+    case ValueKind::InitExistentialAddrInst: {
+      auto *IEI = cast<InitExistentialAddrInst>(I);
+      for (ProtocolConformanceRef CRef : IEI->getConformances()) {
+        if (CRef.isConcrete()) {
+          scanConformance(CRef.getConcrete()->getRootNormalConformance());
+        }
+      }
+      scanType(IEI->getFormalConcreteType());
+      break;
+    }
+    case ValueKind::InitExistentialRefInst:
+      scanConformances(cast<InitExistentialRefInst>(I)->getConformances());
+      break;
+    case ValueKind::InitExistentialMetatypeInst:
+      scanConformances(cast<InitExistentialMetatypeInst>(I)->getConformances());
+      break;
+    case ValueKind::WitnessMethodInst:
+      scanConformance(cast<WitnessMethodInst>(I)->getConformance());
+      break;
+    case ValueKind::AllocBoxInst: {
+      CanSILBoxType BTy = cast<AllocBoxInst>(I)->getBoxType();
+      size_t NumFields = BTy->getLayout()->getFields().size();
+      for (size_t Idx = 0; Idx < NumFields; ++Idx) {
+        scanType(BTy->getFieldLoweredType(M, Idx));
+      }
+      scanType(I->getType().getSwiftRValueType());
+      break;
+    }
+    case ValueKind::AllocExistentialBoxInst: {
+      auto *AEBI = cast<AllocExistentialBoxInst>(I);
+      scanType(AEBI->getFormalConcreteType());
+      scanConformances(AEBI->getConformances());
+      break;
+    }
+    case ValueKind::AllocRefInst:
+    case ValueKind::AllocRefDynamicInst:
+    case ValueKind::MetatypeInst:
+    case ValueKind::UnconditionalCheckedCastInst:
+      scanType(I->getType().getSwiftRValueType());
+      break;
+    case ValueKind::AllocStackInst: {
+      Type Ty = I->getType().getSwiftRValueType();
+      if (Ty->hasArchetype())
+        scanType(Ty);
+      break;
+    }
+    case ValueKind::CheckedCastAddrBranchInst: {
+      auto *CCABI = cast<CheckedCastAddrBranchInst>(I);
+      scanType(CCABI->getSourceType());
+      scanType(CCABI->getTargetType());
+      break;
+    }
+    case ValueKind::UnconditionalCheckedCastAddrInst: {
+      auto *UCCAI = cast<UnconditionalCheckedCastAddrInst>(I);
+      scanType(UCCAI->getSourceType());
+      scanType(UCCAI->getTargetType());
+      break;
+    }
+    case ValueKind::CheckedCastBranchInst:
+      scanType(cast<CheckedCastBranchInst>(I)->getCastType().
+                 getSwiftRValueType());
+      break;
+    case ValueKind::ValueMetatypeInst: {
+      auto *VMTI = cast<ValueMetatypeInst>(I);
+      scanType(VMTI->getOperand()->getType().getSwiftRValueType());
+      break;
+    }
+    case ValueKind::DestroyAddrInst: {
+      auto *DAI = cast<DestroyAddrInst>(I);
+      scanType(DAI->getOperand()->getType().getSwiftRValueType());
+      break;
+    }
+    default:
+      if (ApplySite AS = ApplySite::isa(I)) {
+        auto substs = AS.getSubstitutions();
+        scanSubsts(substs);
+
+        CanSILFunctionType OrigFnTy = AS.getOrigCalleeType();
+        CanSILFunctionType SubstFnTy = AS.getSubstCalleeType();
+
+        scanFuncParams(OrigFnTy->getParameters(), SubstFnTy->getParameters());
+        scanFuncParams(OrigFnTy->getAllResults(), SubstFnTy->getAllResults());
+
+        if (OrigFnTy->getRepresentation() ==
+            SILFunctionType::Representation::WitnessMethod) {
+          // The self parameter of a witness method is always generic.
+          scanType(OrigFnTy->getSelfInstanceType());
+        }
+      }
+      break;
+  }
+}
+
+void ConformanceCollector::collect(SILWitnessTable *WT) {
+  scanConformance(WT->getConformance());
+}
+
+void ConformanceCollector::dump() {
+  llvm::errs() << "ConformanceCollector:\n";
+  for (const ProtocolConformance *C : Conformances) {
+    C->dump();
+  }
+}
+
 namespace {
 
 enum class OwnershipQualifiedKind {
diff --git a/lib/SIL/Linker.cpp b/lib/SIL/Linker.cpp
index 6198de6..0437014 100644
--- a/lib/SIL/Linker.cpp
+++ b/lib/SIL/Linker.cpp
@@ -17,6 +17,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Debug.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/FormalLinkage.h"
 #include <functional>
 
diff --git a/lib/SIL/LoopInfo.cpp b/lib/SIL/LoopInfo.cpp
index ae7247f..ae2cae5 100644
--- a/lib/SIL/LoopInfo.cpp
+++ b/lib/SIL/LoopInfo.cpp
@@ -31,8 +31,8 @@
 #endif
 }
 
-SILLoopInfo::SILLoopInfo(SILFunction *F, DominanceInfo *DT) {
-  LI.analyze(*DT);
+SILLoopInfo::SILLoopInfo(SILFunction *F, DominanceInfo *DT) : Dominance(DT) {
+  LI.analyze(*Dominance);
 }
 
 bool SILLoop::canDuplicate(SILInstruction *I) const {
@@ -82,5 +82,5 @@
 }
 
 void SILLoopInfo::verify() const {
-  LI.verify();
+  LI.verify(*Dominance);
 }
diff --git a/lib/SIL/SIL.cpp b/lib/SIL/SIL.cpp
index a8c08d7..f2f30ca 100644
--- a/lib/SIL/SIL.cpp
+++ b/lib/SIL/SIL.cpp
@@ -22,6 +22,7 @@
 #include "swift/AST/Expr.h"
 #include "swift/AST/Mangle.h"
 #include "swift/AST/Pattern.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/ClangImporter/ClangModule.h"
 #include "swift/Basic/Fallthrough.h"
 #include "clang/AST/Attr.h"
@@ -129,14 +130,9 @@
       && conformanceModule == typeUnit->getParentModule())
     return SILLinkage::Shared;
 
-  // If we're building with -sil-serialize-all, give the conformance public
-  // linkage.
-  if (conformanceModule->getResilienceStrategy()
-      == ResilienceStrategy::Fragile)
-    return (definition ? SILLinkage::Public : SILLinkage::PublicExternal);
-
-  // FIXME: This should be using std::min(protocol's access, type's access).
-  switch (C->getProtocol()->getEffectiveAccess()) {
+  Accessibility accessibility = std::min(C->getProtocol()->getEffectiveAccess(),
+                                         typeDecl->getEffectiveAccess());
+  switch (accessibility) {
     case Accessibility::Private:
     case Accessibility::FilePrivate:
       return (definition ? SILLinkage::Private : SILLinkage::PrivateExternal);
diff --git a/lib/SIL/SILFunction.cpp b/lib/SIL/SILFunction.cpp
index 77c9c58..5449b24 100644
--- a/lib/SIL/SILFunction.cpp
+++ b/lib/SIL/SILFunction.cpp
@@ -24,17 +24,32 @@
 using namespace swift;
 using namespace Lowering;
 
-SILSpecializeAttr::SILSpecializeAttr(ArrayRef<Substitution> subs)
-  : numSubs(subs.size()) {
-  std::copy(subs.begin(), subs.end(), getTrailingObjects<Substitution>());
+ArrayRef<Requirement> SILSpecializeAttr::getRequirements() const {
+  return {const_cast<SILSpecializeAttr *>(this)->getRequirementsData(),
+          numRequirements};
+}
+
+SILSpecializeAttr::SILSpecializeAttr(ArrayRef<Requirement> requirements,
+                                     bool exported, SpecializationKind kind)
+    : numRequirements(requirements.size()), kind(kind), exported(exported) {
+  std::copy(requirements.begin(), requirements.end(), getRequirementsData());
 }
 
 SILSpecializeAttr *SILSpecializeAttr::create(SILModule &M,
-                                             ArrayRef<Substitution> subs) {
+                                             ArrayRef<Requirement> requirements,
+                                             bool exported,
+                                             SpecializationKind kind) {
   unsigned size =
-    sizeof(SILSpecializeAttr) + (subs.size() * sizeof(Substitution));
+      sizeof(SILSpecializeAttr) + sizeof(Requirement) * requirements.size();
   void *buf = M.allocate(size, alignof(SILSpecializeAttr));
-  return ::new (buf) SILSpecializeAttr(subs);
+  return ::new (buf) SILSpecializeAttr(requirements, exported, kind);
+}
+
+void SILFunction::addSpecializeAttr(SILSpecializeAttr *Attr) {
+  if (getLoweredFunctionType()->getGenericSignature()) {
+    Attr->F = this;
+    SpecializeAttrSet.push_back(Attr);
+  }
 }
 
 SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
@@ -318,8 +333,7 @@
                clEnumValN(LongLineBehavior::None, "none", "Print everything"),
                clEnumValN(LongLineBehavior::Truncate, "truncate",
                           "Truncate long lines"),
-               clEnumValN(LongLineBehavior::Wrap, "wrap", "Wrap long lines"),
-               clEnumValEnd));
+               clEnumValN(LongLineBehavior::Wrap, "wrap", "Wrap long lines")));
 
 static llvm::cl::opt<bool>
 RemoveUseListComments("view-cfg-remove-use-list-comments",
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 1c735b8..ee81c9c 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -16,6 +16,7 @@
 
 #include "swift/SIL/SILInstruction.h"
 #include "swift/AST/AST.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/type_traits.h"
 #include "swift/Basic/Unicode.h"
 #include "swift/Basic/AssertImplements.h"
@@ -672,6 +673,10 @@
     : SILInstruction(ValueKind::EndBorrowInst, DebugLoc),
       Operands(this, Src, Dest) {}
 
+EndBorrowArgumentInst::EndBorrowArgumentInst(SILDebugLocation DebugLoc,
+                                             SILArgument *Arg)
+    : UnaryInstructionBase(DebugLoc, SILValue(Arg)) {}
+
 AssignInst::AssignInst(SILDebugLocation Loc, SILValue Src, SILValue Dest)
     : SILInstruction(ValueKind::AssignInst, Loc), Operands(this, Src, Dest) {}
 
diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp
index 872d87d..17ce7bf 100644
--- a/lib/SIL/SILModule.cpp
+++ b/lib/SIL/SILModule.cpp
@@ -13,6 +13,7 @@
 #define DEBUG_TYPE "sil-module"
 #include "swift/Serialization/SerializedSILLoader.h"
 #include "swift/AST/GenericEnvironment.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Substitution.h"
 #include "swift/SIL/FormalLinkage.h"
 #include "swift/SIL/SILDebugScope.h"
@@ -218,6 +219,13 @@
   return SILDefaultWitnessTable::create(*this, Linkage, Protocol);
 }
 
+void SILModule::deleteWitnessTable(SILWitnessTable *Wt) {
+  NormalProtocolConformance *Conf = Wt->getConformance();
+  assert(lookUpWitnessTable(Conf, false) == Wt);
+  WitnessTableMap.erase(Conf);
+  witnessTables.erase(Wt);
+}
+
 SILFunction *SILModule::getOrCreateFunction(SILLocation loc,
                                             StringRef name,
                                             SILLinkage linkage,
@@ -376,8 +384,12 @@
     for (auto *A :
            Attrs.getAttributes<SpecializeAttr, false /*AllowInvalid*/>()) {
       auto *SA = cast<SpecializeAttr>(A);
-      auto subs = SA->getConcreteDecl().getSubstitutions();
-      F->addSpecializeAttr(SILSpecializeAttr::create(*this, subs));
+      auto kind = SA->getSpecializationKind() ==
+                          SpecializeAttr::SpecializationKind::Full
+                      ? SILSpecializeAttr::SpecializationKind::Full
+                      : SILSpecializeAttr::SpecializationKind::Partial;
+      F->addSpecializeAttr(SILSpecializeAttr::create(
+          *this, SA->getRequirements(), SA->isExported(), kind));
     }
   }
 
@@ -434,8 +446,7 @@
 
   // Otherwise, lookup the ID and Type and store them in the map.
   StringRef NameRef = getBuiltinBaseName(getASTContext(), ID.str(), Info.Types);
-  Info.ID =
-    (llvm::Intrinsic::ID)getLLVMIntrinsicID(NameRef, !Info.Types.empty());
+  Info.ID = (llvm::Intrinsic::ID)getLLVMIntrinsicID(NameRef);
 
   return Info;
 }
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index 9d5b071..dd83260 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -19,10 +19,12 @@
 #include "swift/AST/Module.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/Range.h"
+#include "swift/Basic/STLExtras.h"
 #include "swift/ClangImporter/ClangModule.h"
 #include "swift/SIL/Dominance.h"
 #include "swift/SIL/DynamicCasts.h"
 #include "swift/SIL/PrettyStackTrace.h"
+#include "swift/SIL/Projection.h"
 #include "swift/SIL/SILDebugScope.h"
 #include "swift/SIL/SILFunction.h"
 #include "swift/SIL/SILModule.h"
@@ -42,10 +44,21 @@
 // prevent release builds from triggering spurious unused variable warnings.
 #ifndef NDEBUG
 
-llvm::cl::opt<bool> PrintMessageInsteadOfAssert(
-    "sil-ownership-verifier-do-not-assert",
-    llvm::cl::desc("Print out message instead of asserting. "
-                   "Meant for debugging"));
+// This is an option to put the SILOwnershipVerifier in testing mode. This
+// causes the following:
+//
+// 1. Instead of printing an error message and aborting, the verifier will print
+// the message and continue. This allows for FileCheck testing of the verifier.
+//
+// 2. SILInstruction::verifyOperandOwnership() is disabled. This is used for
+// verification in SILBuilder. This causes errors to be printed twice, once when
+// we build the IR and a second time when we perform a full verification of the
+// IR. For testing purposes, we just want the later.
+llvm::cl::opt<bool> IsSILOwnershipVerifierTestingEnabled(
+    "sil-ownership-verifier-enable-testing",
+    llvm::cl::desc("Put the sil ownership verifier in testing mode. See "
+                   "comment in SILOwnershipVerifier.cpp above option for more "
+                   "information."));
 
 //===----------------------------------------------------------------------===//
 //                                  Utility
@@ -57,11 +70,41 @@
 }
 
 static bool isValueAddressOrTrivial(SILValue V, SILModule &M) {
+  // TODO: Change this to use V->getOwnershipKind() == OwnershipKind::Trivial;
   return V->getType().isAddress() || V->getType().isTrivial(M);
 }
 
+static bool isOwnershipForwardingValueKind(ValueKind K) {
+  switch (K) {
+  case ValueKind::TupleInst:
+  case ValueKind::StructInst:
+  case ValueKind::EnumInst:
+  case ValueKind::OpenExistentialRefInst:
+  case ValueKind::UpcastInst:
+  case ValueKind::UncheckedRefCastInst:
+  case ValueKind::ConvertFunctionInst:
+  case ValueKind::RefToBridgeObjectInst:
+  case ValueKind::BridgeObjectToRefInst:
+  case ValueKind::UnconditionalCheckedCastInst:
+  case ValueKind::TupleExtractInst:
+  case ValueKind::StructExtractInst:
+  case ValueKind::UncheckedEnumDataInst:
+    return true;
+  default:
+    return false;
+  }
+}
+
+static bool isOwnershipForwardingValue(SILValue V) {
+  return isOwnershipForwardingValueKind(V->getKind());
+}
+
+static bool isOwnershipForwardingInst(SILInstruction *I) {
+  return isOwnershipForwardingValueKind(I->getKind());
+}
+
 //===----------------------------------------------------------------------===//
-//                    OwnershipCompatibilityCheckerVisitor
+//                      OwnershipCompatibilityUseChecker
 //===----------------------------------------------------------------------===//
 
 namespace {
@@ -76,14 +119,34 @@
                                    OwnershipUseCheckerResult> {
   SILModule &Mod;
   const Operand &Op;
+  SILValue BaseValue;
 
 public:
-  OwnershipCompatibilityUseChecker(SILModule &M, const Operand &Op)
-      : Mod(M), Op(Op) {}
+  /// Create a new OwnershipCompatibilityUseChecker.
+  ///
+  /// In most cases, one should only pass in \p Op and \p BaseValue will be set
+  /// to Op.get(). In cases where one is trying to verify subobjects, Op.get()
+  /// should be the subobject and Value should be the parent object. An example
+  /// of where one would want to do this is in the case of value projections
+  /// like struct_extract.
+  OwnershipCompatibilityUseChecker(SILModule &M, const Operand &Op,
+                                   SILValue BaseValue)
+      : Mod(M), Op(Op), BaseValue(BaseValue) {
+    assert((BaseValue == Op.get() ||
+            BaseValue.getOwnershipKind() == ValueOwnershipKind::Guaranteed) &&
+           "Guaranteed values are the only values allowed to have subobject");
+    // We only support subobjects on objects.
+    assert((BaseValue->getType().isObject() || !isCheckingSubObject()) &&
+           "Checking a subobject, but do not have an object base value?!");
+  }
+
+  bool isCheckingSubObject() const { return Op.get() != BaseValue; }
 
   SILValue getValue() const { return Op.get(); }
 
   ValueOwnershipKind getOwnershipKind() const {
+    assert(getValue().getOwnershipKind() == Op.get().getOwnershipKind() &&
+           "Expected ownership kind of parent value and operand");
     return getValue().getOwnershipKind();
   }
 
@@ -101,15 +164,6 @@
     return getType().isTrivial(Mod);
   }
 
-  void error(SILInstruction *User) {
-    llvm::errs() << "Have operand with incompatible ownership?!\n"
-                 << "Value: " << *getValue() << "User: " << *User
-                 << "Conv: " << getOwnershipKind() << "\n";
-    if (PrintMessageInsteadOfAssert)
-      return;
-    llvm_unreachable("triggering standard assertion failure routine");
-  }
-
   OwnershipUseCheckerResult visitForwardingInst(SILInstruction *I);
 
   /// Check if \p User as compatible ownership with the SILValue that we are
@@ -120,7 +174,14 @@
   bool check(SILInstruction *User) {
     auto Result = visit(User);
     if (!Result.HasCompatibleOwnership) {
-      error(User);
+      llvm::errs() << "Function: '" << User->getFunction()->getName() << "'\n"
+                   << "Have operand with incompatible ownership?!\n"
+                   << "Value: " << *getValue() << "BaseValue: " << *BaseValue
+                   << "User: " << *User << "Conv: " << getOwnershipKind()
+                   << "\n\n";
+      if (IsSILOwnershipVerifierTestingEnabled)
+        return false;
+      llvm_unreachable("triggering standard assertion failure routine");
     }
 
     assert((!Result.ShouldCheckForDataflowViolations ||
@@ -136,6 +197,8 @@
   }
 
   OwnershipUseCheckerResult visitCallee(CanSILFunctionType SubstCalleeType);
+  OwnershipUseCheckerResult
+  checkTerminatorArgumentMatchesDestBB(SILBasicBlock *DestBB, unsigned OpIndex);
 
 // Create declarations for all instructions, so we get a warning at compile
 // time if any instructions do not have an implementation.
@@ -192,9 +255,7 @@
     return {compatibleWithOwnership(ValueOwnershipKind::OWNERSHIP),            \
             SHOULD_CHECK_FOR_DATAFLOW_VIOLATIONS};                             \
   }
-CONSTANT_OWNERSHIP_INST(Guaranteed, false, TupleExtract)
-CONSTANT_OWNERSHIP_INST(Guaranteed, false, StructExtract)
-CONSTANT_OWNERSHIP_INST(Guaranteed, false, UncheckedEnumData)
+CONSTANT_OWNERSHIP_INST(Guaranteed, true, EndBorrowArgument)
 CONSTANT_OWNERSHIP_INST(Owned, true, AutoreleaseValue)
 CONSTANT_OWNERSHIP_INST(Owned, true, DeallocBox)
 CONSTANT_OWNERSHIP_INST(Owned, true, DeallocExistentialBox)
@@ -206,10 +267,9 @@
 CONSTANT_OWNERSHIP_INST(Owned, true, StrongRelease)
 CONSTANT_OWNERSHIP_INST(Owned, true, StrongUnpin)
 CONSTANT_OWNERSHIP_INST(Owned, true, SwitchEnum)
+CONSTANT_OWNERSHIP_INST(Owned, true, CheckedCastBranch)
 CONSTANT_OWNERSHIP_INST(Owned, true, UnownedRelease)
 CONSTANT_OWNERSHIP_INST(Owned, true, InitExistentialRef)
-CONSTANT_OWNERSHIP_INST(Guaranteed, true,
-                        OpenExistentialRef) // We may need a take here.
 CONSTANT_OWNERSHIP_INST(Trivial, false, AddressToPointer)
 CONSTANT_OWNERSHIP_INST(Trivial, false, BindMemory)
 CONSTANT_OWNERSHIP_INST(Trivial, false, CheckedCastAddrBranch)
@@ -278,6 +338,8 @@
 ACCEPTS_ANY_OWNERSHIP_INST(UncheckedBitwiseCast) // Is this right?
 ACCEPTS_ANY_OWNERSHIP_INST(WitnessMethod)        // Is this right?
 ACCEPTS_ANY_OWNERSHIP_INST(ProjectBox)           // The result is a T*.
+ACCEPTS_ANY_OWNERSHIP_INST(UnmanagedRetainValue)
+ACCEPTS_ANY_OWNERSHIP_INST(UnmanagedReleaseValue)
 #undef ACCEPTS_ANY_OWNERSHIP_INST
 
 // Trivial if trivial typed, otherwise must accept owned?
@@ -315,6 +377,8 @@
 OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitForwardingInst(SILInstruction *I) {
   assert(I->getNumOperands() && "Expected to have non-zero operands");
+  assert(isOwnershipForwardingInst(I) &&
+         "Expected to have an ownership forwarding inst");
   ArrayRef<Operand> Ops = I->getAllOperands();
   ValueOwnershipKind Base = getOwnershipKind();
   for (const Operand &Op : Ops) {
@@ -326,41 +390,105 @@
   return {true, !isAddressOrTrivialType()};
 }
 
-#define FORWARD_OWNERSHIP_INST(INST)                                           \
+#define FORWARD_ANY_OWNERSHIP_INST(INST)                                       \
   OwnershipUseCheckerResult                                                    \
       OwnershipCompatibilityUseChecker::visit##INST##Inst(INST##Inst *I) {     \
     return visitForwardingInst(I);                                             \
   }
+FORWARD_ANY_OWNERSHIP_INST(Tuple)
+FORWARD_ANY_OWNERSHIP_INST(Struct)
+FORWARD_ANY_OWNERSHIP_INST(Enum)
+FORWARD_ANY_OWNERSHIP_INST(OpenExistentialRef)
+FORWARD_ANY_OWNERSHIP_INST(Upcast)
+FORWARD_ANY_OWNERSHIP_INST(UncheckedRefCast)
+FORWARD_ANY_OWNERSHIP_INST(ConvertFunction)
+FORWARD_ANY_OWNERSHIP_INST(RefToBridgeObject)
+FORWARD_ANY_OWNERSHIP_INST(BridgeObjectToRef)
+FORWARD_ANY_OWNERSHIP_INST(UnconditionalCheckedCast)
+#undef FORWARD_ANY_OWNERSHIP_INST
 
-FORWARD_OWNERSHIP_INST(Tuple)
-FORWARD_OWNERSHIP_INST(Struct)
-FORWARD_OWNERSHIP_INST(Enum)
-// All of these should really have take falgs and be guaranteed otherwise.
-FORWARD_OWNERSHIP_INST(Upcast)
-FORWARD_OWNERSHIP_INST(UncheckedRefCast)
-FORWARD_OWNERSHIP_INST(ConvertFunction)
-FORWARD_OWNERSHIP_INST(RefToBridgeObject)
-FORWARD_OWNERSHIP_INST(BridgeObjectToRef)
-FORWARD_OWNERSHIP_INST(UnconditionalCheckedCast)
-// This should be based off of the argument.
-FORWARD_OWNERSHIP_INST(Branch)
-FORWARD_OWNERSHIP_INST(CondBranch)
-FORWARD_OWNERSHIP_INST(CheckedCastBranch)
-#undef FORWARD_OWNERSHIP_INST
+// An instruction that forwards a constant ownership or trivial ownership.
+#define FORWARD_CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(                            \
+    OWNERSHIP, SHOULD_CHECK_FOR_DATAFLOW_VIOLATIONS, INST)                     \
+  OwnershipUseCheckerResult                                                    \
+      OwnershipCompatibilityUseChecker::visit##INST##Inst(INST##Inst *I) {     \
+    assert(I->getNumOperands() && "Expected to have non-zero operands");       \
+    assert(isOwnershipForwardingInst(I) &&                                     \
+           "Expected an ownership forwarding inst");                           \
+    if (ValueOwnershipKind::OWNERSHIP != ValueOwnershipKind::Trivial &&        \
+        getOwnershipKind() == ValueOwnershipKind::Trivial) {                   \
+      assert(isAddressOrTrivialType() &&                                       \
+             "Trivial ownership requires a trivial type or an address");       \
+      return {true, false};                                                    \
+    }                                                                          \
+    if (ValueOwnershipKind::OWNERSHIP == ValueOwnershipKind::Trivial) {        \
+      assert(isAddressOrTrivialType() &&                                       \
+             "Trivial ownership requires a trivial type or an address");       \
+    }                                                                          \
+                                                                               \
+    return {compatibleWithOwnership(ValueOwnershipKind::OWNERSHIP),            \
+            SHOULD_CHECK_FOR_DATAFLOW_VIOLATIONS};                             \
+  }
+FORWARD_CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, false, TupleExtract)
+FORWARD_CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, false, StructExtract)
+FORWARD_CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, false, UncheckedEnumData)
+#undef CONSTANT_OR_TRIVIAL_OWNERSHIP_INST
+
+OwnershipUseCheckerResult
+OwnershipCompatibilityUseChecker::checkTerminatorArgumentMatchesDestBB(
+    SILBasicBlock *DestBB, unsigned OpIndex) {
+  // Make sure that the ValueOwnershipKind of the branch argument that we are
+  // verifying matches the ownership kind of the corresponding argument of the
+  // destination block.
+  ValueOwnershipKind DestBlockArgOwnershipKind =
+      DestBB->getArgument(OpIndex)->getOwnershipKind();
+  return {DestBlockArgOwnershipKind.merge(getOwnershipKind()).hasValue(),
+          getOwnershipKind() == ValueOwnershipKind::Owned};
+}
+
+OwnershipUseCheckerResult
+OwnershipCompatibilityUseChecker::visitBranchInst(BranchInst *BI) {
+  return checkTerminatorArgumentMatchesDestBB(BI->getDestBB(),
+                                              getOperandIndex());
+}
+
+OwnershipUseCheckerResult
+OwnershipCompatibilityUseChecker::visitCondBranchInst(CondBranchInst *CBI) {
+  // If our conditional branch is the condition, it is trivial. Check that the
+  // ownership kind is trivial.
+  if (CBI->isConditionOperandIndex(getOperandIndex()))
+    return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
+
+  // Otherwise, make sure that our operand matches the
+  if (CBI->isTrueOperandIndex(getOperandIndex())) {
+    unsigned TrueOffset = 1;
+    return checkTerminatorArgumentMatchesDestBB(CBI->getTrueBB(),
+                                                getOperandIndex() - TrueOffset);
+  }
+
+  assert(CBI->isFalseOperandIndex(getOperandIndex()) &&
+         "If an operand is not the condition index or a true operand index, it "
+         "must be a false operand index");
+  unsigned FalseOffset = 1 + CBI->getTrueOperands().size();
+  return checkTerminatorArgumentMatchesDestBB(CBI->getFalseBB(),
+                                              getOperandIndex() - FalseOffset);
+}
 
 OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitReturnInst(ReturnInst *RI) {
   SILModule &M = RI->getModule();
   bool IsTrivial = RI->getOperand()->getType().isTrivial(M);
-  auto Results =
-      RI->getFunction()->getLoweredFunctionType()->getDirectResults();
+  auto FnType = RI->getFunction()->getLoweredFunctionType();
+  auto Results = FnType->getDirectResults();
   if (Results.empty() || IsTrivial) {
     return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
   }
 
+  CanGenericSignature Sig = FnType->getGenericSignature();
+
   // Find the first index where we have a trivial value.
-  auto Iter = find_if(Results, [&M](const SILResultInfo &Info) -> bool {
-    return Info.getOwnershipKind(M) != ValueOwnershipKind::Trivial;
+  auto Iter = find_if(Results, [&M, &Sig](const SILResultInfo &Info) -> bool {
+    return Info.getOwnershipKind(M, Sig) != ValueOwnershipKind::Trivial;
   });
 
   // If we have all trivial, then we must be trivial. Why wasn't our original
@@ -370,10 +498,10 @@
     llvm_unreachable("Should have already checked a trivial type?!");
 
   unsigned Index = std::distance(Results.begin(), Iter);
-  ValueOwnershipKind Base = Results[Index].getOwnershipKind(M);
+  ValueOwnershipKind Base = Results[Index].getOwnershipKind(M, Sig);
 
   for (const SILResultInfo &ResultInfo : Results.slice(Index + 1)) {
-    auto RKind = ResultInfo.getOwnershipKind(M);
+    auto RKind = ResultInfo.getOwnershipKind(M, Sig);
     // Ignore trivial types.
     if (RKind.merge(ValueOwnershipKind::Trivial))
       continue;
@@ -393,9 +521,11 @@
 
 OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitEndBorrowInst(EndBorrowInst *I) {
-  // We do not consider the source to be a verified use for now.
-  if (getOperandIndex() == EndBorrowInst::Src)
+  // We do not consider the original value to be a verified use. But the value
+  // does need to be alive.
+  if (getOperandIndex() == EndBorrowInst::OriginalValue)
     return {true, false};
+  // The borrowed value is a verified use though of the begin_borrow.
   return {compatibleWithOwnership(ValueOwnershipKind::Guaranteed), true};
 }
 
@@ -519,15 +649,24 @@
 
 OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitAssignInst(AssignInst *I) {
-  if (getValue() == I->getSrc())
+  if (getValue() == I->getSrc()) {
+    if (isAddressOrTrivialType()) {
+      return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
+    }
     return {compatibleWithOwnership(ValueOwnershipKind::Owned), true};
+  }
+
   return {true, false};
 }
 
 OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitStoreInst(StoreInst *I) {
-  if (getValue() == I->getSrc())
+  if (getValue() == I->getSrc()) {
+    if (isAddressOrTrivialType()) {
+      return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
+    }
     return {compatibleWithOwnership(ValueOwnershipKind::Owned), true};
+  }
   return {true, false};
 }
 
@@ -609,6 +748,8 @@
   /// were found to properly be post-dominated by a lifetime ending use.
   bool doesBlockContainUseAfterFree(SILInstruction *LifetimeEndingUser,
                                     SILBasicBlock *UserBlock);
+
+  bool checkValueWithoutLifetimeEndingUses();
 };
 
 } // end anonymous namespace
@@ -626,12 +767,12 @@
                    [&NonLifetimeEndingUser](const SILInstruction &I) -> bool {
                      return NonLifetimeEndingUser == &I;
                    }) != UserBlock->end()) {
-    llvm::errs() << "Found use after free?!\n"
-                 << "Function: '" << Value->getFunction()->getName() << "'\n"
+    llvm::errs() << "Function: '" << Value->getFunction()->getName() << "'\n"
+                 << "Found use after free?!\n"
                  << "Value: " << *Value
                  << "Consuming User: " << *LifetimeEndingUser
-                 << "Non Consuming User: " << *Iter->second << "Block:\n"
-                 << *UserBlock << "\n";
+                 << "Non Consuming User: " << *Iter->second << "Block: bb"
+                 << UserBlock->getDebugID() << "\n\n";
     return true;
   }
 
@@ -652,7 +793,7 @@
                << "Value: " << *Value;
   if (LifetimeEndingUser)
     llvm::errs() << "User: " << *LifetimeEndingUser;
-  llvm::errs() << "Block:\n" << *UserBlock << "\n";
+  llvm::errs() << "Block: bb" << UserBlock->getDebugID() << "\n\n";
 
   return true;
 }
@@ -660,15 +801,55 @@
 void SILValueOwnershipChecker::gatherUsers(
     llvm::SmallVectorImpl<SILInstruction *> &LifetimeEndingUsers,
     llvm::SmallVectorImpl<SILInstruction *> &NonLifetimeEndingUsers) {
-  for (Operand *Op : Value->getUses()) {
+
+  // See if Value is guaranteed. If we are guaranteed and not forwarding, then
+  // we need to look through subobject uses for more uses. Otherwise, if we are
+  // forwarding, we do not create any lifetime ending users/non lifetime ending
+  // users since we verify against our base.
+  bool IsGuaranteed =
+      Value.getOwnershipKind() == ValueOwnershipKind::Guaranteed;
+
+  if (IsGuaranteed && isOwnershipForwardingValue(Value))
+    return;
+
+  // Then gather up our initial list of users.
+  llvm::SmallVector<Operand *, 8> Users;
+  std::copy(Value->use_begin(), Value->use_end(), std::back_inserter(Users));
+
+  while (!Users.empty()) {
+    Operand *Op = Users.pop_back_val();
+
     auto *User = Op->getUser();
-    if (OwnershipCompatibilityUseChecker(Mod, *Op).check(User)) {
+    if (OwnershipCompatibilityUseChecker(Mod, *Op, Value).check(User)) {
       DEBUG(llvm::dbgs() << "        Lifetime Ending User: " << *User);
       LifetimeEndingUsers.push_back(User);
     } else {
       DEBUG(llvm::dbgs() << "        Regular User: " << *User);
       NonLifetimeEndingUsers.push_back(User);
     }
+
+    // If our base value is not guaranteed or our intermediate value is not an
+    // ownership forwarding inst, continue. We do not want to visit any
+    // subobjects recursively.
+    if (!IsGuaranteed || !isOwnershipForwardingInst(User)) {
+      continue;
+    }
+
+    // At this point, we know that we must have a forwarded subobject. Since the
+    // base type is guaranteed, we know that the subobject is either guaranteed
+    // or trivial. The trivial case is not interesting for ARC verification, so
+    // if the user has a trivial ownership kind, continue.
+    if (SILValue(User).getOwnershipKind() == ValueOwnershipKind::Trivial) {
+      continue;
+    }
+
+    // Now, we /must/ have a guaranteed subobject, so lets assert that the user
+    // is actually guaranteed and add the subobject's users to our worklist.
+    assert(SILValue(User).getOwnershipKind() ==
+               ValueOwnershipKind::Guaranteed &&
+           "Our value is guaranteed and this is a forwarding instruction. "
+           "Should have guaranteed ownership as well.");
+    std::copy(User->use_begin(), User->use_end(), std::back_inserter(Users));
   }
 }
 
@@ -706,6 +887,95 @@
   }
 }
 
+static bool checkFunctionArgWithoutLifetimeEndingUses(SILFunctionArgument *Arg,
+                                                      SILModule &Mod) {
+  switch (Arg->getOwnershipKind()) {
+  case ValueOwnershipKind::Guaranteed:
+  case ValueOwnershipKind::Unowned:
+  case ValueOwnershipKind::Trivial:
+    return true;
+  case ValueOwnershipKind::Any:
+    llvm_unreachable(
+        "Function arguments should never have ValueOwnershipKind::Any");
+  case ValueOwnershipKind::Owned:
+    break;
+  }
+
+  llvm::errs() << "Function: '" << Arg->getFunction()->getName() << "'\n"
+               << "    Owned function parameter without life "
+                  "ending uses!\n"
+               << "Value: " << *Arg << '\n';
+  if (IsSILOwnershipVerifierTestingEnabled)
+    return true;
+  llvm_unreachable("triggering standard assertion failure routine");
+}
+
+bool SILValueOwnershipChecker::checkValueWithoutLifetimeEndingUses() {
+  DEBUG(llvm::dbgs() << "    No lifetime ending users?! Bailing early.\n");
+  if (auto *Arg = dyn_cast<SILFunctionArgument>(Value)) {
+    if (checkFunctionArgWithoutLifetimeEndingUses(Arg, Mod)) {
+      return true;
+    }
+  }
+
+  // Check if we are a guaranteed subobject. In such a case, we should never
+  // have lifetime ending uses, since our lifetime is guaranteed by our
+  // operand, so there is nothing further to do. So just return true.
+  if (isOwnershipForwardingValue(Value) &&
+      Value.getOwnershipKind() == ValueOwnershipKind::Guaranteed)
+    return true;
+
+  // If we have an unowned value, then again there is nothing left to do.
+  if (Value.getOwnershipKind() == ValueOwnershipKind::Unowned)
+    return true;
+
+  if (!isValueAddressOrTrivial(Value, Mod)) {
+    llvm::errs() << "Function: '" << Value->getFunction()->getName() << "'\n"
+                 << "Non trivial values, non address values, and non "
+                    "guaranteed function args must have at least one "
+                    "lifetime ending use?!\n"
+                 << "Value: " << *Value << '\n';
+    if (IsSILOwnershipVerifierTestingEnabled)
+      return true;
+    llvm_unreachable("triggering standard assertion failure routine");
+  }
+
+  return true;
+}
+
+static bool isGuaranteedFunctionArgWithLifetimeEndingUses(
+    SILFunctionArgument *Arg,
+    const llvm::SmallVectorImpl<SILInstruction *> &LifetimeEndingUsers) {
+  if (Arg->getOwnershipKind() != ValueOwnershipKind::Guaranteed)
+    return true;
+
+  llvm::errs() << "    Function: '" << Arg->getFunction()->getName() << "'\n"
+               << "    Guaranteed function parameter with life ending uses!\n"
+               << "    Value: " << *Arg;
+  for (auto *U : LifetimeEndingUsers) {
+    llvm::errs() << "    Lifetime Ending User: " << *U;
+  }
+  llvm::errs() << '\n';
+  if (IsSILOwnershipVerifierTestingEnabled)
+    return false;
+  llvm_unreachable("triggering standard assertion failure routine");
+}
+
+static bool isSubobjectProjectionWithLifetimeEndingUses(
+    SILValue Value,
+    const llvm::SmallVectorImpl<SILInstruction *> &LifetimeEndingUsers) {
+  llvm::errs() << "    Function: '" << Value->getFunction()->getName() << "'\n"
+               << "    Subobject projection with life ending uses!\n"
+               << "    Value: " << *Value;
+  for (auto *U : LifetimeEndingUsers) {
+    llvm::errs() << "    Lifetime Ending User: " << *U;
+  }
+  llvm::errs() << '\n';
+  if (IsSILOwnershipVerifierTestingEnabled)
+    return false;
+  llvm_unreachable("triggering standard assertion failure routine");
+}
+
 bool SILValueOwnershipChecker::checkUses() {
   DEBUG(llvm::dbgs() << "    Gathering and classifying uses!\n");
 
@@ -718,18 +988,46 @@
   llvm::SmallVector<SILInstruction *, 16> NonLifetimeEndingUsers;
   gatherUsers(LifetimeEndingUsers, NonLifetimeEndingUsers);
 
-  // If we do not have any lifetime ending users, there is nothing to
-  // check. This occurs with trivial types and addresses. Return false.
-  if (LifetimeEndingUsers.empty()) {
-    DEBUG(llvm::dbgs() << "    No lifetime ending users?! Bailing early.\n");
-    assert(isValueAddressOrTrivial(Value, Mod) &&
-           "Must always check the lifetime for non-trivial, non-address types");
+  // We can only have no lifetime ending uses if we have:
+  //
+  // 1. A trivial typed value.
+  // 2. An address type value.
+  // 3. A guaranteed function argument.
+  //
+  // In the first two cases, it is easy to see that there is nothing further to
+  // do but return false.
+  //
+  // In the case of a function argument, one must think about the issues a bit
+  // more. Specifically, we should have /no/ lifetime ending uses of a
+  // guaranteed function argument, since a guaranteed function argument should
+  // outlive the current function always.
+  if (LifetimeEndingUsers.empty() && checkValueWithoutLifetimeEndingUses()) {
     return false;
   }
 
   DEBUG(llvm::dbgs() << "    Found lifetime ending users! Performing initial "
                         "checks\n");
 
+  // See if we have a guaranteed function address. Guaranteed function addresses
+  // should never have any lifetime ending uses.
+  if (auto *Arg = dyn_cast<SILFunctionArgument>(Value)) {
+    if (!isGuaranteedFunctionArgWithLifetimeEndingUses(Arg,
+                                                       LifetimeEndingUsers)) {
+      return false;
+    }
+  }
+
+  // Check if we are an instruction that forwards ownership that forwards
+  // guaranteed ownership. In such a case, we are a subobject projection. We
+  // should not have any lifetime ending uses.
+  if (isOwnershipForwardingValue(Value) &&
+      Value.getOwnershipKind() == ValueOwnershipKind::Guaranteed) {
+    if (!isSubobjectProjectionWithLifetimeEndingUses(Value,
+                                                     LifetimeEndingUsers)) {
+      return false;
+    }
+  }
+
   // Then add our non lifetime ending users and their blocks to the
   // BlocksWithNonLifetimeEndingUses map. While we do this, if we have multiple
   // uses in the same block, we only accept the last use since from a liveness
@@ -754,14 +1052,14 @@
     // If the block does over consume, we either assert or return false. We only
     // return false when debugging.
     if (doesBlockDoubleConsume(UserBlock, User, true)) {
-      if (PrintMessageInsteadOfAssert)
+      if (IsSILOwnershipVerifierTestingEnabled)
         return false;
       llvm_unreachable("triggering standard assertion failure routine");
     }
 
     // Then check if the given block has a use after free.
     if (doesBlockContainUseAfterFree(User, UserBlock)) {
-      if (PrintMessageInsteadOfAssert)
+      if (IsSILOwnershipVerifierTestingEnabled)
         return false;
       llvm_unreachable("triggering standard assertion failure routine");
     }
@@ -791,7 +1089,7 @@
     // Make sure that the predecessor is not in our
     // BlocksWithLifetimeEndingUses list.
     if (doesBlockDoubleConsume(PredBlock, User)) {
-      if (PrintMessageInsteadOfAssert)
+      if (IsSILOwnershipVerifierTestingEnabled)
         return false;
       llvm_unreachable("triggering standard assertion failure routine");
     }
@@ -810,7 +1108,7 @@
   while (!Worklist.empty()) {
     // Grab the next block to visit.
     SILBasicBlock *BB = Worklist.pop_back_val();
-    DEBUG(llvm::dbgs() << "    Visiting Block:\n" << *BB);
+    DEBUG(llvm::dbgs() << "    Visiting Block: bb" << BB->getDebugID() << '\n');
 
     // Since the block is on our worklist, we know already that it is not a
     // block with lifetime ending uses, due to the invariants of our loop.
@@ -849,7 +1147,7 @@
     // 2. We add the predecessor to the worklist if we have not visited it yet.
     for (auto *PredBlock : BB->getPredecessorBlocks()) {
       if (doesBlockDoubleConsume(PredBlock)) {
-        if (PrintMessageInsteadOfAssert)
+        if (IsSILOwnershipVerifierTestingEnabled)
           return;
         llvm_unreachable("triggering standard assertion failure routine");
       }
@@ -857,6 +1155,7 @@
       if (VisitedBlocks.count(PredBlock)) {
         continue;
       }
+      VisitedBlocks.insert(PredBlock);
       Worklist.push_back(PredBlock);
     }
   }
@@ -865,13 +1164,14 @@
   // make sure we didn't leak.
   if (!SuccessorBlocksThatMustBeVisited.empty()) {
     llvm::errs()
-        << "Error! Found a leak due to a consuming post-dominance failure!\n"
         << "Function: '" << Value->getFunction()->getName() << "'\n"
+        << "Error! Found a leak due to a consuming post-dominance failure!\n"
         << "    Value: " << *Value << "    Post Dominating Failure Blocks:\n";
     for (auto *BB : SuccessorBlocksThatMustBeVisited) {
-      llvm::errs() << *BB;
+      llvm::errs() << "bb" << BB->getDebugID();
     }
-    if (PrintMessageInsteadOfAssert)
+    llvm::errs() << '\n';
+    if (IsSILOwnershipVerifierTestingEnabled)
       return;
     llvm_unreachable("triggering standard assertion failure routine");
   }
@@ -881,14 +1181,15 @@
   // blocks implying a use-after free.
   if (!BlocksWithNonLifetimeEndingUses.empty()) {
     llvm::errs()
-        << "Found use after free due to unvisited non lifetime ending uses?!\n"
         << "Function: '" << Value->getFunction()->getName() << "'\n"
+        << "Found use after free due to unvisited non lifetime ending uses?!\n"
         << "Value: " << *Value << "    Remaining Users:\n";
     for (auto &Pair : BlocksWithNonLifetimeEndingUses) {
-      llvm::errs() << "User:" << *Pair.second << "Block:\n"
-                   << *Pair.first << "\n";
+      llvm::errs() << "User:" << *Pair.second << "Block: bb"
+                   << Pair.first->getDebugID() << "\n";
     }
-    if (PrintMessageInsteadOfAssert)
+    llvm::errs() << "\n";
+    if (IsSILOwnershipVerifierTestingEnabled)
       return;
     llvm_unreachable("triggering standard assertion failure routine");
   }
@@ -905,9 +1206,20 @@
   // If SILOwnership is not enabled, do not perform verification.
   if (!getModule().getOptions().EnableSILOwnership)
     return;
+  // If we are testing the verifier, bail so we only print errors once when
+  // performing a full verification, instead of additionally in the SILBuilder.
+  if (IsSILOwnershipVerifierTestingEnabled)
+    return;
+
+  // If this is a terminator instruction, do not verify in SILBuilder. This is
+  // because when building a new function, one must create the destination block
+  // first which is an unnatural pattern and pretty brittle.
+  if (isa<TermInst>(this))
+    return;
+
   auto *Self = const_cast<SILInstruction *>(this);
   for (const Operand &Op : getAllOperands()) {
-    OwnershipCompatibilityUseChecker(getModule(), Op).check(Self);
+    OwnershipCompatibilityUseChecker(getModule(), Op, Op.get()).check(Self);
   }
 #endif
 }
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index d2f2cde..63d0736 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -33,6 +33,7 @@
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/PrintOptions.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/STLExtras.h"
 #include "llvm/ADT/APFloat.h"
@@ -139,9 +140,17 @@
 }
 
 /// IDAndType - Used when a client wants to print something like "%0 : $Int".
-struct IDAndType {
-  ID id;
-  SILType Ty;
+struct SILValuePrinterInfo {
+  ID ValueID;
+  SILType Type;
+  Optional<ValueOwnershipKind> OwnershipKind;
+
+  SILValuePrinterInfo(ID ValueID) : ValueID(ValueID), Type(), OwnershipKind() {}
+  SILValuePrinterInfo(ID ValueID, SILType Type)
+      : ValueID(ValueID), Type(Type), OwnershipKind() {}
+  SILValuePrinterInfo(ID ValueID, SILType Type,
+                      ValueOwnershipKind OwnershipKind)
+      : ValueID(ValueID), Type(Type), OwnershipKind(OwnershipKind) {}
 };
 
 /// Return the fully qualified dotted path for DeclContext.
@@ -410,13 +419,21 @@
   SIMPLE_PRINTER(QuotedString)
   SIMPLE_PRINTER(SILDeclRef)
   SIMPLE_PRINTER(APInt)
+  SIMPLE_PRINTER(ValueOwnershipKind)
 #undef SIMPLE_PRINTER
-  
-  SILPrinter &operator<<(IDAndType i) {
+
+  SILPrinter &operator<<(SILValuePrinterInfo i) {
     SILColor C(PrintState.OS, SC_Type);
-    return *this << i.id << " : " << i.Ty;
+    *this << i.ValueID;
+    if (!i.Type)
+      return *this;
+    *this << " : ";
+    if (i.OwnershipKind) {
+      *this << "@" << i.OwnershipKind.getValue() << " ";
+    }
+    return *this << i.Type;
   }
-  
+
   SILPrinter &operator<<(Type t) {
     // Print the type using our print options.
     t.print(PrintState.OS, PrintState.ASTOptions);
@@ -442,9 +459,12 @@
 
   ID getID(const SILBasicBlock *B);
   ID getID(SILValue V);
-  IDAndType getIDAndType(SILValue V) {
+  SILValuePrinterInfo getIDAndType(SILValue V) {
     return { getID(V), V->getType() };
   }
+  SILValuePrinterInfo getIDAndTypeAndOwnership(SILValue V) {
+    return {getID(V), V->getType(), V.getOwnershipKind()};
+  }
 
   //===--------------------------------------------------------------------===//
   // Big entrypoints.
@@ -470,52 +490,70 @@
                [&] { *this << '\n'; });
   }
 
-  void print(const SILBasicBlock *BB) {
-    // Output uses for BB arguments.
-    if (!BB->args_empty()) {
-      for (auto I = BB->args_begin(), E = BB->args_end(); I != E; ++I) {
-        SILValue V = *I;
-        if (V->use_empty())
-          continue;
-        *this << "// " << getID(V);
-        PrintState.OS.PadToColumn(50);
-        *this << "// user";
-        if (std::next(V->use_begin()) != V->use_end())
-          *this << 's';
-        *this << ": ";
+  void printBlockArgumentUses(const SILBasicBlock *BB) {
+    if (BB->args_empty())
+      return;
 
-        llvm::SmallVector<ID, 32> UserIDs;
-        for (auto *Op : V->getUses())
-          UserIDs.push_back(getID(Op->getUser()));
+    for (SILValue V : BB->getArguments()) {
+      if (V->use_empty())
+        continue;
+      *this << "// " << getID(V);
+      PrintState.OS.PadToColumn(50);
+      *this << "// user";
+      if (std::next(V->use_begin()) != V->use_end())
+        *this << 's';
+      *this << ": ";
 
-        // Display the user ids sorted to give a stable use order in the
-        // printer's output if we are asked to do so. This makes diffing large
-        // sections of SIL significantly easier at the expense of not showing
-        // the _TRUE_ order of the users in the use list.
-        if (Ctx.sortSIL()) {
-          std::sort(UserIDs.begin(), UserIDs.end());
-        }
+      llvm::SmallVector<ID, 32> UserIDs;
+      for (auto *Op : V->getUses())
+        UserIDs.push_back(getID(Op->getUser()));
 
-        interleave(UserIDs.begin(), UserIDs.end(),
-            [&] (ID id) { *this << id; },
-            [&] { *this << ", "; });
-        *this << '\n';
+      // Display the user ids sorted to give a stable use order in the
+      // printer's output if we are asked to do so. This makes diffing large
+      // sections of SIL significantly easier at the expense of not showing
+      // the _TRUE_ order of the users in the use list.
+      if (Ctx.sortSIL()) {
+        std::sort(UserIDs.begin(), UserIDs.end());
       }
+
+      interleave(UserIDs.begin(), UserIDs.end(),
+                 [&] (ID id) { *this << id; },
+                 [&] { *this << ", "; });
+      *this << '\n';
     }
+  }
 
-    *this << getID(BB);
+  void printBlockArguments(const SILBasicBlock *BB) {
+    if (BB->args_empty())
+      return;
+    *this << '(';
+    ArrayRef<SILArgument *> Args = BB->getArguments();
 
-    if (!BB->args_empty()) {
-      *this << '(';
-      for (auto I = BB->args_begin(), E = BB->args_end(); I != E; ++I) {
-        if (I != BB->args_begin())
-          *this << ", ";
-        *this << getIDAndType(*I);
+    // If SIL ownership is enabled, print out ownership of SILArguments.
+    if (BB->getModule().getOptions().EnableSILOwnership) {
+      *this << getIDAndTypeAndOwnership(Args[0]);
+      for (SILArgument *Arg : Args.drop_front()) {
+        *this << ", " << getIDAndTypeAndOwnership(Arg);
       }
       *this << ')';
+      return;
     }
 
-    *this << ":";
+    // Otherwise, fall back to the old behavior
+    *this << getIDAndType(Args[0]);
+    for (SILArgument *Arg : Args.drop_front()) {
+      *this << ", " << getIDAndType(Arg);
+    }
+    *this << ')';
+  }
+
+  void print(const SILBasicBlock *BB) {
+    // Output uses for BB arguments. These are put into place as comments before
+    // the block header.
+    printBlockArgumentUses(BB);
+
+    // Then print the name of our block, the arguments, and the block colon.
+    *this << getID(BB); printBlockArguments(BB); *this << ":";
 
     if (!BB->pred_empty()) {
       PrintState.OS.PadToColumn(50);
@@ -606,7 +644,7 @@
   void printDebugLocRef(SILLocation Loc, const SourceManager &SM,
                         bool PrintComma = true) {
     auto DL = Loc.decodeDebugLoc(SM);
-    if (DL.Filename) {
+    if (!DL.Filename.empty()) {
       if (PrintComma)
         *this << ", ";
       *this << "loc " << QuotedString(DL.Filename) << ':' << DL.Line << ':'
@@ -1069,8 +1107,14 @@
   }
 
   void visitEndBorrowInst(EndBorrowInst *EBI) {
-    *this << getID(EBI->getDest()) << " from " << getID(EBI->getSrc()) << " : "
-          << EBI->getDest()->getType() << ", " << EBI->getSrc()->getType();
+    *this << getID(EBI->getBorrowedValue()) << " from "
+          << getID(EBI->getOriginalValue()) << " : "
+          << EBI->getBorrowedValue()->getType() << ", "
+          << EBI->getOriginalValue()->getType();
+  }
+
+  void visitEndBorrowArgumentInst(EndBorrowArgumentInst *EBAI) {
+    *this << getIDAndType(EBAI->getOperand());
   }
 
   void visitAssignInst(AssignInst *AI) {
@@ -2332,7 +2376,38 @@
 
 void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
   SILPrintContext Ctx(OS);
-  SILPrinter(Ctx).printSubstitutions(getSubstitutions());
+  // Print other types as their Swift representation.
+  PrintOptions SubPrinter = PrintOptions::printSIL();
+  auto exported = isExported() ? "true" : "false";
+  auto kind = isPartialSpecialization() ? "partial" : "full";
+
+  OS << "exported: " << exported << ", ";
+  OS << "kind: " << kind << ", ";
+
+  if (!getRequirements().empty()) {
+    OS << "where ";
+    SILFunction *F = getFunction();
+    assert(F);
+    auto GenericEnv = F->getGenericEnvironment();
+    assert(GenericEnv);
+    interleave(getRequirements(),
+               [&](Requirement req) {
+                 // Use GenericEnvironment to produce user-friendly
+                 // names instead of something like t_0_0.
+                 auto FirstTy = GenericEnv->getSugaredType(req.getFirstType());
+                 if (req.getKind() != RequirementKind::Layout) {
+                   auto SecondTy =
+                       GenericEnv->getSugaredType(req.getSecondType());
+                   Requirement ReqWithDecls(req.getKind(), FirstTy, SecondTy);
+                   ReqWithDecls.print(OS, SubPrinter);
+                 } else {
+                   Requirement ReqWithDecls(req.getKind(), FirstTy,
+                                            req.getLayoutConstraint());
+                   ReqWithDecls.print(OS, SubPrinter);
+                 }
+               },
+               [&] { OS << ", "; });
+  }
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/SIL/SILType.cpp b/lib/SIL/SILType.cpp
index a8d48ef..181f721 100644
--- a/lib/SIL/SILType.cpp
+++ b/lib/SIL/SILType.cpp
@@ -586,9 +586,14 @@
   return fieldTy;
 }
 
-ValueOwnershipKind SILResultInfo::getOwnershipKind(SILModule &M) const {
-  SILType Ty = M.Types.getLoweredType(getType());
-  bool IsTrivial = Ty.isTrivial(M);
+ValueOwnershipKind
+SILResultInfo::getOwnershipKind(SILModule &M,
+                                CanGenericSignature signature) const {
+  if (signature)
+    M.Types.pushGenericContext(signature);
+  bool IsTrivial = getSILType().isTrivial(M);
+  if (signature)
+    M.Types.popGenericContext(signature);
   switch (getConvention()) {
   case ResultConvention::Indirect:
     return ValueOwnershipKind::Trivial; // Should this be an Any?
diff --git a/lib/SIL/SILValue.cpp b/lib/SIL/SILValue.cpp
index 48fe2df..4ac97b7 100644
--- a/lib/SIL/SILValue.cpp
+++ b/lib/SIL/SILValue.cpp
@@ -104,15 +104,15 @@
                                      ValueOwnershipKind Kind) {
   switch (Kind) {
   case ValueOwnershipKind::Trivial:
-    return os << "Trivial";
+    return os << "trivial";
   case ValueOwnershipKind::Unowned:
-    return os << "Unowned";
+    return os << "unowned";
   case ValueOwnershipKind::Owned:
-    return os << "Owned";
+    return os << "owned";
   case ValueOwnershipKind::Guaranteed:
-    return os << "Guaranteed";
+    return os << "guaranteed";
   case ValueOwnershipKind::Any:
-    return os << "Any";
+    return os << "any";
   }
 
   llvm_unreachable("Unhandled ValueOwnershipKind in switch.");
@@ -254,6 +254,7 @@
 CONSTANT_OWNERSHIP_INST(Trivial, UnconditionalCheckedCastAddr)
 CONSTANT_OWNERSHIP_INST(Trivial, ValueMetatype)
 CONSTANT_OWNERSHIP_INST(Trivial, WitnessMethod)
+CONSTANT_OWNERSHIP_INST(Trivial, StoreBorrow)
 // TODO: It would be great to get rid of these.
 CONSTANT_OWNERSHIP_INST(Unowned, RawPointerToRef)
 CONSTANT_OWNERSHIP_INST(Unowned, RefToUnowned)
@@ -262,11 +263,12 @@
 #undef CONSTANT_OWNERSHIP_INST
 
 #define CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(OWNERSHIP, INST)                    \
-  ValueOwnershipKind ValueOwnershipKindVisitor::visit##INST##Inst(INST##Inst *I) { \
-    if (I->getType().isTrivial(I->getModule())) {                       \
-      return ValueOwnershipKind::Trivial;                               \
-    }                                                                   \
-    return ValueOwnershipKind::OWNERSHIP;                               \
+  ValueOwnershipKind ValueOwnershipKindVisitor::visit##INST##Inst(             \
+      INST##Inst *I) {                                                         \
+    if (I->getType().isTrivial(I->getModule())) {                              \
+      return ValueOwnershipKind::Trivial;                                      \
+    }                                                                          \
+    return ValueOwnershipKind::OWNERSHIP;                                      \
   }
 CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, StructExtract)
 CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, TupleExtract)
@@ -291,10 +293,10 @@
 NO_RESULT_OWNERSHIP_INST(DeallocBox)
 NO_RESULT_OWNERSHIP_INST(DeallocExistentialBox)
 NO_RESULT_OWNERSHIP_INST(EndBorrow)
+NO_RESULT_OWNERSHIP_INST(EndBorrowArgument)
 NO_RESULT_OWNERSHIP_INST(Store)
 NO_RESULT_OWNERSHIP_INST(StoreWeak)
 NO_RESULT_OWNERSHIP_INST(StoreUnowned)
-NO_RESULT_OWNERSHIP_INST(StoreBorrow)
 NO_RESULT_OWNERSHIP_INST(Assign)
 NO_RESULT_OWNERSHIP_INST(DebugValue)
 NO_RESULT_OWNERSHIP_INST(DebugValueAddr)
@@ -304,6 +306,8 @@
 NO_RESULT_OWNERSHIP_INST(StrongRelease)
 NO_RESULT_OWNERSHIP_INST(StrongRetainUnowned)
 NO_RESULT_OWNERSHIP_INST(StrongUnpin)
+NO_RESULT_OWNERSHIP_INST(UnmanagedRetainValue)
+NO_RESULT_OWNERSHIP_INST(UnmanagedReleaseValue)
 NO_RESULT_OWNERSHIP_INST(UnownedRetain)
 NO_RESULT_OWNERSHIP_INST(UnownedRelease)
 NO_RESULT_OWNERSHIP_INST(RetainValue)
@@ -409,7 +413,7 @@
     // If we do have a trivial value ownership kind, see if our result type is
     // trivial or non-trivial. If it is trivial, then we have trivial
     // ownership. Otherwise, we have unowned ownership since from an ownership
-    // perspective, the value has instantaneously come into existance and
+    // perspective, the value has instantaneously come into existence and
     // nothing has taken ownership of it.
     if (ResultTypeIsTrivial) {
       return ValueOwnershipKind::Trivial;
@@ -448,30 +452,7 @@
 
 ValueOwnershipKind
 ValueOwnershipKindVisitor::visitSILFunctionArgument(SILFunctionArgument *Arg) {
-  // Discover our ownership kind from our function signature.
-  switch (Arg->getArgumentConvention()) {
-  // These involve addresses and from an ownership perspective, addresses are
-  // trivial. This is distinct from the ownership properties of the values that
-  // they may contain.
-  case SILArgumentConvention::Indirect_In:
-  case SILArgumentConvention::Indirect_In_Guaranteed:
-  case SILArgumentConvention::Indirect_Inout:
-  case SILArgumentConvention::Indirect_InoutAliasable:
-  case SILArgumentConvention::Indirect_Out:
-    return ValueOwnershipKind::Trivial;
-  case SILArgumentConvention::Direct_Owned:
-    return ValueOwnershipKind::Owned;
-  case SILArgumentConvention::Direct_Unowned:
-    if (Arg->getType().isTrivial(Arg->getModule()))
-      return ValueOwnershipKind::Trivial;
-    return ValueOwnershipKind::Unowned;
-  case SILArgumentConvention::Direct_Guaranteed:
-    return ValueOwnershipKind::Guaranteed;
-  case SILArgumentConvention::Direct_Deallocating:
-    llvm_unreachable("No ownership associated with deallocating");
-  }
-
-  llvm_unreachable("Unhandled SILArgumentConvention in switch.");
+  return Arg->getOwnershipKind();
 }
 
 // This is a forwarding instruction through only one of its arguments.
@@ -489,19 +470,20 @@
   if (Results.empty() || IsTrivial)
     return ValueOwnershipKind::Trivial;
 
+  CanGenericSignature Sig = AI->getSubstCalleeType()->getGenericSignature();
   // Find the first index where we have a trivial value.
-  auto Iter = find_if(Results, [&M](const SILResultInfo &Info) -> bool {
-    return Info.getOwnershipKind(M) != ValueOwnershipKind::Trivial;
+  auto Iter = find_if(Results, [&M, &Sig](const SILResultInfo &Info) -> bool {
+    return Info.getOwnershipKind(M, Sig) != ValueOwnershipKind::Trivial;
   });
   // If we have all trivial, then we must be trivial.
   if (Iter == Results.end())
     return ValueOwnershipKind::Trivial;
 
   unsigned Index = std::distance(Results.begin(), Iter);
-  ValueOwnershipKind Base = Results[Index].getOwnershipKind(M);
+  ValueOwnershipKind Base = Results[Index].getOwnershipKind(M, Sig);
 
   for (const SILResultInfo &ResultInfo : Results.slice(Index+1)) {
-    auto RKind = ResultInfo.getOwnershipKind(M);
+    auto RKind = ResultInfo.getOwnershipKind(M, Sig);
     if (RKind.merge(ValueOwnershipKind::Trivial))
       continue;
 
@@ -680,6 +662,10 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, USCheckedConversion)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, IntToFPWithOverflow)
 
+// This is surprising, Builtin.unreachable returns a "Never" value which is
+// trivially typed.
+CONSTANT_OWNERSHIP_BUILTIN(Trivial, Unreachable)
+
 /// AtomicRMW has type (Builtin.RawPointer, T) -> T. But it provides overloads
 /// for integer or rawpointer, so it should be trivial.
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, AtomicRMW)
@@ -698,7 +684,6 @@
     llvm_unreachable("Should never get a SILValue to a Builtin "               \
                      "without result");                                        \
   }
-NO_OWNERSHIP_BUILTIN(Unreachable)
 NO_OWNERSHIP_BUILTIN(DestroyArray)
 NO_OWNERSHIP_BUILTIN(CopyArray)
 NO_OWNERSHIP_BUILTIN(TakeArrayFrontToBack)
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 0b6e718..3f6243f 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -24,6 +24,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Types.h"
 #include "swift/SIL/PrettyStackTrace.h"
 #include "swift/SIL/TypeLowering.h"
@@ -1184,8 +1185,8 @@
     // We allow for end_borrow to express relationships in between addresses and
     // values, but we require that the types are the same ignoring value
     // category.
-    require(EBI->getDest()->getType().getObjectType() ==
-                EBI->getSrc()->getType().getObjectType(),
+    require(EBI->getBorrowedValue()->getType().getObjectType() ==
+                EBI->getOriginalValue()->getType().getObjectType(),
             "end_borrow can only relate the same types ignoring value "
             "category");
   }
diff --git a/lib/SIL/SILWitnessTable.cpp b/lib/SIL/SILWitnessTable.cpp
index 388a2d0..ed0a3f4 100644
--- a/lib/SIL/SILWitnessTable.cpp
+++ b/lib/SIL/SILWitnessTable.cpp
@@ -22,6 +22,7 @@
 #include "swift/SIL/SILWitnessTable.h"
 #include "swift/AST/Mangle.h"
 #include "swift/AST/ASTMangler.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/SILModule.h"
 #include "llvm/ADT/SmallString.h"
 
diff --git a/lib/SILGen/CMakeLists.txt b/lib/SILGen/CMakeLists.txt
index a0090f1..8251684 100644
--- a/lib/SILGen/CMakeLists.txt
+++ b/lib/SILGen/CMakeLists.txt
@@ -7,6 +7,7 @@
   SILGen.cpp
   SILGenApply.cpp
   SILGenBridging.cpp
+  SILGenBuilder.cpp
   SILGenBuiltin.cpp
   SILGenConstructor.cpp
   SILGenConvert.cpp
diff --git a/lib/SILGen/ManagedValue.h b/lib/SILGen/ManagedValue.h
index 1f5cb86..60ac453 100644
--- a/lib/SILGen/ManagedValue.h
+++ b/lib/SILGen/ManagedValue.h
@@ -116,33 +116,30 @@
 
   /// Create a managed value for a +0 borrowed non-trivial rvalue object.
   static ManagedValue
-  forBorrowedObjectRValue(SILValue value,
-                          CleanupHandle cleanup = CleanupHandle::invalid()) {
+  forBorrowedObjectRValue(SILValue value) {
     assert(value && "No value specified");
     assert(value->getType().isObject() &&
            "Expected borrowed rvalues to be objects");
     assert(value.getOwnershipKind() != ValueOwnershipKind::Trivial);
-    return ManagedValue(value, false, cleanup);
+    return ManagedValue(value, false, CleanupHandle::invalid());
   }
 
   /// Create a managed value for a +0 borrowed non-trivial rvalue address.
   static ManagedValue
-  forBorrowedAddressRValue(SILValue value,
-                           CleanupHandle cleanup = CleanupHandle::invalid()) {
+  forBorrowedAddressRValue(SILValue value) {
     assert(value && "No value specified");
     assert(value->getType().isAddress() && "Expected value to be an address");
     assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial &&
            "Addresses always have trivial ownership");
-    return ManagedValue(value, false, cleanup);
+    return ManagedValue(value, false, CleanupHandle::invalid());
   }
 
   /// Create a managed value for a +0 guaranteed rvalue.
   static ManagedValue
-  forBorrowedRValue(SILValue value,
-                    CleanupHandle cleanup = CleanupHandle::invalid()) {
+  forBorrowedRValue(SILValue value) {
     if (value->getType().isAddress())
-      return ManagedValue::forBorrowedAddressRValue(value, cleanup);
-    return ManagedValue::forBorrowedObjectRValue(value, cleanup);
+      return ManagedValue::forBorrowedAddressRValue(value);
+    return ManagedValue::forBorrowedObjectRValue(value);
   }
 
   /// Create a managed value for a +0 trivial object rvalue.
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index d2c984f..00ce183 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/DiagnosticsSIL.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/ResilienceExpansion.h"
 #include "swift/Basic/Timer.h"
 #include "swift/ClangImporter/ClangModule.h"
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index da454b1..e43b12c 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -2580,14 +2580,19 @@
                                                  ManagedValue object) {
   auto temporary = gen.emitTemporaryAllocation(loc, object.getType());
   bool hadCleanup = object.hasCleanup();
-  gen.B.emitStoreValueOperation(loc, object.forward(gen), temporary,
-                                StoreOwnershipQualifier::Init);
 
   // The temporary memory is +0 if the value was.
   if (hadCleanup) {
-    return ManagedValue(temporary, gen.enterDestroyCleanup(temporary));
+    gen.B.emitStoreValueOperation(loc, object.forward(gen), temporary,
+                                  StoreOwnershipQualifier::Init);
+
+    // SEMANTIC SIL TODO: This should really be called a temporary LValue.
+    return ManagedValue::forOwnedAddressRValue(temporary,
+                                               gen.enterDestroyCleanup(temporary));
   } else {
-    return ManagedValue::forUnmanaged(temporary);
+    object = gen.emitManagedBeginBorrow(loc, object.getValue());
+    gen.emitManagedStoreBorrow(loc, object.getValue(), temporary);
+    return ManagedValue::forBorrowedAddressRValue(temporary);
   }
 }
 
@@ -4349,7 +4354,7 @@
             // The captures are represented as a placeholder curry level in the
             // formal type.
             // TODO: Remove this hack.
-            paramLowering.claimCaptureParams(callee.getCaptures());
+            (void)paramLowering.claimCaptureParams(callee.getCaptures());
             claimNextParamClause(origFormalType);
             claimNextParamClause(formalType);
             args.push_back({});
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index fc2e069..0910656 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/ParameterList.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Fallthrough.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILUndef.h"
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
new file mode 100644
index 0000000..48fbc65
--- /dev/null
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -0,0 +1,148 @@
+//===--- SILGenBuilder.cpp ------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "SILGenBuilder.h"
+#include "SILGenFunction.h"
+
+using namespace swift;
+using namespace Lowering;
+
+//===----------------------------------------------------------------------===//
+//                              Utility Methods
+//===----------------------------------------------------------------------===//
+
+SILGenModule &SILGenBuilder::getSILGenModule() const { return gen.SGM; }
+
+//===----------------------------------------------------------------------===//
+//                                Constructors
+//===----------------------------------------------------------------------===//
+
+SILGenBuilder::SILGenBuilder(SILGenFunction &gen)
+    : SILBuilder(gen.F), gen(gen) {}
+
+SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB)
+    : SILBuilder(insertBB), gen(gen) {}
+
+SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
+                             SmallVectorImpl<SILInstruction *> *insertedInsts)
+    : SILBuilder(insertBB, insertedInsts), gen(gen) {}
+
+SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
+                             SILBasicBlock::iterator insertInst)
+    : SILBuilder(insertBB, insertInst), gen(gen) {}
+
+//===----------------------------------------------------------------------===//
+//                            Instruction Emission
+//===----------------------------------------------------------------------===//
+
+MetatypeInst *SILGenBuilder::createMetatype(SILLocation loc, SILType metatype) {
+  auto theMetatype = metatype.castTo<MetatypeType>();
+  // Getting a nontrivial metatype requires forcing any conformances necessary
+  // to instantiate the type.
+  switch (theMetatype->getRepresentation()) {
+  case MetatypeRepresentation::Thin:
+    break;
+  case MetatypeRepresentation::Thick:
+  case MetatypeRepresentation::ObjC: {
+    // Walk the type recursively to look for substitutions we may need.
+    theMetatype.getInstanceType().findIf([&](Type t) -> bool {
+      if (!t->getAnyNominal())
+        return false;
+
+      auto subs =
+          t->gatherAllSubstitutions(getSILGenModule().SwiftModule, nullptr);
+      getSILGenModule().useConformancesFromSubstitutions(subs);
+      return false;
+    });
+
+    break;
+  }
+  }
+
+  return SILBuilder::createMetatype(loc, metatype);
+}
+
+ApplyInst *SILGenBuilder::createApply(SILLocation Loc, SILValue Fn,
+                                      SILType SubstFnTy, SILType Result,
+                                      ArrayRef<Substitution> Subs,
+                                      ArrayRef<SILValue> Args) {
+  getSILGenModule().useConformancesFromSubstitutions(Subs);
+  return SILBuilder::createApply(Loc, Fn, SubstFnTy, Result, Subs, Args, false);
+}
+
+TryApplyInst *SILGenBuilder::createTryApply(SILLocation loc, SILValue Fn,
+                                            SILType substFnTy,
+                                            ArrayRef<Substitution> subs,
+                                            ArrayRef<SILValue> args,
+                                            SILBasicBlock *normalBB,
+                                            SILBasicBlock *errorBB) {
+  getSILGenModule().useConformancesFromSubstitutions(subs);
+  return SILBuilder::createTryApply(loc, Fn, substFnTy, subs, args, normalBB,
+                                    errorBB);
+}
+
+PartialApplyInst *SILGenBuilder::createPartialApply(
+    SILLocation Loc, SILValue Fn, SILType SubstFnTy,
+    ArrayRef<Substitution> Subs, ArrayRef<SILValue> Args, SILType ClosureTy) {
+  getSILGenModule().useConformancesFromSubstitutions(Subs);
+  return SILBuilder::createPartialApply(Loc, Fn, SubstFnTy, Subs, Args,
+                                        ClosureTy);
+}
+
+BuiltinInst *SILGenBuilder::createBuiltin(SILLocation Loc, Identifier Name,
+                                          SILType ResultTy,
+                                          ArrayRef<Substitution> Subs,
+                                          ArrayRef<SILValue> Args) {
+  getSILGenModule().useConformancesFromSubstitutions(Subs);
+  return SILBuilder::createBuiltin(Loc, Name, ResultTy, Subs, Args);
+}
+
+InitExistentialAddrInst *SILGenBuilder::createInitExistentialAddr(
+    SILLocation Loc, SILValue Existential, CanType FormalConcreteType,
+    SILType LoweredConcreteType,
+    ArrayRef<ProtocolConformanceRef> Conformances) {
+  for (auto conformance : Conformances)
+    getSILGenModule().useConformance(conformance);
+
+  return SILBuilder::createInitExistentialAddr(
+      Loc, Existential, FormalConcreteType, LoweredConcreteType, Conformances);
+}
+
+InitExistentialMetatypeInst *SILGenBuilder::createInitExistentialMetatype(
+    SILLocation loc, SILValue metatype, SILType existentialType,
+    ArrayRef<ProtocolConformanceRef> conformances) {
+  for (auto conformance : conformances)
+    getSILGenModule().useConformance(conformance);
+
+  return SILBuilder::createInitExistentialMetatype(
+      loc, metatype, existentialType, conformances);
+}
+
+InitExistentialRefInst *SILGenBuilder::createInitExistentialRef(
+    SILLocation Loc, SILType ExistentialType, CanType FormalConcreteType,
+    SILValue Concrete, ArrayRef<ProtocolConformanceRef> Conformances) {
+  for (auto conformance : Conformances)
+    getSILGenModule().useConformance(conformance);
+
+  return SILBuilder::createInitExistentialRef(
+      Loc, ExistentialType, FormalConcreteType, Concrete, Conformances);
+}
+
+AllocExistentialBoxInst *SILGenBuilder::createAllocExistentialBox(
+    SILLocation Loc, SILType ExistentialType, CanType ConcreteType,
+    ArrayRef<ProtocolConformanceRef> Conformances) {
+  for (auto conformance : Conformances)
+    getSILGenModule().useConformance(conformance);
+
+  return SILBuilder::createAllocExistentialBox(Loc, ExistentialType,
+                                               ConcreteType, Conformances);
+}
diff --git a/lib/SILGen/SILGenBuilder.h b/lib/SILGen/SILGenBuilder.h
new file mode 100644
index 0000000..4e11e71
--- /dev/null
+++ b/lib/SILGen/SILGenBuilder.h
@@ -0,0 +1,109 @@
+//===--- SILGenBuilder.h ----------------------------------------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SILGEN_SILGENBUILDER_H
+#define SWIFT_SILGEN_SILGENBUILDER_H
+
+#include "swift/SIL/SILBuilder.h"
+
+namespace swift {
+namespace Lowering {
+
+class SILGenFunction;
+
+/// A subclass of SILBuilder that tracks used protocol conformances and will
+/// eventually only traffic in ownership endowed APIs.
+///
+/// The goal is to make this eventually composed with SILBuilder so that all
+/// APIs only vend ManagedValues.
+class SILGenBuilder : public SILBuilder {
+  SILGenFunction &gen;
+
+public:
+  SILGenBuilder(SILGenFunction &gen);
+  SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB);
+  SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
+                SmallVectorImpl<SILInstruction *> *insertedInsts);
+  SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
+                SILBasicBlock::iterator insertInst);
+
+  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB)
+      : SILGenBuilder(gen, &*insertBB) {}
+  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
+                SmallVectorImpl<SILInstruction *> *insertedInsts)
+      : SILGenBuilder(gen, &*insertBB, insertedInsts) {}
+  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
+                SILInstruction *insertInst)
+      : SILGenBuilder(gen, &*insertBB, insertInst->getIterator()) {}
+  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
+                SILBasicBlock::iterator insertInst)
+      : SILGenBuilder(gen, &*insertBB, insertInst) {}
+
+  SILGenModule &getSILGenModule() const;
+
+  // Metatype instructions use the conformances necessary to instantiate the
+  // type.
+
+  MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype);
+
+  // Generic apply instructions use the conformances necessary to form the call.
+
+  using SILBuilder::createApply;
+
+  ApplyInst *createApply(SILLocation Loc, SILValue Fn, SILType SubstFnTy,
+                         SILType Result, ArrayRef<Substitution> Subs,
+                         ArrayRef<SILValue> Args);
+
+  TryApplyInst *createTryApply(SILLocation loc, SILValue fn, SILType substFnTy,
+                               ArrayRef<Substitution> subs,
+                               ArrayRef<SILValue> args, SILBasicBlock *normalBB,
+                               SILBasicBlock *errorBB);
+
+  PartialApplyInst *createPartialApply(SILLocation Loc, SILValue Fn,
+                                       SILType SubstFnTy,
+                                       ArrayRef<Substitution> Subs,
+                                       ArrayRef<SILValue> Args,
+                                       SILType ClosureTy);
+
+  BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy,
+                             ArrayRef<Substitution> Subs,
+                             ArrayRef<SILValue> Args);
+
+  // Existential containers use the conformances needed by the existential
+  // box.
+
+  InitExistentialAddrInst *
+  createInitExistentialAddr(SILLocation Loc, SILValue Existential,
+                            CanType FormalConcreteType,
+                            SILType LoweredConcreteType,
+                            ArrayRef<ProtocolConformanceRef> Conformances);
+
+  InitExistentialMetatypeInst *
+  createInitExistentialMetatype(SILLocation loc, SILValue metatype,
+                                SILType existentialType,
+                                ArrayRef<ProtocolConformanceRef> conformances);
+
+  InitExistentialRefInst *
+  createInitExistentialRef(SILLocation Loc, SILType ExistentialType,
+                           CanType FormalConcreteType, SILValue Concrete,
+                           ArrayRef<ProtocolConformanceRef> Conformances);
+
+  AllocExistentialBoxInst *
+  createAllocExistentialBox(SILLocation Loc, SILType ExistentialType,
+                            CanType ConcreteType,
+                            ArrayRef<ProtocolConformanceRef> Conformances);
+};
+
+} // namespace Lowering
+} // namespace swift
+
+#endif
diff --git a/lib/SILGen/SILGenConvert.cpp b/lib/SILGen/SILGenConvert.cpp
index 3392cce..d4085c4 100644
--- a/lib/SILGen/SILGenConvert.cpp
+++ b/lib/SILGen/SILGenConvert.cpp
@@ -14,6 +14,7 @@
 #include "Scope.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/Fallthrough.h"
 #include "swift/Basic/type_traits.h"
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index 9916ba6..2280b99 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -28,6 +28,7 @@
 #include "swift/AST/ASTMangler.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Fallthrough.h"
 #include "llvm/ADT/SmallString.h"
 #include <iterator>
@@ -203,15 +204,15 @@
 
 namespace {
 class EndBorrowCleanup : public Cleanup {
-  SILValue borrowee;
+  SILValue original;
   SILValue borrowed;
 
 public:
-  EndBorrowCleanup(SILValue borrowee, SILValue borrowed)
-      : borrowee(borrowee), borrowed(borrowed) {}
+  EndBorrowCleanup(SILValue original, SILValue borrowed)
+      : original(original), borrowed(borrowed) {}
 
   void emit(SILGenFunction &gen, CleanupLocation l) override {
-    gen.B.createEndBorrow(l, borrowee, borrowed);
+    gen.B.createEndBorrow(l, borrowed, original);
   }
 };
 } // end anonymous namespace
@@ -1159,9 +1160,9 @@
   return Cleanups.getTopCleanup();
 }
 
-CleanupHandle SILGenFunction::enterEndBorrowCleanup(SILValue borrowee,
+CleanupHandle SILGenFunction::enterEndBorrowCleanup(SILValue original,
                                                     SILValue borrowed) {
-  Cleanups.pushCleanup<EndBorrowCleanup>(borrowee, borrowed);
+  Cleanups.pushCleanup<EndBorrowCleanup>(original, borrowed);
   return Cleanups.getTopCleanup();
 }
 
@@ -1776,9 +1777,7 @@
       specialized = ctx.getSpecializedConformance(concreteTy, conformance,
                                                   concreteSubs);
 
-    SmallVector<ProtocolConformanceRef, 1> conformances;
-    conformances.push_back(ProtocolConformanceRef(specialized));
-    reqtSubs.addConformances(selfTy, ctx.AllocateCopy(conformances));
+    reqtSubs.addConformance(selfTy, ProtocolConformanceRef(specialized));
 
     auto input = reqtOrigTy->getInput().subst(reqtSubs)->getCanonicalType();
     auto result = reqtOrigTy->getResult().subst(reqtSubs)->getCanonicalType();
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 9a12214..670a8ea 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -134,22 +134,24 @@
 }
 
 ManagedValue
-SILGenFunction::emitManagedBorrowedRValueWithCleanup(SILValue borrowee,
+SILGenFunction::emitManagedBorrowedRValueWithCleanup(SILValue original,
                                                      SILValue borrowed) {
-  assert(borrowee->getType().getObjectType() ==
+  assert(original->getType().getObjectType() ==
          borrowed->getType().getObjectType());
-  auto &lowering = getTypeLowering(borrowee->getType());
-  return emitManagedBorrowedRValueWithCleanup(borrowee, borrowed, lowering);
+  auto &lowering = getTypeLowering(original->getType());
+  return emitManagedBorrowedRValueWithCleanup(original, borrowed, lowering);
 }
 
 ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup(
-    SILValue borrowee, SILValue borrowed, const TypeLowering &lowering) {
+    SILValue original, SILValue borrowed, const TypeLowering &lowering) {
   assert(lowering.getLoweredType().getObjectType() ==
-         borrowee->getType().getObjectType());
+         original->getType().getObjectType());
   if (lowering.isTrivial())
     return ManagedValue::forUnmanaged(borrowed);
 
-  return ManagedValue(borrowed, enterEndBorrowCleanup(borrowee, borrowed));
+  if (borrowed->getType().isObject())
+    enterEndBorrowCleanup(original, borrowed);
+  return ManagedValue(borrowed, CleanupHandle::invalid());
 }
 
 ManagedValue SILGenFunction::emitManagedRValueWithCleanup(SILValue v) {
@@ -1924,7 +1926,14 @@
   // If we're emitting into an initialization, we can try shuffling the
   // elements of the initialization.
   if (Initialization *I = C.getEmitInto()) {
-    if (I->canSplitIntoTupleElements()) {
+    // In Swift 3 mode, we might be stripping off labels from a
+    // one-element tuple; the destination type is a ParenType in
+    // that case.
+    //
+    // FIXME: Remove this eventually.
+    if (I->canSplitIntoTupleElements() &&
+        !(isa<ParenType>(E->getType().getPointer()) &&
+          SGF.getASTContext().isSwiftVersion3())) {
       emitTupleShuffleExprInto(*this, E, I);
       return RValue();
     }
@@ -1940,7 +1949,25 @@
   
   // Prepare a new tuple to hold the shuffled result.
   RValue result(E->getType()->getCanonicalType());
-  
+
+  // In Swift 3 mode, we might be stripping off labels from a
+  // one-element tuple; the destination type is a ParenType in
+  // that case.
+  //
+  // FIXME: Remove this eventually.
+  if (isa<ParenType>(E->getType().getPointer()) &&
+      SGF.getASTContext().isSwiftVersion3()) {
+    assert(E->getElementMapping().size() == 1);
+    auto shuffleIndex = E->getElementMapping()[0];
+    assert(shuffleIndex != TupleShuffleExpr::DefaultInitialize &&
+           shuffleIndex != TupleShuffleExpr::CallerDefaultInitialize &&
+           shuffleIndex != TupleShuffleExpr::Variadic &&
+           "Only argument tuples can have default initializers & varargs");
+
+    result.addElement(std::move(elements[shuffleIndex]));
+    return result;
+  }
+
   auto outerFields = E->getType()->castTo<TupleType>()->getElements();
   auto shuffleIndexIterator = E->getElementMapping().begin();
   auto shuffleIndexEnd = E->getElementMapping().end();
@@ -2977,8 +3004,6 @@
                                         ->getSemanticsProvidingExpr());
   if (!BO || BO->getDepth() != 0) return false;
   
-  auto &optTL = SGF.getTypeLowering(E->getType());
-
   // If the subexpression type is exactly the same, then just peephole the
   // whole thing away.
   if (BO->getSubExpr()->getType()->isEqual(E->getType())) {
@@ -2997,17 +3022,7 @@
   // address only or because we have a contextual memory location to
   // initialize).
   if (optInit == nullptr) {
-    auto subMV = SGF.emitRValueAsSingleValue(BO->getSubExpr());
-    SILValue result;
-    if (optTL.isTrivial())
-      result = SGF.B.createUncheckedTrivialBitCast(E, subMV.forward(SGF),
-                                                   optTL.getLoweredType());
-    else
-      // The optional object type is the same, so we assume the optional types
-      // are layout identical, allowing the use of unchecked bit casts.
-      result = SGF.B.createUncheckedBitCast(E, subMV.forward(SGF),
-                                            optTL.getLoweredType());
-    LoadableResult = result;
+    LoadableResult = SGF.emitRValueAsSingleValue(BO->getSubExpr()).forward(SGF);
     return true;
   }
   
@@ -3017,11 +3032,7 @@
   SILValue optAddr = getAddressForInPlaceInitialization(optInit);
   assert(optAddr && "Caller should have provided a buffer");
   
-  auto &subTL = SGF.getTypeLowering(BO->getSubExpr()->getType());
-  SILValue subAddr = SGF.B.createUncheckedAddrCast(E, optAddr,
-                                 subTL.getLoweredType().getAddressType());
-  
-  KnownAddressInitialization subInit(subAddr);
+  KnownAddressInitialization subInit(optAddr);
   SGF.emitExprInto(BO->getSubExpr(), &subInit);
   optInit->finishInitialization(SGF);
   return true;
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index 157f2e0..83c26e4 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -876,134 +876,3 @@
   emitReturnExpr(Loc, value);
   emitEpilog(Loc);
 }
-
-SILGenBuilder::SILGenBuilder(SILGenFunction &gen)
-  : SILBuilder(gen.F), SGM(gen.SGM) {}
-SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB)
-  : SILBuilder(insertBB), SGM(gen.SGM) {}
-SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
-                             SmallVectorImpl<SILInstruction *> *insertedInsts)
-  : SILBuilder(insertBB, insertedInsts), SGM(gen.SGM) {}
-SILGenBuilder::SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
-                             SILBasicBlock::iterator insertInst)
-    : SILBuilder(insertBB, insertInst), SGM(gen.SGM) {}
-
-MetatypeInst *SILGenBuilder::createMetatype(SILLocation loc, SILType metatype) {
-  auto theMetatype = metatype.castTo<MetatypeType>();
-  // Getting a nontrivial metatype requires forcing any conformances necessary
-  // to instantiate the type.
-  switch (theMetatype->getRepresentation()) {
-  case MetatypeRepresentation::Thin:
-    break;
-  case MetatypeRepresentation::Thick:
-  case MetatypeRepresentation::ObjC: {
-    // Walk the type recursively to look for substitutions we may need.
-    theMetatype.getInstanceType().findIf([&](Type t) -> bool {
-      if (!t->getAnyNominal())
-        return false;
-
-      auto subs = t->gatherAllSubstitutions(SGM.SwiftModule, nullptr);
-      SGM.useConformancesFromSubstitutions(subs);
-      return false;
-    });
-
-    break;
-  }
-  }
-
-  return SILBuilder::createMetatype(loc, metatype);
-}
-
-ApplyInst *SILGenBuilder::createApply(SILLocation Loc, SILValue Fn,
-                                      SILType SubstFnTy,
-                                      SILType Result,
-                                      ArrayRef<Substitution> Subs,
-                                      ArrayRef<SILValue> Args) {
-  SGM.useConformancesFromSubstitutions(Subs);
-  return SILBuilder::createApply(Loc, Fn, SubstFnTy, Result, Subs, Args, false);
-}
-
-TryApplyInst *SILGenBuilder::createTryApply(SILLocation loc, SILValue Fn,
-                                            SILType substFnTy,
-                                            ArrayRef<Substitution> subs,
-                                            ArrayRef<SILValue> args,
-                                            SILBasicBlock *normalBB,
-                                            SILBasicBlock *errorBB) {
-  SGM.useConformancesFromSubstitutions(subs);
-  return SILBuilder::createTryApply(loc, Fn, substFnTy, subs, args, normalBB,
-                                    errorBB);
-}
-
-PartialApplyInst *SILGenBuilder::createPartialApply(SILLocation Loc,
-                                                    SILValue Fn,
-                                                    SILType SubstFnTy,
-                                                    ArrayRef<Substitution> Subs,
-                                                    ArrayRef<SILValue> Args,
-                                                    SILType ClosureTy) {
-  SGM.useConformancesFromSubstitutions(Subs);
-  return SILBuilder::createPartialApply(Loc, Fn, SubstFnTy, Subs, Args,
-                                        ClosureTy);
-}
-
-BuiltinInst *SILGenBuilder::createBuiltin(SILLocation Loc, Identifier Name,
-                                          SILType ResultTy,
-                                          ArrayRef<Substitution> Subs,
-                                          ArrayRef<SILValue> Args) {
-  SGM.useConformancesFromSubstitutions(Subs);
-  return SILBuilder::createBuiltin(Loc, Name, ResultTy, Subs, Args);
-}
-
-InitExistentialAddrInst *
-SILGenBuilder::createInitExistentialAddr(SILLocation Loc,
-                                   SILValue Existential,
-                                   CanType FormalConcreteType,
-                                   SILType LoweredConcreteType,
-                                ArrayRef<ProtocolConformanceRef> Conformances) {
-  for (auto conformance : Conformances)
-    SGM.useConformance(conformance);
-
-  return SILBuilder::createInitExistentialAddr(Loc, Existential,
-                                               FormalConcreteType,
-                                               LoweredConcreteType,
-                                               Conformances);
-}
-
-InitExistentialMetatypeInst *
-SILGenBuilder::createInitExistentialMetatype(SILLocation loc,
-                                             SILValue metatype,
-                                             SILType existentialType,
-                                ArrayRef<ProtocolConformanceRef> conformances) {
-  for (auto conformance : conformances)
-    SGM.useConformance(conformance);
-
-  return SILBuilder::createInitExistentialMetatype(loc, metatype,
-                                                   existentialType,
-                                                   conformances);
-}
-
-InitExistentialRefInst *
-SILGenBuilder::createInitExistentialRef(SILLocation Loc,
-                                        SILType ExistentialType,
-                                        CanType FormalConcreteType,
-                                        SILValue Concrete,
-                                ArrayRef<ProtocolConformanceRef> Conformances) {
-  for (auto conformance : Conformances)
-    SGM.useConformance(conformance);
-
-  return SILBuilder::createInitExistentialRef(Loc, ExistentialType,
-                                              FormalConcreteType, Concrete,
-                                              Conformances);
-}
-
-AllocExistentialBoxInst *
-SILGenBuilder::createAllocExistentialBox(SILLocation Loc,
-                                         SILType ExistentialType,
-                                         CanType ConcreteType,
-                                ArrayRef<ProtocolConformanceRef> Conformances) {
-  for (auto conformance : Conformances)
-    SGM.useConformance(conformance);
-
-  return SILBuilder::createAllocExistentialBox(Loc, ExistentialType,
-                                               ConcreteType,
-                                               Conformances);
-}
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index f9b10a5..22fd781 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -13,9 +13,10 @@
 #ifndef SWIFT_SILGEN_SILGENFUNCTION_H
 #define SWIFT_SILGEN_SILGENFUNCTION_H
 
-#include "SILGen.h"
-#include "JumpDest.h"
 #include "Initialization.h"
+#include "JumpDest.h"
+#include "SILGen.h"
+#include "SILGenBuilder.h"
 #include "swift/AST/AnyFunctionRef.h"
 #include "swift/SIL/SILBuilder.h"
 #include "llvm/ADT/PointerIntPair.h"
@@ -175,91 +176,6 @@
   Postmatter,
 };
 
-/// A subclass of SILBuilder that tracks used protocol conformances.
-class SILGenBuilder : public SILBuilder {
-  SILGenModule &SGM;
-public:
-  SILGenBuilder(SILGenFunction &gen);
-  SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB);
-  SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
-                SmallVectorImpl<SILInstruction *> *insertedInsts);
-  SILGenBuilder(SILGenFunction &gen, SILBasicBlock *insertBB,
-                SILBasicBlock::iterator insertInst);
-
-  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB)
-      : SILGenBuilder(gen, &*insertBB) {}
-  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
-                SmallVectorImpl<SILInstruction *> *insertedInsts)
-      : SILGenBuilder(gen, &*insertBB, insertedInsts) {}
-  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
-                SILInstruction *insertInst)
-      : SILGenBuilder(gen, &*insertBB, insertInst->getIterator()) {}
-  SILGenBuilder(SILGenFunction &gen, SILFunction::iterator insertBB,
-                SILBasicBlock::iterator insertInst)
-      : SILGenBuilder(gen, &*insertBB, insertInst) {}
-
-  SILGenModule &getSILGenModule() const { return SGM; }
-
-  // Metatype instructions use the conformances necessary to instantiate the
-  // type.
-  
-  MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype);
-
-  // Generic apply instructions use the conformances necessary to form the call.
-
-  using SILBuilder::createApply;
-
-  ApplyInst *createApply(SILLocation Loc, SILValue Fn,
-                         SILType SubstFnTy,
-                         SILType Result,
-                         ArrayRef<Substitution> Subs,
-                         ArrayRef<SILValue> Args);
-
-
-  TryApplyInst *createTryApply(SILLocation loc, SILValue fn,
-                               SILType substFnTy,
-                               ArrayRef<Substitution> subs,
-                               ArrayRef<SILValue> args,
-                               SILBasicBlock *normalBB,
-                               SILBasicBlock *errorBB);
-
-  PartialApplyInst *createPartialApply(SILLocation Loc, SILValue Fn,
-                                       SILType SubstFnTy,
-                                       ArrayRef<Substitution> Subs,
-                                       ArrayRef<SILValue> Args,
-                                       SILType ClosureTy);
-
-  BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name,
-                             SILType ResultTy, ArrayRef<Substitution> Subs,
-                             ArrayRef<SILValue> Args);
-
-  // Existential containers use the conformances needed by the existential
-  // box.
-
-  InitExistentialAddrInst *
-  createInitExistentialAddr(SILLocation Loc,
-                            SILValue Existential,
-                            CanType FormalConcreteType,
-                            SILType LoweredConcreteType,
-                            ArrayRef<ProtocolConformanceRef> Conformances);
-
-  InitExistentialMetatypeInst *
-  createInitExistentialMetatype(SILLocation loc, SILValue metatype,
-                                SILType existentialType,
-                                ArrayRef<ProtocolConformanceRef> conformances);
-  
-  InitExistentialRefInst *
-  createInitExistentialRef(SILLocation Loc, SILType ExistentialType,
-                           CanType FormalConcreteType,
-                           SILValue Concrete,
-                           ArrayRef<ProtocolConformanceRef> Conformances);
-
-  AllocExistentialBoxInst *createAllocExistentialBox(SILLocation Loc,
-                                 SILType ExistentialType,
-                                 CanType ConcreteType,
-                                 ArrayRef<ProtocolConformanceRef> Conformances);
-};
-
 /// Parameter to \c SILGenFunction::emitCaptures that indicates what the
 /// capture parameters are being emitted for.
 enum class CaptureEmission {
@@ -349,10 +265,9 @@
 
   /// \brief Is emission currently within an inout conversion?
   bool InInOutConversionScope = false;
-  
-  /// B - The SILGenBuilder used to construct the SILFunction.  It is
-  /// what maintains the notion of the current block being emitted
-  /// into.
+
+  /// The SILGenBuilder used to construct the SILFunction.  It is what maintains
+  /// the notion of the current block being emitted into.
   SILGenBuilder B;
 
   SILOpenedArchetypesTracker OpenedArchetypesTracker;
@@ -1173,11 +1088,10 @@
                                       const TypeLowering &lowering);
   ManagedValue emitManagedBeginBorrow(SILLocation loc, SILValue v);
 
-  ManagedValue emitManagedBorrowedRValueWithCleanup(SILValue borrowee,
-                                                    SILValue borrower);
-  ManagedValue
-  emitManagedBorrowedRValueWithCleanup(SILValue borrowee, SILValue borrower,
-                                       const TypeLowering &lowering);
+  ManagedValue emitManagedBorrowedRValueWithCleanup(SILValue original,
+                                                    SILValue borrowedValue);
+  ManagedValue emitManagedBorrowedRValueWithCleanup(
+      SILValue original, SILValue borrowedValue, const TypeLowering &lowering);
 
   ManagedValue emitManagedRValueWithCleanup(SILValue v);
   ManagedValue emitManagedRValueWithCleanup(SILValue v,
@@ -1624,9 +1538,9 @@
                                               ExistentialRepresentation repr);
 
   /// Enter a cleanup to emit an EndBorrow stating that \p borrowed (the
-  /// borrowed entity) is no longer borrowed from \p borrowee, the original
+  /// borrowed entity) is no longer borrowed from \p original, the original
   /// value.
-  CleanupHandle enterEndBorrowCleanup(SILValue borrowee, SILValue borrowed);
+  CleanupHandle enterEndBorrowCleanup(SILValue original, SILValue borrowed);
 
   /// Evaluate an Expr as an lvalue.
   LValue emitLValue(Expr *E, AccessKind accessKind);
diff --git a/lib/SILGen/SILGenMaterializeForSet.cpp b/lib/SILGen/SILGenMaterializeForSet.cpp
index f731cb3..aa8a242 100644
--- a/lib/SILGen/SILGenMaterializeForSet.cpp
+++ b/lib/SILGen/SILGenMaterializeForSet.cpp
@@ -27,6 +27,7 @@
 #include "swift/AST/DiagnosticsCommon.h"
 #include "swift/AST/Mangle.h"
 #include "swift/AST/ASTMangler.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/PrettyStackTrace.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILUndef.h"
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index ebb1b5d..4a1e863 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -2456,18 +2456,6 @@
       [&](Type depTy, ArrayRef<Requirement> reqs) -> bool {
     auto canTy = depTy->getCanonicalType();
 
-    // Add abstract conformances.
-    auto conformances =
-        ctx.AllocateUninitialized<ProtocolConformanceRef>(
-            reqs.size());
-    for (unsigned i = 0, e = reqs.size(); i < e; i++) {
-      auto reqt = reqs[i];
-      assert(reqt.getKind() == RequirementKind::Conformance);
-      auto *proto = reqt.getSecondType()
-          ->castTo<ProtocolType>()->getDecl();
-      conformances[i] = ProtocolConformanceRef(proto);
-    }
-
     ArchetypeType *oldArchetype;
     // The opened existential archetype maps to the new generic parameter's
     // archetype.
@@ -2484,11 +2472,19 @@
 
     if (isa<SubstitutableType>(canTy)) {
       interfaceSubs.addSubstitution(cast<SubstitutableType>(canTy),
-                                  oldArchetype);
+                                    oldArchetype);
     }
 
-    contextSubs.addConformances(CanType(oldArchetype), conformances);
-    interfaceSubs.addConformances(canTy, conformances);
+    // Add abstract conformances.
+    for (unsigned i = 0, e = reqs.size(); i < e; i++) {
+      auto reqt = reqs[i];
+      assert(reqt.getKind() == RequirementKind::Conformance);
+      auto *proto = reqt.getSecondType()
+          ->castTo<ProtocolType>()->getDecl();
+      auto conformance = ProtocolConformanceRef(proto);
+      contextSubs.addConformance(CanType(oldArchetype), conformance);
+      interfaceSubs.addConformance(canTy, conformance);
+    }
 
     return false;
   });
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 807c3a6..976e612 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -22,6 +22,7 @@
 #include "Scope.h"
 #include "ManagedValue.h"
 #include "swift/AST/AST.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeMemberVisitor.h"
 #include "swift/Basic/Fallthrough.h"
 #include "swift/SIL/SILArgument.h"
diff --git a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp
index 41815be..d801684 100644
--- a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp
@@ -68,8 +68,7 @@
                                          "typed-access-tb-aa"),
                               clEnumValN(AAKind::All,
                                          "all",
-                                         "all"),
-                              clEnumValEnd));
+                                         "all")));
 
 static inline bool shouldRunAA() {
   return unsigned(AAKind(DebugAAKinds));
diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
index 772b822..83c5468 100644
--- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
@@ -728,7 +728,6 @@
   /// GraphTraits specialization so the CGForDotView can be
   /// iterable by generic graph iterators.
   template <> struct GraphTraits<CGForDotView::Node *> {
-    typedef CGForDotView::Node NodeType;
     typedef CGForDotView::child_iterator ChildIteratorType;
     typedef CGForDotView::Node *NodeRef;
 
@@ -748,11 +747,13 @@
 
     static NodeRef getEntryNode(GraphType F) { return nullptr; }
 
-    typedef CGForDotView::iterator nodes_iterator;
+    typedef pointer_iterator<CGForDotView::iterator> nodes_iterator;
     static nodes_iterator nodes_begin(GraphType OCG) {
-      return OCG->Nodes.begin();
+      return nodes_iterator(OCG->Nodes.begin());
     }
-    static nodes_iterator nodes_end(GraphType OCG) { return OCG->Nodes.end(); }
+    static nodes_iterator nodes_end(GraphType OCG) {
+      return nodes_iterator(OCG->Nodes.end());
+    }
     static unsigned size(GraphType CG) { return CG->Nodes.size(); }
   };
 
@@ -1156,7 +1157,7 @@
     // The object is local, but we cannot determine its type.
     return false;
   }
-  // If Ty is a an optional, its deallocation is equivalent to the deallocation
+  // If Ty is an optional, its deallocation is equivalent to the deallocation
   // of its payload.
   // TODO: Generalize it. Destructor of an aggregate type is equivalent to calling
   // destructors for its components.
diff --git a/lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp b/lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp
index 08a17cb..9cb2ec3 100644
--- a/lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp
@@ -1034,7 +1034,6 @@
 
 namespace llvm {
 template <> struct GraphTraits<LoopRegionWrapper> {
-  using NodeType = LoopRegionWrapper;
   using ChildIteratorType = alledge_iterator;
   typedef LoopRegionWrapper *NodeRef;
 
@@ -1052,10 +1051,15 @@
 
   static NodeRef getEntryNode(GraphType *F) { return &F->Data[0]; }
 
-  using nodes_iterator = std::vector<LoopRegionWrapper>::iterator;
+  using nodes_iterator =
+          pointer_iterator<std::vector<LoopRegionWrapper>::iterator>;
 
-  static nodes_iterator nodes_begin(GraphType *F) { return F->Data.begin(); }
-  static nodes_iterator nodes_end(GraphType *F) { return F->Data.end(); }
+  static nodes_iterator nodes_begin(GraphType *F) {
+    return nodes_iterator(F->Data.begin());
+  }
+  static nodes_iterator nodes_end(GraphType *F) {
+    return nodes_iterator(F->Data.end());
+  }
   static unsigned size(GraphType *F) { return F->Data.size(); }
 };
 
@@ -1078,8 +1082,7 @@
         clEnumValN(LongLineBehavior::None, "none", "Print everything"),
         clEnumValN(LongLineBehavior::Truncate, "truncate",
                    "Truncate long lines"),
-        clEnumValN(LongLineBehavior::Wrap, "wrap", "Wrap long lines"),
-        clEnumValEnd));
+        clEnumValN(LongLineBehavior::Wrap, "wrap", "Wrap long lines")));
 
 static llvm::cl::opt<bool> RemoveUseListComments(
     "view-loop-regions-remove-use-list-comments", llvm::cl::init(false),
diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
index a1e1500..13b796b 100644
--- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
+++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
@@ -11,11 +11,13 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "sil-dead-function-elimination"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 #include "swift/SIL/PatternMatch.h"
 #include "swift/SIL/SILBuilder.h"
 #include "swift/SIL/SILVisitor.h"
+#include "swift/SIL/InstructionUtils.h"
 #include "swift/SILOptimizer/Utils/Local.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
@@ -33,19 +35,54 @@
 /// It provides a common logic for computing live (i.e. reachable) functions.
 class FunctionLivenessComputation {
 protected:
+
+  /// Represents a function which is implementing a vtable or witness table
+  /// method.
+  struct FuncImpl {
+    FuncImpl(SILFunction *F, ClassDecl *Cl) : F(F) { Impl.Cl = Cl; }
+    FuncImpl(SILFunction *F, ProtocolConformance *C) : F(F) { Impl.Conf = C; }
+
+    /// The implementing function.
+    SILFunction *F;
+
+    union {
+      /// In case of a vtable method.
+      ClassDecl *Cl;
+
+      /// In case of a witness method.
+      ProtocolConformance *Conf;
+    } Impl;
+  };
+
   /// Stores which functions implement a vtable or witness table method.
   struct MethodInfo {
 
-    MethodInfo() : isAnchor(false) {}
+    MethodInfo(bool isWitnessMethod) :
+      methodIsCalled(false), isWitnessMethod(isWitnessMethod) {}
 
     /// All functions which implement the method. Together with the class for
     /// which the function implements the method. In case of a witness method,
     /// the class pointer is null.
-    SmallVector<std::pair<SILFunction *, ClassDecl *>, 8> implementingFunctions;
+    SmallVector<FuncImpl, 8> implementingFunctions;
 
-    /// True, if the whole method is alive, e.g. because it's class is visible
-    /// from outside. This implies that all implementing functions are alive.
-    bool isAnchor;
+    /// True, if the method is called, meaning that any of it's implementations
+    /// may be called.
+    bool methodIsCalled;
+
+    /// True if this is a witness method, false if it's a vtable method.
+    bool isWitnessMethod;
+
+    /// Adds an implementation of the method in a specific class.
+    void addClassMethodImpl(SILFunction *F, ClassDecl *C) {
+      assert(!isWitnessMethod);
+      implementingFunctions.push_back(FuncImpl(F, C));
+    }
+
+    /// Adds an implementation of the method in a specific conformance.
+    void addWitnessFunction(SILFunction *F, ProtocolConformance *Conf) {
+      assert(isWitnessMethod);
+      implementingFunctions.push_back(FuncImpl(F, Conf));
+    }
   };
 
   SILModule *Module;
@@ -55,7 +92,9 @@
 
   llvm::SmallSetVector<SILFunction *, 16> Worklist;
 
-  llvm::SmallPtrSet<SILFunction *, 32> AliveFunctions;
+  llvm::SmallPtrSet<void *, 32> AliveFunctionsAndTables;
+
+  ConformanceCollector FoundConformances;
 
   /// Checks is a function is alive, e.g. because it is visible externally.
   bool isAnchorFunction(SILFunction *F) {
@@ -86,32 +125,73 @@
   /// Gets or creates the MethodInfo for a vtable or witness table method.
   /// \p decl The method declaration. In case of a vtable method this is always
   ///         the most overridden method.
-  MethodInfo *getMethodInfo(AbstractFunctionDecl *decl) {
+  MethodInfo *getMethodInfo(AbstractFunctionDecl *decl, bool isWitnessMethod) {
     MethodInfo *&entry = MethodInfos[decl];
     if (entry == nullptr) {
-      entry = new (MethodInfoAllocator.Allocate()) MethodInfo();
+      entry = new (MethodInfoAllocator.Allocate()) MethodInfo(isWitnessMethod);
     }
+    assert(entry->isWitnessMethod == isWitnessMethod);
     return entry;
   }
 
-  /// Adds a function which implements a vtable or witness method. If it's a
-  /// vtable method, \p C is the class for which the function implements the
-  /// method. For witness methods \C is null.
-  void addImplementingFunction(MethodInfo *mi, SILFunction *F, ClassDecl *C) {
-    if (mi->isAnchor)
-      ensureAlive(F);
-    mi->implementingFunctions.push_back(std::make_pair(F, C));
+  /// Returns true if a function is marked as alive.
+  bool isAlive(SILFunction *F) {
+    return AliveFunctionsAndTables.count(F) != 0;
   }
 
-  /// Returns true if a function is marked as alive.
-  bool isAlive(SILFunction *F) { return AliveFunctions.count(F) != 0; }
+  /// Returns true if a witness table is marked as alive.
+  bool isAlive(SILWitnessTable *WT) {
+    return AliveFunctionsAndTables.count(WT) != 0;
+  }
 
   /// Marks a function as alive.
   void makeAlive(SILFunction *F) {
-    AliveFunctions.insert(F);
+    AliveFunctionsAndTables.insert(F);
     assert(F && "function does not exist");
     Worklist.insert(F);
   }
+
+  /// Marks all contained functions and witness tables of a witness table as
+  /// alive.
+  void makeAlive(SILWitnessTable *WT) {
+    DEBUG(llvm::dbgs() << "    scan witness table " << WT->getName() << '\n');
+
+    AliveFunctionsAndTables.insert(WT);
+    for (const SILWitnessTable::Entry &entry : WT->getEntries()) {
+      switch (entry.getKind()) {
+        case SILWitnessTable::Method: {
+
+          auto methodWitness = entry.getMethodWitness();
+          auto *fd = cast<AbstractFunctionDecl>(methodWitness.Requirement.
+                                                getDecl());
+          assert(fd == getBase(fd) && "key in witness table is overridden");
+          SILFunction *F = methodWitness.Witness;
+          if (F) {
+            MethodInfo *MI = getMethodInfo(fd, /*isWitnessMethod*/ true);
+            if (MI->methodIsCalled || !F->isDefinition())
+              ensureAlive(F);
+          }
+        } break;
+
+        case SILWitnessTable::AssociatedTypeProtocol: {
+          ProtocolConformanceRef CRef =
+             entry.getAssociatedTypeProtocolWitness().Witness;
+          if (CRef.isConcrete())
+            ensureAliveConformance(CRef.getConcrete());
+          break;
+        }
+        case SILWitnessTable::BaseProtocol:
+          ensureAliveConformance(entry.getBaseProtocolWitness().Witness);
+          break;
+
+        case SILWitnessTable::Invalid:
+        case SILWitnessTable::MissingOptional:
+        case SILWitnessTable::AssociatedType:
+          break;
+      }
+    }
+
+  }
   
   /// Marks a function as alive if it is not alive yet.
   void ensureAlive(SILFunction *F) {
@@ -119,6 +199,15 @@
       makeAlive(F);
   }
 
+  /// Marks a witness table as alive if it is not alive yet.
+  void ensureAliveConformance(const ProtocolConformance *C) {
+    SILWitnessTable *WT = Module->lookUpWitnessTable(C,
+                                                 /*deserializeLazily*/ false);
+    if (!WT || isAlive(WT))
+      return;
+    makeAlive(WT);
+  }
+
   /// Returns true if \a Derived is the same as \p Base or derived from it.
   static bool isDerivedOrEqual(ClassDecl *Derived, ClassDecl *Base) {
     for (;;) {
@@ -157,12 +246,37 @@
   /// Marks the implementing functions of the method \p FD as alive. If it is a
   /// class method, \p MethodCl is the type of the class_method instruction's
   /// operand.
-  void ensureAlive(MethodInfo *mi, FuncDecl *FD, ClassDecl *MethodCl) {
-    for (auto &Pair : mi->implementingFunctions) {
-      SILFunction *FImpl = Pair.first;
-      if (!isAlive(FImpl) &&
-          canHaveSameImplementation(FD, MethodCl, Pair.second)) {
-        makeAlive(FImpl);
+  void ensureAliveClassMethod(MethodInfo *mi, FuncDecl *FD, ClassDecl *MethodCl) {
+    if (mi->methodIsCalled)
+      return;
+    bool allImplsAreCalled = true;
+
+    for (FuncImpl &FImpl : mi->implementingFunctions) {
+      if (!isAlive(FImpl.F) &&
+          canHaveSameImplementation(FD, MethodCl, FImpl.Impl.Cl)) {
+        makeAlive(FImpl.F);
+      } else {
+        allImplsAreCalled = false;
+      }
+    }
+    if (allImplsAreCalled)
+      mi->methodIsCalled = true;
+  }
+
+  /// Marks the implementing functions of the protocol method \p mi as alive.
+  void ensureAliveProtocolMethod(MethodInfo *mi) {
+    assert(mi->isWitnessMethod);
+    if (mi->methodIsCalled)
+      return;
+    mi->methodIsCalled = true;
+    for (FuncImpl &FImpl : mi->implementingFunctions) {
+      if (FImpl.Impl.Conf) {
+        SILWitnessTable *WT = Module->lookUpWitnessTable(FImpl.Impl.Conf,
+                                                  /*deserializeLazily*/ false);
+        if (!WT || isAlive(WT))
+          makeAlive(FImpl.F);
+      } else {
+        makeAlive(FImpl.F);
       }
     }
   }
@@ -178,19 +292,48 @@
 
   /// Scans all references inside a function.
   void scanFunction(SILFunction *F) {
+
+    DEBUG(llvm::dbgs() << "    scan function " << F->getName() << '\n');
+
+    size_t ExistingNumConfs = FoundConformances.getUsedConformances().size();
+    size_t ExistingMetaTypes = FoundConformances.getEscapingMetaTypes().size();
+
+    // First scan all instructions of the function.
     for (SILBasicBlock &BB : *F) {
       for (SILInstruction &I : BB) {
-        if (auto *MI = dyn_cast<MethodInst>(&I)) {
+        if (auto *WMI = dyn_cast<WitnessMethodInst>(&I)) {
+          auto *funcDecl = cast<AbstractFunctionDecl>(WMI->getMember().getDecl());
+          assert(funcDecl == getBase(funcDecl));
+          MethodInfo *mi = getMethodInfo(funcDecl, /*isWitnessTable*/ true);
+          ensureAliveProtocolMethod(mi);
+        } else if (auto *MI = dyn_cast<MethodInst>(&I)) {
           auto *funcDecl = getBase(
               cast<AbstractFunctionDecl>(MI->getMember().getDecl()));
-          MethodInfo *mi = getMethodInfo(funcDecl);
-          ClassDecl *MethodCl = nullptr;
-          if (MI->getNumOperands() == 1)
-            MethodCl = MI->getOperand(0)->getType().getClassOrBoundGenericClass();
-          ensureAlive(mi, dyn_cast<FuncDecl>(funcDecl), MethodCl);
+          assert(MI->getNumOperands() - MI->getNumTypeDependentOperands() == 1
+                 && "method insts except witness_method must have 1 operand");
+          ClassDecl *MethodCl = MI->getOperand(0)->getType().
+                                  getClassOrBoundGenericClass();
+          MethodInfo *mi = getMethodInfo(funcDecl, /*isWitnessTable*/ false);
+          ensureAliveClassMethod(mi, dyn_cast<FuncDecl>(funcDecl), MethodCl);
         } else if (auto *FRI = dyn_cast<FunctionRefInst>(&I)) {
           ensureAlive(FRI->getReferencedFunction());
         }
+        FoundConformances.collect(&I);
+      }
+    }
+    // Now we scan all _new_ conformances we found in the function.
+    auto UsedConfs = FoundConformances.getUsedConformances();
+    for (size_t Idx = ExistingNumConfs; Idx < UsedConfs.size(); ++Idx) {
+      ensureAliveConformance(UsedConfs[Idx]);
+    }
+    // All conformances of a type for which the meta-type escapes, must stay
+    // alive.
+    auto UsedMTs = FoundConformances.getEscapingMetaTypes();
+    for (size_t Idx = ExistingMetaTypes; Idx < UsedMTs.size(); ++Idx) {
+      const NominalTypeDecl *NT = UsedMTs[Idx];
+      auto Confs = NT->getAllConformances();
+      for (ProtocolConformance *C : Confs) {
+        ensureAliveConformance(C);
       }
     }
   }
@@ -254,7 +397,7 @@
 
 public:
   FunctionLivenessComputation(SILModule *module) :
-    Module(module) {}
+    Module(module), FoundConformances(*module) {}
 
   /// The main entry point of the optimization.
   bool findAliveFunctions() {
@@ -272,6 +415,7 @@
       Worklist.pop_back();
       scanFunction(F);
     }
+    FoundConformances.clear();
 
     return false;
   }
@@ -289,43 +433,26 @@
 
 class DeadFunctionElimination : FunctionLivenessComputation {
 
-  /// DeadFunctionElimination pass takes functions
-  /// reachable via vtables and witness_tables into account
-  /// when computing a function liveness information.
-  void findAnchorsInTables() override {
-    // Check vtable methods.
+  void collectMethodImplementations() {
+    // Collect vtable method implementations.
     for (SILVTable &vTable : Module->getVTableList()) {
-      for (auto &entry : vTable.getEntries()) {
-        // Destructors are alive because they are called from swift_release
+      for (const SILVTable::Entry &entry : vTable.getEntries()) {
+        // We don't need to collect destructors because we mark them as alive
+        // anyway.
         if (entry.Method.kind == SILDeclRef::Kind::Deallocator ||
             entry.Method.kind == SILDeclRef::Kind::IVarDestroyer) {
-          ensureAlive(entry.Implementation);
           continue;
         }
-
         SILFunction *F = entry.Implementation;
-        auto *fd = cast<AbstractFunctionDecl>(entry.Method.getDecl());
-        fd = getBase(fd);
-        MethodInfo *mi = getMethodInfo(fd);
-        addImplementingFunction(mi, F, vTable.getClass());
-
-        if (// A conservative approach: if any of the overridden functions is
-            // visible externally, we mark the whole method as alive.
-            isPossiblyUsedExternally(entry.Linkage, Module->isWholeModule())
-            // We also have to check the method declaration's accessibility.
-            // Needed if it's a public base method declared in another
-            // compilation unit (for this we have no SILFunction).
-            || isVisibleExternally(fd)
-            // Declarations are always accessible externally, so they are alive.
-            || !F->isDefinition()) {
-          ensureAlive(mi, nullptr, nullptr);
-        }
+        auto *fd = getBase(cast<AbstractFunctionDecl>(entry.Method.getDecl()));
+        MethodInfo *mi = getMethodInfo(fd, /*isWitnessTable*/ false);
+        mi->addClassMethodImpl(F, vTable.getClass());
       }
     }
 
-    // Check witness methods.
+    // Collect witness method implementations.
     for (SILWitnessTable &WT : Module->getWitnessTableList()) {
-      bool tableIsAlive = isVisibleExternally(WT.getConformance()->getProtocol());
+      ProtocolConformance *Conf = WT.getConformance();
       for (const SILWitnessTable::Entry &entry : WT.getEntries()) {
         if (entry.getKind() != SILWitnessTable::Method)
           continue;
@@ -338,14 +465,12 @@
         if (!F)
           continue;
 
-        MethodInfo *mi = getMethodInfo(fd);
-        addImplementingFunction(mi, F, nullptr);
-        if (tableIsAlive || !F->isDefinition())
-          ensureAlive(mi, nullptr, nullptr);
+        MethodInfo *mi = getMethodInfo(fd, /*isWitnessTable*/ true);
+        mi->addWitnessFunction(F, Conf);
       }
     }
 
-    // Check default witness methods.
+    // Collect default witness method implementations.
     for (SILDefaultWitnessTable &WT : Module->getDefaultWitnessTableList()) {
       for (const SILDefaultWitnessTable::Entry &entry : WT.getEntries()) {
         if (!entry.isValid())
@@ -353,10 +478,95 @@
 
         SILFunction *F = entry.getWitness();
         auto *fd = cast<AbstractFunctionDecl>(entry.getRequirement().getDecl());
+        MethodInfo *mi = getMethodInfo(fd, /*isWitnessTable*/ true);
+        mi->addWitnessFunction(F, nullptr);
+      }
+    }
+    
 
-        MethodInfo *mi = getMethodInfo(fd);
-        addImplementingFunction(mi, F, nullptr);
-        ensureAlive(mi, nullptr, nullptr);
+  }
+
+  /// DeadFunctionElimination pass takes functions
+  /// reachable via vtables and witness_tables into account
+  /// when computing a function liveness information.
+  void findAnchorsInTables() override {
+
+    collectMethodImplementations();
+
+    // Check vtable methods.
+    for (SILVTable &vTable : Module->getVTableList()) {
+      for (const SILVTable::Entry &entry : vTable.getEntries()) {
+        if (entry.Method.kind == SILDeclRef::Kind::Deallocator ||
+            entry.Method.kind == SILDeclRef::Kind::IVarDestroyer) {
+          // Destructors are alive because they are called from swift_release
+          ensureAlive(entry.Implementation);
+          continue;
+        }
+
+        SILFunction *F = entry.Implementation;
+        auto *fd = getBase(cast<AbstractFunctionDecl>(entry.Method.getDecl()));
+
+        if (// A conservative approach: if any of the overridden functions is
+            // visible externally, we mark the whole method as alive.
+            isPossiblyUsedExternally(entry.Linkage, Module->isWholeModule())
+            // We also have to check the method declaration's accessibility.
+            // Needed if it's a public base method declared in another
+            // compilation unit (for this we have no SILFunction).
+            || isVisibleExternally(fd)
+            // Declarations are always accessible externally, so they are alive.
+            || !F->isDefinition()) {
+          MethodInfo *mi = getMethodInfo(fd, /*isWitnessTable*/ false);
+          ensureAliveClassMethod(mi, nullptr, nullptr);
+        }
+      }
+    }
+
+    // Check witness table methods.
+    for (SILWitnessTable &WT : Module->getWitnessTableList()) {
+      ProtocolConformance *Conf = WT.getConformance();
+      if (isVisibleExternally(Conf->getProtocol())) {
+        // The witness table is visible from "outside". Therefore all methods
+        // might be called and we mark all methods as alive.
+        for (const SILWitnessTable::Entry &entry : WT.getEntries()) {
+          if (entry.getKind() != SILWitnessTable::Method)
+            continue;
+
+          auto methodWitness = entry.getMethodWitness();
+          auto *fd = cast<AbstractFunctionDecl>(methodWitness.Requirement.
+                                                getDecl());
+          assert(fd == getBase(fd) && "key in witness table is overridden");
+          SILFunction *F = methodWitness.Witness;
+          if (!F)
+            continue;
+
+          MethodInfo *mi = getMethodInfo(fd, /*isWitnessTable*/ true);
+          ensureAliveProtocolMethod(mi);
+        }
+      }
+
+      ProtocolConformance *C = WT.getConformance();
+      CanType ConformingTy = C->getType()->getCanonicalType();
+      if (ConformingTy.isAnyClassReferenceType()) {
+        // We are very conservative with class conformances. Even if a private/
+        // internal class is never instantiated, it might be created via
+        // reflection by using the stdlib's _getTypeByMangledName function.
+        makeAlive(&WT);
+      } else {
+        NominalTypeDecl *decl = ConformingTy.getNominalOrBoundGenericNominal();
+        assert(decl);
+        if (isVisibleExternally(decl))
+          makeAlive(&WT);
+      }
+    }
+    // Check default witness methods.
+    for (SILDefaultWitnessTable &WT : Module->getDefaultWitnessTableList()) {
+      for (const SILDefaultWitnessTable::Entry &entry : WT.getEntries()) {
+        if (!entry.isValid())
+          continue;
+
+        auto *fd = cast<AbstractFunctionDecl>(entry.getRequirement().getDecl());
+        MethodInfo *mi = getMethodInfo(fd, /*isWitnessTable*/ true);
+        ensureAliveProtocolMethod(mi);
       }
     }
   }
@@ -411,7 +621,19 @@
       }
     }
 
-    // Next step: delete all dead functions.
+    // Next step: delete dead witness tables.
+    SILModule::WitnessTableListType &WTables = Module->getWitnessTableList();
+    for (auto Iter = WTables.begin(), End = WTables.end(); Iter != End;) {
+      SILWitnessTable *Wt = &*Iter;
+      Iter++;
+      if (!isAlive(Wt)) {
+        DEBUG(llvm::dbgs() << "  erase dead witness table " << Wt->getName()
+                           << '\n');
+        Module->deleteWitnessTable(Wt);
+      }
+    }
+
+    // Last step: delete all dead functions.
     auto InvalidateEverything = SILAnalysis::InvalidationKind::Everything;
     while (!DeadFunctions.empty()) {
       SILFunction *F = DeadFunctions.back();
diff --git a/lib/SILOptimizer/IPO/EagerSpecializer.cpp b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
index 9563e80..258c33b 100644
--- a/lib/SILOptimizer/IPO/EagerSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
@@ -220,7 +220,9 @@
 /// Helper class for emitting code to dispatch to a specialized function.
 class EagerDispatch {
   SILFunction *GenericFunc;
+#if 0
   const SILSpecializeAttr &SA;
+#endif
   const ReabstractionInfo &ReInfo;
 
   SILBuilder Builder;
@@ -231,12 +233,11 @@
   // original generic function.
   EagerDispatch(SILFunction *GenericFunc, const SILSpecializeAttr &SA,
                 const ReabstractionInfo &ReInfo)
-    : GenericFunc(GenericFunc), SA(SA), ReInfo(ReInfo), Builder(*GenericFunc),
-      Loc(GenericFunc->getLocation()) {
-
+      : GenericFunc(GenericFunc), ReInfo(ReInfo), Builder(*GenericFunc),
+        Loc(GenericFunc->getLocation()) {
     Builder.setCurrentDebugScope(GenericFunc->getDebugScope());
   }
-  
+
   void emitDispatchTo(SILFunction *NewFunc);
 
 protected:
@@ -264,8 +265,12 @@
   // Iterate over all dependent types in the generic signature, which will match
   // the specialized attribute's substitution list. Visit only
   // SubstitutableTypes, skipping DependentTypes.
+  // TODO: Uncomment when Generics.cpp is updated to use the
+  // new @_specialize attribute for partial specializations.
+#if 0
   auto GenericSig =
     GenericFunc->getLoweredFunctionType()->getGenericSignature();
+
   auto SubIt = SA.getSubstitutions().begin();
   auto SubEnd = SA.getSubstitutions().end();
   for (auto DepTy : GenericSig->getAllDependentTypes()) {
@@ -277,7 +282,9 @@
   }
   assert(SubIt == SubEnd && "Too many substitutions.");
   (void) SubEnd;
-
+#else
+  static_cast<void>(FailedTypeCheckBB);
+#endif
   // 2. Convert call arguments, casting and adjusting for calling convention.
 
   SmallVector<SILValue, 8> CallArgs;
@@ -428,6 +435,9 @@
 };
 } // end anonymous namespace
 
+    // TODO: Uncomment when Generics.cpp is updated to use the
+    // new @_specialize attribute for partial specializations.
+#if 0
 /// Specializes a generic function for a concrete type list.
 static SILFunction *eagerSpecialize(SILFunction *GenericFunc,
                                     const SILSpecializeAttr &SA,
@@ -447,6 +457,9 @@
         SA.print(dbgs()); dbgs() << "\n");
   
   // Create a specialized function.
+  // TODO: Uncomment when Generics.cpp is updated to use the
+  // new @_specialize attribute for partial specializations.
+#if 0
   GenericFuncSpecializer
         FuncSpecializer(GenericFunc, SA.getSubstitutions(),
                         GenericFunc->isFragile(), ReInfo);
@@ -454,9 +467,12 @@
   SILFunction *NewFunc = FuncSpecializer.trySpecialization();
   if (!NewFunc)
     DEBUG(dbgs() << "  Failed. Cannot specialize function.\n");
-
   return NewFunc;
+#else
+  return nullptr;
+#endif
 }
+#endif
 
 /// Run the pass.
 void EagerSpecializerTransform::run() {
@@ -480,6 +496,9 @@
     SmallVector<ReabstractionInfo, 4> ReInfoVec;
     ReInfoVec.reserve(F.getSpecializeAttrs().size());
 
+    // TODO: Uncomment when Generics.cpp is updated to use the
+    // new @_specialize attribute for partial specializations.
+#if 0
     for (auto *SA : F.getSpecializeAttrs()) {
       ReInfoVec.emplace_back(&F, SA->getSubstitutions());
       auto *NewFunc = eagerSpecialize(&F, *SA, ReInfoVec.back());
@@ -495,6 +514,7 @@
         EagerDispatch(&F, *SA, ReInfo).emitDispatchTo(NewFunc);
       }
     });
+#endif
     // As specializations are created, the attributes should be removed.
     F.clearSpecializeAttrs();
   }
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
index 388644d..b622216 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
@@ -410,7 +410,7 @@
 
     /// How should address_to_pointer be handled?
     ///
-    /// In DefinitInitialization it is considered as an inout parameter to get
+    /// In DefiniteInitialization it is considered as an inout parameter to get
     /// diagnostics about passing a let variable to an inout mutable-pointer
     /// argument.
     /// In PredictableMemOpt it is considered as an escape point to be
diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp
index d8e19ba..97daa54 100644
--- a/lib/SILOptimizer/PassManager/PassManager.cpp
+++ b/lib/SILOptimizer/PassManager/PassManager.cpp
@@ -27,7 +27,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/GraphWriter.h"
 #include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/Chrono.h"
 
 using namespace swift;
 
@@ -321,7 +321,7 @@
     F->dump(getOptions().EmitVerboseSIL);
   }
 
-  llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now();
+  llvm::sys::TimePoint<> StartTime = std::chrono::system_clock::now();
   Mod->registerDeleteNotificationHandler(SFT);
   if (breakBeforeRunning(F->getName(), SFT->getName()))
     LLVM_BUILTIN_DEBUGTRAP;
@@ -330,8 +330,7 @@
   Mod->removeDeleteNotificationHandler(SFT);
 
   if (SILPrintPassTime) {
-    auto Delta =
-        llvm::sys::TimeValue::now().nanoseconds() - StartTime.nanoseconds();
+    auto Delta = (std::chrono::system_clock::now() - StartTime).count();
     llvm::dbgs() << Delta << " (" << SFT->getName() << "," << F->getName()
                  << ")\n";
   }
@@ -445,7 +444,7 @@
     printModule(Mod, Options.EmitVerboseSIL);
   }
 
-  llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now();
+  llvm::sys::TimePoint<> StartTime = std::chrono::system_clock::now();
   assert(analysesUnlocked() && "Expected all analyses to be unlocked!");
   Mod->registerDeleteNotificationHandler(SMT);
   SMT->run();
@@ -453,8 +452,7 @@
   assert(analysesUnlocked() && "Expected all analyses to be unlocked!");
 
   if (SILPrintPassTime) {
-    auto Delta = llvm::sys::TimeValue::now().nanoseconds() -
-      StartTime.nanoseconds();
+    auto Delta = (std::chrono::system_clock::now() - StartTime).count();
     llvm::dbgs() << Delta << " (" << SMT->getName() << ",Module)\n";
   }
 
@@ -758,7 +756,6 @@
   /// CallGraph GraphTraits specialization so the CallGraph can be
   /// iterable by generic graph iterators.
   template <> struct GraphTraits<CallGraph::Node *> {
-    typedef CallGraph::Node NodeType;
     typedef CallGraph::child_iterator ChildIteratorType;
     typedef CallGraph::Node *NodeRef;
 
@@ -778,11 +775,13 @@
 
     static NodeRef getEntryNode(GraphType F) { return nullptr; }
 
-    typedef CallGraph::iterator nodes_iterator;
+    typedef pointer_iterator<CallGraph::iterator> nodes_iterator;
     static nodes_iterator nodes_begin(GraphType CG) {
-      return CG->Nodes.begin();
+      return nodes_iterator(CG->Nodes.begin());
     }
-    static nodes_iterator nodes_end(GraphType CG) { return CG->Nodes.end(); }
+    static nodes_iterator nodes_end(GraphType CG) {
+      return nodes_iterator(CG->Nodes.end());
+    }
     static unsigned size(GraphType CG) { return CG->Nodes.size(); }
   };
 
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index dfcab64..e26f83d 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -714,7 +714,7 @@
   } else {
     SubstitutionMap Subs;
     Subs.addSubstitution(CanArchetypeType(OpenedArchetype), ConcreteType);
-    Subs.addConformances(CanType(OpenedArchetype), Conformance);
+    Subs.addConformance(CanType(OpenedArchetype), Conformance);
     NewSubstCalleeType = SubstCalleeType.subst(AI.getModule(), Subs);
   }
 
diff --git a/lib/SILOptimizer/Transforms/Devirtualizer.cpp b/lib/SILOptimizer/Transforms/Devirtualizer.cpp
index 60ff2e3..a652f5c 100644
--- a/lib/SILOptimizer/Transforms/Devirtualizer.cpp
+++ b/lib/SILOptimizer/Transforms/Devirtualizer.cpp
@@ -55,6 +55,7 @@
   llvm::SmallVector<SILInstruction *, 8> DeadApplies;
   llvm::SmallVector<ApplySite, 8> NewApplies;
 
+  SmallVector<FullApplySite, 16> Applies;
   for (auto &BB : F) {
     for (auto It = BB.begin(), End = BB.end(); It != End;) {
       auto &I = *It++;
@@ -64,20 +65,22 @@
       auto Apply = FullApplySite::isa(&I);
       if (!Apply)
         continue;
+      Applies.push_back(Apply);
+   }
+  }
+  for (auto Apply : Applies) {
+    auto NewInstPair = tryDevirtualizeApply(Apply, CHA);
+    if (!NewInstPair.second)
+      continue;
 
-      auto NewInstPair = tryDevirtualizeApply(Apply, CHA);
-      if (!NewInstPair.second)
-        continue;
+    Changed = true;
 
-      Changed = true;
+    auto *AI = Apply.getInstruction();
+    if (!isa<TryApplyInst>(AI))
+      AI->replaceAllUsesWith(NewInstPair.first);
 
-      auto *AI = Apply.getInstruction();
-      if (!isa<TryApplyInst>(AI))
-        AI->replaceAllUsesWith(NewInstPair.first);
-
-      DeadApplies.push_back(AI);
-      NewApplies.push_back(NewInstPair.second);
-    }
+    DeadApplies.push_back(AI);
+    NewApplies.push_back(NewInstPair.second);
   }
 
   // Remove all the now-dead applies.
diff --git a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
index 414bada..f8bddc8 100644
--- a/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
+++ b/lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
@@ -64,6 +64,8 @@
     EBI->eraseFromParent();
     return true;
   }
+  bool visitUnmanagedRetainValueInst(UnmanagedRetainValueInst *URVI);
+  bool visitUnmanagedReleaseValueInst(UnmanagedReleaseValueInst *URVI);
 };
 
 } // end anonymous namespace
@@ -147,6 +149,25 @@
   return true;
 }
 
+bool OwnershipModelEliminatorVisitor::visitUnmanagedRetainValueInst(
+    UnmanagedRetainValueInst *URVI) {
+  // Now that we have set the unqualified ownership flag, destroy value
+  // operation will delegate to the appropriate strong_release, etc.
+  B.emitCopyValueOperation(URVI->getLoc(), URVI->getOperand());
+  URVI->replaceAllUsesWith(URVI->getOperand());
+  URVI->eraseFromParent();
+  return true;
+}
+
+bool OwnershipModelEliminatorVisitor::visitUnmanagedReleaseValueInst(
+    UnmanagedReleaseValueInst *URVI) {
+  // Now that we have set the unqualified ownership flag, destroy value
+  // operation will delegate to the appropriate strong_release, etc.
+  B.emitDestroyValueOperation(URVI->getLoc(), URVI->getOperand());
+  URVI->eraseFromParent();
+  return true;
+}
+
 bool OwnershipModelEliminatorVisitor::visitDestroyValueInst(DestroyValueInst *DVI) {
   // Now that we have set the unqualified ownership flag, destroy value
   // operation will delegate to the appropriate strong_release, etc.
diff --git a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp
index 2cf1960..e0906d9 100644
--- a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp
+++ b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp
@@ -505,6 +505,15 @@
         break;
       }
     }
+
+    // Remove dead address instructions that may be uses of the allocation.
+    while (Inst->use_empty() && (isa<StructElementAddrInst>(Inst) ||
+                                 isa<TupleElementAddrInst>(Inst))) {
+      SILValue Next = Inst->getOperand(0);
+      Inst->eraseFromParent();
+      NumInstRemoved++;
+      Inst = cast<SILInstruction>(Next);
+    }
   }
 }
 
diff --git a/lib/SILOptimizer/Transforms/StackPromotion.cpp b/lib/SILOptimizer/Transforms/StackPromotion.cpp
index 78355d0..ed06f68 100644
--- a/lib/SILOptimizer/Transforms/StackPromotion.cpp
+++ b/lib/SILOptimizer/Transforms/StackPromotion.cpp
@@ -300,10 +300,6 @@
                          NonUnreachableBlockIter rhs) {
     return lhs.BaseIterator == rhs.BaseIterator;
   }
-  friend bool operator!=(NonUnreachableBlockIter lhs,
-                         NonUnreachableBlockIter rhs) {
-    return !(lhs == rhs);
-  }
 };
 } // end anonymous namespace
 
@@ -320,12 +316,14 @@
     return &SP->getFunction()->front();
   }
 
-  typedef NonUnreachableBlockIter nodes_iterator;
+  typedef pointer_iterator<NonUnreachableBlockIter> nodes_iterator;
   static nodes_iterator nodes_begin(GraphType SP) {
-    return nodes_iterator(SP->getFunction()->begin(), SP->getFunction()->end());
+    return nodes_iterator(NonUnreachableBlockIter(SP->getFunction()->begin(),
+                                                  SP->getFunction()->end()));
   }
   static nodes_iterator nodes_end(GraphType SP) {
-    return nodes_iterator(SP->getFunction()->end(), SP->getFunction()->end());
+    return nodes_iterator(NonUnreachableBlockIter(SP->getFunction()->end(),
+                                                  SP->getFunction()->end()));
   }
   static unsigned size(GraphType SP) {
     return std::distance(SP->getFunction()->begin(), SP->getFunction()->end());
diff --git a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
index 6b6a585..57e5252 100644
--- a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
+++ b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
@@ -54,8 +54,7 @@
                    "miscompile that is not a crasher"),
         clEnumValN(FailureKind::RuntimeCrasher, "runtime-crasher",
                    "Delete the target function call to cause a runtime "
-                   "miscompile that is not a crasher"),
-        clEnumValEnd),
+                   "miscompile that is not a crasher")),
     llvm::cl::init(FailureKind::None));
 
 
diff --git a/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp b/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp
index 52ec795..c221654 100644
--- a/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp
+++ b/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp
@@ -50,7 +50,7 @@
         clEnumValN(MLKind::OnlyReduction, "only-reduction", "only-reduction"),
         clEnumValN(MLKind::OnlyTypeExpansion, "only-type-expansion",
                    "only-type-expansion"),
-        clEnumValN(MLKind::All, "all", "all"), clEnumValEnd));
+        clEnumValN(MLKind::All, "all", "all")));
 
 static llvm::cl::opt<bool> UseProjection("lslocation-dump-use-new-projection",
                                             llvm::cl::init(false));
diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp
index 84f56ad..6924ed5 100644
--- a/lib/SILOptimizer/Utils/Devirtualize.cpp
+++ b/lib/SILOptimizer/Utils/Devirtualize.cpp
@@ -14,6 +14,7 @@
 #include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h"
 #include "swift/SILOptimizer/Utils/Devirtualize.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Types.h"
 #include "swift/SIL/SILDeclRef.h"
 #include "swift/SIL/SILFunction.h"
@@ -471,7 +472,9 @@
         subMap.addSubstitution(cast<SubstitutableType>(canTy),
                                sub.getReplacement());
       }
-      subMap.addConformances(canTy, sub.getConformances());
+
+      for (auto conformance : sub.getConformances())
+        subMap.addConformance(canTy, conformance);
     }
     assert(origSubs.empty());
   }
@@ -849,7 +852,8 @@
     auto gp = cast<GenericTypeParamType>(witnessThunkSig->getGenericParams()
                                                  .front()->getCanonicalType());
     subMap.addSubstitution(gp, origSubs.front().getReplacement());
-    subMap.addConformances(gp, origSubs.front().getConformances());
+    for (auto conformance : origSubs.front().getConformances())
+      subMap.addConformance(gp, conformance);
 
     // For default witnesses, innermost generic parameters are always at
     // depth 1.
@@ -916,7 +920,8 @@
         subMap.addSubstitution(cast<SubstitutableType>(canTy),
                                sub.getReplacement());
       }
-      subMap.addConformances(canTy, sub.getConformances());
+      for (auto conformance : sub.getConformances())
+        subMap.addConformance(canTy, conformance);
     }
     assert(subs.empty() && "Did not consume all substitutions");
   }
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index 2173bcb..e8987f2 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -227,6 +227,7 @@
     case ValueKind::StringLiteralInst:
     case ValueKind::FixLifetimeInst:
     case ValueKind::EndBorrowInst:
+    case ValueKind::EndBorrowArgumentInst:
     case ValueKind::BeginBorrowInst:
     case ValueKind::MarkDependenceInst:
     case ValueKind::FunctionRefInst:
@@ -326,6 +327,7 @@
     case ValueKind::CopyBlockInst:
     case ValueKind::CopyAddrInst:
     case ValueKind::RetainValueInst:
+    case ValueKind::UnmanagedRetainValueInst:
     case ValueKind::CopyValueInst:
     case ValueKind::CopyUnownedValueInst:
     case ValueKind::DeallocBoxInst:
@@ -340,6 +342,7 @@
     case ValueKind::ProjectBoxInst:
     case ValueKind::ProjectExistentialBoxInst:
     case ValueKind::ReleaseValueInst:
+    case ValueKind::UnmanagedReleaseValueInst:
     case ValueKind::DestroyValueInst:
     case ValueKind::AutoreleaseValueInst:
     case ValueKind::DynamicMethodBranchInst:
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index ba24bd1..93b11b5 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -78,14 +78,14 @@
 }
 
 Type Solution::computeSubstitutions(
-       Type origType, DeclContext *dc,
+       GenericSignature *sig,
        Type openedType,
        ConstraintLocator *locator,
        SmallVectorImpl<Substitution> &result) const {
   auto &tc = getConstraintSystem().getTypeChecker();
 
   // Produce the concrete form of the opened type.
-  Type type = simplifyType(tc, openedType);
+  Type type = simplifyType(openedType);
 
   // Gather the substitutions from dependent types to concrete types.
   auto openedTypes = OpenedTypes.find(locator);
@@ -97,13 +97,6 @@
       getFixedType(opened.second);
   }
 
-  GenericSignature *sig;
-  if (auto genericFn = origType->getAs<GenericFunctionType>()) {
-    sig = genericFn->getGenericSignature();
-  } else {
-    sig = dc->getGenericSignatureOfContext();
-  }
-
   auto lookupConformanceFn =
       [&](CanType original, Type replacement, ProtocolType *protoType)
           -> Optional<ProtocolConformanceRef> {
@@ -217,6 +210,11 @@
        member->getDeclContext()->getDeclaredInterfaceType()))
     return false;
 
+  // If the storage is resilient, we cannot access it directly at all.
+  if (!member->hasFixedLayout(DC->getParentModule(),
+                              DC->getResilienceExpansion()))
+    return false;
+
   return true;
 }
 
@@ -229,12 +227,6 @@
   // accessors.  However, in the init and destructor methods for the type
   // immediately containing the property, accesses are done direct.
   if (shouldAccessStorageDirectly(base, member, DC)) {
-    // The storage better not be resilient.
-    assert(member->hasFixedLayout(DC->getParentModule(),
-                                  DC->getResilienceExpansion()) &&
-           "Designated initializers and destructors of resilient types "
-           "cannot be @_transparent or defined in extensions");
-
     // Access this directly instead of going through (e.g.) observing or
     // trivial accessors.
     return AccessSemantics::DirectToStorage;
@@ -483,11 +475,9 @@
       // specialized reference to it.
       if (auto genericFn
             = decl->getInterfaceType()->getAs<GenericFunctionType>()) {
-        auto dc = decl->getInnermostDeclContext();
-
         SmallVector<Substitution, 4> substitutions;
         auto type = solution.computeSubstitutions(
-                      genericFn, dc, openedType,
+                      genericFn->getGenericSignature(), openedType,
                       getConstraintSystem().getConstraintLocator(locator),
                       substitutions);
         auto declRefExpr =
@@ -788,19 +778,14 @@
       // reference itself.
       ConcreteDeclRef memberRef;
       Type refTy;
-      if (member->getInterfaceType()->is<GenericFunctionType>() ||
-          openedFullType->hasTypeVariable()) {
+      if (auto *sig = member->getInnermostDeclContext()
+              ->getGenericSignatureOfContext()) {
         // We require substitutions. Figure out what they are.
 
-        // Figure out the declaration context where we'll get the generic
-        // parameters.
-        auto dc = member->getInnermostDeclContext();
-
         // Build a reference to the generic member.
         SmallVector<Substitution, 4> substitutions;
         refTy = solution.computeSubstitutions(
-                  member->getInterfaceType(),
-                  dc,
+                  sig,
                   openedFullType,
                   getConstraintSystem().getConstraintLocator(memberLocator),
                   substitutions);
@@ -830,7 +815,7 @@
       Type containerTy =
           openedFullType->castTo<FunctionType>()
               ->getInput()->getRValueInstanceType();
-      containerTy = solution.simplifyType(tc, containerTy);
+      containerTy = solution.simplifyType(containerTy);
 
       // If we opened up an existential when referencing this member, update
       // the base accordingly.
@@ -1130,7 +1115,7 @@
     /// \brief Simplify the given type by substituting all occurrences of
     /// type variables for their fixed types.
     Type simplifyType(Type type) {
-      return solution.simplifyType(cs.getTypeChecker(), type);
+      return solution.simplifyType(type);
     }
 
   public:
@@ -1316,14 +1301,12 @@
       }
 
       // Handle subscripting of generics.
-      if (subscript->getDeclContext()->isGenericContext()) {
-        auto dc = subscript->getDeclContext();
-
+      auto *dc = subscript->getInnermostDeclContext();
+      if (auto *sig = dc->getGenericSignatureOfContext()) {
         // Compute the substitutions used to reference the subscript.
         SmallVector<Substitution, 4> substitutions;
         solution.computeSubstitutions(
-          subscript->getInterfaceType(),
-          dc,
+          sig,
           selected->openedFullType,
           getConstraintSystem().getConstraintLocator(
             locator.withPathElement(ConstraintLocator::SubscriptMember)),
@@ -1332,7 +1315,7 @@
         // Convert the base.
         auto openedFullFnType = selected->openedFullType->castTo<FunctionType>();
         auto openedBaseType = openedFullFnType->getInput();
-        containerTy = solution.simplifyType(tc, openedBaseType);
+        containerTy = solution.simplifyType(openedBaseType);
         base = coerceObjectArgumentToType(
             base, containerTy, subscript, AccessSemantics::Ordinary,
             locator.withPathElement(ConstraintLocator::MemberRefBase));
@@ -1387,12 +1370,11 @@
       // Compute the concrete reference.
       ConcreteDeclRef ref;
       Type resultTy;
-      if (ctor->getInitializerInterfaceType()->is<GenericFunctionType>()) {
+      if (auto *sig = ctor->getGenericSignature()) {
         // Compute the reference to the generic constructor.
         SmallVector<Substitution, 4> substitutions;
         resultTy = solution.computeSubstitutions(
-                     ctor->getInterfaceType(),
-                     ctor,
+                     sig,
                      openedFullType,
                      getConstraintSystem().getConstraintLocator(locator),
                      substitutions);
@@ -2683,6 +2665,8 @@
       }
 
       Type argType = TupleType::get(typeElements, tc.Context);
+      assert(isa<TupleType>(argType.getPointer()));
+
       Expr *arg =
           TupleExpr::create(tc.Context, SourceLoc(),
                             expr->getElements(),
@@ -2760,6 +2744,8 @@
       }
 
       Type argType = TupleType::get(typeElements, tc.Context);
+      assert(isa<TupleType>(argType.getPointer()));
+
       Expr *arg =
             TupleExpr::create(tc.Context, expr->getLBracketLoc(),
                               expr->getElements(),
@@ -4074,12 +4060,11 @@
             },
             [&](ValueDecl *decl, Type openedType, ConstraintLocator *locator)
                   -> ConcreteDeclRef {
-              if (decl->getInnermostDeclContext()->isGenericContext()) {
+              if (auto *sig = decl->getInnermostDeclContext()
+                      ->getGenericSignatureOfContext()) {
                 SmallVector<Substitution, 4> subs;
                 computeSubstitutions(
-                  decl->getInterfaceType(),
-                  decl->getInnermostDeclContext(),
-                  openedType, locator, subs);
+                  sig, openedType, locator, subs);
                 return ConcreteDeclRef(cs.getASTContext(), decl, subs);
               }
               
@@ -4714,82 +4699,43 @@
   return cs.cacheType(new (ctx) ErasureExpr(expr, toType, conformances));
 }
 
-static unsigned getOptionalBindDepth(const BoundGenericType *bgt) {
-  
-  if (bgt->getDecl()->classifyAsOptionalType()) {
-    auto tyarg = bgt->getGenericArgs()[0];
-    
-    unsigned innerDepth = 0;
-    
-    if (auto wrappedBGT = tyarg->getAs<BoundGenericType>())
-      innerDepth = getOptionalBindDepth(wrappedBGT);
-
-    return 1 + innerDepth;
-  }
-  
-  return 0;
-}
-
-static Type getOptionalBaseType(Type type) {
-  
-  if (auto bgt = type->getAs<BoundGenericType>()) {
-    if (bgt->getDecl()->classifyAsOptionalType()) {
-      return getOptionalBaseType(bgt->getGenericArgs()[0]);
-    }
-  }
-  
-  return type;
-}
-
 Expr *ExprRewriter::coerceOptionalToOptional(Expr *expr, Type toType,
                                              ConstraintLocatorBuilder locator,
                                           Optional<Pattern*> typeFromPattern) {
   auto &tc = cs.getTypeChecker();
   Type fromType = cs.getType(expr);
   
-  auto fromGenericType = fromType->castTo<BoundGenericType>();
-  auto toGenericType = toType->castTo<BoundGenericType>();
-  assert(fromGenericType->getDecl()->classifyAsOptionalType());
-  assert(toGenericType->getDecl()->classifyAsOptionalType());
   tc.requireOptionalIntrinsics(expr->getLoc());
-  
-  Type fromValueType = fromGenericType->getGenericArgs()[0];
-  Type toValueType = toGenericType->getGenericArgs()[0];
 
-  
-  // If the option kinds are the same, and the wrapped types are the same,
-  // but the arities are different, we can peephole the optional-to-optional
-  // conversion into a series of nested injections.
-  auto toDepth = getOptionalBindDepth(toGenericType);
-  auto fromDepth = getOptionalBindDepth(fromGenericType);
-  
-  if (toDepth > fromDepth) {
-    
-    auto toBaseType = getOptionalBaseType(toGenericType);
-    auto fromBaseType = getOptionalBaseType(fromGenericType);
-    
-    if ((toGenericType->getDecl() == fromGenericType->getDecl()) &&
-        toBaseType->isEqual(fromBaseType)) {
-    
-      auto diff = toDepth - fromDepth;
-      auto isIUO = fromGenericType->getDecl()->
-                    classifyAsOptionalType() == OTK_ImplicitlyUnwrappedOptional;
-      
-      while (diff) {
-        const Type &t = cs.getType(expr);
-        const Type &wrapped = isIUO ?
-                                Type(ImplicitlyUnwrappedOptionalType::get(t)) :
-                                Type(OptionalType::get(t));
-        expr =
-          cs.cacheType(new (tc.Context) InjectIntoOptionalExpr(expr, wrapped));
-        diagnoseOptionalInjection(cast<InjectIntoOptionalExpr>(expr));
-        diff--;
-      }
-      
-      return expr;
+  SmallVector<Type, 4> fromOptionals;
+  (void)fromType->lookThroughAllAnyOptionalTypes(fromOptionals);
+
+  SmallVector<Type, 4> toOptionals;
+  (void)toType->lookThroughAllAnyOptionalTypes(toOptionals);
+
+  assert(!toOptionals.empty());
+  assert(!fromOptionals.empty());
+
+  // If we are adding optionals but the types are equivalent up to the common
+  // depth, peephole the optional-to-optional conversion into a series of nested
+  // injections.
+  auto toDepth = toOptionals.size();
+  auto fromDepth = fromOptionals.size();
+  if (toDepth > fromDepth &&
+      toOptionals[toOptionals.size() - fromDepth]->isEqual(fromType)) {
+    auto diff = toDepth - fromDepth;
+    while (diff--) {
+      Type type = toOptionals[diff];
+      expr = cs.cacheType(new (tc.Context) InjectIntoOptionalExpr(expr, type));
+      diagnoseOptionalInjection(cast<InjectIntoOptionalExpr>(expr));
     }
+
+    return expr;
   }
 
+  Type fromValueType = fromType->getAnyOptionalObjectType();
+  Type toValueType = toType->getAnyOptionalObjectType();
+
   expr =
     cs.cacheType(new (tc.Context) BindOptionalExpr(expr,
                                                    expr->getSourceRange().End,
@@ -5064,9 +5010,9 @@
     auto paramType = param.Ty;
     if (argType->isEqual(paramType)) {
       toSugarFields.push_back(
-          TupleTypeElt(argType, param.Label, param.parameterFlags));
+          TupleTypeElt(argType, getArgLabel(argIdx), param.parameterFlags));
       fromTupleExprFields[argIdx] =
-          TupleTypeElt(paramType, param.Label, param.parameterFlags);
+          TupleTypeElt(paramType, getArgLabel(argIdx), param.parameterFlags);
       fromTupleExpr[argIdx] = arg;
       continue;
     }
@@ -5123,6 +5069,8 @@
 
     // If anything about the TupleExpr changed, rebuild a new one.
     Type argTupleType = TupleType::get(fromTupleExprFields, tc.Context);
+    assert(isa<TupleType>(argTupleType.getPointer()));
+
     if (anyChanged || !cs.getType(argTuple)->isEqual(argTupleType)) {
       auto EltNames = argTuple->getElementNames();
       auto EltNameLocs = argTuple->getElementNameLocs();
@@ -6941,7 +6889,7 @@
 
   case FixKind::ForceOptional: {
     const Expr *unwrapped = affected->getValueProvidingExpr();
-    auto type = solution.simplifyType(TC, getType(affected))
+    auto type = solution.simplifyType(getType(affected))
                   ->getRValueObjectType();
 
     if (auto tryExpr = dyn_cast<OptionalTryExpr>(unwrapped)) {
@@ -6967,7 +6915,7 @@
   }
           
   case FixKind::OptionalChaining: {
-    auto type = solution.simplifyType(TC, getType(affected))
+    auto type = solution.simplifyType(getType(affected))
                 ->getRValueObjectType();
     auto diag = TC.diagnose(affected->getLoc(),
                             diag::missing_unwrap_optional, type);
@@ -6976,10 +6924,9 @@
   }
 
   case FixKind::ForceDowncast: {
-    auto fromType = solution.simplifyType(TC, getType(affected))
+    auto fromType = solution.simplifyType(getType(affected))
                       ->getRValueObjectType();
-    Type toType = solution.simplifyType(TC,
-                                        fix.first.getTypeArgument(*this));
+    Type toType = solution.simplifyType(fix.first.getTypeArgument(*this));
     bool useAs = TC.isExplicitlyConvertibleTo(fromType, toType, DC);
     bool useAsBang = !useAs && TC.checkedCastMaySucceed(fromType, toType,
                                                         DC);
@@ -7014,7 +6961,7 @@
   }
 
   case FixKind::AddressOf: {
-    auto type = solution.simplifyType(TC, getType(affected))
+    auto type = solution.simplifyType(getType(affected))
                   ->getRValueObjectType();
     TC.diagnose(affected->getLoc(), diag::missing_address_of, type)
       .fixItInsert(affected->getStartLoc(), "&");
@@ -7025,9 +6972,9 @@
     if (auto *coerceExpr = dyn_cast<CoerceExpr>(locator->getAnchor())) {
       Expr *subExpr = coerceExpr->getSubExpr();
       auto fromType =
-        solution.simplifyType(TC, getType(subExpr))->getRValueType();
+        solution.simplifyType(getType(subExpr))->getRValueType();
       auto toType =
-        solution.simplifyType(TC, coerceExpr->getCastTypeLoc().getType());
+        solution.simplifyType(coerceExpr->getCastTypeLoc().getType());
       auto castKind = TC.typeCheckCheckedCast(
                         fromType, toType, CheckedCastContextKind::None, DC,
                         coerceExpr->getLoc(), subExpr,
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 5edd414..e46a656 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Initializer.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeWalker.h"
 #include "swift/AST/TypeMatcher.h"
 #include "swift/Basic/Defer.h"
@@ -2430,6 +2431,12 @@
     }
   }
 
+  // If base type has unresolved generic parameters, such might mean
+  // that it's initializer with erroneous argument, otherwise this would
+  // be a simple ambiguous archetype case, neither can be diagnosed here.
+  if (baseTy->hasTypeParameter() && baseTy->hasUnresolvedType())
+    return false;
+
   MemberLookupResult result = CS->performMemberLookup(
       constraint->getKind(), memberName, baseTy,
       constraint->getFunctionRefKind(), constraint->getLocator(),
@@ -4727,13 +4734,23 @@
   // compiler would add implicit 'self.' prefix to the call of 'max'.
   ExprCleaner cleanup(argExpr);
 
-  // Let's type check argument expression without any contextual information.
-  ConcreteDeclRef ref = nullptr;
-  auto typeResult = TC.getTypeOfExpressionWithoutApplying(argExpr, CS->DC, ref);
-  if (!typeResult.hasValue())
-    return false;
+  auto argType = argExpr->getType();
+  // If argument wasn't properly type-checked, let's retry without changing AST.
+  if (!argType || argType->hasUnresolvedType() || argType->hasTypeVariable() ||
+      argType->hasTypeParameter()) {
+    // Let's type check argument expression without any contextual information.
+    ConcreteDeclRef ref = nullptr;
+    auto typeResult = TC.getTypeOfExpressionWithoutApplying(argExpr, CS->DC,
+                                                            ref);
+    if (!typeResult.hasValue())
+      return false;
 
-  auto argType = typeResult.getValue();
+    argType = typeResult.getValue();
+  }
+
+  auto typeKind = argType->getKind();
+  if (typeKind != TypeKind::Tuple && typeKind != TypeKind::Paren)
+    return false;
 
   // If argument type couldn't be properly resolved or has errors,
   // we can't diagnose anything in here, it points to the different problem.
@@ -5723,7 +5740,7 @@
       if (isUnresolvedOrTypeVarType(argType) || argType->hasError())
         return false;
 
-      // Record substituation from generic parameter to the argument type.
+      // Record substitution from generic parameter to the argument type.
       substitutions[env->mapTypeOutOfContext(archetype)
                         ->getCanonicalType()
                         ->castTo<SubstitutableType>()] = argType;
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 744096e..229ff13 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1784,6 +1784,42 @@
                               C.getIdentifier("Value")).front());
 
       auto locator = CS.getConstraintLocator(expr);
+      auto contextualType = CS.getContextualType(expr);
+      Type contextualDictionaryType = nullptr;
+      Type contextualDictionaryKeyType = nullptr;
+      Type contextualDictionaryValueType = nullptr;
+      
+      // If a contextual type exists for this expression, apply it directly.
+      Optional<std::pair<Type, Type>> dictionaryKeyValue;
+      if (contextualType &&
+          (dictionaryKeyValue = ConstraintSystem::isDictionaryType(contextualType))) {
+        // Is the contextual type a dictionary type?
+        contextualDictionaryType = contextualType;
+        std::tie(contextualDictionaryKeyType,
+                 contextualDictionaryValueType) = *dictionaryKeyValue;
+        
+        // Form an explicit tuple type from the contextual type's key and value types.
+        TupleTypeElt tupleElts[2] = { TupleTypeElt(contextualDictionaryKeyType),
+                                      TupleTypeElt(contextualDictionaryValueType) };
+        Type contextualDictionaryElementType = TupleType::get(tupleElts, C);
+        
+        CS.addConstraint(ConstraintKind::LiteralConformsTo, contextualType,
+                         dictionaryProto->getDeclaredType(),
+                         locator);
+        
+        unsigned index = 0;
+        for (auto element : expr->getElements()) {
+          CS.addConstraint(ConstraintKind::Conversion,
+                           element->getType(),
+                           contextualDictionaryElementType,
+                           CS.getConstraintLocator(expr,
+                                                   LocatorPathElt::
+                                                    getTupleElement(index++)));
+        }
+        
+        return contextualDictionaryType;
+      }
+      
       auto dictionaryTy = CS.createTypeVariable(locator,
                                                 TVO_PrefersSubtypeBinding);
 
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index d539ad2..7961a91 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1193,6 +1193,71 @@
   return false;
 }
 
+/// Determine whether this is an implicitly unwrapped optional type.
+static OptionalTypeKind classifyAsOptionalType(Type type) {
+  if (auto boundGeneric = type->getAs<BoundGenericType>())
+    return boundGeneric->getDecl()->classifyAsOptionalType();
+
+  return OTK_None;
+}
+
+/// Determine whether the first type with the given number of optionals
+/// is potentially more optional than the second type with its number of
+/// optionals.
+static bool isPotentiallyMoreOptionalThan(Type objType1,
+                                          unsigned numOptionals1,
+                                          Type objType2,
+                                          unsigned numOptionals2) {
+  if (numOptionals1 <= numOptionals2 && !objType1->isTypeVariableOrMember())
+    return false;
+
+  return true;
+}
+
+/// Enumerate all of the applicable optional conversion restrictions
+static void enumerateOptionalConversionRestrictions(
+                    Type type1, Type type2,
+                    ConstraintKind kind,
+                    llvm::function_ref<void(ConversionRestrictionKind)> fn) {
+  SmallVector<Type, 2> optionals1;
+  Type objType1 = type1->lookThroughAllAnyOptionalTypes(optionals1);
+
+  SmallVector<Type, 2> optionals2;
+  Type objType2 = type2->lookThroughAllAnyOptionalTypes(optionals2);
+
+  if (optionals1.empty() && optionals2.empty())
+    return;
+
+  // Optional-to-optional.
+  if (!optionals1.empty() && !optionals2.empty()) {
+    auto optionalKind1 = classifyAsOptionalType(optionals1.front());
+    auto optionalKind2 = classifyAsOptionalType(optionals2.front());
+
+    // Break cyclic conversions between T? and U! by only allowing it for
+    // conversion constraints.
+    if (kind >= ConstraintKind::Conversion ||
+        !(optionalKind1 == OTK_Optional &&
+          optionalKind2 == OTK_ImplicitlyUnwrappedOptional))
+      fn(ConversionRestrictionKind::OptionalToOptional);
+  }
+
+  // Inject a value into an optional.
+  if (isPotentiallyMoreOptionalThan(objType2, optionals2.size(),
+                                    objType1, optionals1.size())) {
+    fn(ConversionRestrictionKind::ValueToOptional);
+  }
+
+  // Unwrap an implicitly-unwrapped optional.
+  if (!optionals1.empty() &&
+      classifyAsOptionalType(optionals1.front())
+        == OTK_ImplicitlyUnwrappedOptional &&
+      kind >= ConstraintKind::Conversion &&
+      isPotentiallyMoreOptionalThan(objType1, optionals1.size(),
+                                    objType2, optionals2.size())) {
+    fn(ConversionRestrictionKind::ForceUnchecked);
+  }
+}
+
 ConstraintSystem::SolutionKind
 ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
                              TypeMatchOptions flags,
@@ -1413,7 +1478,7 @@
       // Subtype constraints are subject for edge contraction,
       // which is inappropriate in this case, because it's going to
       // erase/lose 'inout' modifier after merging equivalence classes
-      // (if inout containts type var, see ConstraintGraph::contractEdges()),
+      // (if inout constraints type var, see ConstraintGraph::contractEdges()),
       // since right-hand side type variable must not be materializable
       // it can simply get left-hand side as a fixed binding, otherwise fail.
       if (type1->is<InOutType>() &&
@@ -1425,7 +1490,7 @@
         if (typeVar2->getImpl().mustBeMaterializable())
           return SolutionKind::Error;
 
-        // Constriants like `inout T0 subtype T1` where (T0 must be
+        // Constraints like `inout T0 subtype T1` where (T0 must be
         // materializable) are created when closures are part of the generic
         // function parameters e.g. `func foo<T>(_ t: T, (inout T) -> Void) {}`
         // so when such function gets called e.g.
@@ -1985,57 +2050,17 @@
     }
   }
 
-  // A value of type T can be converted to type U? if T is convertible to U.
-  // A value of type T? can be converted to type U? if T is convertible to U.
-  // The above conversions also apply to implicitly unwrapped optional types,
-  // except that there is no implicit conversion from T? to T!.
-  {
-    BoundGenericType *boundGenericType2;
-    
-    if (concrete && kind >= ConstraintKind::Subtype &&
-        (boundGenericType2 = type2->getAs<BoundGenericType>())) {
-      auto decl2 = boundGenericType2->getDecl();
-      if (auto optionalKind2 = decl2->classifyAsOptionalType()) {
-        assert(boundGenericType2->getGenericArgs().size() == 1);
-        
-        BoundGenericType *boundGenericType1 = type1->getAs<BoundGenericType>();
-        if (boundGenericType1) {
-          auto decl1 = boundGenericType1->getDecl();
-          if (decl1 == decl2) {
-            assert(boundGenericType1->getGenericArgs().size() == 1);
-            conversionsOrFixes.push_back(
-                                ConversionRestrictionKind::OptionalToOptional);
-          } else if (optionalKind2 == OTK_Optional &&
-                     decl1 == TC.Context.getImplicitlyUnwrappedOptionalDecl()) {
-            assert(boundGenericType1->getGenericArgs().size() == 1);
-            conversionsOrFixes.push_back(
-                       ConversionRestrictionKind::OptionalToOptional);
-          } else if (optionalKind2 == OTK_ImplicitlyUnwrappedOptional &&
-                     kind >= ConstraintKind::Conversion &&
-                     decl1 == TC.Context.getOptionalDecl()) {
-            assert(boundGenericType1->getGenericArgs().size() == 1);
-            conversionsOrFixes.push_back(
-                       ConversionRestrictionKind::OptionalToOptional);
-          }
-        }
-        
-        conversionsOrFixes.push_back(
-            ConversionRestrictionKind::ValueToOptional);
-      }
-    }
+  // A value of type T! can be converted to type U if T is convertible
+  // to U by force-unwrapping the source value.
+  // A value of type T, T?, or T! can be converted to type U? or U! if
+  // T is convertible to U.
+  if (concrete && kind >= ConstraintKind::Subtype) {
+    enumerateOptionalConversionRestrictions(type1, type2, kind,
+      [&](ConversionRestrictionKind restriction) {
+        conversionsOrFixes.push_back(restriction);
+    });
   }
 
-  // A value of type T! can be (unsafely) forced to U if T
-  // is convertible to U.
-  {
-    Type objectType1;
-    if (concrete && kind >= ConstraintKind::Conversion &&
-        (objectType1 = lookThroughImplicitlyUnwrappedOptionalType(type1))) {
-      conversionsOrFixes.push_back(
-                          ConversionRestrictionKind::ForceUnchecked);
-    }
-  }
-  
   // Allow '() -> T' to '() -> ()' and '() -> Never' to '() -> T' for closure
   // literals.
   if (auto elt = locator.last()) {
@@ -3743,7 +3768,21 @@
       increaseScore(SK_FunctionConversion);
     }
   };
-  
+
+  // Local function to form an unsolved result.
+  auto formUnsolved = [&] {
+    if (flags.contains(TMF_GenerateConstraints)) {
+      addUnsolvedConstraint(
+        Constraint::createRestricted(
+          *this, matchKind, restriction, type1, type2,
+          getConstraintLocator(locator)));
+
+      return SolutionKind::Solved;
+    }
+    
+    return SolutionKind::Unsolved;
+  };
+
   // We'll apply user conversions for operator arguments at the application
   // site.
   if (matchKind == ConstraintKind::OperatorArgumentConversion) {
@@ -3806,10 +3845,18 @@
     increaseScore(SK_ValueToOptional);
 
     assert(matchKind >= ConstraintKind::Subtype);
-    auto generic2 = type2->castTo<BoundGenericType>();
-    assert(generic2->getDecl()->classifyAsOptionalType());
-    return matchTypes(type1, generic2->getGenericArgs()[0],
-                      matchKind, (subflags | TMF_UnwrappingOptional), locator);
+    if (type2->isTypeVariableOrMember())
+      return formUnsolved();
+
+    if (auto generic2 = type2->getAs<BoundGenericType>()) {
+      if (generic2->getDecl()->classifyAsOptionalType()) {
+        return matchTypes(type1, generic2->getGenericArgs()[0],
+                          matchKind, (subflags | TMF_UnwrappingOptional),
+                          locator);
+      }
+    }
+
+    return SolutionKind::Error;
   }
 
   // for $< in { <, <c, <oc }:
@@ -3820,16 +3867,24 @@
   //   T <c U ===> T? <c U!
   case ConversionRestrictionKind::OptionalToOptional: {
     addContextualScore();
+
+    if (type1->isTypeVariableOrMember() || type2->isTypeVariableOrMember())
+      return formUnsolved();
+
     assert(matchKind >= ConstraintKind::Subtype);
-    auto generic1 = type1->castTo<BoundGenericType>();
-    auto generic2 = type2->castTo<BoundGenericType>();
-    assert(generic1->getDecl()->classifyAsOptionalType());
-    assert(generic2->getDecl()->classifyAsOptionalType());
-    return matchTypes(generic1->getGenericArgs()[0],
-                      generic2->getGenericArgs()[0],
-                      matchKind, subflags,
-                      locator.withPathElement(
-                        LocatorPathElt::getGenericArgument(0)));
+    if (auto generic1 = type1->getAs<BoundGenericType>()) {
+      if (auto generic2 = type2->getAs<BoundGenericType>()) {
+        if (generic1->getDecl()->classifyAsOptionalType() &&
+            generic2->getDecl()->classifyAsOptionalType())
+          return matchTypes(generic1->getGenericArgs()[0],
+                            generic2->getGenericArgs()[0],
+                            matchKind, subflags,
+                            locator.withPathElement(
+                              LocatorPathElt::getGenericArgument(0)));
+      }
+    }
+
+    return SolutionKind::Error;
   }
 
   // T <c U ===> T! <c U
@@ -3843,16 +3898,24 @@
   case ConversionRestrictionKind::ForceUnchecked: {
     addContextualScore();
     assert(matchKind >= ConstraintKind::Conversion);
-    auto boundGenericType1 = type1->castTo<BoundGenericType>();
-    assert(boundGenericType1->getDecl()->classifyAsOptionalType()
-             == OTK_ImplicitlyUnwrappedOptional);
-    assert(boundGenericType1->getGenericArgs().size() == 1);
-    Type valueType1 = boundGenericType1->getGenericArgs()[0];
-    increaseScore(SK_ForceUnchecked);
-    return matchTypes(valueType1, type2,
-                      matchKind, subflags,
-                      locator.withPathElement(
-                        LocatorPathElt::getGenericArgument(0)));
+
+    if (type1->isTypeVariableOrMember())
+      return formUnsolved();
+
+    if (auto boundGenericType1 = type1->getAs<BoundGenericType>()) {
+      if (boundGenericType1->getDecl()->classifyAsOptionalType()
+            == OTK_ImplicitlyUnwrappedOptional) {
+        assert(boundGenericType1->getGenericArgs().size() == 1);
+        Type valueType1 = boundGenericType1->getGenericArgs()[0];
+        increaseScore(SK_ForceUnchecked);
+        return matchTypes(valueType1, type2,
+                          matchKind, subflags,
+                          locator.withPathElement(
+                            LocatorPathElt::getGenericArgument(0)));
+      }
+    }
+
+    return SolutionKind::Error;
   }
       
   case ConversionRestrictionKind::ClassMetatypeToAnyObject:
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index bdd20c6..05c178c 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1451,7 +1451,7 @@
 bool ConstraintSystem::Candidate::solve() {
   // Don't attempt to solve candidate if there is closure
   // expression involved, because it's handled specially
-  // by parent constaint system (e.g. parameter lists).
+  // by parent constraint system (e.g. parameter lists).
   bool containsClosure = false;
   E->forEachChildExpr([&](Expr *childExpr) -> Expr * {
     if (isa<ClosureExpr>(childExpr)) {
@@ -1616,7 +1616,7 @@
       }
 
       // Let's not attempt to type-check closures or expressions
-      // which containt closures, because they require special handling
+      // which constrain closures, because they require special handling
       // when dealing with context and parameters declarations.
       if (isa<ClosureExpr>(expr)) {
         return {false, expr};
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index b65bdf0..53f5f0e 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -196,8 +196,6 @@
 }
 
 LookupResult &ConstraintSystem::lookupMember(Type base, DeclName name) {
-  base = base->getCanonicalType();
-
   // Check whether we've already performed this lookup.
   auto knownMember = MemberLookups.find({base, name});
   if (knownMember != MemberLookups.end())
@@ -1547,23 +1545,17 @@
   return Type();
 }
 
-Type ConstraintSystem::simplifyType(Type type) {
+template <typename Fn>
+Type simplifyTypeImpl(ConstraintSystem &cs, Type type, Fn getFixedTypeFn) {
   return type.transform([&](Type type) -> Type {
-    if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer())) {
-      tvt = getRepresentative(tvt);
-      if (auto fixed = getFixedType(tvt)) {
-        return simplifyType(fixed);
-      }
-      
-      return tvt;
-    }
+    if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer()))
+      return getFixedTypeFn(tvt);
 
     // If this is a dependent member type for which we end up simplifying
     // the base to a non-type-variable, perform lookup.
     if (auto depMemTy = dyn_cast<DependentMemberType>(type.getPointer())) {
       // Simplify the base.
-      Type newBase = simplifyType(depMemTy->getBase());
-      if (!newBase) return type;
+      Type newBase = simplifyTypeImpl(cs, depMemTy->getBase(), getFixedTypeFn);
 
       // If nothing changed, we're done.
       if (newBase.getPointer() == depMemTy->getBase().getPointer())
@@ -1571,16 +1563,6 @@
 
       Type lookupBaseType = newBase->getLValueOrInOutObjectType();
 
-      // If the new base is still something we can't handle, just build a
-      // new dependent member type.
-      if (lookupBaseType->is<TypeVariableType>() ||
-          lookupBaseType->is<UnresolvedType>()) {
-        if (auto assocType = depMemTy->getAssocType())
-          return DependentMemberType::get(newBase, assocType);
-        else
-          return DependentMemberType::get(newBase, assocType);
-      }
-
       // Dependent member types should only be created for associated types.
       auto assocType = depMemTy->getAssocType();
       assert(depMemTy->getAssocType());
@@ -1588,7 +1570,7 @@
       if (!lookupBaseType->mayHaveMembers()) return type;
 
       auto result = assocType->getDeclaredInterfaceType()
-          .subst(DC->getParentModule(),
+          .subst(cs.DC->getParentModule(),
                  lookupBaseType->getContextSubstitutions(
                     assocType->getDeclContext()));
 
@@ -1601,78 +1583,45 @@
     // If this is a FunctionType and we inferred new function attributes, apply
     // them.
     if (auto ft = dyn_cast<FunctionType>(type.getPointer())) {
-      auto it = extraFunctionAttrs.find(ft);
-      if (it != extraFunctionAttrs.end()) {
+      auto it = cs.extraFunctionAttrs.find(ft);
+      if (it != cs.extraFunctionAttrs.end()) {
         auto extInfo = ft->getExtInfo();
         if (it->second.isNoEscape())
           extInfo = extInfo.withNoEscape();
         if (it->second.throws())
           extInfo = extInfo.withThrows();
-        return FunctionType::get(ft->getInput(), ft->getResult(), extInfo);
+        return FunctionType::get(
+            simplifyTypeImpl(cs, ft->getInput(), getFixedTypeFn),
+            simplifyTypeImpl(cs, ft->getResult(), getFixedTypeFn),
+            extInfo);
       }
     }
     
-
     return type;
   });
 }
 
-Type Solution::simplifyType(TypeChecker &tc, Type type) const {
-  // FIXME: Nearly identical to ConstraintSystem::simplifyType().
-  return type.transform([&](Type type) -> Type {
-    if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer())) {
-      auto known = typeBindings.find(tvt);
-      assert(known != typeBindings.end());
-      return known->second;
-    }
+Type ConstraintSystem::simplifyType(Type type) {
+  // Map type variables down to the fixed types of their representatives.
+  return simplifyTypeImpl(
+      *this, type,
+      [&](TypeVariableType *tvt) -> Type {
+        tvt = getRepresentative(tvt);
+        if (auto fixed = getFixedType(tvt)) {
+          return simplifyType(fixed);
+        }
 
-    // If this is a dependent member type for which we end up simplifying
-    // the base to a non-type-variable, perform lookup.
-    if (auto depMemTy = dyn_cast<DependentMemberType>(type.getPointer())) {
-      // Simplify the base.
-      Type newBase = simplifyType(tc, depMemTy->getBase());
-      if (!newBase) return type;
+        return tvt;
+      });
+}
 
-      // If nothing changed, we're done.
-      if (newBase.getPointer() == depMemTy->getBase().getPointer())
-        return type;
-
-      Type lookupBaseType = newBase;
-
-      // Look through an inout type.
-      if (auto inout = lookupBaseType->getAs<InOutType>())
-        lookupBaseType = inout->getObjectType();
-
-      // Look through a metatype.
-      if (auto metatype = lookupBaseType->getAs<AnyMetatypeType>())
-        lookupBaseType = metatype->getInstanceType();
-
-      // Dependent member types should only be created for associated types.
-      auto assocType = depMemTy->getAssocType();
-      assert(depMemTy->getAssocType());
-
-      return lookupBaseType->getTypeOfMember(
-               getConstraintSystem().DC->getParentModule(), assocType, &tc,
-               assocType->getDeclaredInterfaceType());
-    }
-
-    // If this is a FunctionType and we inferred new function attributes, apply
-    // them.
-    if (auto ft = dyn_cast<FunctionType>(type.getPointer())) {
-      auto &CS = getConstraintSystem();
-      auto it = CS.extraFunctionAttrs.find(ft);
-      if (it != CS.extraFunctionAttrs.end()) {
-        auto extInfo = ft->getExtInfo();
-        if (it->second.isNoEscape())
-          extInfo = extInfo.withNoEscape();
-        if (it->second.throws())
-          extInfo = extInfo.withThrows();
-        return FunctionType::get(simplifyType(tc, ft->getInput()),
-                                 simplifyType(tc, ft->getResult()),
-                                 extInfo);
-      }
-    }
-
-    return type;
-  });
+Type Solution::simplifyType(Type type) const {
+  // Map type variables to fixed types from bindings.
+  return simplifyTypeImpl(
+      getConstraintSystem(), type,
+      [&](TypeVariableType *tvt) -> Type {
+        auto known = typeBindings.find(tvt);
+        assert(known != typeBindings.end());
+        return known->second;
+      });
 }
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index eb447dc..57f7ef0 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -29,6 +29,7 @@
 #include "swift/AST/ASTVisitor.h"
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Types.h"
 #include "swift/AST/TypeCheckerDebugConsumer.h"
 #include "llvm/ADT/ilist.h"
@@ -552,7 +553,7 @@
 
   /// \brief Simplify the given type by substituting all occurrences of
   /// type variables for their fixed types.
-  Type simplifyType(TypeChecker &tc, Type type) const;
+  Type simplifyType(Type type) const;
 
   /// \brief Coerce the given expression to the given type.
   ///
@@ -609,18 +610,11 @@
   /// Compute the set of substitutions required to map the given type
   /// to the provided "opened" type.
   ///
-  /// Either the generic type (\c origType) must be a \c GenericFunctionType,
-  /// in which case it's generic requirements will be used to compute the
-  /// required substitutions, or \c dc must be a generic context, in which
-  /// case it's generic requirements will be used.
-  ///
-  /// \param origType The generic type.
+  /// \param sig The generic signature.
   ///
   /// \param openedType The type to which this reference to the given
   /// generic function type was opened.
   ///
-  /// \param dc The declaration context that owns the generic type
-  ///
   /// \param locator The locator that describes where the substitutions came
   /// from.
   ///
@@ -628,8 +622,7 @@
   /// to be applied to the generic function type.
   ///
   /// \returns The opened type after applying the computed substitutions.
-  Type computeSubstitutions(Type origType,
-                            DeclContext *dc,
+  Type computeSubstitutions(GenericSignature *sig,
                             Type openedType,
                             ConstraintLocator *locator,
                             SmallVectorImpl<Substitution> &substitutions) const;
@@ -873,11 +866,11 @@
   unsigned TypeCounter = 0;
 
   /// \brief The number of scopes created so far during the solution
-  /// of this constriant system.
+  /// of this constraint system.
   ///
   /// This is a measure of complexity of the solution space. A new
   /// scope is created every time we attempt a type variable binding
-  /// or explore an option in a disjuction.
+  /// or explore an option in a disjunction.
   unsigned CountScopes = 0;
 
   /// \brief Cached member lookups.
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index 958d9b7..393f8b4 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -249,7 +249,12 @@
         checkOptionalPromotions(Call);
         
         // Check for tuple splat.
-        checkTupleSplat(Call);
+        //
+        // Note that in Swift 4 mode, this is rejected much earlier in
+        // the constraint solver; this check only exists to preserve the
+        // behavior of the earlier, incomplete implementation of SE-0110.
+        if (TC.Context.isSwiftVersion3())
+          checkTupleSplat(Call);
 
         // Check the callee, looking through implicit conversions.
         auto Base = Call->getFn();
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index 495ef53..d0bcc3b 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -79,6 +79,9 @@
   auto expansion = DC->getResilienceExpansion();
   if (expansion == ResilienceExpansion::Minimal) {
     if (!isa<GenericTypeParamDecl>(D) &&
+        // Protocol requirements are not versioned because there's no
+        // global entry point
+        !(isa<ProtocolDecl>(D->getDeclContext()) && isRequirement(D)) &&
         // FIXME: Figure out what to do with typealiases
         !isa<TypeAliasDecl>(D) &&
         !D->getDeclContext()->isLocalContext() &&
@@ -96,3 +99,33 @@
 
   return false;
 }
+
+void TypeChecker::diagnoseResilientValueConstructor(ConstructorDecl *ctor) {
+  auto nominalDecl = ctor->getDeclContext()
+    ->getAsNominalTypeOrNominalTypeExtensionContext();
+
+  bool isDelegating =
+      (ctor->getDelegatingOrChainedInitKind(&Diags) ==
+       ConstructorDecl::BodyInitKind::Delegating);
+
+  if (!isDelegating &&
+      !nominalDecl->hasFixedLayout(ctor->getParentModule(),
+                                   ctor->getResilienceExpansion())) {
+    if (ctor->getResilienceExpansion() == ResilienceExpansion::Minimal) {
+      // An @_inlineable designated initializer defined in a resilient type
+      // cannot initialize stored properties directly, and must chain to
+      // another initializer.
+      diagnose(ctor->getLoc(),
+               diag::designated_init_inlineable_resilient,
+               ctor->getDeclContext()->getDeclaredInterfaceType(),
+               getFragileFunctionKind(ctor));
+    } else {
+      // A designated initializer defined on an extension of a resilient
+      // type from a different resilience domain cannot initialize stored
+      // properties directly, and must chain to another initializer.
+      diagnose(ctor->getLoc(),
+               diag::designated_init_in_extension_resilient,
+               ctor->getDeclContext()->getDeclaredInterfaceType());
+    }
+  }
+}
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index c2a30cc..183c005 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -16,11 +16,14 @@
 
 #include "TypeChecker.h"
 #include "MiscDiagnostics.h"
+#include "swift/AST/ArchetypeBuilder.h"
 #include "swift/AST/ASTVisitor.h"
+#include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/Types.h"
 #include "swift/Parse/Lexer.h"
 #include "swift/ClangImporter/ClangModule.h" // FIXME: SDK overlay semantics
+#include "llvm/Support/Debug.h"
 
 using namespace swift;
 
@@ -694,7 +697,6 @@
     IGNORED_ATTR(Dynamic)
     IGNORED_ATTR(Effects)
     IGNORED_ATTR(Exported)
-    IGNORED_ATTR(FixedLayout)
     IGNORED_ATTR(GKInspectable)
     IGNORED_ATTR(IBDesignable)
     IGNORED_ATTR(IBInspectable)
@@ -761,6 +763,7 @@
 
   void visitSpecializeAttr(SpecializeAttr *attr);
 
+  void visitFixedLayoutAttr(FixedLayoutAttr *attr);
   void visitVersionedAttr(VersionedAttr *attr);
   
   void visitDiscardableResultAttr(DiscardableResultAttr *attr);
@@ -1398,136 +1401,401 @@
   }
 }
 
-/// Check that the @_specialize type list has the correct number of entries.
-/// Resolve each type in the list to a concrete type.
-/// Create a Substitution list mapping each nested archetype to a concrete
-/// type, and resolve conformances for each generic parameter requirement.
-/// Store the Substitution list in a ConcreteDeclRef attached to the attribute.
+/// Collect all used generic parameter types from a given type.
+static void collectUsedGenericParameters(
+    Type Ty, SmallPtrSet<TypeBase *, 4> &ConstrainedGenericParams) {
+  if (!Ty)
+    return;
+
+  if (!Ty->hasTypeParameter())
+    return;
+
+  // Add used generic parameters/archetypes.
+  Ty.visit([&](Type Ty) {
+    if (auto GP = dyn_cast<GenericTypeParamType>(Ty->getCanonicalType())) {
+      ConstrainedGenericParams.insert(GP);
+    }
+  });
+}
+
+/// Perform some sanity checks for the requirements provided by
+/// the @_specialize attribute.
+static void checkSpecializeAttrRequirements(
+    SpecializeAttr *attr,
+    AbstractFunctionDecl *FD,
+    ArrayRef<RequirementRepr> requirements,
+    SmallPtrSet<TypeBase *, 4> constrainedGenericParams,
+    TypeChecker &TC) {
+  auto genericSig = FD->getGenericSignature();
+  bool isInvalidAttr = false;
+
+  // Check that requirements are defined only on
+  // generic parameter types and not on their associated or dependent types or
+  // other generic types using these parameters.
+  for (auto &req : requirements) {
+    if (req.getKind() == RequirementReprKind::SameType) {
+      auto firstType = req.getFirstType();
+      auto secondType = req.getSecondType();
+
+      if (!firstType || firstType->is<ErrorType>() ||
+          firstType->hasArchetype()) {
+        isInvalidAttr = true;
+        continue;
+      }
+
+      if (!secondType || secondType->is<ErrorType>() ||
+          secondType->hasArchetype()) {
+        isInvalidAttr = true;
+        continue;
+      }
+
+      collectUsedGenericParameters(firstType, constrainedGenericParams);
+      collectUsedGenericParameters(secondType, constrainedGenericParams);
+
+      // One of the types should be concrete and the other one should not.
+      bool isFirstTypeNonConcrete = firstType->hasTypeParameter();
+      bool isSecondTypeNonConcrete = secondType->hasTypeParameter();
+
+      if (isFirstTypeNonConcrete && isSecondTypeNonConcrete) {
+        TC.diagnose(attr->getLocation(),
+                    diag::specialize_attr_non_concrete_same_type_req)
+            .highlight(req.getSourceRange());
+        continue;
+      }
+      if (!(isFirstTypeNonConcrete ^ isSecondTypeNonConcrete)) {
+        TC.diagnose(attr->getLocation(),
+                    diag::specialize_attr_only_one_concrete_same_type_req)
+            .highlight(req.getSourceRange());
+        continue;
+      }
+      if (isFirstTypeNonConcrete) {
+        if (!isa<GenericTypeParamType>(firstType->getCanonicalType())) {
+          TC.diagnose(attr->getLocation(),
+                      diag::specialize_attr_only_generic_param_req)
+              .highlight(req.getFirstTypeRepr()->getSourceRange());
+        }
+      }
+      if (isSecondTypeNonConcrete) {
+        if (!isa<GenericTypeParamType>(secondType->getCanonicalType())) {
+          TC.diagnose(attr->getLocation(),
+                      diag::specialize_attr_only_generic_param_req)
+              .highlight(req.getSecondTypeRepr()->getSourceRange());
+        }
+      }
+      continue;
+    }
+
+    if (req.getKind() == RequirementReprKind::LayoutConstraint ||
+        req.getKind() == RequirementReprKind::TypeConstraint) {
+      auto subjectType = req.getSubject();
+
+      // Skip any unknown or error types.
+      if (!subjectType || subjectType->is<ErrorType>() ||
+          subjectType->hasArchetype()) {
+        isInvalidAttr = true;
+        continue;
+      }
+
+      if (req.getKind() == RequirementReprKind::TypeConstraint) {
+        auto constraint = req.getConstraint();
+
+        if (!constraint || constraint->hasError() ||
+            constraint->hasArchetype()) {
+          isInvalidAttr = true;
+          continue;
+        }
+
+        auto nominalTy = constraint->getNominalOrBoundGenericNominal();
+        if (!nominalTy) {
+          TC.diagnose(attr->getLocation(),
+                      diag::specialize_attr_non_nominal_type_constraint_req)
+              .highlight(req.getSourceRange());
+          continue;
+        }
+
+        auto proto = dyn_cast<ProtocolDecl>(nominalTy);
+        if (!proto) {
+          TC.diagnose(attr->getLocation(),
+                      diag::specialize_attr_non_protocol_type_constraint_req)
+              .highlight(req.getSourceRange());
+        }
+      }
+
+      bool isSubjectNonConcrete = subjectType->hasTypeParameter();
+
+      if (isSubjectNonConcrete) {
+        collectUsedGenericParameters(subjectType, constrainedGenericParams);
+        if (!isa<GenericTypeParamType>(subjectType->getCanonicalType())) {
+          TC.diagnose(attr->getLocation(),
+                      diag::specialize_attr_only_generic_param_req)
+              .highlight(req.getSubjectRepr()->getSourceRange());
+        }
+      }
+
+      if (req.getKind() == RequirementReprKind::TypeConstraint) {
+        TC.diagnose(attr->getLocation(),
+                    diag::specialize_attr_unsupported_kind_of_req)
+            .highlight(req.getSourceRange());
+      }
+      continue;
+    }
+
+    TC.diagnose(attr->getLocation(),
+                diag::specialize_attr_unsupported_kind_of_req)
+        .highlight(req.getSourceRange());
+  }
+
+  if (isInvalidAttr) {
+    attr->setInvalid();
+  }
+
+  if (!attr->isFullSpecialization())
+    return;
+
+  if (constrainedGenericParams.size() == genericSig->getGenericParams().size())
+    return;
+
+  TC.diagnose(
+      attr->getLocation(), diag::specialize_attr_type_parameter_count_mismatch,
+      genericSig->getGenericParams().size(), constrainedGenericParams.size(),
+      constrainedGenericParams.size() < genericSig->getGenericParams().size());
+
+  if (constrainedGenericParams.size() < genericSig->getGenericParams().size()) {
+    // Figure out which archetypes are not constrained.
+    for (auto gp : genericSig->getGenericParams()) {
+      if (constrainedGenericParams.count(gp->getCanonicalType().getPointer()))
+        continue;
+      auto gpDecl = gp->getDecl();
+      if (gpDecl) {
+        TC.diagnose(attr->getLocation(),
+                    diag::specialize_attr_missing_constraint,
+                    gpDecl->getFullName());
+      }
+    }
+  }
+}
+
+/// Type check that a set of requirements provided by @_specialize.
+/// Store the set of requirements in the attribute.
 void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) {
   DeclContext *DC = D->getDeclContext();
   auto *FD = cast<AbstractFunctionDecl>(D);
   auto *genericSig = FD->getGenericSignature();
+  auto *genericEnv = FD->getGenericEnvironment();
+  auto *trailingWhereClause = attr->getTrailingWhereClause();
 
-  unsigned numTypes = 0;
-  if (genericSig)
-    numTypes = genericSig->getGenericParams().size();
-  if (numTypes != attr->getTypeLocs().size()) {
-    TC.diagnose(attr->getLocation(), diag::type_parameter_count_mismatch,
-                FD->getName(), numTypes, attr->getTypeLocs().size(),
-                numTypes > attr->getTypeLocs().size());
-    attr->setInvalid();
+  if (!trailingWhereClause) {
+    // Report a missing "where" clause.
+    TC.diagnose(attr->getLocation(), diag::specialize_missing_where_clause);
     return;
   }
-  // Initialize each TypeLoc in this attribute with a concrete type,
-  // and populate a substitution map from GenericTypeParamType to concrete Type.
-  SubstitutionMap subMap;
-  for (unsigned paramIdx = 0; paramIdx < numTypes; ++paramIdx) {
 
-    auto *genericTypeParamTy = genericSig->getGenericParams()[paramIdx];
-    auto &tl = attr->getTypeLocs()[paramIdx];
-
-    auto ty = TC.resolveType(tl.getTypeRepr(), DC, None);
-    if (!ty || ty->hasError()) {
-      attr->setInvalid();
-      return;
-    }
-
-    if (ty->hasArchetype()) {
-      TC.diagnose(attr->getLocation(),
-                  diag::cannot_partially_specialize_generic_function);
-      attr->setInvalid();
-      return;
-    }
-
-    tl.setType(ty, /*validated=*/true);
-    subMap.addSubstitution(
-        cast<GenericTypeParamType>(genericTypeParamTy->getCanonicalType()), ty);
+  if (trailingWhereClause->getRequirements().empty()) {
+    // Report an empty "where" clause.
+    TC.diagnose(attr->getLocation(), diag::specialize_empty_where_clause);
+    return;
   }
 
-  // Capture the conformances needed for the substitution map.
-  CanType currentType;
-  SmallVector<ProtocolConformanceRef, 4> currentConformances;
-  auto flushConformances = [&] {
-    subMap.addConformances(currentType,
-                           TC.Context.AllocateCopy(currentConformances));
-    currentConformances.clear();
-  };
+  if (!genericSig) {
+    // Only generic functions are permitted to have trailing where clauses.
+    TC.diagnose(attr->getLocation(),
+                diag::specialize_attr_nongeneric_trailing_where, FD->getName())
+        .highlight(trailingWhereClause->getSourceRange());
+    return;
+  }
 
-  for (const auto &req : genericSig->getRequirements()) {
-    // If we're on to a new dependent type, flush the conformances gathered
-    // thus far.
-    CanType canFirstType = req.getFirstType()->getCanonicalType();
-    if (canFirstType != currentType) {
-      if (currentType) flushConformances();
-      currentType = canFirstType;
+  // Form a new generic signature based on the old one.
+  ArchetypeBuilder Builder(D->getASTContext(),
+                           LookUpConformanceInModule(DC->getParentModule()));
+
+  // First, add the old generic signature.
+  Builder.addGenericSignature(genericSig);
+
+  SmallVector<Requirement, 4> convertedRequirements;
+  SmallVector<RequirementRepr, 4> resolvedRequirements;
+
+  // Add all requirements from the "where" clause to the old signature
+  // to check if there are any inconsistencies.
+  auto options = TypeResolutionOptions();
+
+  // Set of generic parameters being constrained. It is used to
+  // determine if a full specialization misses requirements for
+  // some of the generic parameters.
+  SmallPtrSet<TypeBase *, 4> constrainedGenericParams;
+
+  // Go over the set of requirements and resolve their types.
+  for (auto &req : trailingWhereClause->getRequirements()) {
+    if (req.getKind() == RequirementReprKind::SameType) {
+      auto firstType = TC.resolveType(req.getFirstTypeRepr(), FD, options);
+      auto secondType = TC.resolveType(req.getSecondTypeRepr(), FD, options);
+      Type interfaceFirstType;
+      Type interfaceSecondType;
+
+      // Map types to their interface types.
+      if (firstType)
+        interfaceFirstType = genericEnv->mapTypeOutOfContext(firstType);
+      if (secondType)
+        interfaceSecondType = genericEnv->mapTypeOutOfContext(secondType);
+
+      collectUsedGenericParameters(interfaceFirstType,
+                                   constrainedGenericParams);
+      collectUsedGenericParameters(interfaceSecondType,
+                                   constrainedGenericParams);
+
+      // Skip any unknown or error types.
+      if (!firstType || firstType->is<ErrorType>() || !secondType ||
+          secondType->is<ErrorType>())
+        continue;
+
+      RequirementSource source(RequirementSource::Kind::Explicit,
+                               req.getEqualLoc());
+
+      Type genericType;
+      Type concreteType;
+      if (interfaceFirstType->hasTypeParameter()) {
+        genericType = interfaceFirstType;
+        concreteType = interfaceSecondType;
+      } else {
+        genericType = interfaceSecondType;
+        concreteType = interfaceFirstType;
+      }
+      // Add a resolved requirement.
+      if (interfaceFirstType->hasTypeParameter()) {
+        resolvedRequirements.push_back(RequirementRepr::getSameType(
+            TypeLoc(req.getFirstTypeRepr(), genericType), req.getEqualLoc(),
+            TypeLoc(req.getSecondTypeRepr(), concreteType)));
+      } else {
+        resolvedRequirements.push_back(RequirementRepr::getSameType(
+            TypeLoc(req.getFirstTypeRepr(), concreteType), req.getEqualLoc(),
+            TypeLoc(req.getSecondTypeRepr(), genericType)));
+      }
+      Builder.addRequirement(resolvedRequirements.back());
+
+      // Convert the requirement into a form which uses canonical interface
+      // types.
+      Requirement convertedRequirement(RequirementKind::SameType,
+                                       genericType->getCanonicalType(),
+                                       concreteType->getCanonicalType());
+      convertedRequirements.push_back(convertedRequirement);
+      continue;
     }
 
-    switch (req.getKind()) {
-    case RequirementKind::Conformance: {
-      // Get the conformance and record it.
-      auto firstType = req.getFirstType().subst(subMap);
-      auto protoType = req.getSecondType()->castTo<ProtocolType>();
-      auto conformance =
-        TC.conformsToProtocol(firstType,
-                              protoType->getDecl(),
-                              DC,
-                              (ConformanceCheckFlags::InExpression|
-                               ConformanceCheckFlags::Used));
-      if (!conformance) {
-        TC.diagnose(attr->getLocation(),
-                    diag::cannot_convert_argument_value_protocol,
-                    firstType, protoType);
-        attr->setInvalid();
-        return;
-      }
+    if (req.getKind() == RequirementReprKind::LayoutConstraint) {
+      auto subjectType = TC.resolveType(req.getSubjectRepr(), FD, options);
+      Type interfaceSubjectType;
 
-      currentConformances.push_back(*conformance);
-      break;
+      // Map types to their interface types.
+      if (subjectType)
+        interfaceSubjectType = genericEnv->mapTypeOutOfContext(subjectType);
+
+      collectUsedGenericParameters(interfaceSubjectType,
+                                   constrainedGenericParams);
+
+      // Skip any unknown or error types.
+      if (!subjectType || subjectType->is<ErrorType>() ||
+          !req.getLayoutConstraint() ||
+          !req.getLayoutConstraint()->isKnownLayout())
+        continue;
+
+      // Re-create a requirement using the resolved interface types.
+      auto resolvedReq = RequirementRepr::getLayoutConstraint(
+          TypeLoc(req.getSubjectRepr(), interfaceSubjectType),
+          req.getColonLoc(),
+          req.getLayoutConstraintLoc());
+
+      // Add a resolved requirement.
+      Builder.addRequirement(resolvedReq);
+      resolvedRequirements.push_back(resolvedReq);
+
+      // Convert the requirement into a form which uses canonical interface
+      // types.
+      Requirement convertedRequirement(
+          RequirementKind::Layout,
+          interfaceSubjectType->getCanonicalType(),
+          req.getLayoutConstraint());
+      convertedRequirements.push_back(convertedRequirement);
+      continue;
     }
-    case RequirementKind::Superclass: {
-      // Superclass requirements aren't recorded in substitutions.
-      auto firstTy = req.getFirstType().subst(subMap);
-      auto superTy = req.getSecondType().subst(subMap);
-      if (!TC.isSubtypeOf(firstTy, superTy, DC)) {
-        TC.diagnose(attr->getLocation(), diag::type_does_not_inherit,
-                    FD->getInterfaceType(), firstTy, superTy);
-        attr->setInvalid();
-        return;
-      }
-      break;
-    }
-    case RequirementKind::SameType: {
-      // Same-type requirements are type checked but not recorded in
-      // substitutions.
-      auto firstTy = req.getFirstType().subst(subMap);
-      auto sameTy = req.getSecondType().subst(subMap);
-      if (!firstTy->isEqual(sameTy)) {
-        TC.diagnose(attr->getLocation(), diag::types_not_equal,
-                    FD->getInterfaceType(), firstTy, sameTy);
-        attr->setInvalid();
-        return;
-      }
-      break;
-    }
-    case RequirementKind::Layout: {
-      llvm_unreachable("Layout constraints not supported yet");
-    }
+
+    if (req.getKind() == RequirementReprKind::TypeConstraint) {
+      auto subjectType = TC.resolveType(req.getSubjectRepr(), FD, options);
+      auto constraint = TC.resolveType(
+          req.getConstraintLoc().getTypeRepr(), FD, options);
+
+      Type interfaceSubjectType;
+
+      // Map types to their interface types.
+      if (subjectType)
+        interfaceSubjectType = genericEnv->mapTypeOutOfContext(subjectType);
+
+      collectUsedGenericParameters(interfaceSubjectType,
+                                   constrainedGenericParams);
+
+      // Skip any unknown or error types.
+      if (!subjectType || subjectType->hasError() ||
+          !constraint || constraint->hasError())
+        continue;
+
+
+      auto interfaceLayoutConstraint =
+          genericEnv->mapTypeOutOfContext(constraint);
+
+      // Re-create a requirement using the resolved interface types.
+      auto resolvedReq = RequirementRepr::getTypeConstraint(
+          TypeLoc(req.getSubjectRepr(), interfaceSubjectType),
+          req.getColonLoc(),
+          TypeLoc(req.getConstraintRepr(), interfaceLayoutConstraint));
+
+      // Add a resolved requirement.
+      Builder.addRequirement(resolvedReq);
+      resolvedRequirements.push_back(resolvedReq);
+
+      // Convert the requirement into a form which uses canonical interface
+      // types.
+      Requirement convertedRequirement(
+          RequirementKind::Conformance,
+          interfaceSubjectType->getCanonicalType(),
+          interfaceLayoutConstraint->getCanonicalType());
+      convertedRequirements.push_back(convertedRequirement);
+      continue;
     }
   }
-  if (currentType) flushConformances();
 
-  // Compute the substitutions.
-  SmallVector<Substitution, 4> substitutions;
-  genericSig->getSubstitutions(subMap, substitutions);
+  // Check the validity of provided requirements.
+  checkSpecializeAttrRequirements(attr, FD, resolvedRequirements,
+                                  constrainedGenericParams, TC);
 
-  // Package the Substitution list in the SpecializeAttr's ConcreteDeclRef.
-  attr->setConcreteDecl(
-    ConcreteDeclRef(DC->getASTContext(), FD, substitutions));
+  // Store converted requirements in the attribute so that they are
+  // serialized later.
+  attr->setRequirements(DC->getASTContext(), convertedRequirements);
+}
+
+void AttributeChecker::visitFixedLayoutAttr(FixedLayoutAttr *attr) {
+  auto *VD = cast<ValueDecl>(D);
+
+  if (VD->getEffectiveAccess() < Accessibility::Public) {
+    TC.diagnose(attr->getLocation(),
+                diag::fixed_layout_attr_on_internal_type,
+                VD->getName(),
+                VD->getFormalAccess())
+        .fixItRemove(attr->getRangeWithAt());
+    attr->setInvalid();
+  }
 }
 
 void AttributeChecker::visitVersionedAttr(VersionedAttr *attr) {
   auto *VD = cast<ValueDecl>(D);
 
+  // FIXME: Once protocols can contain nominal types, do we want to allow
+  // these nominal types to have accessibility (and also @_versioned)?
+  if (isa<ProtocolDecl>(VD->getDeclContext())) {
+    TC.diagnose(attr->getLocation(),
+                diag::versioned_attr_in_protocol)
+        .fixItRemove(attr->getRangeWithAt());
+    attr->setInvalid();
+    return;
+  }
+
   if (VD->getFormalAccess() != Accessibility::Internal) {
     TC.diagnose(attr->getLocation(),
                 diag::versioned_attr_with_explicit_accessibility,
@@ -1535,6 +1803,7 @@
                 VD->getFormalAccess())
         .fixItRemove(attr->getRangeWithAt());
     attr->setInvalid();
+    return;
   }
 }
 
diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp
index ceba9b5..01717de 100644
--- a/lib/Sema/TypeCheckAvailability.cpp
+++ b/lib/Sema/TypeCheckAvailability.cpp
@@ -620,7 +620,8 @@
 
 AvailabilityContext
 TypeChecker::overApproximateAvailabilityAtLocation(SourceLoc loc,
-                                                   const DeclContext *DC) {
+                                                   const DeclContext *DC,
+                                                   const TypeRefinementContext **MostRefined) {
   SourceFile *SF = DC->getParentSourceFile();
 
   // If our source location is invalid (this may be synthesized code), climb
@@ -663,6 +664,9 @@
     TypeRefinementContext *TRC =
         rootTRC->findMostRefinedSubContext(loc, Context.SourceMgr);
     OverApproximateContext.constrainWith(TRC->getAvailabilityInfo());
+    if (MostRefined) {
+      *MostRefined = TRC;
+    }
   }
 
   return OverApproximateContext;
@@ -1187,6 +1191,54 @@
       .fixItInsert(InsertLoc, AttrText);
 }
 
+/// In the special case of being in an existing, nontrivial type refinement
+/// context that's close but not quite narrow enough to satisfy requirements
+/// (i.e.  requirements are contained-in the existing TRC but off by a subminor
+/// version), emit a diagnostic and fixit that narrows the existing TRC
+/// condition to the required range.
+static bool fixAvailabilityByNarrowingNearbyVersionCheck(
+    SourceRange ReferenceRange,
+    const DeclContext *ReferenceDC,
+    const VersionRange &RequiredRange,
+    TypeChecker &TC,
+    InFlightDiagnostic &Err) {
+  const TypeRefinementContext *TRC = nullptr;
+  AvailabilityContext RunningOSOverApprox =
+    TC.overApproximateAvailabilityAtLocation(ReferenceRange.Start,
+                                             ReferenceDC, &TRC);
+  VersionRange RunningRange = RunningOSOverApprox.getOSVersion();
+  if (RunningRange.hasLowerEndpoint() &&
+      RequiredRange.hasLowerEndpoint() &&
+      AvailabilityContext(RequiredRange).isContainedIn(RunningOSOverApprox) &&
+      TRC && TRC->getReason() != TypeRefinementContext::Reason::Root) {
+
+    // Only fix situations that are "nearby" versions, meaning
+    // disagreement on a minor-or-less version for non-macOS,
+    // or disagreement on a subminor-or-less version for macOS.
+    auto RunningVers = RunningRange.getLowerEndpoint();
+    auto RequiredVers = RequiredRange.getLowerEndpoint();
+    auto Platform = targetPlatform(TC.Context.LangOpts);
+    if (RunningVers.getMajor() != RequiredVers.getMajor())
+      return false;
+    if ((Platform == PlatformKind::OSX ||
+         Platform == PlatformKind::OSXApplicationExtension) &&
+        !(RunningVers.getMinor().hasValue() &&
+          RequiredVers.getMinor().hasValue() &&
+          RunningVers.getMinor().getValue() ==
+          RequiredVers.getMinor().getValue()))
+      return false;
+
+    auto FixRange = TRC->getAvailabilityConditionVersionSourceRange(
+      Platform, RunningVers);
+    if (!FixRange.isValid())
+      return false;
+    // Have found a nontrivial type refinement context-introducer to narrow.
+    Err.fixItReplace(FixRange, RequiredVers.getAsString());
+    return true;
+  }
+  return false;
+}
+
 /// Emit a diagnostic note and Fix-It to add an if #available(...) { } guard
 /// that checks for the given version range around the given node.
 static void fixAvailabilityByAddingVersionCheck(
@@ -1289,12 +1341,21 @@
     return;
   }
 
-  diagnose(ReferenceRange.Start, diag::availability_decl_only_version_newer,
-           Name, prettyPlatformString(targetPlatform(Context.LangOpts)),
-           Reason.getRequiredOSVersionRange().getLowerEndpoint());
+  auto RequiredRange = Reason.getRequiredOSVersionRange();
+  {
+    auto Err =
+      diagnose(ReferenceRange.Start, diag::availability_decl_only_version_newer,
+               Name, prettyPlatformString(targetPlatform(Context.LangOpts)),
+               Reason.getRequiredOSVersionRange().getLowerEndpoint());
 
-  fixAvailability(ReferenceRange, ReferenceDC,
-                  Reason.getRequiredOSVersionRange(), *this);
+    // Direct a fixit to the error if an existing guard is nearly-correct
+    if (fixAvailabilityByNarrowingNearbyVersionCheck(ReferenceRange,
+                                                     ReferenceDC,
+                                                     RequiredRange, *this, Err))
+      return;
+  }
+
+  fixAvailability(ReferenceRange, ReferenceDC, RequiredRange, *this);
 }
 
 void TypeChecker::diagnosePotentialAccessorUnavailability(
@@ -1309,13 +1370,23 @@
   auto &diag = ForInout ? diag::availability_inout_accessor_only_version_newer
                         : diag::availability_accessor_only_version_newer;
 
-  diagnose(ReferenceRange.Start, diag,
-           static_cast<unsigned>(Accessor->getAccessorKind()), Name,
-           prettyPlatformString(targetPlatform(Context.LangOpts)),
-           Reason.getRequiredOSVersionRange().getLowerEndpoint());
+  auto RequiredRange = Reason.getRequiredOSVersionRange();
+  {
+    auto Err =
+      diagnose(ReferenceRange.Start, diag,
+               static_cast<unsigned>(Accessor->getAccessorKind()), Name,
+               prettyPlatformString(targetPlatform(Context.LangOpts)),
+               Reason.getRequiredOSVersionRange().getLowerEndpoint());
 
-  fixAvailability(ReferenceRange, ReferenceDC,
-                  Reason.getRequiredOSVersionRange(), *this);
+
+    // Direct a fixit to the error if an existing guard is nearly-correct
+    if (fixAvailabilityByNarrowingNearbyVersionCheck(ReferenceRange,
+                                                     ReferenceDC,
+                                                     RequiredRange, *this, Err))
+      return;
+  }
+
+  fixAvailability(ReferenceRange, ReferenceDC, RequiredRange, *this);
 }
 
 const AvailableAttr *TypeChecker::getDeprecated(const Decl *D) {
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 31ece4c..0da1794 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -1383,7 +1383,7 @@
 }
 
 void GenericRequirementsCheckListener::diagnosed(
-    const Requirement *withRequirement) {}
+    const Requirement *requirement) {}
 
 bool TypeChecker::
 solveForExpression(Expr *&expr, DeclContext *dc, Type convertType,
@@ -1676,7 +1676,7 @@
 
   // Get the expression's simplified type.
   auto &solution = viable[0];
-  Type exprType = solution.simplifyType(*this, expr->getType());
+  Type exprType = solution.simplifyType(expr->getType());
 
   assert(exprType && !exprType->hasTypeVariable() &&
          "free type variable with FreeTypeVariableBinding::GenericParameters?");
@@ -1791,8 +1791,8 @@
     solution.dump(log);
   }
 
-  expr->setType(solution.simplifyType(*this, expr->getType()));
-  CCE->setType(solution.simplifyType(*this, CCE->getType()));
+  expr->setType(solution.simplifyType(expr->getType()));
+  CCE->setType(solution.simplifyType(CCE->getType()));
   return false;
 }
 
@@ -1892,7 +1892,7 @@
       // Figure out what type the constraints decided on.
       auto &cs = solution.getConstraintSystem();
       auto &tc = cs.getTypeChecker();
-      InitType = solution.simplifyType(tc, InitType);
+      InitType = solution.simplifyType(InitType);
 
       // Convert the initializer to the type of the pattern.
       // ignoreTopLevelInjection = Binding->isConditional()
@@ -2137,8 +2137,8 @@
       // Figure out what types the constraints decided on.
       auto &cs = solution.getConstraintSystem();
       auto &tc = cs.getTypeChecker();
-      InitType = solution.simplifyType(tc, InitType);
-      SequenceType = solution.simplifyType(tc, SequenceType);
+      InitType = solution.simplifyType(InitType);
+      SequenceType = solution.simplifyType(SequenceType);
 
       // Perform any necessary conversions of the sequence (e.g. [T]! -> [T]).
       if (tc.convertToType(expr, SequenceType, cs.DC)) {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index f7bf565..4946d87 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -2597,21 +2597,36 @@
       // Swift does not permit class methods with Objective-C selectors 'load',
       // 'alloc', or 'allocWithZone:'.
       if (!method->isInstanceMember()) {
-        auto isForbiddenSelector = [&TC](ObjCSelector sel) {
+        auto isForbiddenSelector = [&TC](ObjCSelector sel)
+        -> Optional<Diag<unsigned, DeclName, ObjCSelector>> {
           switch (sel.getNumArgs()) {
           case 0:
-            return sel.getSelectorPieces().front() == TC.Context.Id_load ||
-                   sel.getSelectorPieces().front() == TC.Context.Id_alloc;
+            if (sel.getSelectorPieces().front() == TC.Context.Id_load ||
+                sel.getSelectorPieces().front() == TC.Context.Id_alloc)
+              return diag::objc_class_method_not_permitted;
+            // Swift 3 and earlier allowed you to override `initialize`, but
+            // Swift's semantics do not guarantee that it will be called at
+            // the point you expect. It is disallowed in Swift 4 and later.
+            if (sel.getSelectorPieces().front() == TC.Context.Id_initialize) {
+              if (TC.getLangOpts().isSwiftVersion3())
+                return
+                  diag::objc_class_method_not_permitted_swift3_compat_warning;
+              else
+                return diag::objc_class_method_not_permitted;
+            }
+            return None;
           case 1:
-            return sel.getSelectorPieces().front()==TC.Context.Id_allocWithZone;
+            if (sel.getSelectorPieces().front() == TC.Context.Id_allocWithZone)
+              return diag::objc_class_method_not_permitted;
+            return None;
           default:
-            return false;
+            return None;
           }
         };
         auto sel = method->getObjCSelector(&TC);
-        if (isForbiddenSelector(sel)) {
+        if (auto diagID = isForbiddenSelector(sel)) {
           auto diagInfo = getObjCMethodDiagInfo(method);
-          TC.diagnose(method, diag::objc_class_method_not_permitted,
+          TC.diagnose(method, *diagID,
                       diagInfo.first, diagInfo.second, sel);
         }
       }
@@ -6087,6 +6102,23 @@
           new (TC.Context) OverrideAttr(SourceLoc()));
     }
 
+    // If the overridden method is declared in a Swift Class Declaration,
+    // dispatch will use table dispatch. If the override is in an extension
+    // warn, since it is not added to the class vtable.
+    //
+    // FIXME: Only warn if the extension is in another module, and if
+    // it is in the same module, update the vtable.
+    if (auto *baseDecl = dyn_cast<ClassDecl>(base->getDeclContext())) {
+      if (baseDecl->hasKnownSwiftImplementation() && 
+          !base->isDynamic() &&
+          override->getDeclContext()->isExtensionContext()) {
+        // For compatibility, only generate a warning in Swift 3
+        TC.diagnose(override, (TC.Context.isSwiftVersion3()
+          ? diag::override_class_declaration_in_extension_warning
+          : diag::override_class_declaration_in_extension));
+        TC.diagnose(base, diag::overridden_here);
+      }
+    }
     // If the overriding declaration is 'throws' but the base is not,
     // complain.
     if (auto overrideFn = dyn_cast<AbstractFunctionDecl>(override)) {
@@ -6384,6 +6416,13 @@
     } else if (auto extType = CD->getDeclContext()->getDeclaredInterfaceType()) {
       // A designated initializer for a class must be written within the class
       // itself.
+      //
+      // This is because designated initializers of classes get a vtable entry,
+      // and extensions cannot add vtable entries to the extended type.
+      //
+      // If we implement the ability for extensions defined in the same module
+      // (or the same file) to add vtable entries, we can re-evaluate this
+      // restriction.
       if (extType->getClassOrBoundGenericClass() &&
           isa<ExtensionDecl>(CD->getDeclContext())) {
         TC.diagnose(CD->getLoc(), diag::designated_init_in_extension, extType)
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 7587bd4..ee1a1b5 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -16,6 +16,7 @@
 #include "TypeChecker.h"
 #include "GenericTypeResolver.h"
 #include "swift/AST/ArchetypeBuilder.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/Defer.h"
@@ -55,7 +56,7 @@
   assert(archetype && "Bad generic context nesting?");
   
   return archetype
-           ->getNestedType(assocType->getName(), Builder)
+           ->getNestedType(assocType, Builder)
            ->getDependentType(/*FIXME: */{ }, /*allowUnresolved=*/true);
 }
 
@@ -214,7 +215,7 @@
 Type CompleteGenericTypeResolver::resolveSelfAssociatedType(
        Type selfTy, AssociatedTypeDecl *assocType) {
   return Builder.resolveArchetype(selfTy)
-           ->getNestedType(assocType->getName(), Builder)
+           ->getNestedType(assocType, Builder)
            ->getDependentType(/*FIXME: */{ }, /*allowUnresolved=*/false);
 }
 
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index b18a75b..f35b07a 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -17,6 +17,7 @@
 //===----------------------------------------------------------------------===//
 #include "TypeChecker.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/TopCollection.h"
 #include <algorithm>
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 39608ea..3473544 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -506,13 +506,10 @@
 static AssociatedTypeDecl *
 getReferencedAssocTypeOfProtocol(Type type, ProtocolDecl *proto) {
   if (auto dependentMember = type->getAs<DependentMemberType>()) {
-    if (auto genericParam 
-          = dependentMember->getBase()->getAs<GenericTypeParamType>()) {
-      if (genericParam->getDepth() == 0 && genericParam->getIndex() == 0) {
-        if (auto assocType = dependentMember->getAssocType()) {
-          if (assocType->getDeclContext() == proto)
-            return assocType;
-        }
+    if (auto assocType = dependentMember->getAssocType()) {
+      if (dependentMember->getBase()->isEqual(proto->getSelfInterfaceType()) &&
+          assocType->getProtocol() == proto) {
+        return assocType;
       }
     }
   }
@@ -1009,11 +1006,11 @@
   {
     SmallVector<ProtocolConformanceRef, 1> conformances;
     if (specialized)
-      conformances.push_back(ProtocolConformanceRef(specialized));
+      reqToSyntheticEnvMap.addConformance(
+          selfType, ProtocolConformanceRef(specialized));
     else
-      conformances.push_back(ProtocolConformanceRef(proto));
-    reqToSyntheticEnvMap.addConformances(selfType,
-                                         ctx.AllocateCopy(conformances));
+      reqToSyntheticEnvMap.addConformance(
+          selfType, ProtocolConformanceRef(proto));
   }
 
   // Construct an archetype builder by collecting the constraints from the
@@ -1067,11 +1064,11 @@
     if (auto archetypeType
           = reqEnv->mapTypeIntoContext(genericParam)->getAs<ArchetypeType>()) {
       // Add substitutions.
-      SmallVector<ProtocolConformanceRef, 1> conformances;
-      for (auto proto : archetypeType->getConformsTo())
-        conformances.push_back(ProtocolConformanceRef(proto));
-      reqToSyntheticEnvMap.addConformances(genericParam->getCanonicalType(),
-                                           ctx.AllocateCopy(conformances));
+      for (auto proto : archetypeType->getConformsTo()) {
+        reqToSyntheticEnvMap.addConformance(
+            genericParam->getCanonicalType(),
+            ProtocolConformanceRef(proto));
+      }
     }
   }
 
@@ -1287,8 +1284,8 @@
       auto witnessDC = witness->getInnermostDeclContext();
 
       // Compute the set of substitutions we'll need for the witness.
-      solution->computeSubstitutions(witness->getInterfaceType(),
-                                     witnessDC, openedFullWitnessType,
+      solution->computeSubstitutions(witnessDC->getGenericSignatureOfContext(),
+                                     openedFullWitnessType,
                                      witnessLocator,
                                      result.WitnessSubstitutions);
     }
@@ -2158,7 +2155,7 @@
   // signature.
   auto &assocTypes = ReferencedAssociatedTypes[req];
   llvm::SmallPtrSet<AssociatedTypeDecl *, 4> knownAssocTypes;
-  req->getInterfaceType().visit([&](Type type) {
+  req->getInterfaceType()->getCanonicalType().visit([&](Type type) {
       if (auto assocType = getReferencedAssocTypeOfProtocol(type, Proto)) {
         if (knownAssocTypes.insert(assocType).second) {
           assocTypes.push_back(assocType);
@@ -5377,8 +5374,24 @@
   auto accessorKind = AccessorKind::NotAccessor;
   if (auto *fn = dyn_cast<FuncDecl>(witness)) {
     accessorKind = fn->getAccessorKind();
-    if (accessorKind != AccessorKind::NotAccessor) {
+    switch (accessorKind) {
+    case AccessorKind::IsAddressor:
+    case AccessorKind::IsMutableAddressor:
+    case AccessorKind::IsMaterializeForSet:
+      // These accessors are never exposed to Objective-C.
+      return result;
+    case AccessorKind::IsDidSet:
+    case AccessorKind::IsWillSet:
+      // These accessors are folded into the setter.
+      return result;
+    case AccessorKind::IsGetter:
+    case AccessorKind::IsSetter:
+      // These are found relative to the main decl.
       name = fn->getAccessorStorageDecl()->getFullName();
+      break;
+    case AccessorKind::NotAccessor:
+      // Do nothing.
+      break;
     }
   }
 
@@ -5636,7 +5649,7 @@
 }
 
 // Not all protocol members are requirements.
-bool TypeChecker::isRequirement(ValueDecl *requirement) {
+bool TypeChecker::isRequirement(const ValueDecl *requirement) {
   if (auto *FD = dyn_cast<FuncDecl>(requirement))
     if (FD->isAccessor())
       return false;
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 3716eb2..557e331 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -1489,7 +1489,12 @@
   // Determine whether we need to introduce a super.init call.
   auto nominalDecl = ctor->getDeclContext()
     ->getAsNominalTypeOrNominalTypeExtensionContext();
-  ClassDecl *ClassD = dyn_cast_or_null<ClassDecl>(nominalDecl);
+
+  // Error case.
+  if (nominalDecl == nullptr)
+    return HadError;
+
+  ClassDecl *ClassD = dyn_cast<ClassDecl>(nominalDecl);
   bool wantSuperInitCall = false;
   if (ClassD) {
     bool isDelegating = false;
@@ -1521,7 +1526,7 @@
     }
 
     // A class designated initializer must never be delegating.
-    if (ctor->isDesignatedInit() && ClassD && isDelegating) {
+    if (ctor->isDesignatedInit() && isDelegating) {
       diagnose(ctor->getLoc(),
                diag::delegating_designated_init,
                ctor->getDeclContext()->getDeclaredInterfaceType())
@@ -1529,10 +1534,14 @@
       diagnose(initExpr->getLoc(), diag::delegation_here);
       ctor->setInitKind(CtorInitializerKind::Convenience);
     }
+  } else {
+    diagnoseResilientValueConstructor(ctor);
   }
 
   // If we want a super.init call...
   if (wantSuperInitCall) {
+    assert(ClassD != nullptr);
+
     // Find a default initializer in the superclass.
     if (Expr *SuperInitCall = constructCallToSuperInit(ctor, ClassD)) {
       // If the initializer we found is a designated initializer, we're okay.
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 61d744a..9106721 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -26,6 +26,7 @@
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/TypeLoc.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Basic/Statistic.h"
@@ -494,8 +495,13 @@
 
     // Don't add fixit on module type; that isn't the right type regardless
     // of whether it had generic arguments.
-    if (!type->is<ModuleType>())
-      diag.fixItRemove(generic->getAngleBrackets());
+    if (!type->is<ModuleType>()) {
+      // When turning a SourceRange into CharSourceRange the closing angle
+      // brackets on nested generics are lexed as one token.
+      SourceRange angles = generic->getAngleBrackets();
+      diag.fixItRemoveChars(angles.Start,
+                            angles.End.getAdvancedLocOrInvalid(1));
+    }
 
     generic->setInvalid();
     return type;
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index 542711f..64eafc5 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -26,6 +26,7 @@
 #include "swift/AST/ModuleLoader.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/STLExtras.h"
 #include "swift/Basic/Timer.h"
 #include "swift/ClangImporter/ClangImporter.h"
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 0e95e74..8382c5f 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -346,7 +346,7 @@
   /// \param first The left-hand side type assigned to the requirement,
   /// possibly represented by its generic substitute.
   ///
-  /// \param second The right-hand side type assinged to the requirement,
+  /// \param second The right-hand side type assigned to the requirement,
   /// possibly represented by its generic substitute.
   ///
   ///
@@ -1095,7 +1095,7 @@
   void introduceLazyVarAccessors(VarDecl *var) override;
 
   // Not all protocol members are requirements.
-  bool isRequirement(ValueDecl *requirement);
+  bool isRequirement(const ValueDecl *requirement);
 
   /// Infer default value witnesses for all requirements in the given protocol.
   void inferDefaultWitnesses(ProtocolDecl *proto);
@@ -1943,6 +1943,8 @@
   bool diagnoseInlineableDeclRef(SourceLoc loc, const ValueDecl *D,
                                  const DeclContext *DC);
 
+  void diagnoseResilientValueConstructor(ConstructorDecl *ctor);
+
   /// \name Availability checking
   ///
   /// Routines that perform API availability checking and type checking of
@@ -1964,9 +1966,11 @@
 
   /// Returns an over-approximation of the range of operating system versions
   /// that could the passed-in location could be executing upon for
-  /// the target platform.
+  /// the target platform. If MostRefined != nullptr, set to the most-refined
+  /// TRC found while approximating.
   AvailabilityContext
-  overApproximateAvailabilityAtLocation(SourceLoc loc, const DeclContext *DC);
+  overApproximateAvailabilityAtLocation(SourceLoc loc, const DeclContext *DC,
+                                        const TypeRefinementContext **MostRefined=nullptr);
 
   /// Walk the AST to build the hierarchy of TypeRefinementContexts
   ///
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index c5b4705..a1edf40 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Initializer.h"
 #include "swift/AST/PrettyStackTrace.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/ClangImporter/ClangImporter.h"
 #include "swift/Parse/Parser.h"
 #include "swift/Serialization/BCReadingExtras.h"
@@ -889,15 +890,6 @@
                                            subject, constraint));
         break;
       }
-      case GenericRequirementKind::Layout: {
-        auto subject = getType(rawTypeIDs[0]);
-        // TODO: Deserialize the layout constraint.
-        LayoutConstraint layoutConstraint;
-
-        requirements.push_back(Requirement(RequirementKind::Layout,
-                                           subject, layoutConstraint));
-        break;
-      }
       case GenericRequirementKind::Superclass: {
         auto subject = getType(rawTypeIDs[0]);
         auto constraint = getType(rawTypeIDs[1]);
@@ -921,6 +913,61 @@
       }
       break;
       }
+    case LAYOUT_REQUIREMENT: {
+      uint8_t rawKind;
+      uint64_t rawTypeID;
+      uint32_t size;
+      uint32_t alignment;
+      LayoutRequirementLayout::readRecord(scratch, rawKind, rawTypeID,
+                                          size, alignment);
+
+      auto first = getType(rawTypeID);
+      LayoutConstraintInfo layoutInfo;
+      LayoutConstraintKind kind = LayoutConstraintKind::UnknownLayout;
+      switch (rawKind) {
+      default: {
+        // Unknown layout requirement kind.
+        error();
+        break;
+      }
+      case LayoutRequirementKind::NativeRefCountedObject: {
+        kind = LayoutConstraintKind::NativeRefCountedObject;
+        break;
+      }
+      case LayoutRequirementKind::RefCountedObject: {
+        kind = LayoutConstraintKind::RefCountedObject;
+        break;
+      }
+      case LayoutRequirementKind::Trivial: {
+        kind = LayoutConstraintKind::Trivial;
+        break;
+      }
+      case LayoutRequirementKind::TrivialOfExactSize: {
+        kind = LayoutConstraintKind::TrivialOfExactSize;
+        break;
+      }
+      case LayoutRequirementKind::TrivialOfAtMostSize: {
+        kind = LayoutConstraintKind::TrivialOfAtMostSize;
+        break;
+      }
+      case LayoutRequirementKind::UnknownLayout: {
+        kind = LayoutConstraintKind::UnknownLayout;
+        break;
+      }
+      }
+
+      if (kind != LayoutConstraintKind::TrivialOfAtMostSize &&
+          kind != LayoutConstraintKind::TrivialOfExactSize)
+        layoutInfo = LayoutConstraintInfo(kind);
+      else
+        layoutInfo = LayoutConstraintInfo(kind, size, alignment);
+
+      auto layout = getContext().AllocateObjectCopy(layoutInfo);
+
+      requirements.push_back(
+          Requirement(RequirementKind::Layout, first, layout));
+      break;
+      }
     default:
       // This record is not part of the GenericParamList.
       shouldContinue = false;
@@ -2262,7 +2309,9 @@
         Attr = new (ctx) AvailableAttr(
           SourceLoc(), SourceRange(),
           (PlatformKind)platform, message, rename,
-          Introduced, Deprecated, Obsoleted,
+          Introduced, SourceRange(),
+          Deprecated, SourceRange(),
+          Obsoleted, SourceRange(),
           platformAgnostic, isImplicit);
         break;
 
@@ -2303,16 +2352,23 @@
       }
 
       case decls_block::Specialize_DECL_ATTR: {
-        ArrayRef<uint64_t> rawTypeIDs;
-        serialization::decls_block::SpecializeDeclAttrLayout::readRecord(
-          scratch, rawTypeIDs);
+        unsigned exported;
+        SpecializeAttr::SpecializationKind specializationKind;
+        unsigned specializationKindVal;
+        SmallVector<Requirement, 8> requirements;
 
-        SmallVector<TypeLoc, 8> typeLocs;
-        for (auto tid : rawTypeIDs)
-          typeLocs.push_back(TypeLoc::withoutLoc(getType(tid)));
+        serialization::decls_block::SpecializeDeclAttrLayout::readRecord(
+          scratch, exported, specializationKindVal);
+
+        specializationKind = specializationKindVal
+                                 ? SpecializeAttr::SpecializationKind::Partial
+                                 : SpecializeAttr::SpecializationKind::Full;
+
+        readGenericRequirements(requirements, DeclTypeCursor);
 
         Attr = SpecializeAttr::create(ctx, SourceLoc(), SourceRange(),
-                                      typeLocs);
+                                      requirements, exported != 0,
+                                      specializationKind);
         break;
       }
 
@@ -4335,12 +4391,10 @@
         reqToSyntheticMap.addSubstitution(canonicalGP, concreteTy);
 
         if (unsigned numConformances = *rawIDIter++) {
-          SmallVector<ProtocolConformanceRef, 2> conformances;
           while (numConformances--) {
-            conformances.push_back(readConformance(DeclTypeCursor));
+            reqToSyntheticMap.addConformance(
+                canonicalGP, readConformance(DeclTypeCursor));
           }
-          reqToSyntheticMap.addConformances(canonicalGP,
-                                            ctx.AllocateCopy(conformances));
         }
       }
     }
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 08b1c199..0b2be99 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -13,6 +13,7 @@
 #define DEBUG_TYPE "deserialize"
 #include "DeserializeSIL.h"
 #include "swift/Basic/Defer.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Serialization/ModuleFile.h"
 #include "SILFormat.h"
 #include "swift/SIL/SILArgument.h"
@@ -107,7 +108,7 @@
   SILCursor = MF->getSILCursor();
   SILIndexCursor = MF->getSILIndexCursor();
   // Early return if either sil block or sil index block does not exist.
-  if (!SILCursor.getBitStreamReader() || !SILIndexCursor.getBitStreamReader())
+  if (SILCursor.AtEndOfStream() || SILIndexCursor.AtEndOfStream())
     return;
 
   // Load any abbrev records at the start of the block.
@@ -479,18 +480,20 @@
     scratch.clear();
     kind = SILCursor.readRecord(next.ID, scratch);
     assert(kind == SIL_SPECIALIZE_ATTR && "Missing specialization attribute");
-    
-    unsigned NumSubstitutions;
-    SILSpecializeAttrLayout::readRecord(scratch, NumSubstitutions);
+
+    unsigned exported;
+    unsigned specializationKindVal;
+    SILSpecializeAttrLayout::readRecord(scratch, exported, specializationKindVal);
+    SILSpecializeAttr::SpecializationKind specializationKind =
+        specializationKindVal ? SILSpecializeAttr::SpecializationKind::Partial
+                              : SILSpecializeAttr::SpecializationKind::Full;
+
+    SmallVector<Requirement, 8> requirements;
+    MF->readGenericRequirements(requirements, SILCursor);
 
     // Read the substitution list and construct a SILSpecializeAttr.
-    SmallVector<Substitution, 4> Substitutions;
-    while (NumSubstitutions--) {
-      auto sub = MF->maybeReadSubstitution(SILCursor);
-      assert(sub.hasValue() && "Missing substitution?");
-      Substitutions.push_back(*sub);
-    }
-    fn->addSpecializeAttr(SILSpecializeAttr::create(SILMod, Substitutions));
+    fn->addSpecializeAttr(SILSpecializeAttr::create(
+        SILMod, requirements, exported != 0, specializationKind));
   }
 
   GenericEnvironment *genericEnv = nullptr;
@@ -1323,13 +1326,16 @@
 
   UNARY_INSTRUCTION(CondFail)
   REFCOUNTING_INSTRUCTION(RetainValue)
+  UNARY_INSTRUCTION(UnmanagedRetainValue)
   UNARY_INSTRUCTION(CopyValue)
   UNARY_INSTRUCTION(CopyUnownedValue)
   UNARY_INSTRUCTION(DestroyValue)
   REFCOUNTING_INSTRUCTION(ReleaseValue)
+  UNARY_INSTRUCTION(UnmanagedReleaseValue)
   REFCOUNTING_INSTRUCTION(AutoreleaseValue)
   REFCOUNTING_INSTRUCTION(SetDeallocating)
   UNARY_INSTRUCTION(DeinitExistentialAddr)
+  UNARY_INSTRUCTION(EndBorrowArgument)
   UNARY_INSTRUCTION(DestroyAddr)
   UNARY_INSTRUCTION(IsNonnull)
   UNARY_INSTRUCTION(Return)
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index 15ec5f8..854c818 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -55,7 +55,7 @@
 
   if (next.ID == llvm::bitc::BLOCKINFO_BLOCK_ID) {
     if (shouldReadBlockInfo) {
-      if (cursor.ReadBlockInfoBlock())
+      if (!cursor.ReadBlockInfoBlock())
         return false;
     } else {
       if (cursor.SkipBlock())
@@ -77,23 +77,25 @@
 static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
                              SmallVectorImpl<uint64_t> &scratch,
                              ExtendedValidationInfo &extendedInfo) {
-  auto next = cursor.advance();
-  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
-    if (next.Kind == llvm::BitstreamEntry::Error)
+  while (!cursor.AtEndOfStream()) {
+    auto entry = cursor.advance();
+    if (entry.Kind == llvm::BitstreamEntry::EndBlock)
+      break;
+
+    if (entry.Kind == llvm::BitstreamEntry::Error)
       return false;
 
-    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+    if (entry.Kind == llvm::BitstreamEntry::SubBlock) {
       // Unknown metadata sub-block, possibly for use by a future version of
       // the module format.
       if (cursor.SkipBlock())
         return false;
-      next = cursor.advance();
       continue;
     }
 
     scratch.clear();
     StringRef blobData;
-    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    unsigned kind = cursor.readRecord(entry.ID, scratch, &blobData);
     switch (kind) {
     case options_block::SDK_PATH:
       extendedInfo.setSDKPath(blobData);
@@ -119,8 +121,6 @@
       // module format.
       break;
     }
-
-    next = cursor.advance();
   }
 
   return true;
@@ -135,15 +135,18 @@
   ValidationInfo result;
   bool versionSeen = false;
 
-  auto next = cursor.advance();
-  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
-    if (next.Kind == llvm::BitstreamEntry::Error) {
+  while (!cursor.AtEndOfStream()) {
+    auto entry = cursor.advance();
+    if (entry.Kind == llvm::BitstreamEntry::EndBlock)
+      break;
+
+    if (entry.Kind == llvm::BitstreamEntry::Error) {
       result.status = Status::Malformed;
       return result;
     }
 
-    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
-      if (next.ID == OPTIONS_BLOCK_ID && extendedInfo) {
+    if (entry.Kind == llvm::BitstreamEntry::SubBlock) {
+      if (entry.ID == OPTIONS_BLOCK_ID && extendedInfo) {
         cursor.EnterSubBlock(OPTIONS_BLOCK_ID);
         if (!readOptionsBlock(cursor, scratch, *extendedInfo)) {
           result.status = Status::Malformed;
@@ -157,13 +160,12 @@
           return result;
         }
       }
-      next = cursor.advance();
       continue;
     }
 
     scratch.clear();
     StringRef blobData;
-    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    unsigned kind = cursor.readRecord(entry.ID, scratch, &blobData);
     switch (kind) {
     case control_block::METADATA: {
       if (versionSeen) {
@@ -209,8 +211,6 @@
       // module format.
       break;
     }
-
-    next = cursor.advance();
   }
 
   return result;
@@ -232,31 +232,31 @@
       reinterpret_cast<uintptr_t>(data.data()) % 4 != 0)
     return result;
 
-  llvm::BitstreamReader reader(reinterpret_cast<const uint8_t *>(data.begin()),
-                               reinterpret_cast<const uint8_t *>(data.end()));
-  llvm::BitstreamCursor cursor(reader);
+  llvm::BitstreamCursor cursor(data);
   SmallVector<uint64_t, 32> scratch;
 
   if (!checkModuleSignature(cursor) ||
       !enterTopLevelModuleBlock(cursor, MODULE_BLOCK_ID, false))
     return result;
 
-  auto topLevelEntry = cursor.advance();
-  while (topLevelEntry.Kind == llvm::BitstreamEntry::SubBlock) {
+  llvm::BitstreamEntry topLevelEntry;
+
+  while (!cursor.AtEndOfStream()) {
+    topLevelEntry = cursor.advance(AF_DontPopBlockAtEnd);
+    if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
+      break;
+
     if (topLevelEntry.ID == CONTROL_BLOCK_ID) {
       cursor.EnterSubBlock(CONTROL_BLOCK_ID);
       result = validateControlBlock(cursor, scratch, extendedInfo);
       if (result.status == Status::Malformed)
         return result;
-
     } else {
       if (cursor.SkipBlock()) {
         result.status = Status::Malformed;
         return result;
       }
     }
-
-    topLevelEntry = cursor.advance(AF_DontPopBlockAtEnd);
   }
 
   if (topLevelEntry.Kind == llvm::BitstreamEntry::EndBlock) {
@@ -466,9 +466,9 @@
   SmallVector<uint64_t, 4> scratch;
   StringRef blobData;
 
-  while (true) {
-    auto next = cursor.advance();
-    switch (next.Kind) {
+  while (!cursor.AtEndOfStream()) {
+    auto entry = cursor.advance();
+    switch (entry.Kind) {
     case llvm::BitstreamEntry::EndBlock:
       return true;
 
@@ -484,7 +484,7 @@
     case llvm::BitstreamEntry::Record:
       scratch.clear();
       blobData = {};
-      unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+      unsigned kind = cursor.readRecord(entry.ID, scratch, &blobData);
 
       switch (kind) {
       case index_block::DECL_OFFSETS:
@@ -656,9 +656,9 @@
   SmallVector<uint64_t, 4> scratch;
   StringRef blobData;
 
-  while (true) {
-    auto next = cursor.advance();
-    switch (next.Kind) {
+  while (!cursor.AtEndOfStream()) {
+    auto entry = cursor.advance();
+    switch (entry.Kind) {
     case llvm::BitstreamEntry::EndBlock:
       return true;
 
@@ -673,7 +673,7 @@
 
     case llvm::BitstreamEntry::Record:
       scratch.clear();
-      unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+      unsigned kind = cursor.readRecord(entry.ID, scratch, &blobData);
 
       switch (kind) {
       case comment_block::DECL_COMMENTS:
@@ -707,18 +707,6 @@
   return None;
 }
 
-static const uint8_t *getStartBytePtr(llvm::MemoryBuffer *buffer) {
-  if (!buffer)
-    return nullptr;
-  return reinterpret_cast<const uint8_t *>(buffer->getBufferStart());
-}
-
-static const uint8_t *getEndBytePtr(llvm::MemoryBuffer *buffer) {
-  if (!buffer)
-    return nullptr;
-  return reinterpret_cast<const uint8_t *>(buffer->getBufferEnd());
-}
-
 static bool areCompatibleArchitectures(const llvm::Triple &moduleTarget,
                                        const llvm::Triple &ctxTarget) {
   if (moduleTarget.getArch() == ctxTarget.getArch())
@@ -772,17 +760,13 @@
     serialization::ExtendedValidationInfo *extInfo)
     : ModuleInputBuffer(std::move(moduleInputBuffer)),
       ModuleDocInputBuffer(std::move(moduleDocInputBuffer)),
-      ModuleInputReader(getStartBytePtr(this->ModuleInputBuffer.get()),
-                        getEndBytePtr(this->ModuleInputBuffer.get())),
-      ModuleDocInputReader(getStartBytePtr(this->ModuleDocInputBuffer.get()),
-                           getEndBytePtr(this->ModuleDocInputBuffer.get())),
       DeserializedTypeCallback([](Type ty) {}) {
   assert(getStatus() == Status::Valid);
   Bits.IsFramework = isFramework;
 
   PrettyModuleFileDeserialization stackEntry(*this);
 
-  llvm::BitstreamCursor cursor{ModuleInputReader};
+  llvm::BitstreamCursor cursor{ModuleInputBuffer->getMemBufferRef()};
 
   if (!checkModuleSignature(cursor) ||
       !enterTopLevelModuleBlock(cursor, MODULE_BLOCK_ID)) {
@@ -795,8 +779,13 @@
   bool hasValidControlBlock = false;
   SmallVector<uint64_t, 64> scratch;
 
-  auto topLevelEntry = cursor.advance();
-  while (topLevelEntry.Kind == llvm::BitstreamEntry::SubBlock) {
+  llvm::BitstreamEntry topLevelEntry;
+
+  while (!cursor.AtEndOfStream()) {
+    topLevelEntry = cursor.advance(AF_DontPopBlockAtEnd);
+    if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
+      break;
+
     switch (topLevelEntry.ID) {
     case CONTROL_BLOCK_ID: {
       cursor.EnterSubBlock(CONTROL_BLOCK_ID);
@@ -992,8 +981,6 @@
       }
       break;
     }
-
-    topLevelEntry = cursor.advance(AF_DontPopBlockAtEnd);
   }
 
   if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) {
@@ -1004,15 +991,18 @@
   if (!this->ModuleDocInputBuffer)
     return;
 
-  llvm::BitstreamCursor docCursor{ModuleDocInputReader};
+  llvm::BitstreamCursor docCursor{ModuleDocInputBuffer->getMemBufferRef()};
   if (!checkModuleDocSignature(docCursor) ||
       !enterTopLevelModuleBlock(docCursor, MODULE_DOC_BLOCK_ID)) {
     error(Status::MalformedDocumentation);
     return;
   }
 
-  topLevelEntry = docCursor.advance();
-  while (topLevelEntry.Kind == llvm::BitstreamEntry::SubBlock) {
+  while (!docCursor.AtEndOfStream()) {
+    topLevelEntry = docCursor.advance(AF_DontPopBlockAtEnd);
+    if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
+      break;
+
     switch (topLevelEntry.ID) {
     case COMMENT_BLOCK_ID: {
       if (!hasValidControlBlock || !readCommentBlock(docCursor)) {
@@ -1031,8 +1021,6 @@
       }
       break;
     }
-
-    topLevelEntry = docCursor.advance(AF_DontPopBlockAtEnd);
   }
 
   if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock) {
diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h
index 41bab6b..3a9576d 100644
--- a/lib/Serialization/SILFormat.h
+++ b/lib/Serialization/SILFormat.h
@@ -155,6 +155,7 @@
       = decls_block::INHERITED_PROTOCOL_CONFORMANCE,
     GENERIC_PARAM = decls_block::GENERIC_PARAM,
     GENERIC_REQUIREMENT = decls_block::GENERIC_REQUIREMENT,
+    LAYOUT_REQUIREMENT = decls_block::LAYOUT_REQUIREMENT,
   };
 
   using SILInstNoOperandLayout = BCRecordLayout<
@@ -257,8 +258,8 @@
 
   using SILSpecializeAttrLayout =
       BCRecordLayout<SIL_SPECIALIZE_ATTR,
-                     BCFixed<5> // number of substitutions
-                     // followed by bound generic substitutions
+                     BCFixed<1>, // exported
+                     BCFixed<1> // specialization kind
                      >;
 
   // Has an optional argument list where each argument is a typed valueref.
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 5239b38..c5ff68e 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -20,6 +20,7 @@
 #include "swift/AST/Initializer.h"
 #include "swift/AST/LinkLibrary.h"
 #include "swift/AST/Mangle.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/RawComment.h"
 #include "swift/AST/USRGeneration.h"
 #include "swift/Basic/Dwarf.h"
@@ -983,6 +984,7 @@
     return;
 
   auto reqAbbrCode = abbrCodes[GenericRequirementLayout::Code];
+  auto layoutReqAbbrCode = abbrCodes[LayoutRequirementLayout::Code];
   for (const auto &req : requirements) {
     if (req.getKind() != RequirementKind::Layout)
       GenericRequirementLayout::emitRecord(
@@ -990,7 +992,17 @@
           getRawStableRequirementKind(req.getKind()),
           addTypeRef(req.getFirstType()), addTypeRef(req.getSecondType()));
     else {
-      // TODO: write layout requirement here.
+      // Write layout requirement.
+      auto layout = req.getLayoutConstraint();
+      unsigned size = 0;
+      unsigned alignment = 0;
+      if (layout->isKnownSizeTrivial()) {
+        size = layout->getTrivialSizeInBits();
+        alignment = layout->getAlignment();
+      }
+      LayoutRequirementLayout::emitRecord(
+          Out, ScratchRecord, layoutReqAbbrCode, (unsigned)layout->getKind(),
+          addTypeRef(req.getFirstType()), size, alignment);
     }
   }
 }
@@ -1968,11 +1980,12 @@
 
   case DAK_Specialize: {
     auto abbrCode = DeclTypeAbbrCodes[SpecializeDeclAttrLayout::Code];
-    SmallVector<TypeID, 8> typeIDs;
-    for (auto tl : cast<SpecializeAttr>(DA)->getTypeLocs())
-      typeIDs.push_back(addTypeRef(tl.getType()));
+    auto SA = cast<SpecializeAttr>(DA);
 
-    SpecializeDeclAttrLayout::emitRecord(Out, ScratchRecord, abbrCode, typeIDs);
+    SpecializeDeclAttrLayout::emitRecord(Out, ScratchRecord, abbrCode,
+                                         (unsigned)SA->isExported(),
+                                         (unsigned)SA->getSpecializationKind());
+    writeGenericRequirements(SA->getRequirements(), DeclTypeAbbrCodes);
     return;
   }
   }
@@ -3794,8 +3807,8 @@
       auto PathOp = VD->getDeclContext()->getParentSourceFile()->getBufferID();
       if (!PathOp.hasValue())
         return NullGroupName;
-      StringRef FullPath = StringRef(VD->getASTContext().SourceMgr.
-                                     getIdentifierForBuffer(PathOp.getValue()));
+      StringRef FullPath =
+        VD->getASTContext().SourceMgr.getIdentifierForBuffer(PathOp.getValue());
       if (!pMap) {
         YamlGroupInputParser Parser(RecordPath);
         if (!Parser.parse()) {
diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h
index a43975f..ed1153b 100644
--- a/lib/Serialization/Serialization.h
+++ b/lib/Serialization/Serialization.h
@@ -276,10 +276,6 @@
   /// Writes a generic parameter list.
   bool writeGenericParams(const GenericParamList *genericParams);
 
-  /// Writes a set of generic requirements.
-  void writeGenericRequirements(ArrayRef<Requirement> requirements,
-                                const std::array<unsigned, 256> &abbrCodes);
-
   /// Writes a list of protocol conformances.
   void writeConformances(ArrayRef<ProtocolConformanceRef> conformances,
                          const std::array<unsigned, 256> &abbrCodes);
@@ -474,6 +470,10 @@
   void writeConformance(ProtocolConformance *conformance,
                         const std::array<unsigned, 256> &abbrCodes,
                         GenericEnvironment *genericEnv = nullptr);
+
+  /// Writes a set of generic requirements.
+  void writeGenericRequirements(ArrayRef<Requirement> requirements,
+                                const std::array<unsigned, 256> &abbrCodes);
 };
 } // end namespace serialization
 } // end namespace swift
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index fb6197d..09db515 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -15,6 +15,7 @@
 #include "Serialization.h"
 #include "swift/Strings.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/SIL/CFG.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILModule.h"
@@ -373,11 +374,10 @@
 
   for (auto *SA : F.getSpecializeAttrs()) {
     unsigned specAttrAbbrCode = SILAbbrCodes[SILSpecializeAttrLayout::Code];
-
-    auto subs = SA->getSubstitutions();
-    SILSpecializeAttrLayout::emitRecord(
-      Out, ScratchRecord, specAttrAbbrCode, (unsigned)subs.size());
-    S.writeSubstitutions(subs, SILAbbrCodes);
+    SILSpecializeAttrLayout::emitRecord(Out, ScratchRecord, specAttrAbbrCode,
+                                        (unsigned)SA->isExported(),
+                                        (unsigned)SA->getSpecializationKind());
+    S.writeGenericRequirements(SA->getRequirements(), SILAbbrCodes);
   }
 
   // Assign a unique ID to each basic block of the SILFunction.
@@ -1025,10 +1025,13 @@
   }
   case ValueKind::CondFailInst:
   case ValueKind::RetainValueInst:
+  case ValueKind::UnmanagedRetainValueInst:
+  case ValueKind::EndBorrowArgumentInst:
   case ValueKind::CopyValueInst:
   case ValueKind::CopyUnownedValueInst:
   case ValueKind::DestroyValueInst:
   case ValueKind::ReleaseValueInst:
+  case ValueKind::UnmanagedReleaseValueInst:
   case ValueKind::AutoreleaseValueInst:
   case ValueKind::SetDeallocatingInst:
   case ValueKind::DeallocStackInst:
@@ -1301,15 +1304,17 @@
     unsigned abbrCode = SILAbbrCodes[SILTwoOperandsLayout::Code];
     unsigned Attr = 0;
     auto *EBI = cast<EndBorrowInst>(&SI);
-    SILValue Src = EBI->getSrc();
-    SILValue Dest = EBI->getDest();
+    SILValue BorrowedValue = EBI->getBorrowedValue();
+    SILValue OriginalValue = EBI->getOriginalValue();
 
     SILTwoOperandsLayout::emitRecord(
         Out, ScratchRecord, abbrCode, (unsigned)SI.getKind(), Attr,
-        S.addTypeRef(Src->getType().getSwiftRValueType()),
-        (unsigned)Src->getType().getCategory(), addValueRef(Src),
-        S.addTypeRef(Dest->getType().getSwiftRValueType()),
-        (unsigned)Dest->getType().getCategory(), addValueRef(Dest));
+        S.addTypeRef(BorrowedValue->getType().getSwiftRValueType()),
+        (unsigned)BorrowedValue->getType().getCategory(),
+        addValueRef(BorrowedValue),
+        S.addTypeRef(OriginalValue->getType().getSwiftRValueType()),
+        (unsigned)OriginalValue->getType().getCategory(),
+        addValueRef(OriginalValue));
     break;
   }
 
@@ -1940,6 +1945,7 @@
   registerSILAbbr<decls_block::NormalProtocolConformanceIdLayout>();
   registerSILAbbr<decls_block::ProtocolConformanceXrefLayout>();
   registerSILAbbr<decls_block::GenericRequirementLayout>();
+  registerSILAbbr<decls_block::LayoutRequirementLayout>();
 
   for (const SILGlobalVariable &g : SILMod->getSILGlobals())
     writeSILGlobalVar(g);
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index 4c3e7c4..4489d70 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -162,8 +162,8 @@
     bool isFramework) {
   assert(moduleInputBuffer);
 
-  const char *moduleBufferID = moduleInputBuffer->getBufferIdentifier();
-  const char *moduleDocBufferID = nullptr;
+  StringRef moduleBufferID = moduleInputBuffer->getBufferIdentifier();
+  StringRef moduleDocBufferID;
   if (moduleDocInputBuffer)
     moduleDocBufferID = moduleDocInputBuffer->getBufferIdentifier();
 
@@ -248,9 +248,9 @@
     break;
 
   case serialization::Status::MalformedDocumentation:
-    assert(moduleDocBufferID);
+    assert(!moduleDocBufferID.empty());
     Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
-                       moduleDocBufferID ? moduleDocBufferID : "");
+                       moduleDocBufferID);
     break;
 
   case serialization::Status::MissingDependency: {
diff --git a/stdlib/private/StdlibUnittest/CMakeLists.txt b/stdlib/private/StdlibUnittest/CMakeLists.txt
index e18d39f..fb9d19b 100644
--- a/stdlib/private/StdlibUnittest/CMakeLists.txt
+++ b/stdlib/private/StdlibUnittest/CMakeLists.txt
@@ -38,6 +38,7 @@
   SWIFT_MODULE_DEPENDS_WATCHOS Darwin Foundation
   SWIFT_MODULE_DEPENDS_LINUX Glibc
   SWIFT_MODULE_DEPENDS_FREEBSD Glibc
+  SWIFT_MODULE_DEPENDS_CYGWIN Glibc
   SWIFT_COMPILE_FLAGS ${swift_stdlib_unittest_compile_flags}
   TARGET_SDKS ALL_POSIX_PLATFORMS
   INSTALL_IN_COMPONENT stdlib-experimental)
diff --git a/stdlib/private/StdlibUnittest/RaceTest.swift b/stdlib/private/StdlibUnittest/RaceTest.swift
index ea07016..e53d776 100644
--- a/stdlib/private/StdlibUnittest/RaceTest.swift
+++ b/stdlib/private/StdlibUnittest/RaceTest.swift
@@ -41,7 +41,7 @@
 import SwiftPrivatePthreadExtras
 #if os(OSX) || os(iOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 import Glibc
 #endif
 
diff --git a/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift b/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift
index 784f075..7307e81 100644
--- a/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift
+++ b/stdlib/private/StdlibUnittest/StdlibCoreExtras.swift
@@ -14,7 +14,7 @@
 import SwiftPrivateLibcExtras
 #if os(OSX) || os(iOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 import Glibc
 #endif
 
diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
index 46e61fb..fa6c8ca 100644
--- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
+++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
@@ -20,7 +20,7 @@
 
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 import Glibc
 #endif
 
@@ -1429,6 +1429,8 @@
   case freeBSD
   case android
   case ps4
+  case windowsCygnus
+  case windows
 
   public var description: String {
     switch self {
@@ -1454,6 +1456,10 @@
       return "PS4"
     case .android:
       return "Android"
+    case .windowsCygnus:
+      return "Cygwin"
+    case .windows:
+      return "Windows"
     }
   }
 }
@@ -1492,6 +1498,10 @@
   return .ps4
 #elseif os(Android)
   return .android
+#elseif os(Windows) && CYGWIN
+  return .windowsCygnus
+#elseif os(Windows)
+  return .windows
 #else
   let productVersion = _stdlib_getSystemVersionPlistProperty("ProductVersion")!
   let (major, minor, bugFix) = _parseDottedVersionTriple(productVersion)
@@ -1570,6 +1580,10 @@
 
   case androidAny(reason: String)
 
+  case windowsAny(reason: String)
+
+  case windowsCygnusAny(reason: String)
+
   case objCRuntime(/*reason:*/ String)
   case nativeRuntime(/*reason:*/ String)
 
@@ -1656,6 +1670,12 @@
     case .ps4Any(reason: let reason):
       return "ps4Any(*, reason: \(reason))"
 
+    case .windowsAny(reason: let reason):
+      return "windowsAny(*, reason: \(reason))"
+
+    case .windowsCygnusAny(reason: let reason):
+      return "windowsCygnusAny(*, reason: \(reason))"
+
     case .objCRuntime(let reason):
       return "Objective-C runtime, reason: \(reason))"
     case .nativeRuntime(let reason):
@@ -1921,6 +1941,24 @@
         return false
       }
 
+    case .windowsAny:
+      switch _getRunningOSVersion() {
+      case .windowsCygnus:
+        return true
+      case .windows:
+        return true
+      default:
+        return false
+      }
+
+    case .windowsCygnusAny:
+      switch _getRunningOSVersion() {
+      case .windowsCygnus:
+        return true
+      default:
+        return false
+      }
+
     case .objCRuntime:
 #if _runtime(_ObjC)
       return true
diff --git a/stdlib/private/SwiftPrivateLibcExtras/CMakeLists.txt b/stdlib/private/SwiftPrivateLibcExtras/CMakeLists.txt
index 842a234..5381c5a 100644
--- a/stdlib/private/SwiftPrivateLibcExtras/CMakeLists.txt
+++ b/stdlib/private/SwiftPrivateLibcExtras/CMakeLists.txt
@@ -13,4 +13,5 @@
   SWIFT_MODULE_DEPENDS_WATCHOS Darwin
   SWIFT_MODULE_DEPENDS_LINUX Glibc
   SWIFT_MODULE_DEPENDS_FREEBSD Glibc
+  SWIFT_MODULE_DEPENDS_CYGWIN Glibc
   INSTALL_IN_COMPONENT stdlib-experimental)
diff --git a/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift b/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
index 1b60d3e..2e240ed 100644
--- a/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
+++ b/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
@@ -13,7 +13,7 @@
 import SwiftPrivate
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 import Glibc
 #endif
 
@@ -264,9 +264,19 @@
 
 public func posixWaitpid(_ pid: pid_t) -> ProcessTerminationStatus {
   var status: CInt = 0
+#if CYGWIN
+  withUnsafeMutablePointer(to: &status) {
+    statusPtr in
+    let statusPtrWrapper = __wait_status_ptr_t(__int_ptr: statusPtr)
+    if waitpid(pid, statusPtrWrapper, 0) < 0 {
+      preconditionFailure("waitpid() failed")
+    }
+  }
+#else
   if waitpid(pid, &status, 0) < 0 {
     preconditionFailure("waitpid() failed")
   }
+#endif
   if WIFEXITED(status) {
     return .exit(Int(WEXITSTATUS(status)))
   }
@@ -290,6 +300,8 @@
   return environ
 #elseif os(Android)
   return environ
+#elseif CYGWIN
+  return environ
 #else
   return __environ
 #endif
diff --git a/stdlib/private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift b/stdlib/private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift
index 870305d..2850883 100644
--- a/stdlib/private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift
+++ b/stdlib/private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift
@@ -99,6 +99,9 @@
         let readAddr = readfds.baseAddress
         let writeAddr = writefds.baseAddress
         let errorAddr = errorfds.baseAddress
+#if CYGWIN
+        typealias fd_set = _types_fd_set
+#endif
         func asFdSetPtr(
           _ p: UnsafeMutablePointer<UInt>?
         ) -> UnsafeMutablePointer<fd_set>? {
diff --git a/stdlib/private/SwiftPrivatePthreadExtras/CMakeLists.txt b/stdlib/private/SwiftPrivatePthreadExtras/CMakeLists.txt
index 92ed806..cf867d6 100644
--- a/stdlib/private/SwiftPrivatePthreadExtras/CMakeLists.txt
+++ b/stdlib/private/SwiftPrivatePthreadExtras/CMakeLists.txt
@@ -10,6 +10,7 @@
   SWIFT_MODULE_DEPENDS_WATCHOS Darwin
   SWIFT_MODULE_DEPENDS_LINUX Glibc
   SWIFT_MODULE_DEPENDS_FREEBSD Glibc
+  SWIFT_MODULE_DEPENDS_CYGWIN Glibc
   SWIFT_COMPILE_FLAGS ${STDLIB_SIL_SERIALIZE_ALL}
   TARGET_SDKS ALL_POSIX_PLATFORMS
   INSTALL_IN_COMPONENT stdlib-experimental)
diff --git a/stdlib/private/SwiftPrivatePthreadExtras/PthreadBarriers.swift b/stdlib/private/SwiftPrivatePthreadExtras/PthreadBarriers.swift
index 987ade1..2ebe4b3 100644
--- a/stdlib/private/SwiftPrivatePthreadExtras/PthreadBarriers.swift
+++ b/stdlib/private/SwiftPrivatePthreadExtras/PthreadBarriers.swift
@@ -12,7 +12,7 @@
 
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 import Glibc
 #endif
 
diff --git a/stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift b/stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift
index 62b7cc8..fe0c4f0 100644
--- a/stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift
+++ b/stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift
@@ -17,7 +17,7 @@
 
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 import Glibc
 #endif
 
diff --git a/stdlib/public/Platform/Platform.swift b/stdlib/public/Platform/Platform.swift
index 63e82af..1512aa0 100644
--- a/stdlib/public/Platform/Platform.swift
+++ b/stdlib/public/Platform/Platform.swift
@@ -382,7 +382,7 @@
 }
 #elseif os(Windows)
 #if CYGWIN
-public typealias sighandler_t = __sighandler_t
+public typealias sighandler_t = _sig_func_ptr
 
 public var SIG_DFL: sighandler_t? { return nil }
 public var SIG_IGN: sighandler_t {
@@ -417,16 +417,9 @@
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
   // The value is ABI.  Value verified to be correct for OS X, iOS, watchOS, tvOS.
   return UnsafeMutablePointer<sem_t>(bitPattern: -1)
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
   // The value is ABI.  Value verified to be correct on Glibc.
   return UnsafeMutablePointer<sem_t>(bitPattern: 0)
-#elseif os(Windows)
-#if CYGWIN
-  // The value is ABI.  Value verified to be correct on Glibc.
-  return UnsafeMutablePointer<sem_t>(bitPattern: 0)
-#else
-  _UnsupportedPlatformError()
-#endif
 #else
   _UnsupportedPlatformError()
 #endif
diff --git a/stdlib/public/Platform/glibc.modulemap.gyb b/stdlib/public/Platform/glibc.modulemap.gyb
index 0455203..7f2d109 100644
--- a/stdlib/public/Platform/glibc.modulemap.gyb
+++ b/stdlib/public/Platform/glibc.modulemap.gyb
@@ -219,6 +219,10 @@
       header "${GLIBC_INCLUDE_PATH}/netdb.h"
       export *
     }
+    module ifaddrs {
+      header "${GLIBC_INCLUDE_PATH}/ifaddrs.h"
+      export *
+    }
     module search {
       header "${GLIBC_INCLUDE_PATH}/search.h"
       export *
diff --git a/stdlib/public/Platform/tgmath.swift.gyb b/stdlib/public/Platform/tgmath.swift.gyb
index ae688e0..55be7b3 100644
--- a/stdlib/public/Platform/tgmath.swift.gyb
+++ b/stdlib/public/Platform/tgmath.swift.gyb
@@ -215,22 +215,14 @@
 %if T == 'Double':
 #if os(Linux)
   return Int(__fpclassify(CDouble(value)))
-#elseif os(Windows)
-#if CYGWIN
-  return Int(__fpclassify(CDouble(value)))
-#else
+#elseif os(Windows) && !CYGWIN
   return Int(_dclass(CDouble(value)))
-#endif
 #else
   return Int(__fpclassifyd(CDouble(value)))
 #endif
 %else:
-#if os(Windows)
-#if CYGWIN
-  return Int(__fpclassify${f}(${CT}(value)))
-#else
+#if os(Windows) && !CYGWIN
   return Int(_${f}dclass(${CT}(value)))
-#endif
 #else
   return Int(__fpclassify${f}(${CT}(value)))
 #endif
@@ -305,7 +297,7 @@
 
 % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return.
 % for T, CT, f in AllFloatTypes():
-#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || CYGWIN
 @_transparent
 public func lgamma(_ x: ${T}) -> (${T}, Int) {
   var sign = Int32(0)
diff --git a/stdlib/public/Reflection/TypeRefBuilder.cpp b/stdlib/public/Reflection/TypeRefBuilder.cpp
index 27733ba..9ff750f 100644
--- a/stdlib/public/Reflection/TypeRefBuilder.cpp
+++ b/stdlib/public/Reflection/TypeRefBuilder.cpp
@@ -165,6 +165,8 @@
     MangledName = B->getMangledName();
   else if (auto N = dyn_cast<NominalTypeRef>(TR))
     MangledName = N->getMangledName();
+  else if (auto B = dyn_cast<BoundGenericTypeRef>(TR))
+    MangledName = B->getMangledName();
   else
     return nullptr;
 
diff --git a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
index ab81421..7191e4c 100644
--- a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
+++ b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift
@@ -313,6 +313,11 @@
   return lhs.dx == rhs.dx  &&  lhs.dy == rhs.dy
 }
 
+extension CGVector : CustomDebugStringConvertible {
+  public var debugDescription : String {
+    return "(\(dx), \(dy))"
+  }
+}
 
 public extension CGRect {
   static var zero: CGRect {
diff --git a/stdlib/public/SDK/Dispatch/Private.swift b/stdlib/public/SDK/Dispatch/Private.swift
index ffd5402..fe0a928 100644
--- a/stdlib/public/SDK/Dispatch/Private.swift
+++ b/stdlib/public/SDK/Dispatch/Private.swift
@@ -108,7 +108,7 @@
 	fatalError()
 }
 
-@available(*, unavailable, renamed:"DispatchQueue.asynchronously(self:group:qos:flags:execute:)")
+@available(*, unavailable, renamed:"DispatchQueue.async(self:group:qos:flags:execute:)")
 public func dispatch_group_async(_ group: DispatchGroup, _ queue: DispatchQueue, _ block: () -> Void)
 {
 	fatalError()
@@ -144,7 +144,7 @@
 	fatalError()
 }
 
-@available(*, unavailable, renamed:"DispatchQueue.asynchronously(self:execute:)")
+@available(*, unavailable, renamed:"DispatchQueue.async(self:execute:)")
 public func dispatch_async(_ queue: DispatchQueue, _ block: () -> Void)
 {
 	fatalError()
diff --git a/stdlib/public/SDK/Dispatch/Queue.swift b/stdlib/public/SDK/Dispatch/Queue.swift
index 2a3fc92..64315ab 100644
--- a/stdlib/public/SDK/Dispatch/Queue.swift
+++ b/stdlib/public/SDK/Dispatch/Queue.swift
@@ -340,10 +340,10 @@
 		return nil
 	}
 
-	public func setSpecific<T>(key: DispatchSpecificKey<T>, value: T) {
-		let v = _DispatchSpecificValue(value: value)
+	public func setSpecific<T>(key: DispatchSpecificKey<T>, value: T?) {
 		let k = Unmanaged.passUnretained(key).toOpaque()
-		let p = Unmanaged.passRetained(v).toOpaque()
+		let v = value.flatMap { _DispatchSpecificValue(value: $0) }
+		let p = v.flatMap { Unmanaged.passRetained($0).toOpaque() }
 		__dispatch_queue_set_specific(self, k, p, _destructDispatchSpecificValue)
 	}
 }
diff --git a/stdlib/public/SDK/Dispatch/Time.swift b/stdlib/public/SDK/Dispatch/Time.swift
index 6101bcd..6e6d625 100644
--- a/stdlib/public/SDK/Dispatch/Time.swift
+++ b/stdlib/public/SDK/Dispatch/Time.swift
@@ -111,12 +111,16 @@
 }
 
 public func +(time: DispatchTime, seconds: Double) -> DispatchTime {
-	let t = __dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC)))
+	let interval = seconds * Double(NSEC_PER_SEC)
+	let t = __dispatch_time(time.rawValue,
+		interval.isInfinite || interval.isNaN ? Int64.max : Int64(interval))
 	return DispatchTime(rawValue: t)
 }
 
 public func -(time: DispatchTime, seconds: Double) -> DispatchTime {
-	let t = __dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC)))
+	let interval = -seconds * Double(NSEC_PER_SEC)
+	let t = __dispatch_time(time.rawValue,
+		interval.isInfinite || interval.isNaN ? Int64.min : Int64(interval))
 	return DispatchTime(rawValue: t)
 }
 
@@ -131,11 +135,15 @@
 }
 
 public func +(time: DispatchWallTime, seconds: Double) -> DispatchWallTime {
-	let t = __dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC)))
+	let interval = seconds * Double(NSEC_PER_SEC)
+	let t = __dispatch_time(time.rawValue,
+		interval.isInfinite || interval.isNaN ? Int64.max : Int64(interval))
 	return DispatchWallTime(rawValue: t)
 }
 
 public func -(time: DispatchWallTime, seconds: Double) -> DispatchWallTime {
-	let t = __dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC)))
+	let interval = -seconds * Double(NSEC_PER_SEC)
+	let t = __dispatch_time(time.rawValue,
+		interval.isInfinite || interval.isNaN ? Int64.min : Int64(interval))
 	return DispatchWallTime(rawValue: t)
 }
diff --git a/stdlib/public/SDK/Foundation/AffineTransform.swift b/stdlib/public/SDK/Foundation/AffineTransform.swift
index 82ef2f7..34925d0 100644
--- a/stdlib/public/SDK/Foundation/AffineTransform.swift
+++ b/stdlib/public/SDK/Foundation/AffineTransform.swift
@@ -124,8 +124,8 @@
          [    0       0    1 ]
      */
     public init(rotationByDegrees angle: CGFloat) {
-        let α = Double(angle) * M_PI / 180.0
-        self.init(rotationByRadians: CGFloat(α))
+        let α = angle * .pi / 180.0
+        self.init(rotationByRadians: α)
     }
     
     /**
@@ -153,8 +153,8 @@
          [    0       0    1 ]
      */
     public mutating func rotate(byDegrees angle: CGFloat) {
-        let α = Double(angle) * M_PI / 180.0
-        return rotate(byRadians: CGFloat(α))
+        let α = angle * .pi / 180.0
+        return rotate(byRadians: α)
     }
     
     /**
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index 6dd6ce8..579c010 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -973,10 +973,10 @@
         }
     }
 
-    /// Initialze a `Data` with a repeating byte pattern
+    /// Initialize a `Data` with a repeating byte pattern
     ///
-    /// - parameter repeatedValue: A byte to initialze the pattern
-    /// - parameter count: The number of bytes the data initially contains initialzed to the repeatedValue
+    /// - parameter repeatedValue: A byte to initialize the pattern
+    /// - parameter count: The number of bytes the data initially contains initialized to the repeatedValue
     public init(repeating repeatedValue: UInt8, count: Int) {
         self.init(count: count)
         withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in
diff --git a/stdlib/public/SDK/XCTest/XCTest.swift b/stdlib/public/SDK/XCTest/XCTest.swift
index 7bf9237..683cbbe 100644
--- a/stdlib/public/SDK/XCTest/XCTest.swift
+++ b/stdlib/public/SDK/XCTest/XCTest.swift
@@ -297,8 +297,8 @@
             let expressionValueStr1 = String(describing: expressionValue1Optional)
             let expressionValueStr2 = String(describing: expressionValue2Optional)
 
-            // FIXME: this file seems to use `as NSString` unnecesarily a lot,
-            // unlesss I'm missing something.
+            // FIXME: this file seems to use `as NSString` unnecessarily a lot,
+            // unless I'm missing something.
             _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
         }
 
diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h
index 47b78d3..63f8b9a 100644
--- a/stdlib/public/SwiftShims/LibcShims.h
+++ b/stdlib/public/SwiftShims/LibcShims.h
@@ -91,30 +91,36 @@
 _swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound);
 
 // Math library functions
-static inline float _swift_stdlib_remainderf(float _self, float _other) {
+static inline __attribute__((always_inline))
+float _swift_stdlib_remainderf(float _self, float _other) {
   return __builtin_remainderf(_self, _other);
 }
   
-static inline float _swift_stdlib_squareRootf(float _self) {
-  return __builtin_sqrtf(_self);
+static inline __attribute__((always_inline))
+float _swift_stdlib_squareRootf(float _self) {
+  return __builtin_sqrt(_self);
 }
 
-static inline double _swift_stdlib_remainder(double _self, double _other) {
+static inline __attribute__((always_inline))
+double _swift_stdlib_remainder(double _self, double _other) {
   return __builtin_remainder(_self, _other);
 }
 
-static inline double _swift_stdlib_squareRoot(double _self) {
+static inline __attribute__((always_inline))
+double _swift_stdlib_squareRoot(double _self) {
   return __builtin_sqrt(_self);
 }
 
 // TODO: Remove horrible workaround when importer does Float80 <-> long double.
 #if (defined __i386__ || defined __x86_64__) && !defined _MSC_VER
-static inline void _swift_stdlib_remainderl(void *_self, const void *_other) {
+static inline __attribute__((always_inline))
+void _swift_stdlib_remainderl(void *_self, const void *_other) {
   long double *_f80self = (long double *)_self;
   *_f80self = __builtin_remainderl(*_f80self, *(const long double *)_other);
 }
 
-static inline void _swift_stdlib_squareRootl(void *_self) {
+static inline __attribute__((always_inline))
+void _swift_stdlib_squareRootl(void *_self) {
   long double *_f80self = (long double *)_self;
   *_f80self = __builtin_sqrtl(*_f80self);
 }
diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb
index 0ffe616..6b50ebc 100644
--- a/stdlib/public/core/Arrays.swift.gyb
+++ b/stdlib/public/core/Arrays.swift.gyb
@@ -1999,53 +1999,42 @@
     _arrayOutOfPlaceUpdate(&newBuffer, bufferCount, 0, _IgnorePointer())
   }
 
-  internal mutating func _arrayReserve(_ minimumCapacity: Int) {
-
-    let oldCount = self.count
-    let requiredCapacity = Swift.max(count, minimumCapacity)
-
-    if _fastPath(
-        requestUniqueMutableBackingBuffer(
-          minimumCapacity: requiredCapacity) != nil
-    ) {
-      return
-    }
-
-    var newBuffer = _forceCreateUniqueMutableBuffer(
-      newCount: oldCount, requiredCapacity: requiredCapacity)
-
-    _arrayOutOfPlaceUpdate(&newBuffer, oldCount, 0, _IgnorePointer())
-  }
-
   /// Append items from `newItems` to a buffer.
   internal mutating func _arrayAppendSequence<S : Sequence>(
     _ newItems: S
   ) where S.Iterator.Element == Element {
+    
+    // this function is only ever called from append(contentsOf:)
+    // which should always have exhausted its capacity before calling
+    _sanityCheck(count == capacity)
+    var newCount = self.count
 
+    // there might not be any elements to append remaining,
+    // so check for nil element first, then increase capacity,
+    // then inner-loop to fill that capacity with elements
     var stream = newItems.makeIterator()
     var nextItem = stream.next()
+    while nextItem != nil {
 
-    if nextItem == nil {
-      return
-    }
+      // grow capacity, first time around and when filled
+      var newBuffer = _forceCreateUniqueMutableBuffer(
+        countForNewBuffer: newCount, 
+        // minNewCapacity handles the exponential growth, just
+        // need to request 1 more than current count/capacity
+        minNewCapacity: newCount + 1)
 
-    // This will force uniqueness
-    var newCount = self.count
-    _arrayReserve(newCount + 1)
-    while true {
+      _arrayOutOfPlaceUpdate(&newBuffer, newCount, 0, _IgnorePointer())
+
       let currentCapacity = self.capacity
       let base = self.firstElementAddress
 
-      while (nextItem != nil) && newCount < currentCapacity {
-        (base + newCount).initialize(to: nextItem!)
+      // fill while there is another item and spare capacity
+      while let next = nextItem, newCount < currentCapacity {
+        (base + newCount).initialize(to: next)
         newCount += 1
         nextItem = stream.next()
       }
       self.count = newCount
-      if nextItem == nil {
-        return
-      }
-      self._arrayReserve(_growArrayCapacity(currentCapacity))
     }
   }
 }
diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift
index af4de77..c29bbc0 100644
--- a/stdlib/public/core/BridgeObjectiveC.swift
+++ b/stdlib/public/core/BridgeObjectiveC.swift
@@ -527,7 +527,6 @@
   return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
 }
 
-@_fixed_layout
 internal struct _CocoaFastEnumerationStackBuf {
   // Clang uses 16 pointers.  So do we.
   internal var _item0: UnsafeRawPointer?
diff --git a/stdlib/public/core/CTypes.swift b/stdlib/public/core/CTypes.swift
index fc1351b..8ae4b61 100644
--- a/stdlib/public/core/CTypes.swift
+++ b/stdlib/public/core/CTypes.swift
@@ -43,10 +43,18 @@
 public typealias CInt = Int32
 
 /// The C 'long' type.
+#if os(Windows) && !CYGWIN && arch(x86_64)
+public typealias CLong = Int32
+#else
 public typealias CLong = Int
+#endif
 
 /// The C 'long long' type.
+#if os(Windows) && !CYGWIN && arch(x86_64)
+public typealias CLongLong = Int
+#else
 public typealias CLongLong = Int64
+#endif
 
 /// The C 'float' type.
 public typealias CFloat = Float
diff --git a/stdlib/public/core/FloatingPoint.swift.gyb b/stdlib/public/core/FloatingPoint.swift.gyb
index 446b457..2e61719 100644
--- a/stdlib/public/core/FloatingPoint.swift.gyb
+++ b/stdlib/public/core/FloatingPoint.swift.gyb
@@ -1577,7 +1577,7 @@
   /// - Parameter value: A floating-point value.
   init(_ value: Double)
 
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
   /// Creates a new instance from the given value, rounded to the closest
   /// possible representation.
   ///
diff --git a/stdlib/public/core/FloatingPointParsing.swift.gyb b/stdlib/public/core/FloatingPointParsing.swift.gyb
index b647108..1fe02dd 100644
--- a/stdlib/public/core/FloatingPointParsing.swift.gyb
+++ b/stdlib/public/core/FloatingPointParsing.swift.gyb
@@ -38,7 +38,7 @@
 %   Self = floatName(bits)
 
 % if bits == 80:
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
 % end
 
 //===--- Parsing ----------------------------------------------------------===//
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index 395e58e..bb22661 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -66,7 +66,7 @@
 }%
 
 % if bits == 80:
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
 % end
 
 ${SelfDocComment}
@@ -706,7 +706,7 @@
   }
 }
 
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
 
 % builtinFloatLiteralBits = 80
 extension ${Self} : _ExpressibleByBuiltinFloatLiteral {
@@ -851,7 +851,7 @@
 %   That = src_type.stdlib_name
 
 %   if srcBits == 80:
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
 %   end
 
 %   if srcBits == bits:
diff --git a/stdlib/public/core/Policy.swift b/stdlib/public/core/Policy.swift
index cdf9a89..992de1d 100644
--- a/stdlib/public/core/Policy.swift
+++ b/stdlib/public/core/Policy.swift
@@ -104,7 +104,7 @@
 // IEEE Binary64, and we need 1 bit to represent the sign.  Instead of using
 // 1025, we use the next round number -- 2048.
 public typealias _MaxBuiltinIntegerType = Builtin.Int2048
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
 public typealias _MaxBuiltinFloatType = Builtin.FPIEEE80
 #else
 public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64
diff --git a/stdlib/public/core/Runtime.swift.gyb b/stdlib/public/core/Runtime.swift.gyb
index fb01bde..1d11ee4 100644
--- a/stdlib/public/core/Runtime.swift.gyb
+++ b/stdlib/public/core/Runtime.swift.gyb
@@ -348,7 +348,7 @@
 % for bits in [ 32, 64, 80 ]:
 
 % if bits == 80:
-#if !os(Windows) && (arch(i386) || arch(x86_64))
+#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
 % end
 
 @_silgen_name("swift_float${bits}ToString")
diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt
index 1fa324f..c67344f 100644
--- a/stdlib/public/runtime/CMakeLists.txt
+++ b/stdlib/public/runtime/CMakeLists.txt
@@ -62,6 +62,7 @@
     CygwinPort.cpp
     ImageInspectionELF.cpp
     ImageInspectionStatic.cpp
+    StaticBinaryELF.cpp
     ${swift_runtime_sources}
     ${swift_runtime_objc_sources}
     ${swift_runtime_leaks_sources})
@@ -76,7 +77,9 @@
   string(TOLOWER "${sdk}" lowercase_sdk)
 
   # These two libraries are only used with the static swiftcore
-  add_library(swiftImageInspectionStatic STATIC ImageInspectionStatic.cpp)
+  add_library(swiftImageInspectionStatic STATIC
+              ImageInspectionStatic.cpp
+              StaticBinaryELF.cpp)
   set_target_properties(swiftImageInspectionStatic PROPERTIES
     ARCHIVE_OUTPUT_DIRECTORY "${SWIFTSTATICLIB_DIR}/${lowercase_sdk}")
 
diff --git a/stdlib/public/runtime/CygwinPort.cpp b/stdlib/public/runtime/CygwinPort.cpp
index 82b5651..56b2907 100644
--- a/stdlib/public/runtime/CygwinPort.cpp
+++ b/stdlib/public/runtime/CygwinPort.cpp
@@ -30,9 +30,9 @@
 
 using namespace swift;
 
+#if !defined(_MSC_VER)
 static std::mutex swiftOnceMutex;
 
-#if !defined(_MSC_VER)
 void swift::_swift_once_f(uintptr_t *predicate, void *context,
                           void (*function)(void *)) {
   // FIXME: This implementation does a global lock, which is much worse than
diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp
index 690f051..3ff4184 100644
--- a/stdlib/public/runtime/Errors.cpp
+++ b/stdlib/public/runtime/Errors.cpp
@@ -152,7 +152,7 @@
 // The layout of this struct is CrashReporter ABI, so there are no ABI concerns
 // here.
 extern "C" {
-CRASH_REPORTER_CLIENT_HIDDEN
+LLVM_LIBRARY_VISIBILITY
 struct crashreporter_annotations_t gCRAnnotations
 __attribute__((__section__("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = {
     CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0};
diff --git a/stdlib/public/runtime/ImageInspectionStatic.cpp b/stdlib/public/runtime/ImageInspectionStatic.cpp
index 7031889..906e9f7 100644
--- a/stdlib/public/runtime/ImageInspectionStatic.cpp
+++ b/stdlib/public/runtime/ImageInspectionStatic.cpp
@@ -53,12 +53,4 @@
                                           typeMetadata.size);
 }
 
-// This is called from Errors.cpp when dumping a stack trace entry.
-// It could be implemented by parsing the ELF information in the
-// executable. For now it returns 0 for error (can't lookup address).
-int
-swift::lookupSymbol(const void *address, SymbolInfo *info) {
-  return 0;
-}
-
-#endif
+#endif // defined(__ELF__) && defined(__linux__)
diff --git a/stdlib/public/runtime/MutexWin32.cpp b/stdlib/public/runtime/MutexWin32.cpp
index 6f195df..0bcc500 100644
--- a/stdlib/public/runtime/MutexWin32.cpp
+++ b/stdlib/public/runtime/MutexWin32.cpp
@@ -15,7 +15,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(_WIN32) || defined(__CYGWIN__)
+#if defined(_WIN32)
 #include "swift/Runtime/Mutex.h"
 #include "swift/Runtime/Debug.h"
 
diff --git a/stdlib/public/runtime/StaticBinaryELF.cpp b/stdlib/public/runtime/StaticBinaryELF.cpp
new file mode 100644
index 0000000..d46f565
--- /dev/null
+++ b/stdlib/public/runtime/StaticBinaryELF.cpp
@@ -0,0 +1,324 @@
+//===--- StaticBinaryELF.cpp ----------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// Parse a static ELF binary to implement lookupSymbol() address lookup.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__ELF__) && defined(__linux__)
+
+#include "ImageInspection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "swift/Basic/Lazy.h"
+#include <cassert>
+#include <string>
+#include <vector>
+#include <elf.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <linux/limits.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+using namespace std;
+using namespace llvm;
+
+#ifdef __LP64__
+#define ELFCLASS ELFCLASS64
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Phdr Elf_Phdr;
+typedef Elf64_Addr Elf_Addr;
+typedef Elf64_Word Elf_Word;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Section Elf_Section;
+#define ELF_ST_TYPE(x) ELF64_ST_TYPE(x)
+#else
+#define ELFCLASS ELFCLASS32
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Phdr Elf_Phdr;
+typedef Elf32_Addr Elf_Addr;
+typedef Elf32_Word Elf_Word;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Section Elf_Section;
+#define ELF_ST_TYPE(x) ELF32_ST_TYPE(x)
+#endif
+
+extern const Elf_Ehdr elfHeader asm("__ehdr_start");
+
+class StaticBinaryELF {
+
+private:
+  // mmap a section of a file that might not be page aligned.
+  class Mapping {
+  public:
+    void *mapping;
+    size_t mapLength;
+    off_t diff;
+
+    Mapping(int fd, size_t fileSize, off_t offset, size_t length) {
+      if (fd < 0 || offset + length > fileSize) {
+        mapping = nullptr;
+        mapLength = 0;
+        diff = 0;
+        return;
+      }
+      long pageSize = sysconf(_SC_PAGESIZE);
+      long pageMask = ~(pageSize - 1);
+
+      off_t alignedOffset = offset & pageMask;
+      diff = (offset - alignedOffset);
+      mapLength = diff + length;
+      mapping = mmap(nullptr, mapLength, PROT_READ, MAP_PRIVATE, fd,
+                     alignedOffset);
+      if (mapping == MAP_FAILED) {
+        mapping = nullptr;
+        mapLength = 0;
+        diff = 0;
+      }
+    }
+
+    template<typename T>
+    ArrayRef<T> data() {
+      size_t elements = (mapLength - diff) / sizeof(T);
+      const T *data = reinterpret_cast<T *>(reinterpret_cast<char *>(mapping)
+                                            + diff);
+      return ArrayRef<T>(data, elements);
+    }
+
+    ~Mapping() {
+      if (mapping && mapLength > 0) {
+        munmap(mapping, mapLength);
+      }
+    }
+  };
+
+  string fullPathName;
+  const Elf_Phdr *programHeaders = nullptr;
+  Optional<Mapping> symbolTable;
+  Optional<Mapping> stringTable;
+
+public:
+  StaticBinaryELF() {
+    getExecutablePathName();
+
+    programHeaders = reinterpret_cast<const Elf_Phdr *>(getauxval(AT_PHDR));
+    if (programHeaders == nullptr) {
+      return;
+    }
+    // If an interpreter is set in the program headers then this is a
+    // dynamic executable and therefore not valid.
+    for (size_t idx = 0; idx < elfHeader.e_phnum; idx++) {
+      if (programHeaders[idx].p_type == PT_INTERP) {
+        programHeaders = nullptr;
+        return;
+      }
+    }
+
+    if (!fullPathName.empty()) {
+      mmapExecutable();
+    }
+  }
+
+  const char *getPathName() {
+    return fullPathName.empty() ? nullptr : fullPathName.c_str();
+  }
+
+  void *getSectionLoadAddress(const void *addr) {
+    if (programHeaders) {
+      auto searchAddr = reinterpret_cast<Elf_Addr>(addr);
+
+      for (size_t idx = 0; idx < elfHeader.e_phnum; idx++) {
+        auto header = &programHeaders[idx];
+        if (header->p_type == PT_LOAD && searchAddr >= header->p_vaddr
+            && searchAddr <= (header->p_vaddr + header->p_memsz)) {
+          return reinterpret_cast<void *>(header->p_vaddr);
+        }
+      }
+    }
+    return nullptr;
+  }
+
+  // Lookup a function symbol by address.
+  const Elf_Sym *findSymbol(const void *addr) {
+    if (symbolTable.hasValue()) {
+      auto searchAddr = reinterpret_cast<Elf_Addr>(addr);
+      auto symbols = symbolTable->data<Elf_Sym>();
+
+      for (size_t idx = 0; idx < symbols.size(); idx++) {
+        auto symbol = &symbols[idx];
+        if (ELF_ST_TYPE(symbol->st_info) == STT_FUNC
+            && searchAddr >= symbol->st_value
+            && searchAddr < (symbol->st_value + symbol->st_size)) {
+          return symbol;
+        }
+      }
+    }
+    return nullptr;
+  }
+
+  const char *symbolName(const Elf_Sym *symbol) {
+    if (stringTable.hasValue()) {
+      auto strings = stringTable->data<char>();
+      if (symbol->st_name < strings.size()) {
+        return &strings[symbol->st_name];
+      }
+    }
+    return nullptr;
+  }
+
+private:
+  // This is Linux specific - find the full path of the executable
+  // by looking in /proc/self/maps for a mapping holding the current
+  // address space. For a static binary it should only be mapping one
+  // file anyway. Don't use /proc/self/exe as the symlink will be removed
+  // if the main thread terminates - see proc(5).
+  void getExecutablePathName() {
+    uintptr_t address = (uintptr_t)&elfHeader;
+
+    FILE *fp = fopen("/proc/self/maps", "r");
+    if (!fp) {
+      perror("Unable to open /proc/self/maps");
+    } else {
+      char *line = nullptr;
+      size_t size = 0;
+      // Format is: addrLo-addrHi perms offset dev inode pathname.
+      // If the executable has been deleted the last column will be '(deleted)'.
+      StringRef deleted = StringRef("(deleted)");
+
+      while(getdelim(&line, &size, '\n', fp) != -1) {
+        StringRef entry = StringRef(line).rsplit('\n').first;
+        auto addrRange = entry.split(' ').first.split('-');
+        unsigned long long low = strtoull(addrRange.first.str().c_str(),
+                                          nullptr, 16);
+        if (low == 0 || low > UINTPTR_MAX || address < (uintptr_t)low) {
+          continue;
+        }
+
+        unsigned long long high = strtoull(addrRange.second.str().c_str(),
+                                           nullptr, 16);
+        if (high == 0 || high > UINTPTR_MAX || address > (uintptr_t)high) {
+          continue;
+        }
+
+        auto fname = entry.split('/').second;
+        if (fname.empty() || fname.endswith(deleted)) {
+          continue;
+        }
+
+        fullPathName = "/" + fname.str();
+        break;
+      }
+      if (line) {
+        free(line);
+      }
+      fclose(fp);
+    }
+  }
+
+
+  // Parse the ELF binary using mmap for the section headers, symbol table and
+  // string table.
+  void mmapExecutable() {
+    struct stat buf;
+    int fd = open(fullPathName.c_str(), O_RDONLY);
+    if (fd < 0) {
+      return;
+    }
+
+    if (fstat(fd, &buf) != 0) {
+      close(fd);
+      return;
+    }
+
+    // Map in the section headers.
+    size_t sectionHeadersSize = (elfHeader.e_shentsize * elfHeader.e_shnum);
+    Mapping sectionHeaders = Mapping(fd, buf.st_size, elfHeader.e_shoff,
+                                     sectionHeadersSize);
+    if (sectionHeaders.mapping) {
+      auto headers = sectionHeaders.data<Elf_Shdr>();
+      auto section = findSectionHeader(headers, SHT_SYMTAB);
+      if (section) {
+        assert(section->sh_entsize == sizeof(Elf_Sym));
+        symbolTable.emplace(fd, buf.st_size, section->sh_offset,
+                            section->sh_size);
+        if (symbolTable->mapping == nullptr) {
+          symbolTable.reset();
+        }
+      }
+      section = findSectionHeader(headers, SHT_STRTAB);
+      if (section) {
+        stringTable.emplace(fd, buf.st_size, section->sh_offset,
+                            section->sh_size);
+        if (stringTable->mapping == nullptr) {
+          stringTable.reset();
+        }
+      }
+    }
+    close(fd);
+    return;
+  }
+
+  // Find the section header of a specified type in the section headers table.
+  const Elf_Shdr *findSectionHeader(ArrayRef<Elf_Shdr> headers,
+                                    Elf_Word sectionType) {
+    assert(elfHeader.e_shnum == headers.size());
+    for (size_t idx = 0; idx < headers.size(); idx++) {
+      if (idx == elfHeader.e_shstrndx) {
+        continue;
+      }
+      auto header = &headers[idx];
+      if (header->sh_type == sectionType) {
+        if (header->sh_entsize > 0 && header->sh_size % header->sh_entsize) {
+          fprintf(stderr,
+                  "section size is not a multiple of entrysize (%ld/%ld)\n",
+                  header->sh_size, header->sh_entsize);
+          return nullptr;
+        }
+        return header;
+      }
+    }
+    return nullptr;
+  }
+};
+
+
+static swift::Lazy<StaticBinaryELF> TheBinary;
+
+int
+swift::lookupSymbol(const void *address, SymbolInfo *info) {
+  // The pointers returned point into the mmap()'d binary so keep the
+  // object once instantiated.
+  auto &binary = TheBinary.get();
+
+  info->fileName = binary.getPathName();
+  info->baseAddress = binary.getSectionLoadAddress(address);
+
+  auto symbol = binary.findSymbol(address);
+  if (symbol != nullptr) {
+    info->symbolAddress = reinterpret_cast<void *>(symbol->st_value);
+    info->symbolName = binary.symbolName(symbol);
+  } else {
+    info->symbolAddress = nullptr;
+    info->symbolName = nullptr;
+  }
+
+  return 1;
+}
+
+#endif // defined(__ELF__) && defined(__linux__)
diff --git a/stdlib/public/stubs/CommandLine.cpp b/stdlib/public/stubs/CommandLine.cpp
index 4110399..1c1813c 100644
--- a/stdlib/public/stubs/CommandLine.cpp
+++ b/stdlib/public/stubs/CommandLine.cpp
@@ -120,15 +120,15 @@
     return _swift_stdlib_ProcessOverrideUnsafeArgv;
   }
 
-  char *argPtr = NULL; // or use ARG_MAX? 8192 is used in LLDB though..
+  char *argPtr = nullptr; // or use ARG_MAX? 8192 is used in LLDB though..
   int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() };
   size_t argPtrSize = 0;
   for (int i = 0; i < 3 && !argPtr; i++) { // give up after 3 tries
-    if (sysctl(mib, 4, NULL, &argPtrSize, NULL, 0) != -1) {
+    if (sysctl(mib, 4, nullptr, &argPtrSize, nullptr, 0) != -1) {
       argPtr = (char *)malloc(argPtrSize);
-      if (sysctl(mib, 4, argPtr, &argPtrSize, NULL, 0) == -1) {
+      if (sysctl(mib, 4, argPtr, &argPtrSize, nullptr, 0) == -1) {
         free(argPtr);
-        argPtr = NULL;
+        argPtr = nullptr;
         if (errno != ENOMEM)
           break;
       }
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
index 1257ddc..747e0bb 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
@@ -39,6 +39,27 @@
   - Version: 3.0
     Classes:
       - Name: TestProperties
+        Methods:
+          - Selector: accessorsOnlyRenamedRetyped
+            MethodKind: Instance
+            SwiftName: 'renamedAndRetyped()'
+            ResultType: 'id _Nonnull'
+          - Selector: 'setAccessorsOnlyRenamedRetyped:'
+            MethodKind: Instance
+            SwiftName: 'setRenamedAndRetyped(_:)'
+            Parameters:
+              - Position: 0
+                Type: 'id _Nullable'
+          - Selector: accessorsOnlyRenamedRetypedClass
+            MethodKind: Class
+            SwiftName: 'renamedAndRetypedClass()'
+            ResultType: 'id _Nonnull'
+          - Selector: 'setAccessorsOnlyRenamedRetypedClass:'
+            MethodKind: Class
+            SwiftName: 'setRenamedAndRetypedClass(_:)'
+            Parameters:
+              - Position: 0
+                Type: 'id _Nullable'
         Properties:
           - Name: accessorsOnlyInVersion3
             PropertyKind:    Instance
@@ -52,6 +73,12 @@
           - Name: accessorsOnlyForClassExceptInVersion3
             PropertyKind:    Class
             SwiftImportAsAccessors: false
+          - Name: accessorsOnlyRenamedRetyped
+            PropertyKind:    Instance
+            SwiftImportAsAccessors: true
+          - Name: accessorsOnlyRenamedRetypedClass
+            PropertyKind:    Class
+            SwiftImportAsAccessors: true
     Functions:
       - Name: acceptDoublePointer
         SwiftName: 'acceptPointer(_:)'
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h
index 4300cc2..93ab5b0 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h
@@ -27,4 +27,9 @@
 @property (nonatomic, readwrite, retain) id accessorsOnlyWithNewType;
 @end
 
+@interface TestProperties (AccessorsOnlyCustomized)
+@property (nonatomic, readwrite, retain, null_resettable) id accessorsOnlyRenamedRetyped;
+@property (class, nonatomic, readwrite, retain, null_resettable) id accessorsOnlyRenamedRetypedClass;
+@end
+
 #pragma clang assume_nonnull end
diff --git a/test/APINotes/properties.swift b/test/APINotes/properties.swift
index 7d1d7f0..10e0da5 100644
--- a/test/APINotes/properties.swift
+++ b/test/APINotes/properties.swift
@@ -45,3 +45,13 @@
 // CHECK-BOTH-DAG: func setAccessorsOnlyWithNewType(_ accessorsOnlyWithNewType: Base)
 
 // CHECK-BOTH: {{^}$}}
+
+// CHECK-SWIFT-3-DAG: func renamedAndRetyped() -> Any{{$}}
+// CHECK-SWIFT-3-DAG: func setRenamedAndRetyped(_ accessorsOnlyRenamedRetyped: Any?)
+// CHECK-SWIFT-4-DAG: var accessorsOnlyRenamedRetyped: Any!
+
+// CHECK-SWIFT-3-DAG: class func renamedAndRetypedClass() -> Any{{$}}
+// CHECK-SWIFT-3-DAG: class func setRenamedAndRetypedClass(_ accessorsOnlyRenamedRetypedClass: Any?)
+// CHECK-SWIFT-4-DAG: class var accessorsOnlyRenamedRetypedClass: Any!
+
+// CHECK-BOTH: {{^}$}}
diff --git a/test/Compatibility/attr_objc.swift b/test/Compatibility/attr_objc.swift
new file mode 100644
index 0000000..a5ce190
--- /dev/null
+++ b/test/Compatibility/attr_objc.swift
@@ -0,0 +1,28 @@
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 3
+
+class Load1 {
+  class func load() { }
+  class func alloc() {}
+  class func allocWithZone(_: Int) {}
+  class func initialize() {}
+}
+
+@objc class Load2 {
+  class func load() { } // expected-error{{method 'load()' defines Objective-C class method 'load', which is not permitted by Swift}}
+  class func alloc() {} // expected-error{{method 'alloc()' defines Objective-C class method 'alloc', which is not permitted by Swift}}
+  class func allocWithZone(_: Int) {} // expected-error{{method 'allocWithZone' defines Objective-C class method 'allocWithZone:', which is not permitted by Swift}}
+  class func initialize() {} // expected-warning{{method 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions}}
+}
+
+@objc class Load3 {
+  class var load: Load3 {
+    get { return Load3() } // expected-error{{getter for 'load' defines Objective-C class method 'load', which is not permitted by Swift}}
+    set { }
+  }
+
+  @objc(alloc) class var prop: Int { return 0 } // expected-error{{getter for 'prop' defines Objective-C class method 'alloc', which is not permitted by Swift}}
+  @objc(allocWithZone:) class func fooWithZone(_: Int) {} // expected-error{{method 'fooWithZone' defines Objective-C class method 'allocWithZone:', which is not permitted by Swift}}
+  @objc(initialize) class func barnitialize() {} // expected-warning{{method 'barnitialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions}}
+}
+
+
diff --git a/test/Compatibility/bridging-nsnumber-and-nsvalue.swift.gyb b/test/Compatibility/bridging-nsnumber-and-nsvalue.swift.gyb
index 23781f7..11d60b0 100644
--- a/test/Compatibility/bridging-nsnumber-and-nsvalue.swift.gyb
+++ b/test/Compatibility/bridging-nsnumber-and-nsvalue.swift.gyb
@@ -91,33 +91,33 @@
   _ = dictKeys as? [${Type}: AnyObject]
   _ = dictKeys as! [${Type}: AnyObject]
 
-  _ = dictValues as  [AnyHashable: ${Type}] // expected-warning{{use 'as!'}}
-  _ = dictValues is  [AnyHashable: ${Type}]
+  _ = dictValues as [AnyHashable: ${Type}] // expected-warning{{use 'as!'}}
+  _ = dictValues is [AnyHashable: ${Type}]
   _ = dictValues as? [AnyHashable: ${Type}]
   _ = dictValues as! [AnyHashable: ${Type}]
 
-  _ = dictValues as  [NSObject: ${Type}] // expected-warning{{use 'as!'}}
-  _ = dictValues is  [NSObject: ${Type}]
+  _ = dictValues as [NSObject: ${Type}] // expected-warning{{use 'as!'}}
+  _ = dictValues is [NSObject: ${Type}]
   _ = dictValues as? [NSObject: ${Type}]
   _ = dictValues as! [NSObject: ${Type}]
 
-  _ = dictBoth as  [${ObjectType}: ${Type}] // expected-warning{{use 'as!'}}
-  _ = dictBoth is  [${ObjectType}: ${Type}]
+  _ = dictBoth as [${ObjectType}: ${Type}] // expected-warning{{use 'as!'}}
+  _ = dictBoth is [${ObjectType}: ${Type}]
   _ = dictBoth as? [${ObjectType}: ${Type}]
   _ = dictBoth as! [${ObjectType}: ${Type}]
 
-  _ = dictBoth as  [${Type}: ${ObjectType}] // expected-warning{{use 'as!'}}
-  _ = dictBoth is  [${Type}: ${ObjectType}]
+  _ = dictBoth as [${Type}: ${ObjectType}] // expected-warning{{use 'as!'}}
+  _ = dictBoth is [${Type}: ${ObjectType}]
   _ = dictBoth as? [${Type}: ${ObjectType}]
   _ = dictBoth as! [${Type}: ${ObjectType}]
 
-  _ = dictBoth as  [${Type}: ${Type}] // expected-warning{{use 'as!'}}
-  _ = dictBoth is  [${Type}: ${Type}]
+  _ = dictBoth as [${Type}: ${Type}] // expected-warning{{use 'as!'}}
+  _ = dictBoth is [${Type}: ${Type}]
   _ = dictBoth as? [${Type}: ${Type}]
   _ = dictBoth as! [${Type}: ${Type}]
 
-  _ = set as  Set<${Type}> // expected-warning{{use 'as!'}}
-  _ = set is  Set<${Type}>
+  _ = set as Set<${Type}> // expected-warning{{use 'as!'}}
+  _ = set is Set<${Type}>
   _ = set as? Set<${Type}>
   _ = set as! Set<${Type}>
 %   end
diff --git a/test/Compatibility/conditional_compiliation_expr.swift b/test/Compatibility/conditional_compiliation_expr.swift
new file mode 100644
index 0000000..b26cd51
--- /dev/null
+++ b/test/Compatibility/conditional_compiliation_expr.swift
@@ -0,0 +1,18 @@
+// RUN: %target-typecheck-verify-swift -D FOO -swift-version 3
+
+
+#if FOO = false
+// expected-warning @-1 {{ignoring invalid conditional compilation expression, which will be rejected in future version of Swift}}
+undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}}
+#else
+undefinedFunc() // ignored.
+#endif
+
+#if false
+
+#elseif !FOO ? false : true
+// expected-warning @-1 {{ignoring invalid conditional compilation expression, which will be rejected in future version of Swift}}
+undefinedFunc() // ignored.
+#else
+undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}}
+#endif
diff --git a/test/Compatibility/override.swift b/test/Compatibility/override.swift
new file mode 100644
index 0000000..ddfde0e
--- /dev/null
+++ b/test/Compatibility/override.swift
@@ -0,0 +1,11 @@
+// RUN: %target-typecheck-verify-swift -parse-as-library -swift-version 3
+
+class A { 
+  @objc func objcVirtualFunction() { } // expected-note{{overridden declaration is here}}
+}
+
+class B : A { }
+
+extension B { 
+  override func objcVirtualFunction() { } // expected-warning{{cannot override a non-dynamic class declaration from an extension}}
+}
diff --git a/test/Compatibility/tuple_arguments.swift b/test/Compatibility/tuple_arguments.swift
index 59645ec..227aafc 100644
--- a/test/Compatibility/tuple_arguments.swift
+++ b/test/Compatibility/tuple_arguments.swift
@@ -1274,6 +1274,10 @@
 // with single 'Any' parameter
 func takesAny(_: Any) {}
 
+enum HasAnyCase {
+  case any(_: Any)
+}
+
 do {
   let fn: (Any) -> () = { _ in }
 
@@ -1282,4 +1286,41 @@
 
   takesAny(123)
   takesAny(data: 123)
+
+  _ = HasAnyCase.any(123)
+  _ = HasAnyCase.any(data: 123)
+}
+
+// rdar://problem/29739905 - protocol extension methods on Array had
+// ParenType sugar stripped off the element type
+typealias BoolPair = (Bool, Bool)
+
+func processArrayOfFunctions(f1: [((Bool, Bool)) -> ()],
+                             f2: [(Bool, Bool) -> ()],
+                             c: Bool) {
+  let p = (c, c)
+
+  f1.forEach { block in
+    block(p)
+    block((c, c))
+    block(c, c)
+  }
+
+  f2.forEach { block in
+    block(p) // expected-error {{passing 2 arguments to a callee as a single tuple value has been removed in Swift 3}}
+    block((c, c))
+    block(c, c)
+  }
+
+  f2.forEach { (block: ((Bool, Bool)) -> ()) in
+    block(p)
+    block((c, c))
+    block(c, c)
+  }
+
+  f2.forEach { (block: (Bool, Bool) -> ()) in
+    block(p) // expected-error {{passing 2 arguments to a callee as a single tuple value has been removed in Swift 3}}
+    block((c, c))
+    block(c, c)
+  }
 }
diff --git a/test/Constraints/optional.swift b/test/Constraints/optional.swift
index 261c98c..1cfe594 100644
--- a/test/Constraints/optional.swift
+++ b/test/Constraints/optional.swift
@@ -166,13 +166,15 @@
 _?? = nil // expected-error {{'nil' requires a contextual type}}
 
 
+// rdar://problem/29993596
+func takeAnyObjects(_ lhs: AnyObject?, _ rhs: AnyObject?) { }
+
 infix operator !====
+
 func !====(_ lhs: AnyObject?, _ rhs: AnyObject?) -> Bool { return false }
 
-func calleeRdar29977523(_ lhs: AnyObject?, _ rhs: AnyObject?) { }
-
-func rdar29977523(lhs: AnyObject?!, rhs: AnyObject?) {
+func testAnyObjectImplicitForce(lhs: AnyObject?!, rhs: AnyObject?) {
   if lhs !==== rhs { }
 
-  calleeRdar29977523(lhs, rhs)
+  takeAnyObjects(lhs, rhs)
 }
diff --git a/test/Constraints/same_types.swift b/test/Constraints/same_types.swift
index 7bf37c0..92af412 100644
--- a/test/Constraints/same_types.swift
+++ b/test/Constraints/same_types.swift
@@ -56,14 +56,14 @@
 func fail1<
   T: Fooable, U: Fooable
 >(_ t: T, u: U) -> (X, Y)
-  where T.Foo == X, U.Foo == Y, T.Foo == U.Foo { // expected-error{{generic parameter 'Foo' cannot be equal to both 'X' and 'Y'}}
+  where T.Foo == X, U.Foo == Y, T.Foo == U.Foo { // expected-error{{generic parameter T.Foo cannot be equal to both 'X' and 'Y'}}
   return (t.foo, u.foo)
 }
 
 func fail2<
   T: Fooable, U: Fooable
 >(_ t: T, u: U) -> (X, Y)
-  where T.Foo == U.Foo, T.Foo == X, U.Foo == Y { // expected-error{{generic parameter 'Foo' cannot be equal to both 'X' and 'Y'}}
+  where T.Foo == U.Foo, T.Foo == X, U.Foo == Y { // expected-error{{generic parameter T.Foo cannot be equal to both 'X' and 'Y'}}
   return (t.foo, u.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Y'}}
 }
 
@@ -91,7 +91,7 @@
 func fail4<T: Barrable>(_ t: T) -> (Y, Z)
   where
   T.Bar == Y,
-  T.Bar.Foo == Z { // expected-error{{generic parameter 'Foo' cannot be equal to both 'Y.Foo' (aka 'X') and 'Z'}}
+  T.Bar.Foo == Z { // expected-error{{generic parameter T.Bar.Foo cannot be equal to both 'Y.Foo' (aka 'X') and 'Z'}}
   return (t.bar, t.bar.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Z'}}
 }
 
@@ -99,11 +99,11 @@
 func fail5<T: Barrable>(_ t: T) -> (Y, Z)
   where
   T.Bar.Foo == Z,
-  T.Bar == Y { // expected-error 2{{generic parameter 'Foo' cannot be equal to both 'Z' and 'Y.Foo'}}
+  T.Bar == Y { // expected-error 2{{generic parameter T.Bar.Foo cannot be equal to both 'Z' and 'Y.Foo' (aka 'X')}}
   return (t.bar, t.bar.foo) // expected-error{{cannot convert return expression of type 'X' to return type 'Z'}}
 }
 
-func test8<T: Fooable>(_ t: T) where T.Foo == X, T.Foo == Y {} // expected-error{{generic parameter 'Foo' cannot be equal to both 'X' and 'Y'}}
+func test8<T: Fooable>(_ t: T) where T.Foo == X, T.Foo == Y {} // expected-error{{generic parameter T.Foo cannot be equal to both 'X' and 'Y'}}
 
 func testAssocTypeEquivalence<T: Fooable>(_ fooable: T) -> X.Type
   where T.Foo == X {
diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift
index 75c7b22..f5c6b99 100644
--- a/test/Constraints/tuple_arguments.swift
+++ b/test/Constraints/tuple_arguments.swift
@@ -1259,6 +1259,10 @@
 // with single 'Any' parameter
 func takesAny(_: Any) {}
 
+enum HasAnyCase {
+  case any(_: Any)
+}
+
 do {
   let fn: (Any) -> () = { _ in }
 
@@ -1267,4 +1271,42 @@
 
   takesAny(123)
   takesAny(data: 123) // expected-error {{extraneous argument label 'data:' in call}}
+
+  _ = HasAnyCase.any(123)
+  _ = HasAnyCase.any(data: 123) // expected-error {{extraneous argument label 'data:' in call}}
+}
+
+// rdar://problem/29739905 - protocol extension methods on Array had
+// ParenType sugar stripped off the element type
+func processArrayOfFunctions(f1: [((Bool, Bool)) -> ()],
+                             f2: [(Bool, Bool) -> ()],
+                             c: Bool) {
+  let p = (c, c)
+
+  f1.forEach { block in
+    block(p)
+    block((c, c))
+    block(c, c) // expected-error {{extra argument in call}}
+  }
+
+  f2.forEach { block in
+  // expected-note@-1 2{{'block' declared here}}
+    block(p) // expected-error {{missing argument for parameter #2 in call}}
+    block((c, c)) // expected-error {{missing argument for parameter #2 in call}}
+    block(c, c)
+  }
+
+  f2.forEach { (block: ((Bool, Bool)) -> ()) in
+  // expected-error@-1 {{cannot convert value of type '(((Bool, Bool)) -> ()) -> ()' to expected argument type '((Bool, Bool) -> ()) -> Void'}}
+    block(p)
+    block((c, c))
+    block(c, c)
+  }
+
+  f2.forEach { (block: (Bool, Bool) -> ()) in
+  // expected-note@-1 2{{'block' declared here}}
+    block(p) // expected-error {{missing argument for parameter #2 in call}}
+    block((c, c)) // expected-error {{missing argument for parameter #2 in call}}
+    block(c, c)
+  }
 }
diff --git a/test/DebugInfo/bool.swift b/test/DebugInfo/bool.swift
index a1c5546..b46e81d 100644
--- a/test/DebugInfo/bool.swift
+++ b/test/DebugInfo/bool.swift
@@ -3,7 +3,7 @@
 func markUsed<T>(_ t: T) {}
 
 // Int1 uses 1 bit, but is aligned at 8 bits.
-// CHECK: !DIBasicType(name: "_TtBi1_", size: 1, align: 8, encoding: DW_ATE_unsigned)
+// CHECK: !DIBasicType(name: "_TtBi1_", size: 1, encoding: DW_ATE_unsigned)
 func main() {
   var t = true
   var f = false
diff --git a/test/DebugInfo/nostorage.swift b/test/DebugInfo/nostorage.swift
index ffb6cf1..80badb8 100644
--- a/test/DebugInfo/nostorage.swift
+++ b/test/DebugInfo/nostorage.swift
@@ -36,6 +36,9 @@
 
 public enum empty { case exists }
 public let globalvar = empty.exists
-// CHECK3: !DIGlobalVariable(name: "globalvar", {{.*}}line: [[@LINE-1]],
-// CHECK3-SAME:          isLocal: false, isDefinition: true, expr: ![[ZERO:.*]])
-// CHECK3: ![[ZERO]] = !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)
+// CHECK3: !DIGlobalVariableExpression(var: ![[VAR:[0-9]+]],
+// CHECK3-SAME:          expr: ![[EXPR:[0-9]+]])
+// CHECK3: ![[VAR]] = distinct !DIGlobalVariable(name: "globalvar",
+// CHECK3-SAME:          {{.*}}line: [[@LINE-4]], {{.*}}isLocal: false,
+// CHECK3-SAME:          isDefinition: true)
+// CHECK3: ![[EXPR]] = !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)
diff --git a/test/DebugInfo/top_level_code.swift b/test/DebugInfo/top_level_code.swift
index 561db23..e7dc26f 100644
--- a/test/DebugInfo/top_level_code.swift
+++ b/test/DebugInfo/top_level_code.swift
@@ -3,12 +3,13 @@
 // XFAIL: linux
 
 func markUsed<T>(_ t: T) {}
+// CHECK: _main:
+// CHECK-NEXT: Lfunc_begin0:
+// Verify that the top-level function (main) begins at line 0 and then
+// proceeds to the first line.
+// CHECK: .loc    {{[0-9]}} 0 {{[0-9]}} 
+// CHECK-NOT: Lfunc_end0:
+// CHECK: .loc    {{[0-9]}} [[@LINE+1]] {{[0-9]}} prologue_end
 var a = 1
 var b = 2
 markUsed(a+b)
-// CHECK: _main:
-// Verify that the top-level function (main) begins at line 0 and then
-// proceeds to line 6.
-// CHECK: .loc    {{[0-9]}} 0 {{[0-9]}} 
-// CHECK-NOT: .loc
-// CHECK: .loc    {{[0-9]}} 6 {{[0-9]}} prologue_end
diff --git a/test/Driver/Dependencies/Inputs/touch.py b/test/Driver/Dependencies/Inputs/touch.py
index 6c186eb..99e9c33 100755
--- a/test/Driver/Dependencies/Inputs/touch.py
+++ b/test/Driver/Dependencies/Inputs/touch.py
@@ -11,7 +11,7 @@
 #
 # ----------------------------------------------------------------------------
 #
-# Like /bin/touch, but takes a time using the LLVM epoch.
+# Like /bin/touch, but takes a time using the system_clock epoch.
 #
 # ----------------------------------------------------------------------------
 
@@ -21,9 +21,6 @@
 assert len(sys.argv) >= 2
 timeVal = int(sys.argv[1])
 
-# offset between Unix and LLVM epochs
-timeVal += 946684800
-
 # Update the output file mtime, or create it if necessary.
 # From http://stackoverflow.com/a/1160227.
 for outputFile in sys.argv[1:]:
diff --git a/test/Driver/crash.swift b/test/Driver/crash.swift
index 8d271c0..1380315 100644
--- a/test/Driver/crash.swift
+++ b/test/Driver/crash.swift
@@ -2,7 +2,7 @@
 
 // RUN: not %swiftc_driver -emit-executable -o %t.exe %s -Xfrontend -debug-crash-after-parse 2>&1 | %FileCheck %s
 
-// CHECK: error: compile command failed due to signal
+// CHECK: error: compile command failed due to signal {{-?[0-9]+}}
 
 func anchor() {}
 anchor()
diff --git a/test/Driver/driver-time-compilation.swift b/test/Driver/driver-time-compilation.swift
index 2d488a8..198ff9b 100644
--- a/test/Driver/driver-time-compilation.swift
+++ b/test/Driver/driver-time-compilation.swift
@@ -1,7 +1,7 @@
 // RUN: %target-build-swift -typecheck -driver-time-compilation %s 2>&1 | %FileCheck %s
 // RUN: %target-build-swift -typecheck -driver-time-compilation %s %S/../Inputs/empty.swift 2>&1 | %FileCheck -check-prefix CHECK-MULTIPLE %s
 
-// CHECK: Driver Time Compilation
+// CHECK: Driver Compilation Time
 // CHECK: Total Execution Time: {{[0-9]+}}.{{[0-9]+}} seconds ({{[0-9]+}}.{{[0-9]+}} wall clock)
 // CHECK: ---Wall Time---
 // CHECK: --- Name ---
diff --git a/test/Driver/dump-parse.swift b/test/Driver/dump-parse.swift
index 49ab9b3..cb154d9 100644
--- a/test/Driver/dump-parse.swift
+++ b/test/Driver/dump-parse.swift
@@ -28,3 +28,29 @@
   // CHECK-AST-NEXT:   (declref_expr type='{{[^']+}}' {{.*}} decl=main.(file).foo
   foo foo foo
 }
+
+// CHECK-LABEL: (enum_decl trailing_semi "TrailingSemi"
+enum TrailingSemi {
+
+  // CHECK-LABEL: (enum_case_decl trailing_semi
+  // CHECK-NOT:   (enum_element_decl{{.*}}trailing_semi
+  // CHECK:       (enum_element_decl "A")
+  // CHECK:       (enum_element_decl "B")
+  case A,B;
+
+  // CHECK-LABEL: (subscript_decl trailing_semi
+  // CHECK-NOT:   (func_decl trailing_semi 'anonname={{.*}}' getter_for=subscript(_:)
+  // CHECK:       (func_decl 'anonname={{.*}}' getter_for=subscript(_:)
+  subscript(x: Int) -> Int {
+    // CHECK-LABEL: (pattern_binding_decl trailing_semi
+    // CHECK-NOT:   (var_decl trailing_semi "y"
+    // CHECK:       (var_decl "y"
+    var y = 1;
+
+    // CHECK-LABEL: (sequence_expr {{.*}} trailing_semi
+    y += 1;
+
+    // CHECK-LABEL: (return_stmt trailing_semi
+    return y;
+  };
+};
diff --git a/test/Generics/associated_type_typo.swift b/test/Generics/associated_type_typo.swift
index be337f4..de3849c 100644
--- a/test/Generics/associated_type_typo.swift
+++ b/test/Generics/associated_type_typo.swift
@@ -39,11 +39,10 @@
 // CHECK-GENERIC-LABEL: .typoAssoc4@
 // CHECK-GENERIC-NEXT: Requirements:
 // CHECK-GENERIC-NEXT:   T : P2 [explicit
-// CHECK-GENERIC-NEXT:   T[.P2].AssocP2 == T[.P2].AssocP2 [redundant]
 // CHECK-GENERIC-NEXT:   T[.P2].AssocP2 : P1 [protocol
-// CHECK-GENERIC-NEXT:   T[.P2].AssocP2[.P1].Assoc == T[.P2].AssocP2[.P1].Assoc [redundant
+// CHECK-GENERIC-NEXT:   T[.P2].AssocP2 == T[.P2].AssocP2 [redundant]
 // CHECK-GENERIC-NEXT:   T[.P2].AssocP2[.P1].Assoc : P3 [explicit
-// CHECK-GENERIC-NEXT:   T[.P2].AssocP2[.P1].Assoc == T[.P2].AssocP2[.P1].Assoc [redundant]
+// CHECK-GENERIC-NEXT:   T[.P2].AssocP2[.P1].Assoc == T[.P2].AssocP2[.P1].Assoc [redundant
 // CHECK-GENERIC-NEXT: Generic signature
 
 // <rdar://problem/19620340>
@@ -73,7 +72,6 @@
   associatedtype Element : Equatable
   
   // FIXME: Diagnostics here are very poor
-  // expected-error@+4{{'C.Slice' does not have a member type named 'Iterator'; did you mean 'Slice'?}}
   // expected-error@+3{{'C' does not have a member type named 'Iterator'; did you mean 'Slice'?}}
   // expected-error@+2{{'C.Slice' does not have a member type named 'Element'; did you mean 'Slice'?}}
   // expected-error@+1{{'C.Slice' does not have a member type named 'Iterator'; did you mean 'Slice'?}}
diff --git a/test/Generics/generic_types.swift b/test/Generics/generic_types.swift
index dc563fc..62dec49 100644
--- a/test/Generics/generic_types.swift
+++ b/test/Generics/generic_types.swift
@@ -167,6 +167,7 @@
 
 var dfail : Dictionary<Int> // expected-error{{generic type 'Dictionary' specialized with too few type parameters (got 1, but expected 2)}}
 var notgeneric : Int<Float> // expected-error{{cannot specialize non-generic type 'Int'}}{{21-28=}}
+var notgenericNested : Array<Int<Float>> // expected-error{{cannot specialize non-generic type 'Int'}}{{33-40=}}
 
 // Make sure that redundant typealiases (that map to the same
 // underlying type) don't break protocol conformance or use.
diff --git a/test/IRGen/Inputs/c_functions.h b/test/IRGen/Inputs/c_functions.h
index 5591371..700d677 100644
--- a/test/IRGen/Inputs/c_functions.h
+++ b/test/IRGen/Inputs/c_functions.h
@@ -2,3 +2,10 @@
 
 void overloaded(void) __attribute__((overloadable));
 void overloaded(int) __attribute__((overloadable));
+
+extern void use(const char *);
+
+static inline void test_my_log() {
+  __attribute__((internal_linkage)) static const char fmt[] = "foobar";
+  use(fmt);
+}
diff --git a/test/IRGen/autolink-coff-x86.swift b/test/IRGen/autolink-coff-x86.swift
new file mode 100644
index 0000000..cc372d2
--- /dev/null
+++ b/test/IRGen/autolink-coff-x86.swift
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+
+// RUN: %swift -target x86_64--windows-gnu -parse-as-library -parse-stdlib -emit-module-path %t/module.swiftmodule -module-name module -module-link-name module %s
+// RUN: %swift -target x86_64--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -emit-ir -o - %s | %FileCheck %s -check-prefix CHECK-GNU-IR
+// RUN: %swift -target x86_64--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -S -o - %s | %FileCheck %s -check-prefix CHECK-GNU-ASM
+
+// REQUIRES: CODEGENERATOR=X86
+
+#if MAIN_MODULE
+import module
+#endif
+
+// CHECK-GNU-IR: @_swift1_autolink_entries = private constant [9 x i8] c"-lmodule\00", section ".swift1_autolink_entries", align 8
+// CHECK-GNU-IR: @llvm.used = appending global [{{.*}} x i8*] [{{.*}}i8* getelementptr inbounds ([9 x i8], [9 x i8]* @_swift1_autolink_entries, i32 0, i32 0){{.*}}], section "llvm.metadata", align 8
+
+// CHECK-GNU-ASM: .section	.swift1_autolink_entries{{.*}}
+// CHECK-GNU-ASM: .asciz  "-lmodule"
diff --git a/test/IRGen/autolink-coff.swift b/test/IRGen/autolink-coff.swift
index ded2e97..a1c1bac 100644
--- a/test/IRGen/autolink-coff.swift
+++ b/test/IRGen/autolink-coff.swift
@@ -1,10 +1,6 @@
 // RUN: rm -rf %t
 // RUN: mkdir -p %t
 
-// RUN: %swift -target thumbv7--windows-gnu -parse-as-library -parse-stdlib -emit-module-path %t/module.swiftmodule -module-name module -module-link-name module %s
-// RUN: %swift -target thumbv7--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -emit-ir -o - %s | %FileCheck %s -check-prefix CHECK-GNU-IR
-// RUN: %swift -target thumbv7--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -S -o - %s | %FileCheck %s -check-prefix CHECK-GNU-ASM
-
 // RUN: %swift -target thumbv7--windows-itanium -parse-as-library -parse-stdlib -emit-module-path %t/module.swiftmodule -module-name module -module-link-name module %s
 // RUN: %swift -target thumbv7--windows-itanium -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -emit-ir -o - %s | %FileCheck %s -check-prefix CHECK-MSVC-IR
 // RUN: %swift -target thumbv7--windows-itanium -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -S -o - %s | %FileCheck %s -check-prefix CHECK-MSVC-ASM
@@ -19,13 +15,6 @@
 import module
 #endif
 
-// CHECK-GNU-IR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"Linker Options", [[NODE:![0-9]+]]}
-// CHECK-GNU-IR: [[NODE]] = !{[[LIST:![0-9]+]]}
-// CHECK-GNU-IR: [[LIST]] = !{!"-lmodule"}
-
-// CHECK-GNU-ASM: .section .drectve
-// CHECK-GNU-ASM: .ascii " -lmodule"
-
 // CHECK-MSVC-IR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"Linker Options", [[NODE:![0-9]+]]}
 // CHECK-MSVC-IR: [[NODE]] = !{[[LIST:![0-9]+]]}
 // CHECK-MSVC-IR: [[LIST]] = !{!"/DEFAULTLIB:module.lib"}
diff --git a/test/IRGen/builtin_math.swift b/test/IRGen/builtin_math.swift
index f51b0ac..43a84b5 100644
--- a/test/IRGen/builtin_math.swift
+++ b/test/IRGen/builtin_math.swift
@@ -38,6 +38,20 @@
   return sqrt(f)
 }
 
+// CHECK-LABEL: define {{.*}}test3a
+// CHECK: call double @remainder
+
+public func test3a(d : Double) -> Double {
+  return remainder(1,d)
+}
+
+// CHECK-LABEL: define {{.*}}test4a
+// CHECK: call float @remainder
+
+public func test4a(f : Float) -> Float {
+  return remainder(1,f)
+}
+
 // CHECK-LABEL: define {{.*}}test5
 // CHECK: ret float 2
 
diff --git a/test/IRGen/c_functions.swift b/test/IRGen/c_functions.swift
index 853927a..9e9b7e8 100644
--- a/test/IRGen/c_functions.swift
+++ b/test/IRGen/c_functions.swift
@@ -9,4 +9,6 @@
   overloaded()
   // CHECK: call void @_Z10overloadedi(i32{{( signext)?}} 42)
   overloaded(42)
+  // CHECK: call void @{{.*}}test_my_log
+  test_my_log()
 } // CHECK: {{^}$}}
diff --git a/test/IRGen/c_globals.swift b/test/IRGen/c_globals.swift
index 2586e84..a37b079 100644
--- a/test/IRGen/c_globals.swift
+++ b/test/IRGen/c_globals.swift
@@ -31,5 +31,5 @@
   }) // CHECK: {{^}$}}
 }
 
-// CHECK-DAG: attributes [[CLANG_FUNC_ATTR]] = { inlinehint nounwind {{.*}}"no-frame-pointer-elim"="true"{{.*}}
+// CHECK-DAG: attributes [[CLANG_FUNC_ATTR]] = { noinline nounwind {{.*}}"no-frame-pointer-elim"="true"{{.*}}
 // CHECK-DAG: attributes [[SWIFT_FUNC_ATTR]] = { "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "target-cpu"
diff --git a/test/IRGen/clang_inline.swift b/test/IRGen/clang_inline.swift
index a342256..d66ee06 100644
--- a/test/IRGen/clang_inline.swift
+++ b/test/IRGen/clang_inline.swift
@@ -1,9 +1,14 @@
+// These run lines use "-Xcc -O3" to trick Clang into emitting IR as /if/ we
+// were going to optimize without actually running the optimizer. This lets us
+// check that the static inline functions in Gizmo.h are correctly emitted as
+// inlineable.
+
 // RUN: rm -rf %t && mkdir -p %t
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -emit-ir | %FileCheck %s
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -Xcc -O3 -emit-ir | %FileCheck %s
 
 // RUN: mkdir -p %t/Empty.framework/Modules/Empty.swiftmodule
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module-path %t/Empty.framework/Modules/Empty.swiftmodule/%target-swiftmodule-name %S/../Inputs/empty.swift -module-name Empty
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -F %t -DIMPORT_EMPTY -emit-ir > %t.ll
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -sdk %S/Inputs -primary-file %s -F %t -DIMPORT_EMPTY -Xcc -O3 -emit-ir > %t.ll
 // RUN: %FileCheck %s < %t.ll
 // RUN: %FileCheck -check-prefix=NEGATIVE %s < %t.ll
 
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index f37e8d9..67a16f2 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -1,5 +1,9 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -enable-class-resilience -O %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-class-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience %s | %FileCheck %s
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -enable-class-resilience -O %s
 
 // CHECK: %swift.type = type { [[INT:i32|i64]] }
 
diff --git a/test/IRGen/class_resilience_objc.swift b/test/IRGen/class_resilience_objc.swift
index 054ae6f..e6636f0 100644
--- a/test/IRGen/class_resilience_objc.swift
+++ b/test/IRGen/class_resilience_objc.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
 
 // REQUIRES: objc_interop
 // XFAIL: CPU=armv7k
diff --git a/test/IRGen/class_resilience_objc_armv7k.swift b/test/IRGen/class_resilience_objc_armv7k.swift
index 5ea677f..f6af727 100644
--- a/test/IRGen/class_resilience_objc_armv7k.swift
+++ b/test/IRGen/class_resilience_objc_armv7k.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK
 
 // REQUIRES: objc_interop
 // REQUIRES: CPU=armv7k
diff --git a/test/IRGen/dllimport.swift b/test/IRGen/dllimport.swift
index 17ec043..f637ced 100644
--- a/test/IRGen/dllimport.swift
+++ b/test/IRGen/dllimport.swift
@@ -1,5 +1,5 @@
 // RUN: %swift -target thumbv7--windows-itanium -emit-ir -parse-as-library -parse-stdlib -module-name dllimport %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-NO-OPT
-// RUN: %swift -target thumbv7--windows-itanium -O -emit-ir -parse-as-library -parse-stdlib -module-name dllimport %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-OPT
+// RUN: %swift -target thumbv7--windows-itanium -O -emit-ir -parse-as-library -parse-stdlib -module-name dllimport -primary-file %s -o - -enable-source-import -I %S | %FileCheck %s -check-prefix CHECK -check-prefix CHECK-OPT
 
 // REQUIRES: CODEGENERATOR=ARM
 
@@ -65,7 +65,6 @@
 // CHECK-OPT-DAG: declare dllimport %swift.type* @_TMaC9dllexport1c()
 // CHECK-OPT-DAG: declare dllimport void @swift_deallocClassInstance(%swift.refcounted*, i32, i32)
 // CHECK-OPT-DAG: declare dllimport %swift.refcounted* @_TFC9dllexport1cd(%C9dllexport1c*)
-// CHECK-OPT-DAG: declare dllimport void @swift_deletedMethodError()
 // CHECK-OPT-DAG: define linkonce_odr hidden i8* @swift_rt_swift_slowAlloc(i32, i32)
 // CHECK-OPT-DAG: define linkonce_odr hidden void @swift_rt_swift_slowDealloc(i8*, i32, i32)
 
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index 5b44a75..2173ba4 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -1,5 +1,8 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience %s | %FileCheck %s
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O %s
 
 import resilient_enum
 import resilient_struct
diff --git a/test/IRGen/generic_metatypes.swift b/test/IRGen/generic_metatypes.swift
index cfdf69c..9fabc60 100644
--- a/test/IRGen/generic_metatypes.swift
+++ b/test/IRGen/generic_metatypes.swift
@@ -4,21 +4,13 @@
 // RUN: %swift -target i386-apple-tvos9.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
 // RUN: %swift -target x86_64-apple-tvos9.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s
 // RUN: %swift -target i386-apple-watchos2.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
-// RUN: %swift -target armv7-apple-ios7.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
-// RUN: %swift -target arm64-apple-ios7.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s
-// RUN: %swift -target armv7-apple-tvos9.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
-// RUN: %swift -target arm64-apple-tvos9.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s
-// RUN: %swift -target armv7k-apple-watchos2.0 -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
 // RUN: %swift -target x86_64-unknown-linux-gnu -disable-objc-interop -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s
 
 // REQUIRES: CODEGENERATOR=X86
 
-// FIXME: SR-3591 test is failing after being unintentionally disabled for a while
-// REQUIRES: SR3591
-
 // CHECK: define hidden %swift.type* [[GENERIC_TYPEOF:@_TF17generic_metatypes13genericTypeof.*]](%swift.opaque* noalias nocapture, %swift.type* [[TYPE:%.*]])
 func genericTypeof<T>(_ x: T) -> T.Type {
-  // CHECK: [[METATYPE:%.*]] = call %swift.type* @swift_getDynamicType(%swift.opaque* {{.*}}, %swift.type* [[TYPE]])
+  // CHECK: [[METATYPE:%.*]] = call %swift.type* @swift_getDynamicType(%swift.opaque* {{.*}}, %swift.type* [[TYPE]], i1 false)
   // CHECK: ret %swift.type* [[METATYPE]]
   return type(of: x)
 }
@@ -65,7 +57,7 @@
   // CHECK-64: [[PROJECT:%.*]] = bitcast i8* [[PROJECT_PTR]] to %swift.opaque* ([24 x i8]*, %swift.type*)*
   // CHECK-32: [[PROJECTION:%.*]] = call %swift.opaque* [[PROJECT]]([12 x i8]* [[BUFFER]], %swift.type* [[METADATA]])
   // CHECK-64: [[PROJECTION:%.*]] = call %swift.opaque* [[PROJECT]]([24 x i8]* [[BUFFER]], %swift.type* [[METADATA]])
-  // CHECK: [[METATYPE:%.*]] = call %swift.type* @swift_getDynamicType(%swift.opaque* [[PROJECTION]], %swift.type* [[METADATA]])
+  // CHECK: [[METATYPE:%.*]] = call %swift.type* @swift_getDynamicType(%swift.opaque* [[PROJECTION]], %swift.type* [[METADATA]], i1 true)
   // CHECK: [[T0:%.*]] = getelementptr inbounds %P17generic_metatypes3Bas_, %P17generic_metatypes3Bas_* [[X]], i32 0, i32 2
   // CHECK-32: [[WTABLE:%.*]] = load i8**, i8*** [[T0]], align 4
   // CHECK-64: [[WTABLE:%.*]] = load i8**, i8*** [[T0]], align 8
diff --git a/test/IRGen/generic_metatypes_arm.swift b/test/IRGen/generic_metatypes_arm.swift
new file mode 100644
index 0000000..09cdb1b
--- /dev/null
+++ b/test/IRGen/generic_metatypes_arm.swift
@@ -0,0 +1,209 @@
+// RUN: %swift -target armv7-apple-ios7.0 -module-name generic_metatypes -emit-ir -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
+// RUN: %swift -target arm64-apple-ios7.0 -emit-ir -module-name generic_metatypes -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s
+// RUN: %swift -target armv7-apple-tvos9.0 -emit-ir -module-name generic_metatypes -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
+// RUN: %swift -target arm64-apple-tvos9.0 -emit-ir -module-name generic_metatypes -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s
+// RUN: %swift -target armv7k-apple-watchos2.0 -emit-ir -module-name generic_metatypes -parse-stdlib -primary-file %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s
+
+// REQUIRES: CODEGENERATOR=ARM
+
+// CHECK: define hidden %swift.type* [[GENERIC_TYPEOF:@_TF17generic_metatypes13genericTypeof.*]](%swift.opaque* noalias nocapture, %swift.type* [[TYPE:%.*]])
+func genericTypeof<T>(_ x: T) -> T.Type {
+  // CHECK: [[METATYPE:%.*]] = call %swift.type* @swift_getDynamicType(%swift.opaque* {{.*}}, %swift.type* [[TYPE]], i1 false)
+  // CHECK: ret %swift.type* [[METATYPE]]
+  return type(of: x)
+}
+
+struct Foo {}
+class Bar {}
+
+// CHECK: define hidden %swift.type* @_TF17generic_metatypes27remapToSubstitutedMetatypes{{.*}}(%C17generic_metatypes3Bar*) {{.*}} {
+func remapToSubstitutedMetatypes(_ x: Foo, y: Bar)
+  -> (Foo.Type, Bar.Type)
+{
+  // CHECK: call %swift.type* [[GENERIC_TYPEOF]](%swift.opaque* noalias nocapture undef, %swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}})
+  // CHECK: [[T0:%.*]] = call %swift.type* @_TMaC17generic_metatypes3Bar()
+  // CHECK: [[BAR_META:%.*]] = call %swift.type* [[GENERIC_TYPEOF]](%swift.opaque* noalias nocapture {{%.*}}, %swift.type* [[T0]])
+  // CHECK: ret %swift.type* [[BAR_META]]
+  return (genericTypeof(x), genericTypeof(y))
+}
+
+
+// CHECK: define hidden void @_TF17generic_metatypes23remapToGenericMetatypesFT_T_()
+func remapToGenericMetatypes() {
+  // CHECK: [[T0:%.*]] = call %swift.type* @_TMaC17generic_metatypes3Bar()
+  // CHECK: call void @_TF17generic_metatypes16genericMetatypes{{.*}}(%swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}} %swift.type* [[T0]], %swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}} %swift.type* [[T0]])
+  genericMetatypes(Foo.self, Bar.self)
+}
+
+func genericMetatypes<T, U>(_ t: T.Type, _ u: U.Type) {}
+
+protocol Bas {}
+
+// CHECK: define hidden { %swift.type*, i8** } @_TF17generic_metatypes14protocolTypeof{{.*}}(%P17generic_metatypes3Bas_* noalias nocapture dereferenceable({{.*}}))
+func protocolTypeof(_ x: Bas) -> Bas.Type {
+  // CHECK: [[METADATA_ADDR:%.*]] = getelementptr inbounds %P17generic_metatypes3Bas_, %P17generic_metatypes3Bas_* [[X:%.*]], i32 0, i32 1
+  // CHECK: [[METADATA:%.*]] = load %swift.type*, %swift.type** [[METADATA_ADDR]]
+  // CHECK: [[BUFFER:%.*]] = getelementptr inbounds %P17generic_metatypes3Bas_, %P17generic_metatypes3Bas_* [[X]], i32 0, i32 0
+  // CHECK: [[METADATA_I8:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
+  // CHECK-32: [[VW_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_I8]], i32 -1
+  // CHECK-64: [[VW_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_I8]], i64 -1
+  // CHECK: [[VW:%.*]] = load i8**, i8*** [[VW_ADDR]]
+  // CHECK: [[PROJECT_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VW]], i32 2
+  // CHECK-32: [[PROJECT_PTR:%.*]] = load i8*, i8** [[PROJECT_ADDR]], align 4
+  // CHECK-64: [[PROJECT_PTR:%.*]] = load i8*, i8** [[PROJECT_ADDR]], align 8
+  // CHECK-32: [[PROJECT:%.*]] = bitcast i8* [[PROJECT_PTR]] to %swift.opaque* ([12 x i8]*, %swift.type*)*
+  // CHECK-64: [[PROJECT:%.*]] = bitcast i8* [[PROJECT_PTR]] to %swift.opaque* ([24 x i8]*, %swift.type*)*
+  // CHECK-32: [[PROJECTION:%.*]] = call %swift.opaque* [[PROJECT]]([12 x i8]* [[BUFFER]], %swift.type* [[METADATA]])
+  // CHECK-64: [[PROJECTION:%.*]] = call %swift.opaque* [[PROJECT]]([24 x i8]* [[BUFFER]], %swift.type* [[METADATA]])
+  // CHECK: [[METATYPE:%.*]] = call %swift.type* @swift_getDynamicType(%swift.opaque* [[PROJECTION]], %swift.type* [[METADATA]], i1 true)
+  // CHECK: [[T0:%.*]] = getelementptr inbounds %P17generic_metatypes3Bas_, %P17generic_metatypes3Bas_* [[X]], i32 0, i32 2
+  // CHECK-32: [[WTABLE:%.*]] = load i8**, i8*** [[T0]], align 4
+  // CHECK-64: [[WTABLE:%.*]] = load i8**, i8*** [[T0]], align 8
+  // CHECK: [[T0:%.*]] = insertvalue { %swift.type*, i8** } undef, %swift.type* [[METATYPE]], 0
+  // CHECK: [[T1:%.*]] = insertvalue { %swift.type*, i8** } [[T0]], i8** [[WTABLE]], 1
+  // CHECK: ret { %swift.type*, i8** } [[T1]]
+  return type(of: x)
+}
+
+struct Zim : Bas {}
+class Zang : Bas {}
+
+// CHECK-LABEL: define hidden { %swift.type*, i8** } @_TF17generic_metatypes15metatypeErasureFMVS_3ZimPMPS_3Bas_() #0
+func metatypeErasure(_ z: Zim.Type) -> Bas.Type {
+  // CHECK: ret { %swift.type*, i8** } {{.*}} @_TMfV17generic_metatypes3Zim, {{.*}} @_TWPV17generic_metatypes3ZimS_3BasS_
+  return z
+}
+
+// CHECK-LABEL: define hidden { %swift.type*, i8** } @_TF17generic_metatypes15metatypeErasureFMCS_4ZangPMPS_3Bas_(%swift.type*) #0
+func metatypeErasure(_ z: Zang.Type) -> Bas.Type {
+  // CHECK: [[RET:%.*]] = insertvalue { %swift.type*, i8** } undef, %swift.type* %0, 0
+  // CHECK: [[RET2:%.*]] = insertvalue { %swift.type*, i8** } [[RET]], i8** getelementptr inbounds ([0 x i8*], [0 x i8*]* @_TWPC17generic_metatypes4ZangS_3BasS_, i32 0, i32 0), 1
+  // CHECK: ret { %swift.type*, i8** } [[RET2]]
+  return z
+}
+
+struct OneArg<T> {}
+struct TwoArgs<T, U> {}
+struct ThreeArgs<T, U, V> {}
+struct FourArgs<T, U, V, W> {}
+struct FiveArgs<T, U, V, W, X> {}
+
+func genericMetatype<A>(_ x: A.Type) {}
+
+// CHECK-LABEL: define hidden void @_TF17generic_metatypes20makeGenericMetatypesFT_T_() {{.*}} {
+func makeGenericMetatypes() {
+  // CHECK: call %swift.type* @_TMaGV17generic_metatypes6OneArgVS_3Foo_() [[NOUNWIND_READNONE:#[0-9]+]]
+  genericMetatype(OneArg<Foo>.self)
+
+  // CHECK: call %swift.type* @_TMaGV17generic_metatypes7TwoArgsVS_3FooCS_3Bar_() [[NOUNWIND_READNONE]]
+  genericMetatype(TwoArgs<Foo, Bar>.self)
+
+  // CHECK: call %swift.type* @_TMaGV17generic_metatypes9ThreeArgsVS_3FooCS_3BarS1__() [[NOUNWIND_READNONE]]
+  genericMetatype(ThreeArgs<Foo, Bar, Foo>.self)
+
+  // CHECK: call %swift.type* @_TMaGV17generic_metatypes8FourArgsVS_3FooCS_3BarS1_S2__() [[NOUNWIND_READNONE]]
+  genericMetatype(FourArgs<Foo, Bar, Foo, Bar>.self)
+
+  // CHECK: call %swift.type* @_TMaGV17generic_metatypes8FiveArgsVS_3FooCS_3BarS1_S2_S1__() [[NOUNWIND_READNONE]]
+  genericMetatype(FiveArgs<Foo, Bar, Foo, Bar, Foo>.self)
+}
+
+// CHECK: define linkonce_odr hidden %swift.type* @_TMaGV17generic_metatypes6OneArgVS_3Foo_() [[NOUNWIND_READNONE_OPT:#[0-9]+]]
+// CHECK:   call %swift.type* @_TMaV17generic_metatypes6OneArg(%swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}) [[NOUNWIND_READNONE:#[0-9]+]]
+
+// CHECK-LABEL: define hidden %swift.type* @_TMaV17generic_metatypes6OneArg(%swift.type*)
+// CHECK:   [[BUFFER:%.*]] = alloca { %swift.type* }
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.start
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type* }, { %swift.type* }* [[BUFFER]], i32 0, i32 0
+// CHECK:   store %swift.type* %0, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_rt_swift_getGenericMetadata(%swift.type_pattern* {{.*}} @_TMPV17generic_metatypes6OneArg {{.*}}, i8* [[BUFFER_PTR]])
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.end
+// CHECK:   ret %swift.type* [[METADATA]]
+
+// CHECK: define linkonce_odr hidden %swift.type* @_TMaGV17generic_metatypes7TwoArgsVS_3FooCS_3Bar_() [[NOUNWIND_READNONE_OPT]]
+// CHECK:   [[T0:%.*]] = call %swift.type* @_TMaC17generic_metatypes3Bar()
+// CHECK:   call %swift.type* @_TMaV17generic_metatypes7TwoArgs(%swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}, %swift.type* [[T0]])
+
+// CHECK-LABEL: define hidden %swift.type* @_TMaV17generic_metatypes7TwoArgs(%swift.type*, %swift.type*)
+// CHECK:   [[BUFFER:%.*]] = alloca { %swift.type*, %swift.type* }
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.start
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type* }, { %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 0
+// CHECK:   store %swift.type* %0, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type* }, { %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 1
+// CHECK:   store %swift.type* %1, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_rt_swift_getGenericMetadata(%swift.type_pattern* {{.*}} @_TMPV17generic_metatypes7TwoArgs {{.*}}, i8* [[BUFFER_PTR]])
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.end
+// CHECK:   ret %swift.type* [[METADATA]]
+
+// CHECK: define linkonce_odr hidden %swift.type* @_TMaGV17generic_metatypes9ThreeArgsVS_3FooCS_3BarS1__() [[NOUNWIND_READNONE_OPT]]
+// CHECK:   [[T0:%.*]] = call %swift.type* @_TMaC17generic_metatypes3Bar()
+// CHECK:   call %swift.type* @_TMaV17generic_metatypes9ThreeArgs(%swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}, %swift.type* [[T0]], %swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}) [[NOUNWIND_READNONE]]
+
+// CHECK-LABEL: define hidden %swift.type* @_TMaV17generic_metatypes9ThreeArgs(%swift.type*, %swift.type*, %swift.type*)
+// CHECK:   [[BUFFER:%.*]] = alloca { %swift.type*, %swift.type*, %swift.type* }
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.start
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 0
+// CHECK:   store %swift.type* %0, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 1
+// CHECK:   store %swift.type* %1, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 2
+// CHECK:   store %swift.type* %2, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_rt_swift_getGenericMetadata(%swift.type_pattern* {{.*}} @_TMPV17generic_metatypes9ThreeArgs {{.*}}, i8* [[BUFFER_PTR]])
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.end
+// CHECK:   ret %swift.type* [[METADATA]]
+
+// CHECK: define linkonce_odr hidden %swift.type* @_TMaGV17generic_metatypes8FourArgsVS_3FooCS_3BarS1_S2__() [[NOUNWIND_READNONE_OPT]]
+// CHECK:   [[T0:%.*]] = call %swift.type* @_TMaC17generic_metatypes3Bar()
+// CHECK:   call %swift.type* @_TMaV17generic_metatypes8FourArgs(%swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}, %swift.type* [[T0]], %swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}, %swift.type* [[T0]]) [[NOUNWIND_READNONE]]
+
+// CHECK-LABEL: define hidden %swift.type* @_TMaV17generic_metatypes8FourArgs(%swift.type*, %swift.type*, %swift.type*, %swift.type*)
+// CHECK:   [[BUFFER:%.*]] = alloca { %swift.type*, %swift.type*, %swift.type*, %swift.type* }
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.start
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 0
+// CHECK:   store %swift.type* %0, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 1
+// CHECK:   store %swift.type* %1, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 2
+// CHECK:   store %swift.type* %2, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 3
+// CHECK:   store %swift.type* %3, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_rt_swift_getGenericMetadata(%swift.type_pattern* {{.*}} @_TMPV17generic_metatypes8FourArgs {{.*}}, i8* [[BUFFER_PTR]])
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.end
+// CHECK:   ret %swift.type* [[METADATA]]
+
+// CHECK: define linkonce_odr hidden %swift.type* @_TMaGV17generic_metatypes8FiveArgsVS_3FooCS_3BarS1_S2_S1__() [[NOUNWIND_READNONE_OPT]]
+// CHECK:   [[T0:%.*]] = call %swift.type* @_TMaC17generic_metatypes3Bar()
+// CHECK:   call %swift.type* @_TMaV17generic_metatypes8FiveArgs(%swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}, %swift.type* [[T0]], %swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}, %swift.type* [[T0]], %swift.type* {{.*}} @_TMfV17generic_metatypes3Foo, {{.*}}) [[NOUNWIND_READNONE]]
+
+// CHECK-LABEL: define hidden %swift.type* @_TMaV17generic_metatypes8FiveArgs(%swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type*)
+// CHECK:   [[BUFFER:%.*]] = alloca { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.start
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 0
+// CHECK:   store %swift.type* %0, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 1
+// CHECK:   store %swift.type* %1, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 2
+// CHECK:   store %swift.type* %2, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_ELT:%.*]] = getelementptr inbounds { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }, { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]], i32 0, i32 3
+// CHECK:   store %swift.type* %3, %swift.type** [[BUFFER_ELT]]
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_rt_swift_getGenericMetadata(%swift.type_pattern* {{.*}} @_TMPV17generic_metatypes8FiveArgs {{.*}}, i8* [[BUFFER_PTR]])
+// CHECK:   [[BUFFER_PTR:%.*]] = bitcast { %swift.type*, %swift.type*, %swift.type*, %swift.type*, %swift.type* }* [[BUFFER]] to i8*
+// CHECK:   call void @llvm.lifetime.end
+// CHECK:   ret %swift.type* [[METADATA]]
+
+// CHECK: attributes [[NOUNWIND_READNONE_OPT]] = { nounwind readnone "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "target-cpu"
+// CHECK: attributes [[NOUNWIND_READNONE]] = { nounwind readnone }
diff --git a/test/IRGen/protocol_resilience.sil b/test/IRGen/protocol_resilience.sil
index e0370f3..104b6dd 100644
--- a/test/IRGen/protocol_resilience.sil
+++ b/test/IRGen/protocol_resilience.sil
@@ -1,5 +1,7 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -assume-parsing-unqualified-ownership-sil %s | %FileCheck %s
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O -assume-parsing-unqualified-ownership-sil %s
 
 sil_stage canonical
 
diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift
index 81bab4a..ac5f26b 100644
--- a/test/IRGen/struct_resilience.swift
+++ b/test/IRGen/struct_resilience.swift
@@ -1,5 +1,8 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | %FileCheck %s
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience %s | %FileCheck %s
+// RUN: %target-swift-frontend -I %t -emit-ir -enable-resilience -O %s
 
 import resilient_struct
 import resilient_enum
diff --git a/test/IRGen/tail_alloc.sil b/test/IRGen/tail_alloc.sil
index 448fc13..b2b0b31 100644
--- a/test/IRGen/tail_alloc.sil
+++ b/test/IRGen/tail_alloc.sil
@@ -160,6 +160,25 @@
   return %p : $Builtin.RawPointer
 }
 
+struct Str<T> {
+  var t: T
+}
+
+// CHECK-LABEL: define{{( protected)?}} i8* @project_tail_generic_struct
+// CHECK:      [[S1:%[0-9]+]] = add i64 17, %flags.alignmentMask
+// CHECK-NEXT: [[S2:%[0-9]+]] = xor i64 %flags.alignmentMask, -1
+// CHECK-NEXT: [[S3:%[0-9]+]] = and i64 [[S1]], [[S2]]
+// CHECK-NEXT: [[S4:%[0-9]+]] = bitcast %{{.*}}* %0 to i8*
+// CHECK-NEXT: [[S5:%[0-9]+]] = getelementptr inbounds i8, i8* [[S4]], i64 [[S3]]
+// CHECK-NEXT: %tailaddr = bitcast i8* [[S5]] to %{{.*}}Str
+// CHECK: ret
+sil @project_tail_generic_struct : $@convention(thin) <T> (TestClass, @thick T.Type) -> Builtin.RawPointer {
+bb0(%0 : $TestClass, %1 : $@thick T.Type):
+  %a = ref_tail_addr %0 : $TestClass, $Str<T>
+  %p = address_to_pointer %a : $*Str<T> to $Builtin.RawPointer
+  return %p : $Builtin.RawPointer
+}
+
 // CHECK-LABEL: define{{( protected)?}} void @project_tail_index_byte_to_int
 // CHECK:      [[S1:%[0-9]+]] = bitcast i8* %0 to %Vs4Int8*
 // CHECK-NEXT: [[S2:%[0-9]+]] = getelementptr inbounds %Vs4Int8, %Vs4Int8* [[S1]], i64 2
@@ -179,6 +198,22 @@
   return %r : $()
 }
 
+// CHECK-LABEL: define{{( protected)?}} i8* @project_tail_index_generic_struct
+// CHECK: call %swift.type* @{{.*Str.*}}(%swift.type* %T)
+// CHECK: load
+// CHECK: and
+// CHECK: xor
+// CHECK: and
+// CHECK: ret
+sil @project_tail_index_generic_struct : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> Builtin.RawPointer {
+bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type):
+  %a1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Int8
+  %c = integer_literal $Builtin.Word, 2
+  %a2 = tail_addr %a1 : $*Int8, %c : $Builtin.Word, $Str<T>
+  %p = address_to_pointer %a2 : $*Str<T> to $Builtin.RawPointer
+  return %p : $Builtin.RawPointer
+}
+
 // sizeof(EmptyClass) = 16 bytes
 class EmptyClass {
 }
diff --git a/test/Parse/ConditionalCompilation/basicParseErrors.swift b/test/Parse/ConditionalCompilation/basicParseErrors.swift
index 8e15927..c769cab 100644
--- a/test/Parse/ConditionalCompilation/basicParseErrors.swift
+++ b/test/Parse/ConditionalCompilation/basicParseErrors.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -D FOO -D BAZ
+// RUN: %target-typecheck-verify-swift -D FOO -D BAZ -swift-version 4
 
 #if FOO == BAZ // expected-error{{expected '&&' or '||' expression}}
 var x = 0
@@ -88,3 +88,18 @@
 
 #if foo || bar || nonExistent() // expected-error {{expected only one argument to platform condition}}
 #endif
+
+#if FOO = false
+// expected-error @-1 {{invalid conditional compilation expression}}
+undefinedFunc() // ignored.
+#else
+undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}}
+#endif
+
+#if false
+#elseif FOO ? true : false
+// expected-error @-1 {{invalid conditional compilation expression}}
+undefinedFunc() // ignored.
+#else
+undefinedFunc() // expected-error {{use of unresolved identifier 'undefinedFunc'}}
+#endif
diff --git a/test/Parse/ConditionalCompilation/decl_parse_errors.swift b/test/Parse/ConditionalCompilation/decl_parse_errors.swift
index bd397e8..1e72bb7 100644
--- a/test/Parse/ConditionalCompilation/decl_parse_errors.swift
+++ b/test/Parse/ConditionalCompilation/decl_parse_errors.swift
@@ -31,10 +31,10 @@
 
 #if os(iOS)
 	func foo() {}
-} // expected-error{{expected declaration}} expected-error{{expected #else or #endif at end of conditional compilation block}}
+} // expected-error{{expected declaration}}
 #else
 	func bar() {}
 	func baz() {}
-} // expected-error{{expected declaration}} expected-error{{expected #else or #endif at end of conditional compilation block}}
+} // expected-error{{expected declaration}}
 #endif
 // expected-error@+1{{expected '}' in class}}
diff --git a/test/Parse/trailing-semi.swift b/test/Parse/trailing-semi.swift
index 2f87c84..d38f8bc 100644
--- a/test/Parse/trailing-semi.swift
+++ b/test/Parse/trailing-semi.swift
@@ -8,13 +8,24 @@
 
 struct SpuriousSemi {
   ; // expected-error{{unexpected ';' separator}} {{3-5=}}
-  var a : Int ; ; // FIXME -- we need to consistently track ','/';' separators
+  var a : Int ; ; // expected-error{{unexpected ';' separator}} {{17-19=}}
   func b () {};
-  ; static func c () {} // FIXME -- we need to consistently track ','/';' separators
+  ; static func c () {};  // expected-error{{unexpected ';' separator}} {{3-5=}}
+  ;;
+  // expected-error @-1 {{unexpected ';' separator}} {{3-4=}}
+  // expected-error @-2 {{unexpected ';' separator}} {{4-5=}}
 }
 
 class C {
-  var a : Int = 10
+  var a : Int = 10 func aa() {}; // expected-error {{consecutive declarations on a line must be separated by ';'}} {{19-19=;}}
+#if FLAG1
+  var aaa: Int = 42 func aaaa() {}; // expected-error {{consecutive declarations on a line must be separated by ';'}} {{20-20=;}}
+#elseif FLAG2
+  var aaa: Int = 42 func aaaa() {} // expected-error {{consecutive declarations on a line must be separated by ';'}} {{20-20=;}}
+#else
+  var aaa: Int = 42 func aaaa() {} // expected-error {{consecutive declarations on a line must be separated by ';'}} {{20-20=;}}
+#endif
+
   func b () {};
   class func c () {};
 }
@@ -23,6 +34,7 @@
   //var a : Int ;
   func bb () {};
   static func cc () {};
+  func dd() {} subscript(i: Int) -> Int { return 1 } // expected-error {{consecutive declarations on a line must be separated by ';'}} {{15-15=;}}
 }
 
 protocol P {
@@ -30,4 +42,3 @@
   func b ();
   static func c ();
 }
-
diff --git a/test/Reflection/capture_descriptors.sil b/test/Reflection/capture_descriptors.sil
index 7747eff..1e466c1 100644
--- a/test/Reflection/capture_descriptors.sil
+++ b/test/Reflection/capture_descriptors.sil
@@ -1,4 +1,4 @@
-// REQUIRES: rdar://29605167
+// REQUIRES: no_asan
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: %target-build-swift %s -emit-module -emit-library -module-name capture_descriptors -o %t/capture_descriptors.%target-dylib-extension
 // RUN: %target-swift-reflection-dump -binary-filename %t/capture_descriptors.%target-dylib-extension | %FileCheck %s
diff --git a/test/Reflection/typeref_decoding.swift b/test/Reflection/typeref_decoding.swift
index 5ba5396..d96678b 100644
--- a/test/Reflection/typeref_decoding.swift
+++ b/test/Reflection/typeref_decoding.swift
@@ -1,4 +1,4 @@
-// REQUIRES: rdar://29605167
+// REQUIRES: no_asan
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: %target-build-swift %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift -parse-as-library -emit-module -emit-library -module-name TypesToReflect -o %t/libTypesToReflect.%target-dylib-extension
 // RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect.%target-dylib-extension | %FileCheck %s
diff --git a/test/Reflection/typeref_lowering.swift b/test/Reflection/typeref_lowering.swift
index 5529bb2..1d01b3b 100644
--- a/test/Reflection/typeref_lowering.swift
+++ b/test/Reflection/typeref_lowering.swift
@@ -1,4 +1,4 @@
-// REQUIRES: rdar://29605167
+// REQUIRES: no_asan
 // RUN: rm -rf %t && mkdir -p %t
 // RUN: %target-build-swift %S/Inputs/TypeLowering.swift -parse-as-library -emit-module -emit-library -module-name TypeLowering -o %t/libTypesToReflect.%target-dylib-extension
 // RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect.%target-dylib-extension -binary-filename %platform-module-dir/libswiftCore.%target-dylib-extension -dump-type-lowering < %s | %FileCheck %s --check-prefix=CHECK-%target-ptrsize
diff --git a/test/SIL/Parser/borrow_argument.sil b/test/SIL/Parser/borrow_argument.sil
new file mode 100644
index 0000000..2e4b291
--- /dev/null
+++ b/test/SIL/Parser/borrow_argument.sil
@@ -0,0 +1,19 @@
+// RUN: %target-sil-opt -enable-sil-ownership %s | %target-sil-opt -enable-sil-ownership | %FileCheck %s
+
+sil_stage canonical
+
+import Builtin
+
+// CHECK-LABEL: sil @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+// CHECK: bb1([[PHIBBARG:%.*]] : @guaranteed $Builtin.NativeObject):
+// CHECK: end_borrow_argument [[PHIBBARG]] : $Builtin.NativeObject
+sil @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : @guaranteed $Builtin.NativeObject):
+  br bb1(%0 : $Builtin.NativeObject)
+
+bb1(%1 : @guaranteed $Builtin.NativeObject):
+  end_borrow_argument %1 : $Builtin.NativeObject
+  %4 = tuple()
+  return %4 : $()
+}
+
diff --git a/test/SIL/Parser/ownership_arguments.sil b/test/SIL/Parser/ownership_arguments.sil
new file mode 100644
index 0000000..f2d962c
--- /dev/null
+++ b/test/SIL/Parser/ownership_arguments.sil
@@ -0,0 +1,20 @@
+// RUN: %target-sil-opt -enable-sil-ownership %s | %target-sil-opt -enable-sil-ownership | %FileCheck %s
+
+sil_stage canonical
+
+import Builtin
+
+// CHECK-LABEL: sil @simple : $@convention(thin) (@owned Builtin.NativeObject, Builtin.NativeObject, @guaranteed Builtin.NativeObject, Builtin.Int32) -> () {
+// CHECK: bb0({{%.*}} : @owned $Builtin.NativeObject, {{%.*}} : @unowned $Builtin.NativeObject, {{%.*}} : @guaranteed $Builtin.NativeObject, {{%.*}} : @trivial $Builtin.Int32):
+// CHECK: bb1({{%[0-9][0-9]*}} : @owned $Builtin.NativeObject, {{%[0-9][0-9]*}} : @unowned $Builtin.NativeObject, {{%[0-9][0-9]*}} : @guaranteed $Builtin.NativeObject, {{%[0-9][0-9]*}} : @trivial $Builtin.Int32):
+
+sil @simple : $@convention(thin) (@owned Builtin.NativeObject, Builtin.NativeObject, @guaranteed Builtin.NativeObject, Builtin.Int32) -> () {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @unowned $Builtin.NativeObject, %2 : @guaranteed $Builtin.NativeObject, %3 : @trivial $Builtin.Int32):
+  br bb1(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject, %2 : $Builtin.NativeObject, %3 : $Builtin.Int32)
+
+bb1(%4 : @owned $Builtin.NativeObject, %5 : @unowned $Builtin.NativeObject, %6 : @guaranteed $Builtin.NativeObject, %7 : @trivial $Builtin.Int32):
+  destroy_value %4 : $Builtin.NativeObject
+  end_borrow_argument %6 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SIL/Parser/unmanaged.sil b/test/SIL/Parser/unmanaged.sil
index 787a399..ebccc2d 100644
--- a/test/SIL/Parser/unmanaged.sil
+++ b/test/SIL/Parser/unmanaged.sil
@@ -1,10 +1,25 @@
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil %s
+// RUN: %target-sil-opt %s
 
 import Swift
+import Builtin
+
+class C {}
+
 sil @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
-bb0(%1 : $*Optional<U>):
-  %17 = load %1 : $*Optional<U>
-  %18 = ref_to_unmanaged %17 : $Optional<U> to $@sil_unmanaged Optional<U>
-  %6 = tuple ()
-  return %6 : $()
+bb0(%0 : $*Optional<U>):
+  %1 = load [copy] %0 : $*Optional<U>
+  %2 = ref_to_unmanaged %1 : $Optional<U> to $@sil_unmanaged Optional<U>
+  %3 = unmanaged_to_ref %2 : $@sil_unmanaged Optional<U> to $Optional<U>
+  destroy_value %1 : $Optional<U>
+  %9999 = tuple ()
+  return %9999 : $()
 }
+
+sil @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
+bb0(%0 : $@sil_unmanaged Optional<C>):
+  %1 = unmanaged_to_ref %0 : $@sil_unmanaged Optional<C> to $Optional<C>
+  unmanaged_retain_value %1 : $Optional<C>
+  unmanaged_release_value %1 : $Optional<C>
+  %9999 = tuple()
+  return %9999 : $()
+}
\ No newline at end of file
diff --git a/test/SIL/Serialization/borrow_argument.sil b/test/SIL/Serialization/borrow_argument.sil
new file mode 100644
index 0000000..b134fa2
--- /dev/null
+++ b/test/SIL/Serialization/borrow_argument.sil
@@ -0,0 +1,23 @@
+// First parse this and then emit a *.sib. Then read in the *.sib, then recreate
+// RUN: rm -rfv %t
+// RUN: mkdir %t
+// RUN: %target-sil-opt -enable-sil-ownership %s -emit-sib -o %t/tmp.sib -module-name borrow
+// RUN: %target-sil-opt -enable-sil-ownership %t/tmp.sib -o %t/tmp.2.sib -module-name borrow
+// RUN: %target-sil-opt -enable-sil-ownership %t/tmp.2.sib -module-name borrow | %FileCheck %s
+
+sil_stage canonical
+
+import Builtin
+
+// CHECK-LABEL: sil @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+// CHECK: bb1([[PHIBBARG:%.*]] : @guaranteed $Builtin.NativeObject):
+// CHECK: end_borrow_argument [[PHIBBARG]] : $Builtin.NativeObject
+sil @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : @guaranteed $Builtin.NativeObject):
+  br bb1(%0 : $Builtin.NativeObject)
+
+bb1(%1 : @guaranteed $Builtin.NativeObject):
+  end_borrow_argument %1 : $Builtin.NativeObject
+  %4 = tuple()
+  return %4 : $()
+}
diff --git a/test/SIL/Serialization/unmanaged.sil b/test/SIL/Serialization/unmanaged.sil
new file mode 100644
index 0000000..b5f0767
--- /dev/null
+++ b/test/SIL/Serialization/unmanaged.sil
@@ -0,0 +1,41 @@
+// First parse this and then emit a *.sib. Then read in the *.sib, then recreate
+// RUN: rm -rfv %t
+// RUN: mkdir %t
+// RUN: %target-sil-opt %s -emit-sib -o %t/tmp.sib -module-name unmanaged
+// RUN: %target-sil-opt %t/tmp.sib -o %t/tmp.2.sib -module-name unmanaged
+// RUN: %target-sil-opt %t/tmp.2.sib -module-name unmanaged | %FileCheck %s
+
+import Swift
+import Builtin
+
+class C {}
+
+// CHECK-LABEL: sil @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
+// CHECK: bb0([[ARG:%.*]] : $@sil_unmanaged Optional<C>):
+// CHECK: [[REF:%.*]] = unmanaged_to_ref [[ARG]] : $@sil_unmanaged Optional<C> to $Optional<C>
+// CHECK: unmanaged_retain_value [[REF]]
+// CHECK: unmanaged_release_value [[REF]]
+sil @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
+bb0(%0 : $@sil_unmanaged Optional<C>):
+  %1 = unmanaged_to_ref %0 : $@sil_unmanaged Optional<C> to $Optional<C>
+  unmanaged_retain_value %1 : $Optional<C>
+  unmanaged_release_value %1 : $Optional<C>
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
+// CHECK: bb0([[ARG:%.*]] : $*Optional<U>):
+// CHECK: [[LOADED_ARG:%.*]] = load [copy] [[ARG]]
+// CHECK: [[UNMANGED_LOADED_ARG:%.*]] = ref_to_unmanaged [[LOADED_ARG]] : $Optional<U> to $@sil_unmanaged Optional<U>
+// CHECK: {{%.*}} = unmanaged_to_ref [[UNMANGED_LOADED_ARG]] : $@sil_unmanaged Optional<U> to $Optional<U>
+// CHECK: destroy_value [[LOADED_ARG]]
+sil @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
+bb0(%0 : $*Optional<U>):
+  %1 = load [copy] %0 : $*Optional<U>
+  %2 = ref_to_unmanaged %1 : $Optional<U> to $@sil_unmanaged Optional<U>
+  %3 = unmanaged_to_ref %2 : $@sil_unmanaged Optional<U> to $Optional<U>
+  destroy_value %1 : $Optional<U>
+  %9999 = tuple ()
+  return %9999 : $()
+}
diff --git a/test/SIL/ownership-verifier/basic.sil b/test/SIL/ownership-verifier/basic.sil
deleted file mode 100644
index 05fffc7..0000000
--- a/test/SIL/ownership-verifier/basic.sil
+++ /dev/null
@@ -1,74 +0,0 @@
-// RUN: %target-sil-opt -enable-sil-ownership -sil-ownership-verifier-do-not-assert -enable-sil-verify-all=0 -o /dev/null 2>&1  %s | %FileCheck %s
-// REQUIRES: asserts
-
-sil_stage canonical
-
-import Builtin
-
-// This checks if the dataflow verifier asserts when we have two consuming users
-// in the same block.
-// CHECK-LABEL: Function: 'double_consume_same_bb'
-// CHECK: Found over consume?!
-// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
-// CHECK: User:   destroy_value %0 : $Builtin.NativeObject
-// CHECK: Block
-// CHECK: bb0(
-sil @double_consume_same_bb : $@convention(thin) (@owned Builtin.NativeObject) -> () {
-bb0(%0 : $Builtin.NativeObject):
-  destroy_value %0 : $Builtin.NativeObject
-  destroy_value %0 : $Builtin.NativeObject
-  %9999 = tuple()
-  return %9999 : $()
-}
-
-// This test checks if the dataflow verifier asserts when there are two
-// consuming users in chained blocks.
-// CHECK-LABEL: Function: 'double_consume_jump_thread_blocks'
-// CHECK: Found over consume?!
-// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
-// CHECK: User:   destroy_value %0 : $Builtin.NativeObject
-// CHECK: Block:
-// CHECK: bb0(
-sil @double_consume_jump_thread_blocks : $@convention(thin) (@owned Builtin.NativeObject) -> () {
-bb0(%0 : $Builtin.NativeObject):
-  destroy_value %0 : $Builtin.NativeObject
-  br bb1
-
-bb1:
-  destroy_value %0 : $Builtin.NativeObject
-  %9999 = tuple()
-  return %9999 : $()
-}
-
-
-// We have a double consume, since we need to copy %0 before we store it.
-// CHECK-LABEL: Function: 'double_consume_loop_test'
-// CHECK: Found over consume?!
-// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
-// CHECK: Block:
-// CHECK: bb0(
-sil @double_consume_loop_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
-bb0(%0 : $Builtin.NativeObject):
-  %1 = alloc_stack $Builtin.NativeObject
-  store %0 to [init] %1 : $*Builtin.NativeObject
-  destroy_addr %1 : $*Builtin.NativeObject
-  dealloc_stack %1 : $*Builtin.NativeObject
-  br bb1
-
-bb1:
-  cond_br undef, bb2, bb5
-
-bb2:
-  cond_br undef, bb3, bb4
-
-bb3:
-  br bb1
-
-bb4:
-  br bb1
-
-bb5:
-  destroy_value %0 : $Builtin.NativeObject
-  %9999 = tuple()
-  return %9999 : $()
-}
diff --git a/test/SIL/ownership-verifier/false_positive_leaks.sil b/test/SIL/ownership-verifier/false_positive_leaks.sil
new file mode 100644
index 0000000..3fe9e25
--- /dev/null
+++ b/test/SIL/ownership-verifier/false_positive_leaks.sil
@@ -0,0 +1,48 @@
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all=0 -o /dev/null 2>&1  %s
+// REQUIRES: asserts
+
+// This file is meant to contain dataflow tests that if they fail are false
+// positives.
+
+//////////////////
+// Declarations //
+//////////////////
+
+sil_stage canonical
+
+import Builtin
+
+sil @in_guaranteed_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
+
+///////////
+// Tests //
+///////////
+
+sil @leak_loop_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  %1 = alloc_stack $Builtin.NativeObject
+  %2 = begin_borrow %0 : $Builtin.NativeObject
+  store_borrow %2 to %1 : $*Builtin.NativeObject
+  %3 = function_ref @in_guaranteed_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
+  apply %3(%1) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
+  end_borrow %2 from %0 : $Builtin.NativeObject, $Builtin.NativeObject
+  dealloc_stack %1 : $*Builtin.NativeObject
+  br bb1
+
+bb1:
+  cond_br undef, bb2, bb5
+
+bb2:
+  cond_br undef, bb3, bb4
+
+bb3:
+  br bb1
+
+bb4:
+  br bb1
+
+bb5:
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SIL/ownership-verifier/over_consume.sil b/test/SIL/ownership-verifier/over_consume.sil
new file mode 100644
index 0000000..a31f100
--- /dev/null
+++ b/test/SIL/ownership-verifier/over_consume.sil
@@ -0,0 +1,125 @@
+// RUN: %target-sil-opt -enable-sil-ownership -sil-ownership-verifier-enable-testing -enable-sil-verify-all=0 -o /dev/null 2>&1  %s | %FileCheck %s
+// REQUIRES: asserts
+
+sil_stage canonical
+
+import Builtin
+
+sil @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+
+// This checks if the dataflow verifier asserts when we have two consuming users
+// in the same block.
+// CHECK-LABEL: Function: 'double_consume_same_bb'
+// CHECK: Found over consume?!
+// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
+// CHECK: User:   destroy_value %0 : $Builtin.NativeObject
+// CHECK: Block: bb0
+sil @double_consume_same_bb : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  destroy_value %0 : $Builtin.NativeObject
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// This test checks if the dataflow verifier asserts when there are two
+// consuming users in chained blocks.
+// CHECK-LABEL: Function: 'double_consume_jump_thread_blocks'
+// CHECK: Found over consume?!
+// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
+// CHECK: User:   destroy_value %0 : $Builtin.NativeObject
+// CHECK: Block: bb0
+sil @double_consume_jump_thread_blocks : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  destroy_value %0 : $Builtin.NativeObject
+  br bb1
+
+bb1:
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+
+// We have a double consume, since we need to copy %0 before we store it.
+// CHECK-LABEL: Function: 'double_consume_loop_test'
+// CHECK: Found over consume?!
+// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
+// CHECK: Block: bb0
+sil @double_consume_loop_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  %1 = alloc_stack $Builtin.NativeObject
+  store %0 to [init] %1 : $*Builtin.NativeObject
+  destroy_addr %1 : $*Builtin.NativeObject
+  dealloc_stack %1 : $*Builtin.NativeObject
+  br bb1
+
+bb1:
+  cond_br undef, bb2, bb5
+
+bb2:
+  cond_br undef, bb3, bb4
+
+bb3:
+  br bb1
+
+bb4:
+  br bb1
+
+bb5:
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We have a consume of a guaranteed argument
+// CHECK-LABEL: Function: 'consumed_guaranteed_arg'
+// CHECK: Have operand with incompatible ownership?!
+// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
+// CHECK: User:   destroy_value %0 : $Builtin.NativeObject
+// CHECK: Conv: guaranteed
+sil @consumed_guaranteed_arg : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : @guaranteed $Builtin.NativeObject):
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We have a use of a borrowed value after an end_borrow. This is effectively a
+// use after consume.
+//
+// CHECK-LABEL: Function: 'use_after_end_borrow'
+// CHECK: Found use after free?!
+// CHECK: Value:   %1 = begin_borrow %0 : $Builtin.NativeObject
+// CHECK: Consuming User:   end_borrow %1 from %0 : $Builtin.NativeObject, $Builtin.NativeObject
+// CHECK: Non Consuming User:   %4 = apply %2(%1) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+// CHECK: Block: bb0
+sil @use_after_end_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  %1 = begin_borrow %0 : $Builtin.NativeObject
+  %2 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  end_borrow %1 from %0 : $Builtin.NativeObject, $Builtin.NativeObject
+  apply %2(%1) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We have a destroy value of an owned value before a borrow of the owned value
+// has finished.
+//
+// CHECK-LABEL: Function: 'destroy_before_end_borrow'
+// CHECK: Found use after free?!
+// CHECK: Value:   %0 = argument of bb0 : $Builtin.NativeObject
+// CHECK: Consuming User:   destroy_value %0 : $Builtin.NativeObject
+// CHECK: Non Consuming User:   end_borrow %1 from %0 : $Builtin.NativeObject, $Builtin.NativeObject
+// CHECK: Block: bb0
+sil @destroy_before_end_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  %1 = begin_borrow %0 : $Builtin.NativeObject
+  %2 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  destroy_value %0 : $Builtin.NativeObject
+  end_borrow %1 from %0 : $Builtin.NativeObject, $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SIL/ownership-verifier/subobject_borrowing.sil b/test/SIL/ownership-verifier/subobject_borrowing.sil
new file mode 100644
index 0000000..ac9cc10
--- /dev/null
+++ b/test/SIL/ownership-verifier/subobject_borrowing.sil
@@ -0,0 +1,155 @@
+// RUN: %target-sil-opt -enable-sil-ownership -sil-ownership-verifier-enable-testing -enable-sil-verify-all=0 -o /dev/null 2>&1  %s | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -sil-ownership-verifier-enable-testing -enable-sil-verify-all=0 -o /dev/null 2>&1  %s | %FileCheck -check-prefix=NEGATIVE-TEST %s
+// REQUIRES: asserts
+
+sil_stage canonical
+
+import Builtin
+
+//////////////////
+// Declarations //
+//////////////////
+
+enum Optional<T> {
+case some(T)
+case none
+}
+
+struct A {
+  var ptr: Builtin.NativeObject
+  var ptr2: Optional<(Builtin.NativeObject, Builtin.NativeObject)>
+}
+
+struct B {
+  var a1: A
+  var a2: A
+}
+
+sil @owned_use_of_nativeobject : $@convention(thin) (@owned Builtin.NativeObject) -> ()
+sil @guaranteed_use_of_nativeobject : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+
+///////////
+// Tests //
+///////////
+
+//===---
+// begin_borrow subobject tests
+//
+
+// NEGATIVE-TEST-NOT: Function: 'value_subobject_without_corresponding_end_borrow'
+sil @value_subobject_without_corresponding_end_borrow : $@convention(thin) (@owned B) -> () {
+bb0(%0 : @owned $B):
+  %1 = begin_borrow %0 : $B
+  %2 = struct_extract %1 : $B, #B.a1
+  %3 = struct_extract %2 : $A, #A.ptr
+  %4 = function_ref @guaranteed_use_of_nativeobject : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  end_borrow %1 from %0 : $B, $B
+  destroy_value %0 : $B
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We fail here since we have a use of our subobject after the end_borrow which
+// ends the borrow's lifetime.
+//
+// CHECK-LABEL: Function: 'value_subobject_with_use_after_end_borrow'
+// CHECK: Found use after free?!
+// CHECK: Value:   %1 = begin_borrow %0 : $B
+// CHECK: Consuming User:   end_borrow %1 from %0 : $B, $B
+// CHECK: Non Consuming User:   %4 = struct_extract %2 : $A, #A.ptr
+// CHECK: Block: bb0
+sil @value_subobject_with_use_after_end_borrow : $@convention(thin) (@owned B) -> () {
+bb0(%0 : @owned $B):
+  %1 = begin_borrow %0 : $B
+  %2 = struct_extract %1 : $B, #B.a1
+  end_borrow %1 from %0 : $B, $B
+  %3 = struct_extract %2 : $A, #A.ptr
+  destroy_value %0 : $B
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We fail here since we have a destroy of our subobject. The idea is to make
+// sure that our special handling code for subobjects here does not stop us from
+// detecting violations of ownership kinds on the subobjects.
+//
+// CHECK-LABEL: Function: 'value_subobject_with_destroy_of_subobject'
+// CHECK: Have operand with incompatible ownership?!
+// CHECK: Value:   %5 = tuple_extract %4 : $(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK: BaseValue:   %1 = begin_borrow %0 : $B
+// CHECK: User:   destroy_value %5 : $Builtin.NativeObject
+// CHECK: Conv: guaranteed
+
+// Make sure we only see one failure here. We should process recursively from
+// the borrow root, not from each of the subobjects of the borrow.
+// NEGATIVE-TEST: Function: 'value_subobject_with_destroy_of_subobject'
+// NEGATIVE-TEST-NOT: Function: 'value_subobject_with_destroy_of_subobject'
+sil @value_subobject_with_destroy_of_subobject : $@convention(thin) (@owned B) -> () {
+bb0(%0 : @owned $B):
+  %1 = begin_borrow %0 : $B
+  %2 = struct_extract %1 : $B, #B.a1
+  %3 = struct_extract %2 : $A, #A.ptr2
+  %4 = unchecked_enum_data %3 : $Optional<(Builtin.NativeObject, Builtin.NativeObject)>, #Optional.some!enumelt.1
+  %5 = tuple_extract %4 : $(Builtin.NativeObject, Builtin.NativeObject), 1
+  destroy_value %5 : $Builtin.NativeObject
+  end_borrow %1 from %0 : $B, $B
+  destroy_value %0 : $B
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: Function: 'value_different_subobject_kinds_multiple_levels'
+// CHECK: Found use after free?!
+// CHECK: Value:   %1 = begin_borrow %0 : $B
+// CHECK: Consuming User:   end_borrow %1 from %0 : $B, $B
+// CHECK: Non Consuming User:   %6 = tuple_extract %4 : $(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK: Block: bb0
+sil @value_different_subobject_kinds_multiple_levels : $@convention(thin) (@owned B) -> () {
+bb0(%0 : @owned $B):
+  %1 = begin_borrow %0 : $B
+  %2 = struct_extract %1 : $B, #B.a1
+  %3 = struct_extract %2 : $A, #A.ptr2
+  %4 = unchecked_enum_data %3 : $Optional<(Builtin.NativeObject, Builtin.NativeObject)>, #Optional.some!enumelt.1
+  end_borrow %1 from %0 : $B, $B
+  %5 = tuple_extract %4 : $(Builtin.NativeObject, Builtin.NativeObject), 1
+  destroy_value %0 : $B
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+//===---
+// Function Argument guaranteed tests
+//
+
+// NEGATIVE-TEST-NOT: Function: 'funcarg_subobject_basic_test'
+sil @funcarg_subobject_basic_test : $@convention(thin) (@guaranteed B) -> () {
+bb0(%0 : @guaranteed $B):
+  %2 = struct_extract %0 : $B, #B.a1
+  %3 = struct_extract %2 : $A, #A.ptr
+  %4 = function_ref @guaranteed_use_of_nativeobject : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We fail here since we have a destroy of our subobject. The idea is to make
+// sure that our special handling code for subobjects here does not stop us from
+// detecting violations of ownership kinds on the subobjects.
+//
+// CHECK-LABEL: Function: 'funcarg_subobject_with_destroy_of_subobject'
+// CHECK: Have operand with incompatible ownership?!
+// CHECK: Value:   %4 = tuple_extract %3 : $(Builtin.NativeObject, Builtin.NativeObject), 1
+// CHECK: BaseValue:   %0 = argument of bb0 : $B
+// CHECK: User:   destroy_value %4 : $Builtin.NativeObject
+// CHECK: Conv: guaranteed
+sil @funcarg_subobject_with_destroy_of_subobject : $@convention(thin) (@guaranteed B) -> () {
+bb0(%0 : @guaranteed $B):
+  %2 = struct_extract %0 : $B, #B.a1
+  %3 = struct_extract %2 : $A, #A.ptr2
+  %4 = unchecked_enum_data %3 : $Optional<(Builtin.NativeObject, Builtin.NativeObject)>, #Optional.some!enumelt.1
+  %5 = tuple_extract %4 : $(Builtin.NativeObject, Builtin.NativeObject), 1
+  destroy_value %5 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SIL/ownership-verifier/use_verifier.sil b/test/SIL/ownership-verifier/use_verifier.sil
new file mode 100644
index 0000000..d8c57f8
--- /dev/null
+++ b/test/SIL/ownership-verifier/use_verifier.sil
@@ -0,0 +1,135 @@
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all=0 -module-name Swift -o /dev/null 2>&1  %s
+// REQUIRES: asserts
+
+// This file is meant to contain tests that previously the verifier treated
+// incorrectly. This is important to ensure that the verifier does not
+// regress. It should only deal with use matching.
+
+sil_stage canonical
+
+import Builtin
+
+//////////////////
+// Declarations //
+//////////////////
+
+enum Never {}
+
+enum Optional<T> {
+case some(T)
+case nome
+}
+
+struct TrivialStruct {
+  var f1: Builtin.Int32
+  var f2: Builtin.Int32
+}
+
+struct NonTrivialStructWithTrivialField {
+  var owner: Builtin.NativeObject
+  var payload: Builtin.Int32
+}
+
+struct TupleContainingNonTrivialStruct {
+  var t: (Builtin.NativeObject, Builtin.NativeObject)
+  var opt: Optional<Builtin.NativeObject>
+}
+
+////////////////
+// Test Cases //
+////////////////
+
+// Make sure that guaranteed args do not have a consuming use.
+sil @direct_guaranteed_arg_doesnt_have_consuming_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : @guaranteed $Builtin.NativeObject):
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil @store_borrow_result : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : @guaranteed $Builtin.NativeObject):
+  %1 = alloc_stack $Builtin.NativeObject
+  %2 = store_borrow %0 to %1 : $*Builtin.NativeObject
+  dealloc_stack %1 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil @trivial_struct_extract_from_non_trivial : $@convention(thin) (@guaranteed NonTrivialStructWithTrivialField) -> () {
+bb0(%0 : @guaranteed $NonTrivialStructWithTrivialField):
+  %1 = struct_extract %0 : $NonTrivialStructWithTrivialField, #NonTrivialStructWithTrivialField.payload
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil @trivial_struct_extract_from_trivial : $@convention(thin) (TrivialStruct) -> () {
+bb0(%0 : @trivial $TrivialStruct):
+  %1 = struct_extract %0 : $TrivialStruct, #TrivialStruct.f1
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil @in_address_arg : $@convention(thin) (@in Builtin.NativeObject) -> () {
+bb0(%0 : @trivial $*Builtin.NativeObject):
+  destroy_addr %0 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We shouldn't assert given an unowned argument that is never used.
+sil @non_trivial_unowned_arg : $@convention(thin) (Builtin.NativeObject) -> () {
+bb0(%0 : @unowned $Builtin.NativeObject):
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil @builtin_unreachable_has_a_return_value : $@convention(thin) () -> () {
+bb0:
+  %0 = builtin "unreachable"() : $Never
+  unreachable
+}
+
+//////////////////////
+// Terminator Tests //
+//////////////////////
+
+sil @simple_branch : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : @owned $Builtin.NativeObject):
+  // Simple branch without an argument.
+  br bb1
+
+bb1:
+  // Branch with multiple trivial arguments
+  %1 = integer_literal $Builtin.Int32, 0
+  br bb2(%1 : $Builtin.Int32, %1 : $Builtin.Int32)
+
+bb2(%2 : @trivial $Builtin.Int32, %3 : @trivial $Builtin.Int32):
+  // Branch with mixed trivial and owned argument
+  br bb3(%1 : $Builtin.Int32, %0 : $Builtin.NativeObject, %2 : $Builtin.Int32)
+
+bb3(%4 : @trivial $Builtin.Int32, %5 : @owned $Builtin.NativeObject, %6 : @trivial $Builtin.Int32):
+  destroy_value %5 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+/////////////////////
+// Aggregate Tests //
+/////////////////////
+
+// These tests make sure that we properly handle @owned forwarding of multiple
+// levels of aggregate.
+
+sil @owned_aggregates_simple : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> (@owned (Builtin.NativeObject, Builtin.NativeObject)) {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
+  %2 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+  return %2 : $(Builtin.NativeObject, Builtin.NativeObject)
+}
+
+sil @multiple_level_owned_aggregates : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> (@owned TupleContainingNonTrivialStruct) {
+bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $Builtin.NativeObject, %2 : @owned $Builtin.NativeObject):
+  %3 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject)
+  %4 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt.1, %2 : $Builtin.NativeObject
+  %5 = struct $TupleContainingNonTrivialStruct(%3 : $(Builtin.NativeObject, Builtin.NativeObject), %4 : $Optional<Builtin.NativeObject>)
+  return %5 : $TupleContainingNonTrivialStruct
+}
diff --git a/test/SILGen/argument_shuffle_swift3.swift b/test/SILGen/argument_shuffle_swift3.swift
new file mode 100644
index 0000000..f009080
--- /dev/null
+++ b/test/SILGen/argument_shuffle_swift3.swift
@@ -0,0 +1,25 @@
+// RUN: %target-swift-frontend -emit-silgen %s -swift-version 3 | %FileCheck %s
+
+func fn(_: Any) {}
+
+enum HasAnyCase {
+  case any(_: Any)
+}
+
+// CHECK-LABEL: sil hidden @_TF23argument_shuffle_swift31gFT1xP__T_ : $@convention(thin) (@in Any) -> () {
+func g(x: Any) {
+  // CHECK: [[FN:%.*]] = function_ref @_TF23argument_shuffle_swift32fnFP_T_ : $@convention(thin) (@in Any) -> ()
+  // CHECK: apply [[FN:%.*]]({{.*}}) : $@convention(thin) (@in Any) -> ()
+  fn(data: 123)
+  // CHECK: [[FN:%.*]] = function_ref @_TF23argument_shuffle_swift32fnFP_T_ : $@convention(thin) (@in Any) -> ()
+  // CHECK: apply [[FN:%.*]]({{.*}}) : $@convention(thin) (@in Any) -> ()
+  fn(data: x)
+
+  // CHECK: inject_enum_addr {{.*}} : $*HasAnyCase, #HasAnyCase.any!enumelt.1
+  _ = HasAnyCase.any(123)
+
+  // CHECK: inject_enum_addr {{.*}} : $*HasAnyCase, #HasAnyCase.any!enumelt.1
+  _ = HasAnyCase.any(data: 123)
+
+  // CHECK: return
+}
diff --git a/test/SILGen/class_resilience.swift b/test/SILGen/class_resilience.swift
index 0c471a0..5d88909 100644
--- a/test/SILGen/class_resilience.swift
+++ b/test/SILGen/class_resilience.swift
@@ -1,4 +1,7 @@
-// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
+// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
 
 import resilient_class
 
diff --git a/test/SILGen/coverage_smoke.swift b/test/SILGen/coverage_smoke.swift
index 756809e..8d99c61 100644
--- a/test/SILGen/coverage_smoke.swift
+++ b/test/SILGen/coverage_smoke.swift
@@ -11,6 +11,7 @@
 
 // REQUIRES: profile_runtime
 // REQUIRES: OS=macosx
+// REQUIRES: rdar28221303
 
 // CHECK-INTERNAL: Functions shown: 1
 // CHECK-COV: {{ *}}[[@LINE+1]]|{{ *}}1{{.*}}func f_internal
diff --git a/test/SILGen/dynamic_self.swift b/test/SILGen/dynamic_self.swift
index 7a83447..399f1ed 100644
--- a/test/SILGen/dynamic_self.swift
+++ b/test/SILGen/dynamic_self.swift
@@ -51,7 +51,7 @@
   // CHECK:   [[GY_COPY:%.*]] = copy_value [[GY]]
   // CHECK:   [[GY_AS_GX_COPY:%[0-9]+]] = upcast [[GY_COPY]] : $GY<Int> to $GX<Array<Int>>
   // CHECK:   [[GX_F:%[0-9]+]] = class_method [[GY_AS_GX_COPY]] : $GX<Array<Int>>, #GX.f!1 : <T> (GX<T>) -> () -> @dynamic_self GX<T> , $@convention(method) <τ_0_0> (@guaranteed GX<τ_0_0>) -> @owned GX<τ_0_0>
-  // CHECK:   [[GX_RESULT:%[0-9]+]] = apply [[GX_F]]<Array<Int>>([[GY_AS_GX_COPY]]) : $@convention(method) <τ_0_0> (@guaranteed GX<τ_0_0>) -> @owned GX<τ_0_0>
+  // CHECK:   [[GX_RESULT:%[0-9]+]] = apply [[GX_F]]<[Int]>([[GY_AS_GX_COPY]]) : $@convention(method) <τ_0_0> (@guaranteed GX<τ_0_0>) -> @owned GX<τ_0_0>
   // CHECK:   destroy_value [[GY_AS_GX_COPY]]
   // CHECK:   [[GY_RESULT:%[0-9]+]] = unchecked_ref_cast [[GX_RESULT]] : $GX<Array<Int>> to $GY<Int>
   // CHECK:   destroy_value [[GY_RESULT]] : $GY<Int>
diff --git a/test/SILGen/enum_resilience.swift b/test/SILGen/enum_resilience.swift
index 47fec63..3686d52 100644
--- a/test/SILGen/enum_resilience.swift
+++ b/test/SILGen/enum_resilience.swift
@@ -1,4 +1,7 @@
-// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_enum.swiftmodule -module-name=resilient_enum -I %t %S/../Inputs/resilient_enum.swift
+// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
 
 import resilient_enum
 
diff --git a/test/SILGen/global_resilience.swift b/test/SILGen/global_resilience.swift
index af67003..69455e5 100644
--- a/test/SILGen/global_resilience.swift
+++ b/test/SILGen/global_resilience.swift
@@ -1,5 +1,7 @@
-// RUN: %target-swift-frontend -I %S/../Inputs -emit-silgen -enable-source-import -parse-as-library -enable-resilience %s | %FileCheck %s
-// RUN: %target-swift-frontend -I %S/../Inputs -emit-sil -enable-source-import -parse-as-library -enable-resilience %s -O | %FileCheck --check-prefix=CHECK-OPT %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_global.swiftmodule -module-name=resilient_global %S/../Inputs/resilient_global.swift
+// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience -parse-as-library %s | %FileCheck %s
+// RUN: %target-swift-frontend -I %t -emit-sil -O -enable-resilience -parse-as-library %s | %FileCheck --check-prefix=CHECK-OPT %s
 
 import resilient_global
 
diff --git a/test/SILGen/inherited_protocol_conformance_multi_file_2.swift b/test/SILGen/inherited_protocol_conformance_multi_file_2.swift
index d58bd7f..ef3b518 100644
--- a/test/SILGen/inherited_protocol_conformance_multi_file_2.swift
+++ b/test/SILGen/inherited_protocol_conformance_multi_file_2.swift
@@ -44,23 +44,23 @@
 
 // FILE_A-NOT: sil [transparent] [thunk] @_TTWV4main5Things9EquatableS_ZFS1_oi2ee
 // FILE_A-NOT: sil [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
-// FILE_A-NOT: sil_witness_table Thing: Hashable module main
-// FILE_A-NOT: sil_witness_table Thing: Equatable module main
+// FILE_A-NOT: sil_witness_table hidden Thing: Hashable module main
+// FILE_A-NOT: sil_witness_table hidden Thing: Equatable module main
 
 // FILE_B-NOT: sil [transparent] [thunk] @_TTWV4main5Things9EquatableS_ZFS1_oi2ee
-// FILE_B: sil [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
+// FILE_B: sil hidden [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
 // FILE_B-NOT: sil [transparent] [thunk] @_TTWV4main5Things9EquatableS_ZFS1_oi2ee
 
-// FILE_B-NOT: sil_witness_table Thing: Equatable module main
-// FILE_B: sil_witness_table Thing: Hashable module main
-// FILE_B-NOT: sil_witness_table Thing: Equatable module main
+// FILE_B-NOT: sil_witness_table hidden Thing: Equatable module main
+// FILE_B: sil_witness_table hidden Thing: Hashable module main
+// FILE_B-NOT: sil_witness_table hidden Thing: Equatable module main
 
-// FILE_C-NOT: sil [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
-// FILE_C: sil [transparent] [thunk] @_TTWV4main5Things9EquatableS_ZFS1_oi2ee
-// FILE_C-NOT: sil [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
+// FILE_C-NOT: sil hidden [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
+// FILE_C: sil hidden [transparent] [thunk] @_TTWV4main5Things9EquatableS_ZFS1_oi2ee
+// FILE_C-NOT: sil hidden [transparent] [thunk] @_TTWV4main5Things8HashableS_FS1_g9hashValueSi
 
-// FILE_C-NOT: sil_witness_table Thing: Hashable module main
-// FILE_C: sil_witness_table Thing: Equatable module main
-// FILE_C-NOT: sil_witness_table Thing: Hashable module main
+// FILE_C-NOT: sil_witness_table hidden Thing: Hashable module main
+// FILE_C: sil_witness_table hidden Thing: Equatable module main
+// FILE_C-NOT: sil_witness_table hidden Thing: Hashable module main
 
 struct Thing { var value: Int }
diff --git a/test/SILGen/lying_about_optional_return_objc.swift b/test/SILGen/lying_about_optional_return_objc.swift
index 23638d0..eae6cda 100644
--- a/test/SILGen/lying_about_optional_return_objc.swift
+++ b/test/SILGen/lying_about_optional_return_objc.swift
@@ -53,34 +53,35 @@
 
   // CHECK: enum $Optional<()>, #Optional.some!enumelt.1, {{%.*}} : $()
   _ = dynamic?.voidReturning()
-  // CHECK: unchecked_trivial_bit_cast
+  // CHECK: unchecked_trivial_bit_cast {{.*}} $UnsafeMutableRawPointer to $Optional
   _ = dynamic?.voidPointerReturning()
-  // CHECK: unchecked_trivial_bit_cast
+  // CHECK: unchecked_trivial_bit_cast {{.*}} $OpaquePointer to $Optional
   _ = dynamic?.opaquePointerReturning()
-  // CHECK: unchecked_trivial_bit_cast
+  // CHECK: unchecked_trivial_bit_cast {{.*}} $UnsafeMutablePointer{{.*}} to $Optional
   _ = dynamic?.pointerReturning()
-  // CHECK: unchecked_trivial_bit_cast
+  // CHECK: unchecked_trivial_bit_cast {{.*}} $UnsafePointer{{.*}} to $Optional
   _ = dynamic?.constPointerReturning()
-  // CHECK: unchecked_trivial_bit_cast
+  // CHECK: unchecked_trivial_bit_cast {{.*}} $Selector to $Optional
   _ = dynamic?.selectorReturning()
-  // CHECK: unchecked_ref_cast
+  // CHECK: unchecked_ref_cast {{.*}} $BlockProperty to $Optional
   _ = dynamic?.objectReturning()
-  // CHECK: unchecked_trivial_bit_cast
+  // FIXME: Doesn't opaquely cast the selector result!
+  // C/HECK: unchecked_trivial_bit_cast {{.*}} $Selector to $Optional
   _ = dynamic?.selector
 
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> ()>, #Optional.some
   _ = dynamic?.voidReturning
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> UnsafeMutableRawPointer>, #Optional.some
   _ = dynamic?.voidPointerReturning
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> OpaquePointer>, #Optional.some
   _ = dynamic?.opaquePointerReturning
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> UnsafeMutablePointer{{.*}}>, #Optional.some
   _ = dynamic?.pointerReturning
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> UnsafePointer{{.*}}>, #Optional.some
   _ = dynamic?.constPointerReturning
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> Selector>, #Optional.some
   _ = dynamic?.selectorReturning
-  // CHECK: unchecked_bitwise_cast {{%.*}} : $Optional<{{.*}} -> {{.*}}> to $Optional<{{.*}} -> {{.*}}>
+  // CHECK: inject_enum_addr {{%.*}} : $*Optional<{{.*}} -> @owned BlockProperty>, #Optional.some
   _ = dynamic?.objectReturning
 
   // CHECK: enum $Optional<()>, #Optional.some!enumelt.1, {{%.*}} : $()
diff --git a/test/SILGen/objc_extensions.swift b/test/SILGen/objc_extensions.swift
index 00bb5a0..adbde1b 100644
--- a/test/SILGen/objc_extensions.swift
+++ b/test/SILGen/objc_extensions.swift
@@ -63,7 +63,6 @@
 
     // CHECK: bb3([[OLD_NSSTRING_BRIDGED:%.*]] : $Optional<String>):
     // This next line is completely not needed. But we are emitting it now.
-    // CHECK:   [[OLD_NSSTRING_BRIDGED_CAST:%.*]] = unchecked_bitwise_cast [[OLD_NSSTRING_BRIDGED]]
     // CHECK:   destroy_value [[SELF_COPY]]
     // CHECK:   [[SELF_COPY:%.*]] = copy_value [[SELF]]
     // CHECK:   [[UPCAST_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $Sub to $Base
@@ -74,11 +73,10 @@
     // CHECK:    destroy_value [[BRIDGED_NEW_STRING]]
     // CHECK:    destroy_value [[SELF_COPY]]
     // CHECK:    [[DIDSET_NOTIFIER:%.*]] = function_ref @_TFC15objc_extensions3SubW4propGSQSS_ : $@convention(method) (@owned Optional<String>, @guaranteed Sub) -> ()
-    // CHECK:    [[COPIED_OLD_NSSTRING_BRIDGED_CAST:%.*]] = copy_value [[OLD_NSSTRING_BRIDGED_CAST]]
+    // CHECK:    [[COPIED_OLD_NSSTRING_BRIDGED:%.*]] = copy_value [[OLD_NSSTRING_BRIDGED]]
     // This is an identity cast that should be eliminated by SILGen peepholes.
-    // CHECK:    [[COPIED_OLD_NSSTRING_BRIDGED_CAST2:%.*]] = unchecked_bitwise_cast [[COPIED_OLD_NSSTRING_BRIDGED_CAST]]
-    // CHECK:    apply [[DIDSET_NOTIFIER]]([[COPIED_OLD_NSSTRING_BRIDGED_CAST2]], [[SELF]])
-    // CHECK:    destroy_value [[OLD_NSSTRING_BRIDGED_CAST]]
+    // CHECK:    apply [[DIDSET_NOTIFIER]]([[COPIED_OLD_NSSTRING_BRIDGED]], [[SELF]])
+    // CHECK:    destroy_value [[OLD_NSSTRING_BRIDGED]]
     // CHECK:    destroy_value [[NEW_VALUE]]
     // CHECK: } // end sil function '_TFC15objc_extensions3Subs4propGSQSS_'
 
diff --git a/test/SILGen/objc_imported_generic.swift b/test/SILGen/objc_imported_generic.swift
index 0447574..69d9bce 100644
--- a/test/SILGen/objc_imported_generic.swift
+++ b/test/SILGen/objc_imported_generic.swift
@@ -117,7 +117,7 @@
 
 // CHECK-LABEL: sil hidden @_TF21objc_imported_generic23configureWithoutOptionsFT_T_ : $@convention(thin) () -> ()
 // CHECK: [[NIL_FN:%.*]] = function_ref @_TFSqCfT10nilLiteralT__GSqx_ : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
-// CHECK: apply [[NIL_FN]]<Dictionary<GenericOption, Any>>({{.*}})
+// CHECK: apply [[NIL_FN]]<[GenericOption : Any]>({{.*}})
 // CHECK: return
 func configureWithoutOptions() {
   _ = GenericClass<NSObject>(options: nil)
diff --git a/test/SILGen/optional-cast.swift b/test/SILGen/optional-cast.swift
index b359bde..d4c52a4 100644
--- a/test/SILGen/optional-cast.swift
+++ b/test/SILGen/optional-cast.swift
@@ -131,8 +131,7 @@
 // CHECK-LABEL: sil hidden @_TF4main18opt_to_opt_trivialFGSqSi_GSQSi_
 // CHECK:       bb0(%0 : $Optional<Int>):
 // CHECK-NEXT:  debug_value %0 : $Optional<Int>, let, name "x"
-// CHECK-NEXT:  %2 = unchecked_trivial_bit_cast %0 : $Optional<Int> to $Optional<Int>
-// CHECK-NEXT:  return %2 : $Optional<Int>
+// CHECK-NEXT:  return %0 : $Optional<Int>
 // CHECK-NEXT:}
 func opt_to_opt_trivial(_ x: Int?) -> Int! {
   return x
@@ -141,8 +140,7 @@
 // CHECK-LABEL: sil hidden @_TF4main20opt_to_opt_referenceFGSQCS_1C_GSqS0__ :
 // CHECK:  bb0([[ARG:%.*]] : $Optional<C>):
 // CHECK:    debug_value [[ARG]] : $Optional<C>, let, name "x"
-// CHECK:    [[COPY_ARG:%.*]] = copy_value [[ARG]]
-// CHECK:    [[RESULT:%.*]] = unchecked_ref_cast [[COPY_ARG]] : $Optional<C> to $Optional<C>
+// CHECK:    [[RESULT:%.*]] = copy_value [[ARG]]
 // CHECK:    destroy_value [[ARG]]
 // CHECK:    return [[RESULT]] : $Optional<C>
 // CHECK: } // end sil function '_TF4main20opt_to_opt_referenceFGSQCS_1C_GSqS0__'
@@ -151,8 +149,7 @@
 // CHECK-LABEL: sil hidden @_TF4main22opt_to_opt_addressOnly
 // CHECK:       bb0(%0 : $*Optional<T>, %1 : $*Optional<T>):
 // CHECK-NEXT:  debug_value_addr %1 : $*Optional<T>, let, name "x"
-// CHECK-NEXT:  %3 = unchecked_addr_cast %0 : $*Optional<T> to $*Optional<T>
-// CHECK-NEXT:  copy_addr %1 to [initialization] %3
+// CHECK-NEXT:  copy_addr %1 to [initialization] %0
 // CHECK-NEXT:  destroy_addr %1
 func opt_to_opt_addressOnly<T>(_ x : T!) -> T? { return x }
 
@@ -164,8 +161,7 @@
   // CHECK-LABEL: sil hidden @_TFV4main21TestAddressOnlyStruct8testCall
   // CHECK: bb0(%0 : $*Optional<T>, %1 : $TestAddressOnlyStruct<T>):
   // CHECK: [[TMPBUF:%.*]] = alloc_stack $Optional<T>
-  // CHECK: [[TMPCAST:%.*]] = unchecked_addr_cast [[TMPBUF]]
-  // CHECK-NEXT: copy_addr %0 to [initialization] [[TMPCAST]]
+  // CHECK-NEXT: copy_addr %0 to [initialization] [[TMPBUF]]
   // CHECK-NEXT: apply {{.*}}<T>([[TMPBUF]], %1)
   func testCall(_ a : T!) {
     f(a)
@@ -177,8 +173,7 @@
 // CHECK-NEXT: debug_value %0 : $Optional<Int>, let, name "a"
 // CHECK-NEXT: [[X:%.*]] = alloc_box ${ var Optional<Int> }, var, name "x"
 // CHECK-NEXT: [[PB:%.*]] = project_box [[X]]
-// CHECK-NEXT: [[CAST:%.*]] = unchecked_addr_cast [[PB]] : $*Optional<Int> to $*Optional<Int>
-// CHECK-NEXT: store %0 to [trivial] [[CAST]] : $*Optional<Int>
+// CHECK-NEXT: store %0 to [trivial] [[PB]] : $*Optional<Int>
 // CHECK-NEXT: destroy_value [[X]] : ${ var Optional<Int> }
 func testContextualInitOfNonAddrOnlyType(_ a : Int?) {
   var x: Int! = a
diff --git a/test/SILGen/optional_to_optional.swift b/test/SILGen/optional_to_optional.swift
new file mode 100644
index 0000000..db5fced
--- /dev/null
+++ b/test/SILGen/optional_to_optional.swift
@@ -0,0 +1,32 @@
+// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+
+protocol P {}
+
+class Foo {
+  var x: Foo!
+  var p: P!
+
+  // CHECK-LABEL: {{.*3Foo.*3foo.*}}
+  // CHECK-NOT: unchecked_{{.*}}cast {{.*}} Optional{{.*}} to Optional
+  func foo() -> Foo? {
+    return x
+  }
+  // CHECK-LABEL: {{.*3Foo.*3poo.*}}
+  // CHECK-NOT: unchecked_{{.*}}cast {{.*}} Optional{{.*}} to Optional
+  func poo() -> P? {
+    return p
+  }
+
+  // CHECK-LABEL: {{.*3Foo.*3bar.*}}
+  // CHECK-NOT: unchecked_{{.*}}cast {{.*}} Optional{{.*}} to Optional
+  func bar() -> Foo? {
+    var x2 = x
+  }
+  // CHECK-LABEL: {{.*3Foo.*3par.*}}
+  // CHECK-NOT: unchecked_{{.*}}cast {{.*}} Optional{{.*}} to Optional
+  func par(p3: P) -> P? {
+    var p2 = p
+    p2! = p3
+    p2? = p3
+  }
+}
diff --git a/test/SILGen/protocol_extensions.swift b/test/SILGen/protocol_extensions.swift
index 160d3d5..ff7c359 100644
--- a/test/SILGen/protocol_extensions.swift
+++ b/test/SILGen/protocol_extensions.swift
@@ -69,7 +69,7 @@
 }
 
 //   (materializeForSet test from above)
-// CHECK-LABEL: sil [transparent] [thunk] @_TTWC19protocol_extensions1CS_2P1S_FS1_m9subscriptFSiSi
+// CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWC19protocol_extensions1CS_2P1S_FS1_m9subscriptFSiSi
 // CHECK: bb0(%0 : $Builtin.RawPointer, %1 : $*Builtin.UnsafeValueBuffer, %2 : $Int, %3 : $*C):
 // CHECK: function_ref @_TFE19protocol_extensionsPS_2P1g9subscriptFSiSi
 // CHECK: return
@@ -101,9 +101,11 @@
   // CHECK: [[D2:%[0-9]+]] = alloc_box ${ var D }
   // CHECK: [[RESULT:%.*]] = project_box [[D2]]
   // CHECK: [[FN:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P111returnsSelf{{.*}}
-  // CHECK: [[DCOPY:%[0-9]+]] = alloc_stack $D
-  // CHECK: store [[D]] to [init] [[DCOPY]] : $*D
-  // CHECK: apply [[FN]]<D>([[RESULT]], [[DCOPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> @out τ_0_0
+  // CHECK: [[MATERIALIZED_BORROWED_D:%[0-9]+]] = alloc_stack $D
+  // CHECK: [[BORROWED_D:%.*]] = begin_borrow [[D]]
+  // CHECK: store_borrow [[BORROWED_D]] to [[MATERIALIZED_BORROWED_D]]
+  // CHECK: apply [[FN]]<D>([[RESULT]], [[MATERIALIZED_BORROWED_D]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> @out τ_0_0
+  // CHECK-NEXT: end_borrow [[BORROWED_D]] from [[D]]
   var d2: D = d.returnsSelf()
 
   // CHECK: metatype $@thick D.Type
diff --git a/test/SILGen/protocol_resilience.swift b/test/SILGen/protocol_resilience.swift
index 76d33f1..323a9ea 100644
--- a/test/SILGen/protocol_resilience.swift
+++ b/test/SILGen/protocol_resilience.swift
@@ -1,4 +1,6 @@
-// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s --check-prefix=CHECK
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
+// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
 
 import resilient_protocol
 
diff --git a/test/SILGen/specialize_attr.swift b/test/SILGen/specialize_attr.swift
index 4589e77..210265a 100644
--- a/test/SILGen/specialize_attr.swift
+++ b/test/SILGen/specialize_attr.swift
@@ -1,8 +1,8 @@
 // RUN: %target-swift-frontend -emit-silgen -emit-verbose-sil %s | %FileCheck %s
 
-// CHECK-LABEL: @_specialize(Int, Float)
+// CHECK-LABEL: @_specialize(exported: false, kind: full, where T == Int, U == Float)
 // CHECK-NEXT: func specializeThis<T, U>(_ t: T, u: U)
-@_specialize(Int, Float)
+@_specialize(where T == Int, U == Float)
 func specializeThis<T, U>(_ t: T, u: U) {}
 
 public protocol PP {
@@ -22,19 +22,19 @@
 public struct GG<T : PP> {}
 
 // CHECK-LABEL: public class CC<T> where T : PP {
-// CHECK-NEXT: @_specialize(RR, SS)
+// CHECK-NEXT: @_specialize(exported: false, kind: full, where T == RR, U == SS)
 // CHECK-NEXT: @inline(never) public func foo<U>(_ u: U, g: GG<T>) -> (U, GG<T>) where U : QQ
 public class CC<T : PP> {
   @inline(never)
-  @_specialize(RR, SS)
+  @_specialize(where T == RR, U == SS)
   public func foo<U : QQ>(_ u: U, g: GG<T>) -> (U, GG<T>) {
     return (u, g)
   }
 }
 
-// CHECK-LABEL: sil hidden [_specialize <Int, Float>] @_TF15specialize_attr14specializeThisu0_rFTx1uq__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {
+// CHECK-LABEL: sil hidden [_specialize exported: false, kind: full, where T == Int, U == Float] @_TF15specialize_attr14specializeThisu0_rFTx1uq__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {
 
-// CHECK-LABEL: sil [noinline] [_specialize <RR, SS>] @_TFC15specialize_attr2CC3foouRd__S_2QQrfTqd__1gGVS_2GGx__Tqd__GS2_x__ : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
+// CHECK-LABEL: sil [noinline] [_specialize exported: false, kind: full, where T == RR, U == SS] @_TFC15specialize_attr2CC3foouRd__S_2QQrfTqd__1gGVS_2GGx__Tqd__GS2_x__ : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
 
 // -----------------------------------------------------------------------------
 // Test user-specialized subscript accessors.
@@ -52,11 +52,11 @@
   }
 
   public subscript(i: Int) -> Element {
-    @_specialize(Int)
+    @_specialize(where Element == Int)
     get {
       return storage[i]
     }
-    @_specialize(Int)
+    @_specialize(where Element == Int)
     set(rhs) {
       storage[i] = rhs
     }
@@ -64,10 +64,10 @@
 }
 
 // ASubscriptable.subscript.getter with _specialize
-// CHECK-LABEL: sil [_specialize <Int>] @_TFC15specialize_attr14ASubscriptableg9subscriptFSix : $@convention(method) <Element> (Int, @guaranteed ASubscriptable<Element>) -> @out Element {
+// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_TFC15specialize_attr14ASubscriptableg9subscriptFSix : $@convention(method) <Element> (Int, @guaranteed ASubscriptable<Element>) -> @out Element {
 
 // ASubscriptable.subscript.setter with _specialize
-// CHECK-LABEL: sil [_specialize <Int>] @_TFC15specialize_attr14ASubscriptables9subscriptFSix : $@convention(method) <Element> (@in Element, Int, @guaranteed ASubscriptable<Element>) -> () {
+// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_TFC15specialize_attr14ASubscriptables9subscriptFSix : $@convention(method) <Element> (@in Element, Int, @guaranteed ASubscriptable<Element>) -> () {
 
 // ASubscriptable.subscript.materializeForSet with no attribute
 // CHECK-LABEL: sil @_TFC15specialize_attr14ASubscriptablem9subscriptFSix : $@convention(method) <Element> (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, Int, @guaranteed ASubscriptable<Element>) -> (Builtin.RawPointer, Optional<Builtin.RawPointer>) {
@@ -80,11 +80,11 @@
   }
 
   public subscript(i: Int) -> Element {
-    @_specialize(Int)
+    @_specialize(where Element == Int)
     unsafeAddress {
       return UnsafePointer<Element>(storage + i)
     }
-    @_specialize(Int)
+    @_specialize(where Element == Int)
     unsafeMutableAddress {
       return UnsafeMutablePointer<Element>(storage + i)
     }
@@ -92,10 +92,10 @@
 }
 
 // Addressable.subscript.unsafeAddressor with _specialize
-// CHECK-LABEL: sil [_specialize <Int>] @_TFC15specialize_attr11Addressablelu9subscriptFSix : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> UnsafePointer<Element> {
+// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_TFC15specialize_attr11Addressablelu9subscriptFSix : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> UnsafePointer<Element> {
 
 // Addressable.subscript.unsafeMutableAddressor with _specialize
-// CHECK-LABEL: sil [_specialize <Int>] @_TFC15specialize_attr11Addressableau9subscriptFSix : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> UnsafeMutablePointer<Element> {
+// CHECK-LABEL: sil [_specialize exported: false, kind: full, where Element == Int] @_TFC15specialize_attr11Addressableau9subscriptFSix : $@convention(method) <Element> (Int, @guaranteed Addressable<Element>) -> UnsafeMutablePointer<Element> {
 
 
 // Addressable.subscript.getter with no attribute
diff --git a/test/SILGen/statements.swift b/test/SILGen/statements.swift
index d8ab2ae..f17482e 100644
--- a/test/SILGen/statements.swift
+++ b/test/SILGen/statements.swift
@@ -166,7 +166,7 @@
   // rdar://problem/19316670
   // CHECK: [[NEXT:%[0-9]+]] = function_ref @_TFVs16IndexingIterator4next
   // CHECK-NEXT: alloc_stack $Optional<MyClass>
-  // CHECK-NEXT: apply [[NEXT]]<Array<MyClass>
+  // CHECK-NEXT: apply [[NEXT]]<[MyClass]>
   // CHECK: class_method [[OBJ:%[0-9]+]] : $MyClass, #MyClass.foo!1
   let objects = [MyClass(), MyClass() ]
   for obj in objects {
diff --git a/test/SILGen/struct_resilience.swift b/test/SILGen/struct_resilience.swift
index 9af9cbe..30dd2dd 100644
--- a/test/SILGen/struct_resilience.swift
+++ b/test/SILGen/struct_resilience.swift
@@ -1,4 +1,6 @@
-// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | %FileCheck %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -I %t -emit-silgen -enable-resilience %s | %FileCheck %s
 
 import resilient_struct
 
diff --git a/test/SILGen/testable-multifile.swift b/test/SILGen/testable-multifile.swift
index e261459..e73c067 100644
--- a/test/SILGen/testable-multifile.swift
+++ b/test/SILGen/testable-multifile.swift
@@ -58,7 +58,7 @@
 
 
 
-// CHECK-LABEL: sil_witness_table FooImpl: Fooable module main {
+// CHECK-LABEL: sil_witness_table hidden FooImpl: Fooable module main {
 // CHECK-NEXT:  method #Fooable.foo!1: @_TTWV4main7FooImplS_7FooableS_FS1_3foofT_T_
 // CHECK-NEXT: }
 
diff --git a/test/SILOptimizer/dead_conformance.sil b/test/SILOptimizer/dead_conformance.sil
new file mode 100644
index 0000000..4caa061
--- /dev/null
+++ b/test/SILOptimizer/dead_conformance.sil
@@ -0,0 +1,55 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -sil-deadfuncelim %s | %FileCheck %s
+
+sil_stage canonical
+
+import Builtin
+import Swift
+import SwiftShims
+
+public protocol Proto {
+  func foo()
+}
+
+private struct Struct1 : Proto {
+  func foo()
+}
+
+private struct Struct2 : Proto {
+  func foo()
+}
+
+sil hidden_external @generic_func : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
+
+// CHECK: sil @let_metadata_of_Struct1_escape
+sil @let_metadata_of_Struct1_escape : $@convention(c) () -> () {
+bb0:
+  %2 = function_ref @generic_func : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
+  %3 = struct $Struct1 ()
+  %4 = alloc_stack $Struct1
+  store %3 to %4 : $*Struct1
+  %6 = apply %2<Struct1>(%4) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
+  dealloc_stack %4 : $*Struct1
+  %r = tuple ()
+  return %r : $()
+}
+
+// CHECK-NOT: sil @struct2_witness
+// CHECK: sil @struct1_witness
+// CHECK-NOT: sil @struct2_witness
+
+sil @struct1_witness : $@convention(witness_method) (@in_guaranteed Struct1) -> ()
+
+sil @struct2_witness : $@convention(witness_method) (@in_guaranteed Struct2) -> ()
+
+// CHECK-NOT: sil_witness_table Struct2
+// CHECK: sil_witness_table Struct1
+// CHECK-NOT: sil_witness_table Struct2
+
+sil_witness_table Struct1: Proto module nix {
+  method #Proto.foo!1: @struct1_witness
+}
+
+sil_witness_table Struct2: Proto module nix {
+  method #Proto.foo!1: @struct2_witness
+}
+
diff --git a/test/SILOptimizer/definite_init_existential_let.swift b/test/SILOptimizer/definite_init_existential_let.swift
new file mode 100644
index 0000000..cc6e09e
--- /dev/null
+++ b/test/SILOptimizer/definite_init_existential_let.swift
@@ -0,0 +1,29 @@
+// RUN: %target-swift-frontend -emit-sil -verify %s
+
+// rdar://problem/29716016 - Check that we properly enforce DI on `let`
+// variables and class properties.
+
+protocol P { }
+
+extension P {
+  mutating func foo() {}
+  var bar: Int { get { return 0 } set {} }
+}
+
+class ImmutableP {
+  let field: P // expected-note* {{}}
+
+  init(field: P) {
+    self.field = field
+    self.field.foo() // expected-error{{}}
+    self.field.bar = 4 // expected-error{{}}
+  }
+}
+
+func immutableP(field: P) {
+  let x: P // expected-note* {{}}
+
+  x = field
+  x.foo() // expected-error{{}}
+  x.bar = 4 // expected-error{{}}
+}
diff --git a/test/SILOptimizer/eager_specialize.sil b/test/SILOptimizer/eager_specialize.sil
index 5d48c26..ae63e9f 100644
--- a/test/SILOptimizer/eager_specialize.sil
+++ b/test/SILOptimizer/eager_specialize.sil
@@ -1,5 +1,7 @@
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -eager-specializer  %s | %FileCheck %s
-
+// Remove XFAIL once the specialization of generics is updated to support the
+// new form of the @_specialize attribute.
+// XFAIL: *
 sil_stage canonical
 
 import Builtin
@@ -30,9 +32,9 @@
   init()
 }
 
-// CHECK: @_specialize(S)
+// CHECK: @_specialize(exported: false, kind: full, where T == S)
 // CHECK: public func getGenericContainer<T>(g: G<T>, e: T.Elt) -> T where T : HasElt, T.Elt : AnElt
-@_specialize(S)
+@_specialize(where T == S)
 public func getGenericContainer<T>(g: G<T>, e: T.Elt) -> T where T : HasElt, T.Elt : AnElt
 
 enum ArithmeticError : Error {
@@ -41,25 +43,25 @@
   var _code: Int { get }
 }
 
-// CHECK: @_specialize(Int)
+// CHECK: @_specialize(exported: false, kind: full, where T == Int)
 // CHECK: public func divideNum<T>(num: T, den: T) throws -> T where T : SignedInteger
-@_specialize(Int)
+@_specialize(where T == Int)
 public func divideNum<T : SignedInteger>(num: T, den: T) throws -> T
 
 @inline(never) @_semantics("optimize.sil.never") func foo<T>(t: T) -> Int64
 
-// CHECK: @_specialize(Int64)
-// CHECK: @_specialize(Float)
+// CHECK: @_specialize(exported: false, kind: full, where T == Int64)
+// CHECK: @_specialize(exported: false, kind: full, where T == Float)
 // CHECK: public func voidReturn<T>(t: T)
-@_specialize(Int64)
-@_specialize(Float)
+@_specialize(where T == Int64)
+@_specialize(where T == Float)
 public func voidReturn<T>(t: T)
 
-// CHECK: @_specialize(Int64)
-// CHECK: @_specialize(Float)
+// CHECK: @_specialize(exported: false, kind: full, where T == Int64)
+// CHECK: @_specialize(exported: false, kind: full, where T == Float)
 // CHECK: public func nonvoidReturn<T>(t: T) -> Int64
-@_specialize(Int64)
-@_specialize(Float)
+@_specialize(where T == Int64)
+@_specialize(where T == Float)
 public func nonvoidReturn<T>(t: T) -> Int64
 
 // --- test: protocol conformance, substitution for dependent types
@@ -85,7 +87,7 @@
 sil_scope 6 { parent 5 }
 
 // getGenericContainer<A where ...> (G<A>, e : A.Elt) -> A
-sil [_specialize <S, X>] @_TF16eager_specialize19getGenericContaineruRxS_6HasEltwx3EltS_5AnEltrFTGVS_1Gx_1ewxS1__x : $@convention(thin) <T where T : HasElt, T.Elt : AnElt> (G<T>, @in T.Elt) -> @out T {
+sil [_specialize where T == S] @_TF16eager_specialize19getGenericContaineruRxS_6HasEltwx3EltS_5AnEltrFTGVS_1Gx_1ewxS1__x : $@convention(thin) <T where T : HasElt, T.Elt : AnElt> (G<T>, @in T.Elt) -> @out T {
 bb0(%0 : $*T, %1 : $G<T>, %2 : $*T.Elt):
   // function_ref G.getContainer(A.Elt) -> A
   %5 = function_ref @_TFV16eager_specialize1G12getContainerfwx3Eltx : $@convention(method) <τ_0_0 where τ_0_0 : HasElt> (@in τ_0_0.Elt, G<τ_0_0>) -> @out τ_0_0, scope 6 // user: %6
@@ -159,7 +161,7 @@
 }
 
 // divideNum<A where ...> (A, den : A) throws -> A
-sil [_specialize <Int>] @_TF16eager_specialize9divideNumuRxs13SignedIntegerrFzTx3denx_x : $@convention(thin) <T where T : SignedInteger> (@in T, @in T) -> (@out T, @error Error) {
+sil [_specialize where T == Int] @_TF16eager_specialize9divideNumuRxs13SignedIntegerrFzTx3denx_x : $@convention(thin) <T where T : SignedInteger> (@in T, @in T) -> (@out T, @error Error) {
 // %0                                             // user: %19
 // %1                                             // users: %3, %19, %23
 // %2                                             // users: %4, %7, %19, %22
@@ -270,7 +272,7 @@
 sil_scope 2 { parent 1 }
 
 // voidReturn<A> (A) -> ()
-sil [_specialize <Float>] [_specialize <Int64>] @_TF16eager_specialize10voidReturnurFxT_ : $@convention(thin) <T> (@in T) -> () {
+sil [_specialize where T == Float] [_specialize where T == Int64] @_TF16eager_specialize10voidReturnurFxT_ : $@convention(thin) <T> (@in T) -> () {
 bb0(%0 : $*T):
   // function_ref foo<A> (A) -> Int64
   %2 = function_ref @_TF16eager_specialize3foourFxVs5Int64 : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int64, scope 2 // user: %3
@@ -322,7 +324,7 @@
 sil_scope 4 { parent 3 }
 
 // nonvoidReturn<A> (A) -> Int64
-sil [_specialize <Float>] [_specialize <Int64>] @_TF16eager_specialize13nonvoidReturnurFxVs5Int64 : $@convention(thin) <T> (@in T) -> Int64 {
+sil [_specialize where T == Float] [_specialize where T == Int64] @_TF16eager_specialize13nonvoidReturnurFxVs5Int64 : $@convention(thin) <T> (@in T) -> Int64 {
 // %0                                             // users: %1, %3
 bb0(%0 : $*T):
   // function_ref foo<A> (A) -> Int64
diff --git a/test/SILOptimizer/mem2reg.sil b/test/SILOptimizer/mem2reg.sil
index fe055e9..1054555 100644
--- a/test/SILOptimizer/mem2reg.sil
+++ b/test/SILOptimizer/mem2reg.sil
@@ -327,3 +327,18 @@
   return %7 : $()
 }
 
+// Test cases where there are dead address instructions.
+// CHECK-LABEL: sil @dead_use
+// CHECK-NOT: alloc_stack
+sil @dead_use : $@convention(thin) () -> () {
+  %0 = alloc_stack $Int64
+  %1 = struct_element_addr %0 : $*Int64, #Int64._value
+  dealloc_stack %0 : $*Int64
+  %2 = alloc_stack $(Int64, Int64)
+  %3 = tuple_element_addr %2 : $*(Int64, Int64), 0
+  dealloc_stack %2 : $*(Int64, Int64)
+  // CHECK: [[VAL:%.*]] = tuple ()
+  %4 = tuple ()
+  // CHECK: return [[VAL]]
+  return %4 : $()
+}
diff --git a/test/SILOptimizer/ownership_model_eliminator.sil b/test/SILOptimizer/ownership_model_eliminator.sil
index 34016c8..b7e80bc 100644
--- a/test/SILOptimizer/ownership_model_eliminator.sil
+++ b/test/SILOptimizer/ownership_model_eliminator.sil
@@ -117,3 +117,21 @@
   %9999 = tuple()
   return %9999 : $()
 }
+
+// CHECK-LABEL: sil @unmanaged_retain_release_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject):
+// CHECK: strong_retain [[ARG]] : $Builtin.NativeObject
+// CHECK: strong_release [[ARG]] : $Builtin.NativeObject
+// CHECK: strong_release [[ARG]] : $Builtin.NativeObject
+// CHECK: } // end sil function 'unmanaged_retain_release_test'
+sil @unmanaged_retain_release_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  unmanaged_retain_value %0 : $Builtin.NativeObject
+  br bb1
+
+bb1:
+  unmanaged_release_value %0 : $Builtin.NativeObject
+  destroy_value %0 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/Sema/complex_expressions.swift b/test/Sema/complex_expressions.swift
index 289afd0..92ce057 100644
--- a/test/Sema/complex_expressions.swift
+++ b/test/Sema/complex_expressions.swift
@@ -97,3 +97,21 @@
 let v5 = ([1 + 2 + 3, 4] as [UInt32]) + ([2 * 3] as [UInt32])
 let v6 = [1 + 2 + 3, 4] as Set<UInt32>
 let v7: [UInt32] = [55 * 8, 0]
+
+// SR-3668
+// "Expression was too complex" errors for short dictionary literals
+// of simple closure expressions
+
+let sr3668Dict1: Dictionary<Int, (Int, Int) -> Bool> =
+  [  0: { $0 == $1 },  1: { $0 == $1 },  2: { $0 == $1 },  3: { $0 == $1 },
+     4: { $0 == $1 },  5: { $0 == $1 },  6: { $0 == $1 },  7: { $0 == $1 },
+     8: { $0 == $1 },  9: { $0 == $1 }, 10: { $0 == $1 }, 11: { $0 == $1 },
+    12: { $0 == $1 }, 13: { $0 == $1 }, 14: { $0 == $1 }, 15: { $0 == $1 },
+    16: { $0 == $1 }, 17: { $0 == $1 }, 18: { $0 == $1 }, 19: { $0 == $1 } ]
+
+let sr3668Dict2: [Int: (Int, Int) -> Bool] =
+  [  0: { $0 != $1 },  1: { $0 != $1 },  2: { $0 != $1 },  3: { $0 != $1 },
+     4: { $0 != $1 },  5: { $0 != $1 },  6: { $0 != $1 },  7: { $0 != $1 },
+     8: { $0 != $1 },  9: { $0 != $1 }, 10: { $0 != $1 }, 11: { $0 != $1 },
+    12: { $0 != $1 }, 13: { $0 != $1 }, 14: { $0 != $1 }, 15: { $0 != $1 },
+    16: { $0 != $1 }, 17: { $0 != $1 }, 18: { $0 != $1 }, 19: { $0 != $1 } ]
diff --git a/test/Serialization/serialize_attr.swift b/test/Serialization/serialize_attr.swift
index 909727a..5260af8 100644
--- a/test/Serialization/serialize_attr.swift
+++ b/test/Serialization/serialize_attr.swift
@@ -16,9 +16,9 @@
 // -----------------------------------------------------------------------------
 
 // These lines should be contiguous.
-// CHECK-DAG: @_specialize(Int, Float)
+// CHECK-DAG: @_specialize(exported: false, kind: full, where T == Int, U == Float)
 // CHECK-DAG: func specializeThis<T, U>(_ t: T, u: U)
-@_specialize(Int, Float)
+@_specialize(where T == Int, U == Float)
 func specializeThis<T, U>(_ t: T, u: U) {}
 
 protocol PP {
@@ -42,16 +42,16 @@
 // label, and the declaration order is unpredictable.
 //
 // CHECK-DAG: class CC<T> where T : PP {
-// CHECK-DAG: @_specialize(RR, SS)
+// CHECK-DAG: @_specialize(exported: false, kind: full, where T == RR, U == SS)
 // CHECK-DAG: @inline(never) func foo<U>(_ u: U, g: GG<T>) -> (U, GG<T>) where U : QQ
 class CC<T : PP> {
   @inline(never)
-  @_specialize(RR, SS)
+  @_specialize(where T==RR, U==SS)
   func foo<U : QQ>(_ u: U, g: GG<T>) -> (U, GG<T>) {
     return (u, g)
   }
 }
 
-// CHECK-DAG: sil hidden [fragile] [_specialize <Int, Float>] @_TF14serialize_attr14specializeThisu0_rFTx1uq__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {
+// CHECK-DAG: sil hidden [fragile] [_specialize exported: false, kind: full, where T == Int, U == Float] @_TF14serialize_attr14specializeThisu0_rFTx1uq__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {
 
-// CHECK-DAG: sil hidden [fragile] [noinline] [_specialize <RR, SS>] @_TFC14serialize_attr2CC3foouRd__S_2QQrfTqd__1gGVS_2GGx__Tqd__GS2_x__ : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
+// CHECK-DAG: sil hidden [fragile] [noinline] [_specialize exported: false, kind: full, where T == RR, U == SS] @_TFC14serialize_attr2CC3foouRd__S_2QQrfTqd__1gGVS_2GGx__Tqd__GS2_x__ : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
diff --git a/test/SourceKit/CursorInfo/crash1.swift b/test/SourceKit/CursorInfo/crash1.swift
index bcf7d7f..2d919c8 100644
--- a/test/SourceKit/CursorInfo/crash1.swift
+++ b/test/SourceKit/CursorInfo/crash1.swift
@@ -3,11 +3,17 @@
     init(aName:String) {
         self.name = aName
     }
+
+    subscript(x: Int) -> Int {
+      return x
+    }
 }
 
 // rdar://24133008
 // RUN: %sourcekitd-test -req=cursor -pos=4:16 %s -- %s | %FileCheck %s -check-prefix=CASE1
 // RUN: %sourcekitd-test -req=cursor -pos=4:24 %s -- %s | %FileCheck %s -check-prefix=CASE2
+// RUN: %sourcekitd-test -req=cursor -pos=7:15 %s -- %s | %FileCheck %s -check-prefix=CASE3
 
 // CASE1: source.lang.swift.ref.var.instance (2:9-2:13)
 // CASE2: source.lang.swift.ref.var.local (3:10-3:15)
+// CASE3: source.lang.swift.decl.var.parameter (7:15-7:16)
diff --git a/test/attr/attr_availability_narrow.swift b/test/attr/attr_availability_narrow.swift
new file mode 100644
index 0000000..1dee604
--- /dev/null
+++ b/test/attr/attr_availability_narrow.swift
@@ -0,0 +1,69 @@
+// RUN: %target-typecheck-verify-swift
+// REQUIRES: OS=macosx
+// <rdar://problem/17669805> Suggest narrowing the range of bad availabile checks
+
+import Foundation
+
+@available(macOS 10.12.2, *)
+func foo() { }
+
+func useFoo() {
+  if #available(macOS 10.12.1, *) {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}} {{23-30=10.12.2}}
+  }
+}
+
+func useFooDifferentSpelling() {
+  if #available(OSX 10.12.1, *) {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}} {{21-28=10.12.2}}
+  }
+}
+
+func useFooAlreadyOkRange() {
+  if #available(OSX 10.13, *) {
+    foo()
+  }
+}
+
+func useFooUnaffectedSimilarText() {
+  if #available(iOS 10.12.10, OSX 10.12.1, *) {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}} {{35-42=10.12.2}}
+  }
+}
+
+func useFooWayOff() {
+  if #available(OSX 10.10, *) {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}}
+    // expected-note@-1{{add @available attribute to enclosing global function}}
+    // expected-note@-2{{add 'if #available' version check}}
+  }
+}
+
+@available(OSX 10.12, *)
+class FooUser {
+  func useFoo() {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}} {{16-21=10.12.2}}
+  }
+}
+
+@available(OSX, introduced: 10.12, obsoleted: 10.12.4)
+class FooUser2 {
+  func useFoo() {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}} {{29-34=10.12.2}}
+  }
+}
+
+@available(OSX, introduced: 10.12, obsoleted: 10.12.4)
+@objc
+class FooUser3 : NSObject {
+  func useFoo() {
+    foo() // expected-error {{'foo()' is only available on OS X 10.12.2 or newer}} {{29-34=10.12.2}}
+  }
+}
+
+@available(OSX, introduced: 10.12.4)
+class FooUserOkRange {
+  func useFoo() {
+    foo()
+  }
+}
diff --git a/test/attr/attr_availability_tvos.swift b/test/attr/attr_availability_tvos.swift
index 94638e2..c1d5e17 100644
--- a/test/attr/attr_availability_tvos.swift
+++ b/test/attr/attr_availability_tvos.swift
@@ -59,8 +59,7 @@
 }
 
 if #available(iOS 9.3, tvOS 9.1, *) {
-  functionIntroducedOntvOS9_2() // expected-error {{'functionIntroducedOntvOS9_2()' is only available on tvOS 9.2 or newer}}
-      // expected-note@-1 {{add 'if #available' version check}}
+  functionIntroducedOntvOS9_2() // expected-error {{'functionIntroducedOntvOS9_2()' is only available on tvOS 9.2 or newer}} {{29-32=9.2}}
 }
 
 if #available(iOS 9.1, tvOS 9.2, *) {
diff --git a/test/attr/attr_availability_watchos.swift b/test/attr/attr_availability_watchos.swift
index e71eebe..29f04b9 100644
--- a/test/attr/attr_availability_watchos.swift
+++ b/test/attr/attr_availability_watchos.swift
@@ -59,8 +59,7 @@
 }
 
 if #available(iOS 9.3, watchOS 2.1, *) {
-  functionIntroducedOnwatchOS2_2() // expected-error {{'functionIntroducedOnwatchOS2_2()' is only available on watchOS 2.2 or newer}}
-      // expected-note@-1 {{add 'if #available' version check}}
+  functionIntroducedOnwatchOS2_2() // expected-error {{'functionIntroducedOnwatchOS2_2()' is only available on watchOS 2.2 or newer}} {{32-35=2.2}}
 }
 
 if #available(iOS 9.1, watchOS 2.2, *) {
diff --git a/test/attr/attr_fixed_layout.swift b/test/attr/attr_fixed_layout.swift
index fc352be..d584828 100644
--- a/test/attr/attr_fixed_layout.swift
+++ b/test/attr/attr_fixed_layout.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend -typecheck -dump-ast -enable-resilience %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-ON %s
-// RUN: %target-swift-frontend -typecheck -dump-ast %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-OFF %s
+// RUN: %target-swift-frontend -typecheck -verify -dump-ast -enable-resilience %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-ON %s
+// RUN: %target-swift-frontend -typecheck -verify -dump-ast %s 2>&1 | %FileCheck --check-prefix=RESILIENCE-OFF %s
 
 //
 // Public types with @_fixed_layout are always fixed layout
@@ -45,3 +45,16 @@
   let topLeft: Point
   let bottomRight: Size
 }
+
+//
+// Diagnostics
+//
+
+@_fixed_layout struct InternalStruct {}
+// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'InternalStruct' is internal}}
+
+@_fixed_layout fileprivate struct FileprivateStruct {}
+// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'FileprivateStruct' is fileprivate}}
+
+@_fixed_layout private struct PrivateStruct {}
+// expected-error@-1 {{'@_fixed_layout' attribute can only be applied to '@_versioned' or public declarations, but 'PrivateStruct' is private}}
diff --git a/test/attr/attr_inlineable.swift b/test/attr/attr_inlineable.swift
index 0c5cadf..e088039 100644
--- a/test/attr/attr_inlineable.swift
+++ b/test/attr/attr_inlineable.swift
@@ -193,3 +193,56 @@
     }(),
     y: Int = internalIntFunction()) {}
     // expected-error@-1 {{global function 'internalIntFunction()' is internal and cannot be referenced from a default argument value}}
+
+// Make sure protocol extension members can reference protocol requirements
+// (which do not inherit the @_versioned attribute).
+@_versioned
+protocol VersionedProtocol {
+  associatedtype T
+
+  func requirement() -> T
+}
+
+extension VersionedProtocol {
+  func internalMethod() {}
+  // expected-note@-1 {{instance method 'internalMethod()' is not '@_versioned' or public}}
+
+  @_inlineable
+  @_versioned
+  func versionedMethod() -> T {
+    internalMethod()
+    // expected-error@-1 {{instance method 'internalMethod()' is internal and cannot be referenced from an '@_inlineable' function}}
+
+    return requirement()
+  }
+}
+
+protocol InternalProtocol {
+  associatedtype T
+
+  func requirement() -> T
+}
+
+extension InternalProtocol {
+  func internalMethod() {}
+
+  // FIXME: https://bugs.swift.org/browse/SR-3684
+  //
+  // This should either complain that the method cannot be '@_versioned' since
+  // we're inside an extension of an internal protocol, or if such methods are
+  // allowed, we should diagnose the reference to 'internalMethod()' from the
+  // body.
+  @_inlineable
+  @_versioned
+  func versionedMethod() -> T {
+    internalMethod()
+    return requirement()
+  }
+
+  // Ditto, except s/@_versioned/public/.
+  @_inlineable
+  public func publicMethod() -> T {
+    internalMethod()
+    return requirement()
+  }
+}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index b45cafc..8c394e3 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -1,6 +1,6 @@
-// RUN: %target-typecheck-verify-swift
-// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module | %FileCheck %s
-// RUN: not %target-swift-frontend -typecheck -dump-ast -disable-objc-attr-requires-foundation-module %s 2> %t.dump
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 4
+// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module -swift-version 4 | %FileCheck %s
+// RUN: not %target-swift-frontend -typecheck -dump-ast -disable-objc-attr-requires-foundation-module %s -swift-version 4 2> %t.dump
 // RUN: %FileCheck -check-prefix CHECK-DUMP %s < %t.dump
 // REQUIRES: objc_interop
 
@@ -1901,12 +1901,14 @@
   class func load() { }
   class func alloc() {}
   class func allocWithZone(_: Int) {}
+  class func initialize() {}
 }
 
 @objc class Load2 {
   class func load() { } // expected-error{{method 'load()' defines Objective-C class method 'load', which is not permitted by Swift}}
   class func alloc() {} // expected-error{{method 'alloc()' defines Objective-C class method 'alloc', which is not permitted by Swift}}
   class func allocWithZone(_: Int) {} // expected-error{{method 'allocWithZone' defines Objective-C class method 'allocWithZone:', which is not permitted by Swift}}
+  class func initialize() {} // expected-error{{method 'initialize()' defines Objective-C class method 'initialize', which is not permitted by Swift}}
 }
 
 @objc class Load3 {
@@ -1917,6 +1919,7 @@
 
   @objc(alloc) class var prop: Int { return 0 } // expected-error{{getter for 'prop' defines Objective-C class method 'alloc', which is not permitted by Swift}}
   @objc(allocWithZone:) class func fooWithZone(_: Int) {} // expected-error{{method 'fooWithZone' defines Objective-C class method 'allocWithZone:', which is not permitted by Swift}}
+  @objc(initialize) class func barnitialize() {} // expected-error{{method 'barnitialize()' defines Objective-C class method 'initialize', which is not permitted by Swift}}
 }
 
 // Members of protocol extensions cannot be @objc
diff --git a/test/attr/attr_specialize.swift b/test/attr/attr_specialize.swift
index d34a605..450145f 100644
--- a/test/attr/attr_specialize.swift
+++ b/test/attr/attr_specialize.swift
@@ -3,45 +3,61 @@
 
 struct S<T> {}
 
+public protocol P {
+}
+extension Int: P {
+}
+
+public protocol ProtocolWithDep {
+  associatedtype Element
+}
+
+public class C1 {
+}
+
+class Base {}
+class Sub : Base {}
+class NonSub {}
+
 // Specialize freestanding functions with the correct number of concrete types.
 // ----------------------------------------------------------------------------
 
-// CHECK: @_specialize(Int)
-@_specialize(Int)
-// CHECK: @_specialize(S<Int>)
-@_specialize(S<Int>)
-@_specialize(Int, Int) // expected-error{{generic type 'oneGenericParam' specialized with too many type parameters (got 2, but expected 1)}},
-@_specialize(T) // expected-error{{use of undeclared type 'T'}}
+// CHECK: @_specialize(exported: false, kind: full, where T == Int)
+@_specialize(where T == Int)
+// CHECK: @_specialize(exported: false, kind: full, where T == S<Int>)
+@_specialize(where T == S<Int>)
+@_specialize(where T == Int, U == Int) // expected-error{{use of undeclared type 'U'}},
+@_specialize(where T == T1) // expected-error{{use of undeclared type 'T1'}}
 public func oneGenericParam<T>(_ t: T) -> T {
   return t
 }
 
-// CHECK: @_specialize(Int, Int)
-@_specialize(Int, Int)
-@_specialize(Int) // expected-error{{generic type 'twoGenericParams' specialized with too few type parameters (got 1, but expected 2)}},
+// CHECK: @_specialize(exported: false, kind: full, where T == Int, U == Int)
+@_specialize(where T == Int, U == Int)
+@_specialize(where T == Int) // expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'U' in '_specialize' attribute}}
 public func twoGenericParams<T, U>(_ t: T, u: U) -> (T, U) {
   return (t, u)
 }
 
-@_specialize(Int) // expected-error{{generic type 'nonGenericParam' specialized with too many type parameters (got 1, but expected 0)}}
+@_specialize(where T == Int) // expected-error{{trailing 'where' clause in '_specialize' attribute of non-generic function 'nonGenericParam'}}
 func nonGenericParam(x: Int) {}
 
 // Specialize contextual types.
 // ----------------------------
 
 class G<T> {
-  // CHECK: @_specialize(Int)
-  @_specialize(Int)
-  @_specialize(T) // expected-error{{cannot partially specialize a generic function}}
-  @_specialize(S<T>) // expected-error{{cannot partially specialize a generic function}}
-  @_specialize(Int, Int) // expected-error{{generic type 'noGenericParams' specialized with too many type parameters (got 2, but expected 1)}}
+  // CHECK: @_specialize(exported: false, kind: full, where T == Int)
+  @_specialize(where T == Int)
+  @_specialize(where T == T) // expected-error{{Only concrete type same-type requirements are supported by '_specialize' attribute}}
+  @_specialize(where T == S<T>) // expected-error{{Only concrete type same-type requirements are supported by '_specialize' attribute}}
+  @_specialize(where T == Int, U == Int) // expected-error{{use of undeclared type 'U'}}
   func noGenericParams() {}
 
-  // CHECK: @_specialize(Int, Float)
-  @_specialize(Int, Float)
-  // CHECK: @_specialize(Int, S<Int>)
-  @_specialize(Int, S<Int>)
-  @_specialize(Int) // expected-error{{generic type 'oneGenericParam' specialized with too few type parameters (got 1, but expected 2)}},
+  // CHECK: @_specialize(exported: false, kind: full, where T == Int, U == Float)
+  @_specialize(where T == Int, U == Float)
+  // CHECK: @_specialize(exported: false, kind: full, where T == Int, U == S<Int>)
+  @_specialize(where T == Int, U == S<Int>)
+  @_specialize(where T == Int) // expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error {{Missing constraint for 'U' in '_specialize' attribute}}
   func oneGenericParam<U>(_ t: T, u: U) -> (U, T) {
     return (u, t)
   }
@@ -54,9 +70,9 @@
 
 struct AThing : Thing {}
 
-// CHECK: @_specialize(AThing)
-@_specialize(AThing)
-@_specialize(Int) // expected-error{{argument type 'Int' does not conform to expected type 'Thing'}}
+// CHECK: @_specialize(exported: false, kind: full, where T == AThing)
+@_specialize(where T == AThing)
+@_specialize(where T == Int) // expected-error{{same-type constraint type 'Int' does not conform to required protocol 'Thing'}}
 func oneRequirement<T : Thing>(_ t: T) {}
 
 protocol HasElt {
@@ -68,13 +84,139 @@
 struct FloatElement : HasElt {
   typealias Element = Float
 }
-@_specialize(FloatElement)
-@_specialize(IntElement) // expected-error{{'<T where T : HasElt, T.Element == Float> (T) -> ()' requires the types 'IntElement.Element' (aka 'Int') and 'Float' be equivalent}}
+@_specialize(where T == FloatElement)
+@_specialize(where T == IntElement) // expected-error{{generic parameter T.Element cannot be equal to both 'Float' and 'IntElement.Element' (aka 'Int')}}
 func sameTypeRequirement<T : HasElt>(_ t: T) where T.Element == Float {}
 
-class Base {}
-class Sub : Base {}
-class NonSub {}
-@_specialize(Sub)
-@_specialize(NonSub) // expected-error{{'<T where T : Base> (T) -> ()' requires that 'NonSub' inherit from 'Base'}}
+@_specialize(where T == Sub)
+@_specialize(where T == NonSub) // expected-error{{'T' requires that 'NonSub' inherit from 'Base'}}
 func superTypeRequirement<T : Base>(_ t: T) {}
+
+@_specialize(where X:_Trivial(8), Y == Int) // expected-error{{trailing 'where' clause in '_specialize' attribute of non-generic function 'requirementOnNonGenericFunction'}}
+public func requirementOnNonGenericFunction(x: Int, y: Int) {
+}
+
+@_specialize(where Y == Int) // expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'X' in '_specialize' attribute}}
+public func missingRequirement<X:P, Y>(x: X, y: Y) {
+}
+
+@_specialize(where) // expected-error{{expected identifier for type name}}
+@_specialize() // expected-error{{expected a parameter label or a where clause in '_specialize' attribute}} expected-error{{expected declaration}}
+public func funcWithEmptySpecializeAttr<X: P, Y>(x: X, y: Y) {
+}
+
+
+@_specialize(where X:_Trivial(8), Y:_Trivial(32), Z == Int) // expected-error{{use of undeclared type 'Z'}}
+@_specialize(where X:_Trivial(8), Y:_Trivial(32, 4))
+@_specialize(where X == Int) // expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'Y' in '_specialize' attribute}}
+@_specialize(where Y:_Trivial(32)) // expected-error {{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'X' in '_specialize' attribute}}
+@_specialize(where Y: P) // expected-error{{Only same-type and layout requirements are supported by '_specialize' attribute}} expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'X' in '_specialize' attribute}}
+@_specialize(where Y: MyClass) // expected-error{{use of undeclared type 'MyClass'}} expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'X' in '_specialize' attribute}}
+@_specialize(where X:_Trivial(8), Y == Int)
+@_specialize(where X == Int, Y == Int)
+@_specialize(where X == Int, X == Int) // expected-error{{too few type parameters are specified in '_specialize' attribute (got 1, but expected 2)}} expected-error{{Missing constraint for 'Y' in '_specialize' attribute}}
+@_specialize(where Y:_Trivial(32), X == Float)
+@_specialize(where X1 == Int, Y1 == Int) // expected-error{{use of undeclared type 'X1'}} expected-error{{use of undeclared type 'Y1'}} expected-error{{too few type parameters are specified in '_specialize' attribute (got 0, but expected 2)}} expected-error{{Missing constraint for 'X' in '_specialize' attribute}} expected-error{{Missing constraint for 'Y' in '_specialize' attribute}}
+public func funcWithTwoGenericParameters<X, Y>(x: X, y: Y) {
+}
+
+@_specialize(where X == Int, Y == Int)
+@_specialize(exported: true, where X == Int, Y == Int)
+@_specialize(exported: false, where X == Int, Y == Int)
+@_specialize(exported: false where X == Int, Y == Int) // expected-error{{missing ',' in '_specialize' attribute}}
+@_specialize(exported: yes, where X == Int, Y == Int) // expected-error{{expected a boolean true or false value in '_specialize' attribute}}
+@_specialize(exported: , where X == Int, Y == Int) // expected-error{{expected a boolean true or false value in '_specialize' attribute}}
+
+@_specialize(kind: partial, where X == Int, Y == Int)
+@_specialize(kind: partial, where X == Int)
+@_specialize(kind: full, where X == Int, Y == Int)
+@_specialize(kind: any, where X == Int, Y == Int) // expected-error{{expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute}}
+@_specialize(kind: false, where X == Int, Y == Int) // expected-error{{expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute}}
+@_specialize(kind: partial where X == Int, Y == Int) // expected-error{{missing ',' in '_specialize' attribute}}
+@_specialize(kind: partial, where X == Int, Y == Int)
+@_specialize(kind: , where X == Int, Y == Int)
+
+@_specialize(exported: true, kind: partial, where X == Int, Y == Int)
+@_specialize(exported: true, exported: true, where X == Int, Y == Int) // expected-error{{parameter 'exported' was already defined in '_specialize' attribute}}
+@_specialize(kind: partial, exported: true, where X == Int, Y == Int)
+@_specialize(kind: partial, kind: partial, where X == Int, Y == Int) // expected-error{{parameter 'kind' was already defined in '_specialize' attribute}}
+
+@_specialize(where X == Int, Y == Int, exported: true, kind: partial) // expected-error{{use of undeclared type 'exported'}} expected-error{{use of undeclared type 'kind'}} expected-error{{use of undeclared type 'partial'}} expected-error{{expected identifier for type name}}
+public func anotherFuncWithTwoGenericParameters<X: P, Y>(x: X, y: Y) {
+}
+
+@_specialize(where T: P) // expected-error{{Only same-type and layout requirements are supported by '_specialize' attribute}}
+@_specialize(where T: Int) // expected-error{{Only conformances to protocol types are supported by '_specialize' attribute}} expected-error{{Only same-type and layout requirements are supported by '_specialize' attribute}}
+
+@_specialize(where T: S1) // expected-error{{Only conformances to protocol types are supported by '_specialize' attribute}} expected-error{{Only same-type and layout requirements are supported by '_specialize' attribute}}
+@_specialize(where T: C1) // expected-error{{Only conformances to protocol types are supported by '_specialize' attribute}} expected-error{{Only same-type and layout requirements are supported by '_specialize' attribute}}
+@_specialize(where Int: P) // expected-error{{type 'Int' in conformance requirement does not refer to a generic parameter or associated type}} expected-error{{Only same-type and layout requirements are supported by '_specialize' attribute}} expected-error{{too few type parameters are specified in '_specialize' attribute (got 0, but expected 1)}} expected-error{{Missing constraint for 'T' in '_specialize' attribute}}
+func funcWithForbiddenSpecializeRequirement<T>(_ t: T) {
+}
+
+@_specialize(where T: _Trivial(32), T: _Trivial(64), T: _Trivial, T: _RefCountedObject) // expected-error{{multiple layout constraints cannot be used at the same time: '_Trivial(64)' and '_Trivial(32)'}} expected-note{{previous layout constraint declaration '_Trivial(32)' was here}} expected-error{{multiple layout constraints cannot be used at the same time: '_Trivial' and '_Trivial(32)'}} expected-note{{previous layout constraint declaration '_Trivial(32)' was here}} expected-error{{multiple layout constraints cannot be used at the same time: '_RefCountedObject' and '_Trivial(32)'}} expected-note{{previous layout constraint declaration '_Trivial(32)' was here}}
+@_specialize(where Array<T> == Int) // expected-error{{neither type in same-type refers to a generic parameter or associated type}} expected-error{{Only requirements on generic parameters are supported by '_specialize' attribute}}
+@_specialize(where T.Element == Int) // expected-error{{Only requirements on generic parameters are supported by '_specialize' attribute}}
+public func funcWithComplexSpecializeRequirements<T: ProtocolWithDep>(t: T) -> Int {
+  return 55555
+}
+
+public struct S1 {
+}
+
+@_specialize(exported: false, where T == Int64)
+public func simpleGeneric<T>(t: T) -> T {
+  return t
+}
+
+
+@_specialize(exported: true, where S: _Trivial(64))
+// Check that any bitsize size is OK, not only powers of 8.
+@_specialize(where S: _Trivial(60))
+@_specialize(exported: true, where S: _RefCountedObject)
+@inline(never)
+public func copyValue<S>(_ t: S, s: inout S) -> Int64 where S: P{
+  return 1
+}
+
+@_specialize(exported: true, where S: _Trivial)
+@_specialize(exported: true, where S: _Trivial(64))
+@_specialize(exported: true, where S: _Trivial(32))
+@_specialize(exported: true, where S: _RefCountedObject)
+@inline(never)
+public func copyValueAndReturn<S>(_ t: S, s: inout S) -> S where S: P{
+  return s
+}
+
+struct OuterStruct<S> {
+  struct MyStruct<T> {
+    @_specialize(where T == Int, U == Float) // expected-error{{too few type parameters are specified in '_specialize' attribute (got 2, but expected 3)}} expected-error{{Missing constraint for 'S' in '_specialize' attribute}}
+    public func foo<U>(u : U) {
+    }
+
+    @_specialize(where T == Int, U == Float, S == Int)
+    public func bar<U>(u : U) {
+    }
+  }
+}
+
+// Check _TrivialAtMostN constraints.
+@_specialize(exported: true, where S: _TrivialAtMost(64))
+@inline(never)
+public func copy2<S>(_ t: S, s: inout S) -> S where S: P{
+  return s
+}
+
+// Check missing alignment.
+@_specialize(where S: _Trivial(64, )) // expected-error{{expected non-negative alignment to be specified in layout constraint}}
+// Check non-numeric size.
+@_specialize(where S: _Trivial(Int)) // expected-error{{expected non-negative size to be specified in layout constraint}}
+// Check non-numeric alignment.
+@_specialize(where S: _Trivial(64, X)) // expected-error{{expected non-negative alignment to be specified in layout constraint}}
+@inline(never)
+public func copy3<S>(_ s: S) -> S {
+  return s
+}
+
+public func funcWithWhereClause<T>(t: T) where T:P, T: _Trivial(64) { // expected-error{{layout constraints are only allowed inside '_specialize' attributes}}
+}
diff --git a/test/attr/attr_versioned.swift b/test/attr/attr_versioned.swift
index e74843a..a025e92 100644
--- a/test/attr/attr_versioned.swift
+++ b/test/attr/attr_versioned.swift
@@ -22,3 +22,16 @@
 
 @_versioned extension S {}
 // expected-error@-1 {{@_versioned cannot be applied to this declaration}}
+
+@_versioned
+protocol VersionedProtocol {
+  associatedtype T
+
+  func requirement() -> T
+
+  public func publicRequirement() -> T
+  // expected-error@-1 {{'public' modifier cannot be used in protocols}}
+
+  @_versioned func versionedRequirement() -> T
+  // expected-error@-1 {{'@_versioned' attribute cannot be used in protocols}}
+}
diff --git a/test/decl/inherit/override.swift b/test/decl/inherit/override.swift
index 17a8aec..8248fcf 100644
--- a/test/decl/inherit/override.swift
+++ b/test/decl/inherit/override.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -parse-as-library
+// RUN: %target-typecheck-verify-swift -parse-as-library -swift-version 4
 
 @objc class ObjCClassA {}
 @objc class ObjCClassB : ObjCClassA {}
@@ -7,8 +7,11 @@
   func f1() { } // expected-note{{overridden declaration is here}}
   func f2() -> A { } // expected-note{{overridden declaration is here}}
 
-  @objc func f3() { }
-  @objc func f4() -> ObjCClassA { }
+  @objc func f3() { } // expected-note{{overridden declaration is here}}
+  @objc func f4() -> ObjCClassA { } // expected-note{{overridden declaration is here}}
+
+  dynamic func f3D() { }
+  dynamic func f4D() -> ObjCClassA { }
 }
 
 extension A {
@@ -25,8 +28,11 @@
   func f1() { }  // expected-error{{declarations in extensions cannot override yet}}
   func f2() -> B { } // expected-error{{declarations in extensions cannot override yet}}
 
-  override func f3() { }
-  override func f4() -> ObjCClassB { }
+  override func f3() { } // expected-error{{cannot override a non-dynamic class declaration from an extension}}
+  override func f4() -> ObjCClassB { } // expected-error{{cannot override a non-dynamic class declaration from an extension}}
+
+  override func f3D() { }
+  override func f4D() -> ObjCClassB { }
 
   func f5() { }  // expected-error{{declarations in extensions cannot override yet}}
   func f6() -> A { }  // expected-error{{declarations in extensions cannot override yet}}
diff --git a/test/decl/init/resilience.swift b/test/decl/init/resilience.swift
new file mode 100644
index 0000000..06126a7
--- /dev/null
+++ b/test/decl/init/resilience.swift
@@ -0,0 +1,67 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../../Inputs/resilient_struct.swift
+// RUN: %target-swift-frontend -typecheck -verify -enable-resilience -I %t %s
+
+import resilient_struct
+
+// Point is @_fixed_layout -- this is OK
+extension Point {
+  init(xx: Int, yy: Int) {
+    self.x = xx
+    self.y = yy
+  }
+}
+
+// Size is not @_fixed_layout, so we cannot define a new designated initializer
+extension Size {
+  init(ww: Int, hh: Int) {
+  // expected-error@-1 {{initializer declared in an extension of non-'@_fixed_layout' type 'Size' must delegate to another initializer}}
+    self.w = ww
+    self.h = hh
+  }
+
+  // This is OK
+  init(www: Int, hhh: Int) {
+    self.init(w: www, h: hhh)
+  }
+
+  // FIXME: This should be allowed, but Sema doesn't distinguish this
+  // case from memberwise initialization, and DI explodes the value type
+  init(other: Size) {
+  // expected-error@-1 {{initializer declared in an extension of non-'@_fixed_layout' type 'Size' must delegate to another initializer}}
+    self = other
+  }
+}
+
+// Animal is not @_fixed_layout, so we cannot define an @_inlineable
+// designated initializer
+public struct Animal {
+  public let name: String
+
+  @_inlineable public init(name: String) {
+  // expected-error@-1 {{initializer of non-'@_fixed_layout' type 'Animal' is '@_inlineable' and must delegate to another initializer}}
+    self.name = name
+  }
+
+  @inline(__always) public init(dog: String) {
+  // expected-error@-1 {{initializer of non-'@_fixed_layout' type 'Animal' is '@inline(__always)' and must delegate to another initializer}}
+    self.name = dog
+  }
+
+  @_transparent public init(cat: String) {
+  // expected-error@-1 {{initializer of non-'@_fixed_layout' type 'Animal' is '@_transparent' and must delegate to another initializer}}
+    self.name = cat
+  }
+
+  // This is OK
+  @_inlineable public init(cow: String) {
+    self.init(name: cow)
+  }
+
+  // FIXME: This should be allowed, but Sema doesn't distinguish this
+  // case from memberwise initialization, and DI explodes the value type
+  @_inlineable public init(other: Animal) {
+  // expected-error@-1 {{initializer of non-'@_fixed_layout' type 'Animal' is '@_inlineable' and must delegate to another initializer}}
+    self = other
+  }
+}
diff --git a/test/decl/protocol/objc.swift b/test/decl/protocol/objc.swift
index 8848e5d..eb46aa6 100644
--- a/test/decl/protocol/objc.swift
+++ b/test/decl/protocol/objc.swift
@@ -207,6 +207,19 @@
   }
 }
 
+class C7h : P7 {
+  @objc var prop: Int = 0 {
+    didSet {}
+  }
+}
+
+class C7i : P7 {
+  @objc var prop: Int {
+    unsafeAddress { fatalError() }
+    unsafeMutableAddress { fatalError() }
+  }
+}
+
 @objc protocol P8 {
   @objc optional var prop: Int {
     @objc(getTheProp) get
diff --git a/test/decl/protocol/req/associated_type_inference.swift b/test/decl/protocol/req/associated_type_inference.swift
index ceb1eea..16f7323 100644
--- a/test/decl/protocol/req/associated_type_inference.swift
+++ b/test/decl/protocol/req/associated_type_inference.swift
@@ -343,3 +343,15 @@
 
 struct Thumbprint : Cookie {}
 // expected-error@-1 {{type 'Thumbprint' does not conform to protocol 'Cookie'}}
+
+// Looking through typealiases
+protocol Vector {
+  associatedtype Element
+  typealias Elements = [Element]
+
+  func process(elements: Elements)
+}
+
+struct Int8Vector : Vector {
+  func process(elements: [Int8]) { }
+}
diff --git a/test/stdlib/Dispatch.swift b/test/stdlib/Dispatch.swift
index 681ee85..419e0b9 100644
--- a/test/stdlib/Dispatch.swift
+++ b/test/stdlib/Dispatch.swift
@@ -101,3 +101,31 @@
         })
     }
 }
+
+DispatchAPI.test("DispatchTime.addSubtract") {
+	var then = DispatchTime.now() + Double.infinity
+	expectEqual(DispatchTime.distantFuture, then)
+
+	then = DispatchTime.now() + Double.nan
+	expectEqual(DispatchTime.distantFuture, then)
+
+	then = DispatchTime.now() - Double.infinity
+	expectEqual(DispatchTime(uptimeNanoseconds: 1), then)
+
+	then = DispatchTime.now() - Double.nan
+	expectEqual(DispatchTime(uptimeNanoseconds: 1), then)
+}
+
+DispatchAPI.test("DispatchWallTime.addSubtract") {
+	var then = DispatchWallTime.now() + Double.infinity
+	expectEqual(DispatchWallTime.distantFuture, then)
+
+	then = DispatchWallTime.now() + Double.nan
+	expectEqual(DispatchWallTime.distantFuture, then)
+
+	then = DispatchWallTime.now() - Double.infinity
+	expectEqual(DispatchWallTime.distantFuture.rawValue - UInt64(1), then.rawValue)
+
+	then = DispatchWallTime.now() - Double.nan
+	expectEqual(DispatchWallTime.distantFuture.rawValue - UInt64(1), then.rawValue)
+}
diff --git a/test/stdlib/TestAffineTransform.swift b/test/stdlib/TestAffineTransform.swift
index 29ba030..041a532 100644
--- a/test/stdlib/TestAffineTransform.swift
+++ b/test/stdlib/TestAffineTransform.swift
@@ -169,19 +169,19 @@
         checkPointTransformation(noop, point: point, expectedPoint: point)
         
         var tenEighty = AffineTransform.identity
-        tenEighty.rotate(byRadians: CGFloat(6 * M_PI))
+        tenEighty.rotate(byRadians: 6 * .pi)
         checkPointTransformation(tenEighty, point: point, expectedPoint: point)
         
         var rotateCounterClockwise = AffineTransform.identity
-        rotateCounterClockwise.rotate(byRadians: CGFloat(M_PI_2))
+        rotateCounterClockwise.rotate(byRadians: .pi / 2)
         checkPointTransformation(rotateCounterClockwise, point: point, expectedPoint: NSPoint(x: CGFloat(-10.0), y: CGFloat(10.0)))
         
         var rotateClockwise = AffineTransform.identity
-        rotateClockwise.rotate(byRadians: CGFloat(-M_PI_2))
+        rotateClockwise.rotate(byRadians: -.pi / 2)
         checkPointTransformation(rotateClockwise, point: point, expectedPoint: NSPoint(x: CGFloat(10.0), y: CGFloat(-10.0)))
         
         var reflectAboutOrigin = AffineTransform.identity
-        reflectAboutOrigin.rotate(byRadians: CGFloat(M_PI))
+        reflectAboutOrigin.rotate(byRadians: .pi)
         checkPointTransformation(reflectAboutOrigin, point: point, expectedPoint: NSPoint(x: CGFloat(-10.0), y: CGFloat(-10.0)))
     }
     
diff --git a/tools/SourceKit/CMakeLists.txt b/tools/SourceKit/CMakeLists.txt
index d97272e..3180571 100644
--- a/tools/SourceKit/CMakeLists.txt
+++ b/tools/SourceKit/CMakeLists.txt
@@ -508,6 +508,24 @@
 )
 
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+  if(SWIFT_BUILD_SOURCEKIT)
+    add_custom_command(
+      OUTPUT "${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/.libs/libdispatch.so"
+      COMMAND autoreconf -fvi
+      COMMAND /usr/bin/env "CC=${PATH_TO_CLANG_BUILD}/bin/clang" "CXX=${PATH_TO_CLANG_BUILD}/bin/clang++" ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}/configure --prefix="${CMAKE_INSTALL_PREFIX}"
+      COMMAND /usr/bin/make
+      COMMAND /bin/mkdir -p ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/.libs/
+      COMMAND /bin/cp ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}/src/.libs/libdispatch.so ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/.libs/libdispatch.so
+      COMMAND /usr/bin/make distclean
+      WORKING_DIRECTORY ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}
+      COMMENT "Generating libdispatch.so"
+      USES_TERMINAL
+    )
+    add_custom_target(needs-libdispatch
+      DEPENDS "${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/.libs/libdispatch.so"
+    )
+  endif()
+
   include_directories(AFTER ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE})
 
   add_library(dispatch SHARED IMPORTED)
diff --git a/tools/SourceKit/lib/Support/Tracing.cpp b/tools/SourceKit/lib/Support/Tracing.cpp
index 2d05dc7..d583d6a 100644
--- a/tools/SourceKit/lib/Support/Tracing.cpp
+++ b/tools/SourceKit/lib/Support/Tracing.cpp
@@ -14,7 +14,6 @@
 
 #include "swift/Frontend/Frontend.h"
 
-#include "llvm/Support/TimeValue.h"
 #include "llvm/Support/YAMLTraits.h"
 
 using namespace SourceKit;
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
index 787030e..adbb834 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
@@ -543,7 +543,7 @@
                   << " (" << Ret.message() << ')');
     return -1;
   }
-  return Status.getLastModificationTime().toEpochTime();
+  return Status.getLastModificationTime().time_since_epoch().count();
 }
 
 std::unique_ptr<llvm::MemoryBuffer>
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
index 403e692..7a9d21d 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
@@ -454,6 +454,9 @@
   ++NamesSeen[VD->getFullName()];
   SmallVector<ValueDecl *, 8> RelatedDecls;
 
+  if (isa<ParamDecl>(VD))
+    return; // Parameters don't have interesting related declarations.
+
   // FIXME: Extract useful related declarations, overloaded functions,
   // if VD is an initializer, we should extract other initializers etc.
   // For now we use UnqualifiedLookup to fetch other declarations with the same
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index b90cc8b..9e1df20 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -1493,8 +1493,10 @@
                                                                    nullptr, 0);
     sourcekitd_request_dictionary_set_uid(Exp, KeyRequest,
                                           RequestEditorExpandPlaceholder);
-    sourcekitd_request_dictionary_set_string(Exp, KeyName,
-                                             SourceBuf->getBufferIdentifier());
+    auto SourceBufID = SourceBuf->getBufferIdentifier();
+    sourcekitd_request_dictionary_set_stringbuf(Exp, KeyName,
+                                                SourceBufID.data(),
+                                                SourceBufID.size());
     sourcekitd_request_dictionary_set_string(Exp, KeySourceText, "");
     sourcekitd_request_dictionary_set_int64(Exp, KeyOffset, Offset);
     sourcekitd_request_dictionary_set_int64(Exp, KeyLength, Length);
diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp
index e61c2e8..41a82b7 100644
--- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp
+++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp
@@ -17,7 +17,7 @@
 
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Mutex.h"
-#include "llvm/Support/TimeValue.h"
+#include <chrono>
 #include <xpc/xpc.h>
 #include <dispatch/dispatch.h>
 
@@ -406,26 +406,27 @@
 }
 
 static void updateSemanticEditorDelay() {
-  using namespace llvm::sys;
+  using namespace std::chrono;
+  using TimePoint = time_point<system_clock, nanoseconds>;
 
   // Clear any previous setting.
   SemanticEditorDelaySecondsNum = 0;
 
-  static TimeValue gPrevCrashTime;
+  static TimePoint gPrevCrashTime;
 
-  TimeValue PrevTime = gPrevCrashTime;
-  TimeValue CurrTime = TimeValue::now();
+  TimePoint PrevTime = gPrevCrashTime;
+  TimePoint CurrTime = system_clock::now();
   gPrevCrashTime = CurrTime;
-  if (PrevTime == TimeValue()) {
+  if (PrevTime == TimePoint()) {
     // First time that it crashed.
     return;
   }
 
-  TimeValue Diff = CurrTime - PrevTime;
-  if (Diff.seconds() > 30)
+  auto Diff = duration_cast<seconds>(CurrTime - PrevTime);
+  if (Diff.count() > 30)
     return; // treat this as more likely unrelated to the previous crash.
 
-  size_t Delay = std::min(size_t(20), size_t(Diff.seconds()*2 + 1));
+  size_t Delay = std::min(size_t(20), size_t(Diff.count()*2 + 1));
   LOG_WARN_FUNC("disabling semantic editor for " << Delay << " seconds");
   SemanticEditorDelaySecondsNum = Delay;
 
diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp
index d79ed1b..bc422c1 100644
--- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp
+++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp
@@ -21,12 +21,12 @@
 #include "llvm/Support/Mutex.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/TimeValue.h"
 #include "llvm/Support/YAMLTraits.h"
 
 #include <xpc/xpc.h>
 
 #include <algorithm>
+#include <chrono>
 #include <deque>
 #include <functional>
 #include <iomanip>
@@ -70,7 +70,8 @@
 
 static void fsInitTraceRoot(path_t &RootDir, uint64_t Id) {
   RootDir = trace_root_dir;
-  std::string DirName = llvm::sys::TimeValue::now().str();
+  std::string DirName =
+    std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
   std::for_each(DirName.begin(), DirName.end(),
                 [] (char &C) { if (!isalnum(C)) C = '-'; });
   DirName += '-';
@@ -91,7 +92,7 @@
 typedef SourceKit::trace::OperationKind OperationKind;
 
 struct OperationInfo {
-  sys::TimeValue StartedAt;
+  std::chrono::system_clock::time_point StartedAt;
   OperationKind Kind;
   std::string SwiftArgs;
   trace::StringPairs OpArgs;
@@ -101,7 +102,7 @@
                 std::string &&SwiftArgs,
                 trace::StringPairs &&Files,
                 trace::StringPairs &&OpArgs)
-    : StartedAt(sys::TimeValue::now()),
+    : StartedAt(std::chrono::system_clock::now()),
       Kind(K), SwiftArgs(SwiftArgs), OpArgs(OpArgs), Files(Files) {}
 
   OperationInfo() = default;
diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp
index f22a0ed..e64fd84 100644
--- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp
+++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp
@@ -14,9 +14,9 @@
 
 #include "swift/Frontend/Frontend.h"
 
-#include "llvm/Support/TimeValue.h"
 #include "llvm/Support/YAMLTraits.h"
 
+#include <chrono>
 #include <xpc/xpc.h>
 
 using namespace sourcekitd;
@@ -29,10 +29,13 @@
 // General
 //===----------------------------------------------------------------------===//
 
-static uint64_t tracing_session = llvm::sys::TimeValue::now().msec();
+static auto tracing_session = std::chrono::system_clock::now();
 
 uint64_t trace::getTracingSession() {
-  return tracing_session;
+  using namespace std::chrono;
+  time_point<system_clock, milliseconds> msec =
+    time_point_cast<milliseconds>(tracing_session);
+  return msec.time_since_epoch().count();
 }
 
 static void append(xpc_object_t Contents, uint64_t Value) {
diff --git a/tools/driver/api_notes.cpp b/tools/driver/api_notes.cpp
index 61a9928..8e0c57e 100644
--- a/tools/driver/api_notes.cpp
+++ b/tools/driver/api_notes.cpp
@@ -43,8 +43,7 @@
                                "binary-to-yaml",
                                "Convert binary format to YAML"),
                     clEnumValN(api_notes::ActionType::Dump,
-                            "dump", "Parse and dump the output"),
-                    clEnumValEnd),
+                            "dump", "Parse and dump the output")),
          cl::cat(APINotesCategory));
 
   static cl::opt<std::string>
diff --git a/tools/driver/autolink_extract_main.cpp b/tools/driver/autolink_extract_main.cpp
index 149d3dc..93bbcf6 100644
--- a/tools/driver/autolink_extract_main.cpp
+++ b/tools/driver/autolink_extract_main.cpp
@@ -147,7 +147,7 @@
     extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
     return false;
   } else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
-    llvm::Error Error;
+    llvm::Error Error = llvm::Error::success();
     for (const auto &Child : Archive->children(Error)) {
       auto ChildBinary = Child.getAsBinary();
       // FIXME: BinaryFileName below should instead be ld-style names for
diff --git a/tools/driver/modulewrap_main.cpp b/tools/driver/modulewrap_main.cpp
index b1e23f1..3f6413f 100644
--- a/tools/driver/modulewrap_main.cpp
+++ b/tools/driver/modulewrap_main.cpp
@@ -143,9 +143,7 @@
   }
 
   // Superficially verify that the input is a swift module file.
-  llvm::BitstreamReader Reader((unsigned char *)(*ErrOrBuf)->getBufferStart(),
-                               (unsigned char *)(*ErrOrBuf)->getBufferEnd());
-  llvm::BitstreamCursor Cursor(Reader);
+  llvm::BitstreamCursor Cursor(ErrOrBuf.get()->getMemBufferRef());
   for (unsigned char Byte : serialization::MODULE_SIGNATURE)
     if (Cursor.AtEndOfStream() || Cursor.Read(8) != Byte) {
       Instance.getDiags().diagnose(SourceLoc(), diag::error_parse_input_file,
diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp
index 1a588dc..8044822 100644
--- a/tools/sil-opt/SILOpt.cpp
+++ b/tools/sil-opt/SILOpt.cpp
@@ -96,8 +96,7 @@
     llvm::cl::values(clEnumValN(OptGroup::Diagnostics, "diagnostics",
                                 "Run diagnostic passes"),
                      clEnumValN(OptGroup::Performance, "O",
-                                "Run performance passes"),
-                     clEnumValEnd),
+                                "Run performance passes")),
     llvm::cl::init(OptGroup::Unknown));
 
 static llvm::cl::list<PassKind>
@@ -105,7 +104,7 @@
        llvm::cl::values(
 #define PASS(ID, NAME, DESCRIPTION) clEnumValN(PassKind::ID, NAME, DESCRIPTION),
 #include "swift/SILOptimizer/PassManager/Passes.def"
-       clEnumValEnd));
+       clEnumValN(0, "", "")));
 
 static llvm::cl::opt<bool>
 PrintStats("print-stats", llvm::cl::desc("Print various statistics"));
diff --git a/tools/sil-passpipeline-dumper/SILPassPipelineDumper.cpp b/tools/sil-passpipeline-dumper/SILPassPipelineDumper.cpp
index 1fc2ec9..ee0332f 100644
--- a/tools/sil-passpipeline-dumper/SILPassPipelineDumper.cpp
+++ b/tools/sil-passpipeline-dumper/SILPassPipelineDumper.cpp
@@ -30,7 +30,7 @@
 #define PASSPIPELINE(NAME, DESCRIPTION)                                        \
   clEnumValN(PassPipelineKind::NAME, #NAME, DESCRIPTION),
 #include "swift/SILOptimizer/PassManager/PassPipeline.def"
-                                                        clEnumValEnd));
+                                                        clEnumValN(0, "", "")));
 
 namespace llvm {
 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, PassPipelineKind Kind) {
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index bf32a5d..fa7158207 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -126,8 +126,7 @@
                      "Compare SDK content in JSON file"),
           clEnumValN(ActionType::DiagnoseSDKs,
                      "diagnose-sdk",
-                     "Diagnose SDK content in JSON file"),
-          clEnumValEnd));
+                     "Diagnose SDK content in JSON file")));
 
 static llvm::cl::list<std::string>
 SDKJsonPaths("input-paths",
diff --git a/tools/swift-demangle/swift-demangle.cpp b/tools/swift-demangle/swift-demangle.cpp
index 82ba3ec..b058d12 100644
--- a/tools/swift-demangle/swift-demangle.cpp
+++ b/tools/swift-demangle/swift-demangle.cpp
@@ -14,10 +14,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(__FreeBSD__)
-#define _WITH_GETLINE
-#endif
-
 #include "swift/Basic/DemangleWrappers.h"
 #include "swift/Basic/ManglingMacros.h"
 #include "llvm/ADT/SmallString.h"
@@ -28,14 +24,14 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
 
+// For std::rand, to work around a bug if main()'s first function call passes
+// argv[0].
+#if defined(__CYGWIN__)
 #include <cstdlib>
-#include <string>
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#else
-#include <io.h>
 #endif
 
+#include <iostream>
+
 static llvm::cl::opt<bool>
 ExpandMode("expand",
                llvm::cl::desc("Expand mode (show node structure of the demangling)"));
@@ -53,6 +49,10 @@
            llvm::cl::desc("Remangle test mode (show the remangled string)"));
 
 static llvm::cl::opt<bool>
+RemangleNew("remangle-new",
+           llvm::cl::desc("Remangle the symbol with new mangling scheme"));
+
+static llvm::cl::opt<bool>
 DisableSugar("no-sugar",
            llvm::cl::desc("No sugar mode (disable common language idioms such as ? and [] from the output)"));
 
@@ -108,6 +108,15 @@
     return;
   }
   if (!TreeOnly) {
+    if (RemangleNew) {
+      if (!pointer) {
+        llvm::errs() << "Can't de-mangle " << name << '\n';
+        exit(1);
+      }
+      std::string remangled = swift::Demangle::mangleNodeNew(pointer);
+      llvm::outs() << remangled;
+      return;
+    }
     std::string string = swift::Demangle::nodeToString(pointer, options);
     if (!CompactMode)
       llvm::outs() << name << " ---> ";
@@ -119,18 +128,9 @@
   // This doesn't handle Unicode symbols, but maybe that's okay.
   llvm::Regex maybeSymbol("(_T|" MANGLING_PREFIX_STR ")[_a-zA-Z0-9$]+");
 
-  while (true) {
-    char *inputLine = nullptr;
-    size_t size;
-    if (getline(&inputLine, &size, stdin) == -1 || size <= 0) {
-      if (errno == 0) {
-        break;
-      }
+  for (std::string mangled; std::getline(std::cin, mangled);) {
+    llvm::StringRef inputContents(mangled);
 
-      return EXIT_FAILURE;
-    }
-
-    llvm::StringRef inputContents(inputLine);
     llvm::SmallVector<llvm::StringRef, 1> matches;
     while (maybeSymbol.match(inputContents, &matches)) {
       llvm::outs() << substrBefore(inputContents, matches.front());
@@ -138,8 +138,7 @@
       inputContents = substrAfter(inputContents, matches.front());
     }
 
-    llvm::outs() << inputContents;
-    free(inputLine);
+    llvm::outs() << inputContents << '\n';
   }
 
   return EXIT_SUCCESS;
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 93c197c..75efd06 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -218,8 +218,7 @@
                       "Print information about a given range"),
            clEnumValN(ActionType::PrintIndexedSymbols,
                       "print-indexed-symbols",
-                      "Print indexed symbol information"),
-           clEnumValEnd));
+                      "Print indexed symbol information")));
 
 static llvm::cl::opt<std::string>
 SourceFilename("source-filename", llvm::cl::desc("Name of the source file"));
@@ -483,8 +482,7 @@
         clEnumValN(Accessibility::Internal, "accessibility-filter-internal",
             "Print internal and public declarations"),
         clEnumValN(Accessibility::Public, "accessibility-filter-public",
-            "Print public declarations"),
-        clEnumValEnd));
+            "Print public declarations")));
 
 static llvm::cl::opt<bool>
 SynthesizeExtension("synthesize-extension",
diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp
index 4dc72cb..17132e5 100644
--- a/tools/swift-reflection-dump/swift-reflection-dump.cpp
+++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp
@@ -58,8 +58,7 @@
                     "Dump the field reflection section"),
          clEnumValN(ActionType::DumpTypeLowering,
                     "dump-type-lowering",
-                    "Dump the field layout for typeref strings read from stdin"),
-         clEnumValEnd),
+                    "Dump the field layout for typeref strings read from stdin")),
        llvm::cl::init(ActionType::DumpReflectionSections));
 
 static llvm::cl::list<std::string>
diff --git a/tools/swift-reflection-test/swift-reflection-test.c b/tools/swift-reflection-test/swift-reflection-test.c
index f16b50b..d99eab6 100644
--- a/tools/swift-reflection-test/swift-reflection-test.c
+++ b/tools/swift-reflection-test/swift-reflection-test.c
@@ -51,6 +51,11 @@
 } RemoteReflectionInfo;
 
 static void errorAndExit(const char *message) {
+  fprintf(stderr, "%s\n", message);
+  abort();
+}
+
+static void errnoAndExit(const char *message) {
   fprintf(stderr, "%s: %s\n", message, strerror(errno));
   abort();
 }
@@ -165,10 +170,13 @@
   int ReadFD = PipeMemoryReader_getParentReadFD(Reader);
   while (Size) {
     int bytesRead = read(ReadFD, Dest, Size);
-    if (bytesRead == -EINTR)
-      continue;
-    if (bytesRead <= 0)
-      errorAndExit("collectBytesFromPipe");
+    if (bytesRead < 0)
+      if (errno == EINTR)
+        continue;
+      else
+        errnoAndExit("collectBytesFromPipe");
+    else if (bytesRead == 0)
+      errorAndExit("collectBytesFromPipe: Unexpected end of file");
     Size -= bytesRead;
     Dest += bytesRead;
   }
@@ -232,9 +240,9 @@
 PipeMemoryReader createPipeMemoryReader() {
   PipeMemoryReader Reader;
   if (pipe(Reader.to_child))
-    errorAndExit("Couldn't create pipes to child process");
+    errnoAndExit("Couldn't create pipes to child process");
   if (pipe(Reader.from_child))
-    errorAndExit("Couldn't create pipes from child process");
+    errnoAndExit("Couldn't create pipes from child process");
   return Reader;
 }
 
@@ -265,7 +273,7 @@
   RemoteReflectionInfo *RemoteInfos = calloc(NumReflectionInfos,
                                              sizeof(RemoteReflectionInfo));
   if (RemoteInfos == NULL)
-    errorAndExit("malloc failed");
+    errnoAndExit("malloc failed");
 
   for (size_t i = 0; i < NumReflectionInfos; ++i) {
     RemoteInfos[i] = makeRemoteReflectionInfo(
@@ -385,8 +393,7 @@
   pid_t pid = _fork();
   switch (pid) {
     case -1:
-      errorAndExit("Couldn't fork child process");
-      exit(EXIT_FAILURE);
+      errnoAndExit("Couldn't fork child process");
     case 0: { // Child:
       close(PipeMemoryReader_getParentWriteFD(&Pipe));
       close(PipeMemoryReader_getParentReadFD(&Pipe));
diff --git a/utils/bug_reducer/bug_reducer/func_bug_reducer.py b/utils/bug_reducer/bug_reducer/func_bug_reducer.py
index 91c0396..d5f2b5a 100644
--- a/utils/bug_reducer/bug_reducer/func_bug_reducer.py
+++ b/utils/bug_reducer/bug_reducer/func_bug_reducer.py
@@ -3,13 +3,13 @@
 import os
 import sys
 
-import swift_tools
-
 import list_reducer
 from list_reducer import TESTRESULT_KEEPPREFIX
 from list_reducer import TESTRESULT_KEEPSUFFIX
 from list_reducer import TESTRESULT_NOFAILURE
 
+import swift_tools
+
 
 class ReduceMiscompilingFunctions(list_reducer.ListReducer):
 
@@ -126,8 +126,8 @@
     input_file = args.input_file
     extra_args = args.extra_args
     sil_opt_invoker = swift_tools.SILOptInvoker(config, tools,
-                                                      input_file,
-                                                      extra_args)
+                                                input_file,
+                                                extra_args)
 
     # Make sure that the base case /does/ crash.
     filename = sil_opt_invoker.get_suffixed_filename('base_case')
diff --git a/utils/bug_reducer/bug_reducer/opt_bug_reducer.py b/utils/bug_reducer/bug_reducer/opt_bug_reducer.py
index ce1f045..f5623f1 100644
--- a/utils/bug_reducer/bug_reducer/opt_bug_reducer.py
+++ b/utils/bug_reducer/bug_reducer/opt_bug_reducer.py
@@ -3,8 +3,6 @@
 import md5
 import subprocess
 
-import swift_tools
-
 import func_bug_reducer
 
 import list_reducer
@@ -12,6 +10,8 @@
 from list_reducer import TESTRESULT_KEEPSUFFIX
 from list_reducer import TESTRESULT_NOFAILURE
 
+import swift_tools
+
 
 class ReduceMiscompilingPasses(list_reducer.ListReducer):
 
@@ -116,8 +116,8 @@
     input_file = sil_opt_invoker.input_file
     nm = swift_tools.SILNMInvoker(config, tools)
     sil_extract_invoker = swift_tools.SILFuncExtractorInvoker(config,
-                                                                    tools,
-                                                                    input_file)
+                                                              tools,
+                                                              input_file)
 
     func_bug_reducer.function_bug_reducer(input_file, nm, sil_opt_invoker,
                                           sil_extract_invoker,
diff --git a/utils/bug_reducer/bug_reducer/random_bug_finder.py b/utils/bug_reducer/bug_reducer/random_bug_finder.py
index 2cbff4d..a72343e 100644
--- a/utils/bug_reducer/bug_reducer/random_bug_finder.py
+++ b/utils/bug_reducer/bug_reducer/random_bug_finder.py
@@ -1,13 +1,12 @@
-
 import json
 import random
 import subprocess
 import sys
 
-import swift_tools
-
 import opt_bug_reducer
 
+import swift_tools
+
 
 def random_bug_finder(args):
     """Given a path to a sib file with canonical sil, attempt to find a perturbed
diff --git a/utils/bug_reducer/bug_reducer/subprocess_utils.py b/utils/bug_reducer/bug_reducer/subprocess_utils.py
index 7a46401..c378ae0 100644
--- a/utils/bug_reducer/bug_reducer/subprocess_utils.py
+++ b/utils/bug_reducer/bug_reducer/subprocess_utils.py
@@ -2,6 +2,7 @@
 import hashlib
 import subprocess
 
+
 def call_fingerprint(args, echo_stderr=False, echo_stdout=False):
     p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     (stdoutdata, stderrdata) = p.communicate()
@@ -17,5 +18,3 @@
     fingerprint = h.hexdigest()
 
     return {'exit_code': exit_code, 'fingerprint': fingerprint}
-
-
diff --git a/utils/bug_reducer/bug_reducer/swift_tools.py b/utils/bug_reducer/bug_reducer/swift_tools.py
index b5b5d45..e4e573f 100644
--- a/utils/bug_reducer/bug_reducer/swift_tools.py
+++ b/utils/bug_reducer/bug_reducer/swift_tools.py
@@ -14,7 +14,8 @@
         print('BRCALL: ' + ' '.join(args))
     if dry_run:
         return {'exit_code': 0, 'fingerprint': ''}
-    return subprocess_utils.call_fingerprint(args, echo_stderr=not SQUELCH_STDERR)
+    return subprocess_utils.call_fingerprint(args,
+                                             echo_stderr=not SQUELCH_STDERR)
 
 
 # We use this since our squelching of stderr can hide missing file errors.
@@ -205,7 +206,10 @@
     def _invoke(self, input_file, funclist_path, output_filename,
                 invert=False):
         assert(isinstance(funclist_path, str))
-        cmdline = self._cmdline(input_file, funclist_path, True, output_filename,
+        cmdline = self._cmdline(input_file,
+                                funclist_path,
+                                True,
+                                output_filename,
                                 invert)
         return br_call(cmdline)
 
diff --git a/utils/bug_reducer/tests/test_funcbugreducer.py b/utils/bug_reducer/tests/test_funcbugreducer.py
index 98533fe..03eb0d6 100644
--- a/utils/bug_reducer/tests/test_funcbugreducer.py
+++ b/utils/bug_reducer/tests/test_funcbugreducer.py
@@ -102,9 +102,9 @@
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
-        # Make sure our final output command does not have -emit-sib in the
-        # output. We want users to get sil output when they type in the relevant
-        # command.
+        # Make sure our final output command does not have -emit-sib in
+        # the output. We want users to get sil output when they type in
+        # the relevant command.
         self.assertEquals([], [o for o in output if '-emit-sib' in o])
 
 if __name__ == '__main__':
diff --git a/utils/bug_reducer/tests/test_optbugreducer.py b/utils/bug_reducer/tests/test_optbugreducer.py
index ca5713c..8d426cc 100644
--- a/utils/bug_reducer/tests/test_optbugreducer.py
+++ b/utils/bug_reducer/tests/test_optbugreducer.py
@@ -109,9 +109,9 @@
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
-        # Make sure our final output command does not have -emit-sib in the
-        # output. We want users to get sil output when they type in the relevant
-        # command.
+        # Make sure our final output command does not have -emit-sib in
+        # the output. We want users to get sil output when they type in
+        # the relevant command.
         self.assertEquals([], [o for o in output if '-emit-sib' in o])
 
     def test_suffix_in_need_of_prefix(self):
@@ -139,8 +139,8 @@
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 0)
         # Make sure our final output command does not have -emit-sib in the
-        # output. We want users to get sil output when they type in the relevant
-        # command.
+        # output. We want users to get sil output when they type in the
+        # relevant command.
         self.assertEquals([], [o for o in output if '-emit-sib' in o])
 
     def test_reduce_function(self):
@@ -172,8 +172,8 @@
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
         # Make sure our final output command does not have -emit-sib in the
-        # output. We want users to get sil output when they type in the relevant
-        # command.
+        # output. We want users to get sil output when they type in the
+        # relevant command.
         self.assertEquals([], [o for o in output if '-emit-sib' in o])
 
 
diff --git a/utils/build-script b/utils/build-script
index 71e487f..9e3570d 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -1956,7 +1956,7 @@
         "--clang-user-visible-version",
         help="User-visible version of the embedded Clang and LLVM compilers",
         type=arguments.type.clang_compiler_version,
-        default="3.8.0",
+        default="4.0.0",
         metavar="MAJOR.MINOR.PATCH")
     parser.add_argument(
         "--swift-compiler-version",
@@ -1967,7 +1967,7 @@
         "--swift-user-visible-version",
         help="User-visible version of the embedded Swift compiler",
         type=arguments.type.swift_compiler_version,
-        default="3.0",
+        default="3.1",
         metavar="MAJOR.MINOR")
 
     parser.add_argument(
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 3549e5f..5656dbb 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -170,7 +170,7 @@
     native-clang-tools-path     ""               "directory that contains Clang tools that are executable on the build machine"
     native-swift-tools-path     ""               "directory that contains Swift tools that are executable on the build machine"
     compiler-vendor             "none"           "compiler vendor name [none,apple]"
-    clang-user-visible-version  "3.8.0"          "user-visible version of the embedded Clang and LLVM compilers"
+    clang-user-visible-version  "4.0.0"          "user-visible version of the embedded Clang and LLVM compilers"
     swift-user-visible-version  "3.1"            "user-visible version of the Swift language"
     swift-compiler-version      ""               "string that indicates a compiler version for Swift"
     clang-compiler-version      ""               "string that indicates a compiler version for Clang"
@@ -419,7 +419,7 @@
             USE_GOLD_LINKER=1
             ;;
         cygwin-x86_64)
-            SWIFT_HOST_VARIANT="windows"
+            SWIFT_HOST_VARIANT="cygwin"
             SWIFT_HOST_VARIANT_SDK="CYGWIN"
             SWIFT_HOST_VARIANT_ARCH="x86_64"
             ;;
@@ -722,6 +722,7 @@
     llvm_cmake_options+=(
         -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})"
         -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})"
+        -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING:BOOL=TRUE
     )
 
     # If we are asked to not generate test targets for LLVM and or Swift,
diff --git a/utils/line-directive b/utils/line-directive
index c915b13..49166e2 100755
--- a/utils/line-directive
+++ b/utils/line-directive
@@ -246,12 +246,12 @@
         sources = sys.argv[1:dashes]
 
         # The first argument of command_args is the process to open.
-        # subprocess.Popen doesn't normalise arguments. This means that trying
-        # to open a non-normalised file (e.g. C:/swift/./bin/swiftc.exe) on
+        # subprocess.Popen doesn't normalize arguments. This means that trying
+        # to open a non-normalized file (e.g. C:/swift/./bin/swiftc.exe) on
         # Windows results in file/directory not found errors, as Popen delegates
-        # to the Win32 CreateProcess API. Unix systems handle non-normalised
+        # to the Win32 CreateProcess API. Unix systems handle non-normalized
         # paths, so don't have this problem.
-        # Arguments passed to the process are normalised by the process.
+        # Arguments passed to the process are normalized by the process.
         command_args = sys.argv[dashes + 1:]
         command_args[0] = os.path.normpath(command_args[0])
 
diff --git a/utils/sil-mode.el b/utils/sil-mode.el
index cb02fa3..170077e 100644
--- a/utils/sil-mode.el
+++ b/utils/sil-mode.el
@@ -73,7 +73,7 @@
                   'words) . font-lock-keyword-face)
 
    ;; SIL Instructions - Borrowing
-   `(,(regexp-opt '("load_borrow" "begin_borrow" "store_borrow") 'words) . font-lock-keyword-face)
+   `(,(regexp-opt '("load_borrow" "begin_borrow" "store_borrow" "end_borrow_argument") 'words) . font-lock-keyword-face)
    '("\\(end_borrow\\) %[[:alnum:]] \\(from\\)" (1 font-lock-keyword-face) (2 font-lock-keyword-face))
 
    ;; SIL Instructions - Reference Counting.
@@ -108,6 +108,7 @@
                     "tuple_element_addr" "struct" "struct_extract"
                     "struct_element_addr" "ref_element_addr"
                     "autorelease_value" "copy_value" "destroy_value"
+                    "unmanaged_retain_value" "unmanaged_release_value"
                     "copy_unowned_value")
                   'words) . font-lock-keyword-face)
    ;; Enums. *NOTE* We do not include enum itself here since enum is a
diff --git a/utils/swift_build_support/swift_build_support/products/llvm.py b/utils/swift_build_support/swift_build_support/products/llvm.py
index f75c524..a871a44 100644
--- a/utils/swift_build_support/swift_build_support/products/llvm.py
+++ b/utils/swift_build_support/swift_build_support/products/llvm.py
@@ -46,7 +46,7 @@
         return [
             "-DCLANG_VENDOR=Apple",
             "-DCLANG_VENDOR_UTI=com.apple.compilers.llvm.clang",
-            # This is safe since we always provide a default of 3.8.0
+            # This is safe since we always provide a default.
             "-DPACKAGE_VERSION={}".format(self.args.clang_user_visible_version)
         ]
 
diff --git a/utils/swift_build_support/swift_build_support/shell.py b/utils/swift_build_support/swift_build_support/shell.py
index 9fd117e..fd58e9e 100644
--- a/utils/swift_build_support/swift_build_support/shell.py
+++ b/utils/swift_build_support/swift_build_support/shell.py
@@ -20,8 +20,8 @@
 import shutil
 import subprocess
 import sys
-from multiprocessing import Pool, Lock, cpu_count
 from contextlib import contextmanager
+from multiprocessing import Lock, Pool, cpu_count
 
 from . import diagnostics
 
diff --git a/utils/update-checkout b/utils/update-checkout
index 2ad4d73..1f65673 100755
--- a/utils/update-checkout
+++ b/utils/update-checkout
@@ -97,7 +97,7 @@
     cross_repo = False
     repo_branch = scheme_name
     # This loop is only correct, since we know that each alias set has
-    # unique contents. This is checked by verify config. Thus the first
+    # unique contents. This is checked by validate_config. Thus the first
     # branch scheme data that has scheme_name as one of its aliases is
     # the only possible correct answer.
     for v in config['branch-schemes'].values():
@@ -187,7 +187,7 @@
                 continue
 
             if os.path.isdir(os.path.join(repo_name, ".git")):
-                print("Skipping clone of '" + repo_name + "', directory already eixsts")
+                print("Skipping clone of '" + repo_name + "', directory already exists")
                 continue
 
             # If we have a url override, use that url instead of
@@ -234,6 +234,24 @@
                               echo=False).strip()
             print(fmt.format(repo_name, h))
 
+def dump_hashes_config(args, config):
+    branch_scheme_name = args.dump_hashes_config
+    new_config = {}
+    config_copy_keys = ['ssh-clone-pattern', 'https-clone-pattern', 'repos']
+    for config_copy_key in config_copy_keys:
+        new_config[config_copy_key] = config[config_copy_key]
+    repos = {}
+    branch_scheme = {'aliases': [branch_scheme_name], 'repos': repos}
+    new_config['branch-schemes'] = {args.dump_hashes_config: branch_scheme}
+    for repo_name, repo_info in sorted(config['repos'].items(),
+                                       key=lambda x: x[0]):
+        with shell.pushd(os.path.join(SWIFT_SOURCE_ROOT, repo_name),
+                         dry_run=False,
+                         echo=False):
+            h = shell.capture(["git", "rev-parse", "HEAD"],
+                              echo=False).strip()
+            repos[repo_name] = str(h)
+    print(json.dumps(new_config, indent=4))
 
 def validate_config(config):
     # Make sure that our branch-names are unique.
@@ -241,6 +259,14 @@
     if len(scheme_names) != len(set(scheme_names)):
         raise RuntimeError('Configuration file has duplicate schemes?!')
 
+    # Ensure the branch-scheme name is also an alias
+    # This guarantees sensible behavior of update_repository_to_scheme when
+    # the branch-scheme is passed as the scheme name
+    for scheme_name in config['branch-schemes'].keys():
+        if not scheme_name in config['branch-schemes'][scheme_name]['aliases']:
+            raise RuntimeError('branch-scheme name: "{0}" must be an alias too.'
+                .format(scheme_name))
+
     # Then make sure the alias names used by our branches are unique.
     #
     # We do this by constructing a list consisting of len(names),
@@ -311,6 +337,10 @@
         action='store_true',
         help='Dump the git hashes of all repositories being tracked')
     parser.add_argument(
+        '--dump-hashes-config',
+        help='Dump the git hashes of all repositories packaged into update-checkout-config.json',
+        metavar='BRANCH-SCHEME-NAME')
+    parser.add_argument(
         "--tag",
         help="""Check out each repository to the specified tag.""",
         metavar='TAG-NAME')
@@ -323,7 +353,7 @@
     args = parser.parse_args()
 
     if args.reset_to_remote and not args.scheme:
-        print("update-checkout usage error: --reset-to-remote must specify --branch=foo")
+        print("update-checkout usage error: --reset-to-remote must specify --scheme=foo")
         exit(1)
 
     clone = args.clone
@@ -338,7 +368,11 @@
 
     if args.dump_hashes:
         dump_repo_hashes(config)
-        return 0
+        return (None, None)
+
+    if args.dump_hashes_config:
+        dump_hashes_config(args, config)
+        return (None, None)
 
     cross_repos_pr = {}
     if github_comment:
diff --git a/utils/update-checkout-config.json b/utils/update-checkout-config.json
index 7a40909..56ebf8c 100644
--- a/utils/update-checkout-config.json
+++ b/utils/update-checkout-config.json
@@ -27,7 +27,9 @@
         "swift-integration-tests": {
             "remote": { "id": "apple/swift-integration-tests" } },
         "swift-xcode-playground-support": {
-            "remote": { "id": "apple/swift-xcode-playground-support" } }
+            "remote": { "id": "apple/swift-xcode-playground-support" } },
+        "ninja": {
+            "remote": { "id": "ninja-build/ninja" } }
     },
     "default-branch-scheme": "master",
     "branch-schemes": {
@@ -46,11 +48,12 @@
                 "swift-corelibs-foundation": "master",
                 "swift-corelibs-libdispatch": "master",
                 "swift-integration-tests": "master",
-                "swift-xcode-playground-support": "master"
+                "swift-xcode-playground-support": "master",
+                "ninja": "release"
             }
         },
         "next" : {
-            "aliases": ["master-next", "stable-next"],
+            "aliases": ["next", "master-next", "stable-next"],
             "repos": {
                 "llvm": "stable-next",
                 "clang": "stable-next",
@@ -64,7 +67,8 @@
                 "swift-corelibs-foundation": "master-next",
                 "swift-corelibs-libdispatch": "master-next",
                 "swift-integration-tests": "master-next",
-                "swift-xcode-playground-support": "master-next"
+                "swift-xcode-playground-support": "master-next",
+                "ninja": "release"
             }
         },
         "next-upstream" : {
@@ -82,7 +86,8 @@
                 "swift-corelibs-foundation": "master-next",
                 "swift-corelibs-libdispatch": "master-next",
                 "swift-integration-tests": "master-next",
-                "swift-xcode-playground-support": "master-next"
+                "swift-xcode-playground-support": "master-next",
+                "ninja": "release"
             }
         },
         "upstream": {
@@ -100,11 +105,12 @@
                 "swift-corelibs-foundation": "master",
                 "swift-corelibs-libdispatch": "master",
                 "swift-integration-tests": "master",
-                "swift-xcode-playground-support": "master"
+                "swift-xcode-playground-support": "master",
+                "ninja": "release"
             }
         },
         "swift-3.0-preview-1" : {
-            "aliases": ["swift-3.0-preview-1-branch"],
+            "aliases": ["swift-3.0-preview-1", "swift-3.0-preview-1-branch"],
             "repos": {
                 "llvm": "swift-3.0-branch",
                 "clang": "swift-3.0-branch",
@@ -117,11 +123,12 @@
                 "swift-corelibs-xctest": "swift-3.0-preview-1-branch",
                 "swift-corelibs-foundation": "swift-3.0-preview-1-branch",
                 "swift-corelibs-libdispatch": "swift-3.0-preview-1-branch",
-                "swift-integration-tests": "swift-3.0-preview-1-branch"
+                "swift-integration-tests": "swift-3.0-preview-1-branch",
+                "ninja": "release"
             }
         },
         "swift-3.0-preview-2" : {
-            "aliases": ["swift-3.0-preview-2-branch"],
+            "aliases": ["swift-3.0-preview-2", "swift-3.0-preview-2-branch"],
             "repos": {
                 "llvm": "swift-3.0-branch",
                 "clang": "swift-3.0-branch",
@@ -134,11 +141,12 @@
                 "swift-corelibs-xctest": "swift-3.0-preview-2-branch",
                 "swift-corelibs-foundation": "swift-3.0-preview-2-branch",
                 "swift-corelibs-libdispatch": "swift-3.0-preview-2-branch",
-                "swift-integration-tests": "swift-3.0-preview-2-branch"
+                "swift-integration-tests": "swift-3.0-preview-2-branch",
+                "ninja": "release"
             }
         },
         "swift-3.0-preview-3" : {
-            "aliases": ["swift-3.0-preview-3-branch"],
+            "aliases": ["swift-3.0-preview-3", "swift-3.0-preview-3-branch"],
             "repos": {
                 "llvm": "swift-3.0-branch",
                 "clang": "swift-3.0-branch",
@@ -151,11 +159,12 @@
                 "swift-corelibs-xctest": "swift-3.0-preview-3-branch",
                 "swift-corelibs-foundation": "swift-3.0-preview-3-branch",
                 "swift-corelibs-libdispatch": "swift-3.0-preview-3-branch",
-                "swift-integration-tests": "swift-3.0-preview-3-branch"
+                "swift-integration-tests": "swift-3.0-preview-3-branch",
+                "ninja": "release"
             }
         },
         "swift-3.0-preview-4" : {
-            "aliases": ["swift-3.0-preview-4-branch"],
+            "aliases": ["swift-3.0-preview-4", "swift-3.0-preview-4-branch"],
             "repos": {
                 "llvm": "swift-3.0-branch",
                 "clang": "swift-3.0-branch",
@@ -169,11 +178,12 @@
                 "swift-corelibs-foundation": "swift-3.0-preview-4-branch",
                 "swift-corelibs-libdispatch": "swift-3.0-preview-4-branch",
                 "swift-integration-tests": "swift-3.0-preview-4-branch",
-                "swift-xcode-playground-support": "swift-3.0-preview-4-branch"
+                "swift-xcode-playground-support": "swift-3.0-preview-4-branch",
+                "ninja": "release"
             }
         },
         "swift-3.0-preview-5" : {
-            "aliases": ["swift-3.0-preview-5-branch"],
+            "aliases": ["swift-3.0-preview-5", "swift-3.0-preview-5-branch"],
             "repos": {
                 "llvm": "swift-3.0-branch",
                 "clang": "swift-3.0-branch",
@@ -187,7 +197,8 @@
                 "swift-corelibs-foundation": "swift-3.0-preview-5-branch",
                 "swift-corelibs-libdispatch": "swift-3.0-preview-5-branch",
                 "swift-integration-tests": "swift-3.0-preview-5-branch",
-                "swift-xcode-playground-support": "swift-3.0-preview-5-branch"
+                "swift-xcode-playground-support": "swift-3.0-preview-5-branch",
+                "ninja": "release"
             }
         },
         "swift-3.0-branch" : {
@@ -205,7 +216,8 @@
                 "swift-corelibs-foundation": "swift-3.0-branch",
                 "swift-corelibs-libdispatch": "swift-3.0-branch",
                 "swift-integration-tests": "swift-3.0-branch",
-                "swift-xcode-playground-support": "swift-3.0-branch"
+                "swift-xcode-playground-support": "swift-3.0-branch",
+                "ninja": "release"
             }
         },
         "swift-3.1-branch" : {
@@ -223,7 +235,8 @@
                 "swift-corelibs-foundation": "swift-3.1-branch",
                 "swift-corelibs-libdispatch": "swift-3.1-branch",
                 "swift-integration-tests": "swift-3.1-branch",
-                "swift-xcode-playground-support": "swift-3.1-branch"
+                "swift-xcode-playground-support": "swift-3.1-branch",
+                "ninja": "release"
             }
         }
     }
diff --git a/validation-test/LTO/host-libraries-do-have-bitcode.test-sh b/validation-test/LTO/host-libraries-do-have-bitcode.test-sh
index 3db24bb..d4a79d3 100755
--- a/validation-test/LTO/host-libraries-do-have-bitcode.test-sh
+++ b/validation-test/LTO/host-libraries-do-have-bitcode.test-sh
@@ -31,7 +31,7 @@
     mkdir -p "${LIB_TEMP_DIR}"
     cd "${LIB_TEMP_DIR}"
     ar -x ${ARCHIVE}
-    if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep bit-code)" ]]; then
+    if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep -e bitcode -e bit-code)" ]]; then
         echo "Found bitcode file in thin archive: ${ARCHIVE}"
     else
         echo "No bitcode in thin archive: ${ARCHIVE}"
@@ -76,7 +76,7 @@
         cd ${arch}
         ar -x "${LIB_ARCHIVE_DIR}/${THIN_ARCHIVE}"
 
-        if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep bit-code)" ]]; then
+        if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep -e bitcode -e bit-code)" ]]; then
             echo "Found bitcode file in thin archive: ${THIN_ARCHIVE}. Taken from thick archive: ${ARCHIVE}"
         else
             echo "No bitcode in thin archive: ${THIN_ARCHIVE}. Taken from thick archive: ${ARCHIVE}"
diff --git a/validation-test/LTO/object-files-do-have-bitcode.test-sh b/validation-test/LTO/object-files-do-have-bitcode.test-sh
index 91d3fc0..5d76bf4 100755
--- a/validation-test/LTO/object-files-do-have-bitcode.test-sh
+++ b/validation-test/LTO/object-files-do-have-bitcode.test-sh
@@ -13,14 +13,14 @@
 # REQUIRES: OS=macosx
 # RUN: %s %swift_obj_root
 
-if [[ -n "$(find $1/lib -iname '*.cpp.o' -type f -exec file {} \; | grep -v bit-code)" ]]; then
+if [[ -n "$(find $1/lib -iname '*.cpp.o' -type f -exec file {} \; | grep -v -e bitcode -e bit-code)" ]]; then
     echo "Found a ./lib non-bitcode object file!"
     exit 1
 else
     echo "All ./lib object files are bit-code files!"
 fi
 
-if [[ -n "$(find $1/unittests -iname '*.cpp.o' -type f -exec file {} \; | grep -v bit-code)" ]]; then
+if [[ -n "$(find $1/unittests -iname '*.cpp.o' -type f -exec file {} \; | grep -v -e bitcode -e bit-code)" ]]; then
     echo "Found a ./unittests non-bitcode object file!"
     exit 1
 else
diff --git a/validation-test/LTO/target-libraries-do-not-have-bitcode.test-sh b/validation-test/LTO/target-libraries-do-not-have-bitcode.test-sh
index 7ef67ad..1a42ac1 100755
--- a/validation-test/LTO/target-libraries-do-not-have-bitcode.test-sh
+++ b/validation-test/LTO/target-libraries-do-not-have-bitcode.test-sh
@@ -31,7 +31,7 @@
     mkdir -p "${LIB_TEMP_DIR}"
     cd "${LIB_TEMP_DIR}"
     ar -x ${ARCHIVE}
-    if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep bit-code)" ]]; then
+    if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep -e bitcode -e bit-code)" ]]; then
         echo "Found bitcode file in thin archive: ${ARCHIVE}"
         exit 1
     else
@@ -73,7 +73,7 @@
         cd ${arch}
         ar -x "${LIB_ARCHIVE_DIR}/${THIN_ARCHIVE}"
 
-        if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep bit-code)" ]]; then
+        if [[ -n "$(find ./ -iname '*.o' -exec file {} \; | grep -e bitcode -e bit-code)" ]]; then
             echo "Found bitcode file in thin archive: ${THIN_ARCHIVE}. Taken from thick archive: ${ARCHIVE}"
             exit 1
         else
diff --git a/validation-test/Reflection/reflect_Dictionary.swift b/validation-test/Reflection/reflect_Dictionary.swift
index c829b4a..b88995f 100644
--- a/validation-test/Reflection/reflect_Dictionary.swift
+++ b/validation-test/Reflection/reflect_Dictionary.swift
@@ -23,9 +23,9 @@
 // CHECK-64: (class reflect_Dictionary.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=25 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
 // CHECK-32: Reflecting an object.
@@ -34,9 +34,9 @@
 // CHECK-32: (class reflect_Dictionary.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=17 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
 // CHECK-32:   (field name=t offset=12
-// CHECK-32:     (struct size=5 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_Set.swift b/validation-test/Reflection/reflect_Set.swift
index 1c339e4..6c8d2ff 100644
--- a/validation-test/Reflection/reflect_Set.swift
+++ b/validation-test/Reflection/reflect_Set.swift
@@ -23,9 +23,9 @@
 // CHECK-64: (class reflect_Set.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=25 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
 // CHECK-32: Reflecting an object.
@@ -34,9 +34,9 @@
 // CHECK-32: (class reflect_Set.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=17 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
 // CHECK-32:   (field name=t offset=12
-// CHECK-32:     (struct size=5 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_multiple_types.swift b/validation-test/Reflection/reflect_multiple_types.swift
index f48f191..f0f4caf 100644
--- a/validation-test/Reflection/reflect_multiple_types.swift
+++ b/validation-test/Reflection/reflect_multiple_types.swift
@@ -115,7 +115,7 @@
 // CHECK-64: (class reflect_multiple_types.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=209 alignment=8 stride=216 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=193 alignment=8 stride=200 num_extra_inhabitants=0
 // CHECK-64:   (field name=t00 offset=16
 // CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
 // (unstable implementation details omitted)
@@ -136,67 +136,67 @@
 // CHECK-64:           (field name=small offset=0
 // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647))))))
 // CHECK-64:   (field name=t03 offset=48
-// CHECK-64:     (struct size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-64:   (field name=t04 offset=64
+// CHECK-64:   (field name=t04 offset=56
 // CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t05 offset=72
+// CHECK-64:   (field name=t05 offset=64
 // CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t06 offset=80
+// CHECK-64:   (field name=t06 offset=72
 // CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t07 offset=88
+// CHECK-64:   (field name=t07 offset=80
 // CHECK-64:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t08 offset=92
+// CHECK-64:   (field name=t08 offset=84
 // CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t09 offset=96
+// CHECK-64:   (field name=t09 offset=88
 // CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t10 offset=104
+// CHECK-64:   (field name=t10 offset=96
 // CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t11 offset=112
+// CHECK-64:   (field name=t11 offset=104
 // CHECK-64:     (reference kind=strong refcounting=unknown))
-// CHECK-64:   (field name=t12 offset=120
+// CHECK-64:   (field name=t12 offset=112
 // CHECK-64:     (reference kind=strong refcounting=unknown))
-// CHECK-64:   (field name=t13 offset=128
+// CHECK-64:   (field name=t13 offset=120
 // CHECK-64:     (reference kind=strong refcounting=unknown))
-// CHECK-64:   (field name=t14 offset=136
+// CHECK-64:   (field name=t14 offset=128
 // CHECK-64:     (reference kind=strong refcounting=unknown))
-// CHECK-64:   (field name=t15 offset=144
-// CHECK-64:     (struct size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64:   (field name=t15 offset=136
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-64:   (field name=t16 offset=160
+// CHECK-64:   (field name=t16 offset=144
 // CHECK-64:     (struct size=24 alignment=8 stride=24 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-64:   (field name=t17 offset=184
+// CHECK-64:   (field name=t17 offset=168
 // CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t18 offset=192
+// CHECK-64:   (field name=t18 offset=176
 // CHECK-64:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t19 offset=196
+// CHECK-64:   (field name=t19 offset=180
 // CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t20 offset=200
+// CHECK-64:   (field name=t20 offset=184
 // CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-64:   (field name=t21 offset=208
+// CHECK-64:   (field name=t21 offset=192
 // CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-64:       (field name=_value offset=0
 // CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
@@ -207,7 +207,7 @@
 // CHECK-32: (class reflect_multiple_types.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=137 alignment=8 stride=144 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=129 alignment=8 stride=136 num_extra_inhabitants=0
 // CHECK-32:   (field name=t00 offset=12
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
 // (unstable implementation details omitted)
@@ -228,7 +228,7 @@
 // CHECK-32:           (field name=small offset=0
 // CHECK-32:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647))))))
 // CHECK-32:   (field name=t03 offset=32
-// CHECK-32:     (struct size=5 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
 // CHECK-32:   (field name=t04 offset=40
 // CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
@@ -267,28 +267,28 @@
 // CHECK-32:   (field name=t14 offset=88
 // CHECK-32:     (reference kind=strong refcounting=unknown))
 // CHECK-32:   (field name=t15 offset=92
-// CHECK-32:     (struct size=5 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-32:   (field name=t16 offset=100
+// CHECK-32:   (field name=t16 offset=96
 // CHECK-32:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0
 // (unstable implementation details omitted)
-// CHECK-32:   (field name=t17 offset=112
+// CHECK-32:   (field name=t17 offset=108
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32:   (field name=t18 offset=116
+// CHECK-32:   (field name=t18 offset=112
 // CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
-// CHECK-32:   (field name=t19 offset=120
+// CHECK-32:   (field name=t19 offset=116
 // CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
-// CHECK-32:   (field name=t20 offset=128
+// CHECK-32:   (field name=t20 offset=120
 // CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
-// CHECK-32:   (field name=t21 offset=136
+// CHECK-32:   (field name=t21 offset=128
 // CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
 // CHECK-32:       (field name=_value offset=0
 // CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
diff --git a/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildCrashesDuringShutdown.swift b/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildCrashesDuringShutdown.swift
index 7d9ba05..1589952 100644
--- a/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildCrashesDuringShutdown.swift
+++ b/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildCrashesDuringShutdown.swift
@@ -2,7 +2,7 @@
 // REQUIRES: executable_test
 
 import StdlibUnittest
-#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
 import Glibc
 #else
 import Darwin
diff --git a/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildExitsDuringShutdown.swift b/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildExitsDuringShutdown.swift
index 25334f2..7733925 100644
--- a/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildExitsDuringShutdown.swift
+++ b/validation-test/StdlibUnittest/ChildProcessShutdown/FailIfChildExitsDuringShutdown.swift
@@ -2,7 +2,7 @@
 // REQUIRES: executable_test
 
 import StdlibUnittest
-#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
 import Glibc
 #else
 import Darwin
diff --git a/validation-test/StdlibUnittest/ChildProcessShutdown/PassIfChildCrashedDuringTestExecution.swift b/validation-test/StdlibUnittest/ChildProcessShutdown/PassIfChildCrashedDuringTestExecution.swift
index 5f719e6..567a38b 100644
--- a/validation-test/StdlibUnittest/ChildProcessShutdown/PassIfChildCrashedDuringTestExecution.swift
+++ b/validation-test/StdlibUnittest/ChildProcessShutdown/PassIfChildCrashedDuringTestExecution.swift
@@ -2,7 +2,7 @@
 // REQUIRES: executable_test
 
 import StdlibUnittest
-#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
 import Glibc
 #else
 import Darwin
diff --git a/validation-test/StdlibUnittest/Cygwin.swift b/validation-test/StdlibUnittest/Cygwin.swift
new file mode 100644
index 0000000..74786f0
--- /dev/null
+++ b/validation-test/StdlibUnittest/Cygwin.swift
@@ -0,0 +1,36 @@
+// RUN: %target-run-stdlib-swift | %FileCheck %s
+// REQUIRES: executable_test
+
+import Swift
+import StdlibUnittest
+
+_setOverrideOSVersion(.windowsCygnus)
+_setTestSuiteFailedCallback() { print("abort()") }
+
+var XFailsWindows = TestSuite("XFailsCygwin")
+
+// CHECK: [   UXPASS ] XFailsCygwin.xfail Cygwin passes{{$}}
+XFailsWindows.test("xfail Cygwin passes").xfail(.windowsCygnusAny(reason: "")).code {
+  expectEqual(1, 1)
+}
+
+// CHECK: [    XFAIL ] XFailsCygwin.xfail Cygwin fails{{$}}
+XFailsWindows.test("xfail Cygwin fails").xfail(.windowsCygnusAny(reason: "")).code {
+  expectEqual(1, 2)
+}
+
+// CHECK: [   UXPASS ] XFailsCygwin.xfail Windows passes{{$}}
+XFailsWindows.test("xfail Windows passes").xfail(.windowsAny(reason: "")).code {
+  expectEqual(1, 1)
+}
+
+// CHECK: [    XFAIL ] XFailsCygwin.xfail Windows fails{{$}}
+XFailsWindows.test("xfail Windows fails").xfail(.windowsAny(reason: "")).code {
+  expectEqual(1, 2)
+}
+
+// CHECK: XFailsCygwin: Some tests failed, aborting
+// CHECK: abort()
+
+runAllTests()
+
diff --git a/validation-test/StdlibUnittest/Stdin.swift b/validation-test/StdlibUnittest/Stdin.swift
index 253f1bb..e0c282e 100644
--- a/validation-test/StdlibUnittest/Stdin.swift
+++ b/validation-test/StdlibUnittest/Stdin.swift
@@ -6,7 +6,7 @@
 
 #if os(OSX) || os(iOS) || os(tvOS) || os(watchOS)
 import Darwin
-#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
+#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
 import Glibc
 #endif
 
diff --git a/validation-test/compiler_crashers/28616-swift-parser-parseexprsequence-swift-diag-bool-bool.swift b/validation-test/compiler_crashers/28616-swift-parser-parseexprsequence-swift-diag-bool-bool.swift
index ef01b15..586b1bb 100644
--- a/validation-test/compiler_crashers/28616-swift-parser-parseexprsequence-swift-diag-bool-bool.swift
+++ b/validation-test/compiler_crashers/28616-swift-parser-parseexprsequence-swift-diag-bool-bool.swift
@@ -5,5 +5,7 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
+// REQUIRES: deterministic-behavior
+
 // RUN: not --crash %target-swift-frontend %s -emit-ir
 let x = [{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
diff --git a/validation-test/compiler_crashers/28647-unreachable-executed-at-swift-include-swift-ast-typevisitor-h-39.swift b/validation-test/compiler_crashers/28647-unreachable-executed-at-swift-include-swift-ast-typevisitor-h-39.swift
deleted file mode 100644
index d6868b2..0000000
--- a/validation-test/compiler_crashers/28647-unreachable-executed-at-swift-include-swift-ast-typevisitor-h-39.swift
+++ /dev/null
@@ -1,11 +0,0 @@
-// This source file is part of the Swift.org open source project
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-
-// REQUIRES: deterministic-behavior
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-
-c|[{t in(0/0
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers/28652-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift
similarity index 93%
copy from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
copy to validation-test/compiler_crashers/28652-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift
index 208199a..9f16926 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers/28652-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift
@@ -6,4 +6,4 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-nil as Int!as?Int?!
+func t(UInt=1 + 1 as?Int){
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers/28653-child-source-range-not-contained-within-its-parent.swift
similarity index 94%
rename from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
rename to validation-test/compiler_crashers/28653-child-source-range-not-contained-within-its-parent.swift
index 208199a..fd2634e 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers/28653-child-source-range-not-contained-within-its-parent.swift
@@ -6,4 +6,4 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-nil as Int!as?Int?!
+switch{case.b(u){
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers/28654-hastype-e-expected-type-to-have-been-set.swift
similarity index 93%
copy from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
copy to validation-test/compiler_crashers/28654-hastype-e-expected-type-to-have-been-set.swift
index 990202a..2615c43 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers/28654-hastype-e-expected-type-to-have-been-set.swift
@@ -7,4 +7,5 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-Array(.n).init(
+struct A{let d}A(_
+print(
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers/28655-base-base-hastypeparameter.swift
similarity index 96%
rename from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
rename to validation-test/compiler_crashers/28655-base-base-hastypeparameter.swift
index 990202a..bf9d497 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers/28655-base-base-hastypeparameter.swift
@@ -7,4 +7,4 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-Array(.n).init(
+[_==Set(.b
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers/28656-unreachable-executed-at-swift-lib-ast-type-cpp-1137.swift
similarity index 90%
copy from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
copy to validation-test/compiler_crashers/28656-unreachable-executed-at-swift-lib-ast-type-cpp-1137.swift
index 208199a..1606306 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers/28656-unreachable-executed-at-swift-lib-ast-type-cpp-1137.swift
@@ -6,4 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-nil as Int!as?Int?!
+{ struct A{
+p.init(UInt=1 + 1 as?Int){
diff --git a/validation-test/compiler_crashers/28649-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift b/validation-test/compiler_crashers/28657-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
similarity index 94%
rename from validation-test/compiler_crashers/28649-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
rename to validation-test/compiler_crashers/28657-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
index e4b663d..e716a5a 100644
--- a/validation-test/compiler_crashers/28649-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
+++ b/validation-test/compiler_crashers/28657-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
@@ -6,6 +6,6 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: deterministic-behavior
-// RUN: not --crash %target-swift-frontend %s -emit-ir
 
-c|[({""==$0
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+func b(UInt=1 + 1 as?Int){$
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers/28658-result-case-not-implemented.swift
similarity index 91%
copy from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
copy to validation-test/compiler_crashers/28658-result-case-not-implemented.swift
index 990202a..6fd843c 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers/28658-result-case-not-implemented.swift
@@ -7,4 +7,4 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-Array(.n).init(
+s a){func a(UInt=1 + 1 + 1 as?Int){
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers/28659-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
similarity index 93%
copy from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
copy to validation-test/compiler_crashers/28659-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
index 990202a..2da0df0 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers/28659-isactuallycanonicalornull-forming-a-cantype-out-of-a-non-canonical-type.swift
@@ -7,4 +7,4 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-Array(.n).init(
+{func b(UInt=1 + 1 as?Int){f
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers/28660-false-encountered-error-in-diagnostic-text.swift
similarity index 91%
copy from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
copy to validation-test/compiler_crashers/28660-false-encountered-error-in-diagnostic-text.swift
index 990202a..11a42a9 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers/28660-false-encountered-error-in-diagnostic-text.swift
@@ -7,4 +7,4 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-Array(.n).init(
+class C{@_fixed_layout public struct P
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers/28661-swift-typebase-getcanonicaltype.swift
similarity index 90%
copy from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
copy to validation-test/compiler_crashers/28661-swift-typebase-getcanonicaltype.swift
index 208199a..76cf8a4 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers/28661-swift-typebase-getcanonicaltype.swift
@@ -6,4 +6,4 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-nil as Int!as?Int?!
+{func b(UInt=1 + 1 + 1 as?Int?){class d a{
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers/28662-isa-x-val-cast-ty-argument-of-incompatible-type.swift
similarity index 90%
copy from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
copy to validation-test/compiler_crashers/28662-isa-x-val-cast-ty-argument-of-incompatible-type.swift
index 990202a..bbbc1ae 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers/28662-isa-x-val-cast-ty-argument-of-incompatible-type.swift
@@ -7,4 +7,4 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-Array(.n).init(
+func c{return ReversedRandomAccessIndex(Int
diff --git a/validation-test/compiler_crashers/28603-argumentlabels-size-1.swift b/validation-test/compiler_crashers_fixed/28603-argumentlabels-size-1.swift
similarity index 84%
rename from validation-test/compiler_crashers/28603-argumentlabels-size-1.swift
rename to validation-test/compiler_crashers_fixed/28603-argumentlabels-size-1.swift
index c3419f0..0632142 100644
--- a/validation-test/compiler_crashers/28603-argumentlabels-size-1.swift
+++ b/validation-test/compiler_crashers_fixed/28603-argumentlabels-size-1.swift
@@ -5,8 +5,7 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-// REQUIRES: asserts
+// RUN: not %target-swift-frontend %s -emit-ir
 func a
 struct B{func a{struct A{}a(x:RangeReplaceableCollection
 A
diff --git a/validation-test/compiler_crashers_fixed/28612-val-isa-used-on-a-null-pointer.swift b/validation-test/compiler_crashers_fixed/28612-val-isa-used-on-a-null-pointer.swift
index 7520215..d327687 100644
--- a/validation-test/compiler_crashers_fixed/28612-val-isa-used-on-a-null-pointer.swift
+++ b/validation-test/compiler_crashers_fixed/28612-val-isa-used-on-a-null-pointer.swift
@@ -6,5 +6,4 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not %target-swift-frontend %s -emit-ir
-// REQUIRES: asserts
 switch{case{}|0/(let(0t
diff --git a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift b/validation-test/compiler_crashers_fixed/28636-base-base-hastypeparameter.swift
similarity index 82%
copy from validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
copy to validation-test/compiler_crashers_fixed/28636-base-base-hastypeparameter.swift
index 990202a..5cb9bf2 100644
--- a/validation-test/compiler_crashers/28636-base-base-hastypeparameter.swift
+++ b/validation-test/compiler_crashers_fixed/28636-base-base-hastypeparameter.swift
@@ -5,6 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 Array(.n).init(
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers_fixed/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
similarity index 86%
copy from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
copy to validation-test/compiler_crashers_fixed/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
index 208199a..72af617 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers_fixed/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
@@ -5,5 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: %target-swift-frontend %s -emit-ir
 nil as Int!as?Int?!
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers_fixed/28647-unreachable-executed-at-swift-include-swift-ast-typevisitor-h-39.swift
similarity index 81%
copy from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
copy to validation-test/compiler_crashers_fixed/28647-unreachable-executed-at-swift-include-swift-ast-typevisitor-h-39.swift
index 208199a..5a719bb 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers_fixed/28647-unreachable-executed-at-swift-include-swift-ast-typevisitor-h-39.swift
@@ -5,5 +5,6 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-nil as Int!as?Int?!
+// RUN: not %target-swift-frontend %s -emit-ir
+
+c|[{t in(0/0
diff --git a/validation-test/compiler_crashers_fixed/28648-modifierarguments-empty-foundpipe-index-beyond-bounds-in-select-modifier.swift b/validation-test/compiler_crashers_fixed/28648-modifierarguments-empty-foundpipe-index-beyond-bounds-in-select-modifier.swift
index 9c4b9b8..27d3b82 100644
--- a/validation-test/compiler_crashers_fixed/28648-modifierarguments-empty-foundpipe-index-beyond-bounds-in-select-modifier.swift
+++ b/validation-test/compiler_crashers_fixed/28648-modifierarguments-empty-foundpipe-index-beyond-bounds-in-select-modifier.swift
@@ -5,7 +5,6 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// REQUIRES: asserts
 // RUN: not %target-swift-frontend %s -emit-ir
 @_versioned
 open var a
diff --git a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift b/validation-test/compiler_crashers_fixed/28649-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
similarity index 81%
copy from validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
copy to validation-test/compiler_crashers_fixed/28649-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
index 208199a..f1f4d9b 100644
--- a/validation-test/compiler_crashers/28638-anonymous-namespace-verifier-checksametype-swift-type-swift-type-char-const.swift
+++ b/validation-test/compiler_crashers_fixed/28649-unreachable-executed-at-swift-lib-ast-type-cpp-1344.swift
@@ -5,5 +5,6 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-nil as Int!as?Int?!
+// RUN: not %target-swift-frontend %s -emit-ir
+
+c|[({""==$0
diff --git a/validation-test/compiler_crashers/28651-swift-cleanupillformedexpressionraii-doit-swift-expr-swift-astcontext-cleanupill.swift b/validation-test/compiler_crashers_fixed/28651-swift-cleanupillformedexpressionraii-doit-swift-expr-swift-astcontext-cleanupill.swift
similarity index 85%
rename from validation-test/compiler_crashers/28651-swift-cleanupillformedexpressionraii-doit-swift-expr-swift-astcontext-cleanupill.swift
rename to validation-test/compiler_crashers_fixed/28651-swift-cleanupillformedexpressionraii-doit-swift-expr-swift-astcontext-cleanupill.swift
index 54d133f..d44c328 100644
--- a/validation-test/compiler_crashers/28651-swift-cleanupillformedexpressionraii-doit-swift-expr-swift-astcontext-cleanupill.swift
+++ b/validation-test/compiler_crashers_fixed/28651-swift-cleanupillformedexpressionraii-doit-swift-expr-swift-astcontext-cleanupill.swift
@@ -5,6 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// REQUIRES: deterministic-behavior
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 d}let x[{{{}|[{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{let d