Merge pull request #8089 from hartbit/SR-3936

[SR-3936] Fix it for missing property type
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f40a883..9b37a68 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -585,18 +585,6 @@
 # Configure SDKs.
 #
 
-function(is_sdk_requested name result_var_name)
-  if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${name}")
-    set("${result_var_name}" "TRUE" PARENT_SCOPE)
-  else()
-    if("${name}" IN_LIST SWIFT_SDKS)
-      set("${result_var_name}" "TRUE" PARENT_SCOPE)
-    else()
-      set("${result_var_name}" "FALSE" PARENT_SCOPE)
-    endif()
-  endif()
-endfunction()
-
 if(XCODE)
   # FIXME: Cannot cross-compile the standard library using Xcode.  Xcode
   # insists on passing -mmacosx-version-min to the compiler, and we need
@@ -697,84 +685,7 @@
   message(STATUS "${xcode_version}")
   message(STATUS "")
 
-  is_sdk_requested(OSX swift_build_osx)
-  if(swift_build_osx)
-    configure_sdk_darwin(
-        OSX "OS X" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_OSX}"
-        macosx macosx macosx "x86_64")
-    configure_target_variant(OSX-DA "OS X Debug+Asserts"   OSX DA "Debug+Asserts")
-    configure_target_variant(OSX-RA "OS X Release+Asserts" OSX RA "Release+Asserts")
-    configure_target_variant(OSX-R  "OS X Release"         OSX R  "Release")
-  endif()
-
-  # Compatible cross-compile SDKS for Darwin OSes: IOS, IOS_SIMULATOR, TVOS,
-  #   TVOS_SIMULATOR, WATCHOS, WATCHOS_SIMULATOR (archs hardcoded below).
-
-  is_sdk_requested(IOS swift_build_ios)
-  if(swift_build_ios)
-    configure_sdk_darwin(
-        IOS "iOS" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_IOS}"
-        iphoneos ios ios "armv7;armv7s;arm64")
-    configure_target_variant(IOS-DA "iOS Debug+Asserts"   IOS DA "Debug+Asserts")
-    configure_target_variant(IOS-RA "iOS Release+Asserts" IOS RA "Release+Asserts")
-    configure_target_variant(IOS-R  "iOS Release"         IOS R "Release")
-  endif()
-
-  is_sdk_requested(IOS_SIMULATOR swift_build_ios_simulator)
-  if(swift_build_ios_simulator)
-    configure_sdk_darwin(
-        IOS_SIMULATOR "iOS Simulator" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_IOS}"
-        iphonesimulator ios-simulator ios "i386;x86_64")
-    configure_target_variant(
-        IOS_SIMULATOR-DA "iOS Debug+Asserts"   IOS_SIMULATOR DA "Debug+Asserts")
-    configure_target_variant(
-        IOS_SIMULATOR-RA "iOS Release+Asserts" IOS_SIMULATOR RA "Release+Asserts")
-    configure_target_variant(
-        IOS_SIMULATOR-R  "iOS Release"         IOS_SIMULATOR R "Release")
-  endif()
-
-  is_sdk_requested(TVOS swift_build_tvos)
-  if(swift_build_tvos)
-    configure_sdk_darwin(
-        TVOS "tvOS" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS}"
-        appletvos tvos tvos "arm64")
-    configure_target_variant(TVOS-DA "tvOS Debug+Asserts"   TVOS DA "Debug+Asserts")
-    configure_target_variant(TVOS-RA "tvOS Release+Asserts" TVOS RA "Release+Asserts")
-    configure_target_variant(TVOS-R  "tvOS Release"         TVOS R "Release")
-  endif()
-
-  is_sdk_requested(TVOS_SIMULATOR swift_build_tvos_simulator)
-  if(swift_build_tvos_simulator)
-    configure_sdk_darwin(
-        TVOS_SIMULATOR "tvOS Simulator" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS}"
-        appletvsimulator tvos-simulator tvos "x86_64")
-    configure_target_variant(
-      TVOS_SIMULATOR-DA "tvOS Debug+Asserts"   TVOS_SIMULATOR DA "Debug+Asserts")
-    configure_target_variant(
-      TVOS_SIMULATOR-RA "tvOS Release+Asserts" TVOS_SIMULATOR RA "Release+Asserts")
-    configure_target_variant(
-      TVOS_SIMULATOR-R  "tvOS Release"         TVOS_SIMULATOR R "Release")
-  endif()
-
-  is_sdk_requested(WATCHOS swift_build_watchos)
-  if(swift_build_watchos)
-    configure_sdk_darwin(
-        WATCHOS "watchOS" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS}"
-        watchos watchos watchos "armv7k")
-    configure_target_variant(WATCHOS-DA "watchOS Debug+Asserts"   WATCHOS DA "Debug+Asserts")
-    configure_target_variant(WATCHOS-RA "watchOS Release+Asserts" WATCHOS RA "Release+Asserts")
-    configure_target_variant(WATCHOS-R  "watchOS Release"         WATCHOS R "Release")
-  endif()
-
-  is_sdk_requested(WATCHOS_SIMULATOR swift_build_watchos_simulator)
-  if(swift_build_watchos_simulator)
-    configure_sdk_darwin(
-        WATCHOS_SIMULATOR "watchOS Simulator" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS}"
-        watchsimulator watchos-simulator watchos "i386")
-    configure_target_variant(WATCHOS_SIMULATOR-DA "watchOS Debug+Asserts"   WATCHOS_SIMULATOR DA "Debug+Asserts")
-    configure_target_variant(WATCHOS_SIMULATOR-RA "watchOS Release+Asserts" WATCHOS_SIMULATOR RA "Release+Asserts")
-    configure_target_variant(WATCHOS_SIMULATOR-R  "watchOS Release"         WATCHOS_SIMULATOR R "Release")
-  endif()
+  include(DarwinSDKs)
 
   # FIXME: guess target variant based on the host.
   # if(SWIFT_HOST_VARIANT MATCHES "^macosx")
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 0acbd41..0fe6933 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -101,7 +101,7 @@
 
   # MSVC and clang-cl dont't understand -target.
   if (NOT SWIFT_COMPILER_IS_MSVC_LIKE)
-     list(APPEND result "-target" "${SWIFT_SDK_${CFLAGS_SDK}_ARCH_${CFLAGS_ARCH}_TRIPLE}")
+    list(APPEND result "-target" "${SWIFT_SDK_${CFLAGS_SDK}_ARCH_${CFLAGS_ARCH}_TRIPLE}")
   endif()
 
   is_darwin_based_sdk("${CFLAGS_SDK}" IS_DARWIN)
@@ -277,9 +277,14 @@
     list(APPEND result "-sdk" "${SWIFT_SDK_${sdk}_PATH}")
   endif()
 
-  list(APPEND result
-      "-target" "${SWIFT_SDK_${sdk}_ARCH_${arch}_TRIPLE}"
-      "-resource-dir" "${SWIFTLIB_DIR}")
+  if(BUILD_STANDALONE)
+    list(APPEND result
+        "-target" "${SWIFT_SDK_${sdk}_ARCH_${arch}_TRIPLE}")
+  else()
+    list(APPEND result
+        "-target" "${SWIFT_SDK_${sdk}_ARCH_${arch}_TRIPLE}"
+        "-resource-dir" "${SWIFTLIB_DIR}")
+  endif()
 
   is_darwin_based_sdk("${sdk}" IS_DARWIN)
   if(IS_DARWIN)
@@ -759,19 +764,19 @@
       DEPENDS ${swift_module_dependency_target})
   endif()
 
-  if (swift_sib_dependency_target)
-    add_dependencies(swift-stdlib${VARIANT_SUFFIX}-sib
-      ${swift_sib_dependency_target})
-  endif()
+  # For standalone overlay builds to work
+  if(NOT BUILD_STANDALONE)
+    if (EXISTS swift_sib_dependency_target AND NOT "${swift_sib_dependency_target}" STREQUAL "")
+      add_dependencies(swift-stdlib${VARIANT_SUFFIX}-sib ${swift_sib_dependency_target})
+    endif()
 
-  if (swift_sibopt_dependency_target)
-    add_dependencies(swift-stdlib${VARIANT_SUFFIX}-sibopt
-      ${swift_sibopt_dependency_target})
-  endif()
+    if (EXISTS swift_sibopt_dependency_target AND NOT "${swift_sibopt_dependency_target}" STREQUAL "")
+      add_dependencies(swift-stdlib${VARIANT_SUFFIX}-sibopt ${swift_sibopt_dependency_target})
+    endif()
 
-  if (swift_sibgen_dependency_target)
-    add_dependencies(swift-stdlib${VARIANT_SUFFIX}-sibgen
-      ${swift_sibgen_dependency_target})
+    if (EXISTS swift_sibgen_dependency_target AND NOT "${swift_sibgen_dependency_target}" STREQUAL "")
+      add_dependencies(swift-stdlib${VARIANT_SUFFIX}-sibgen ${swift_sibgen_dependency_target})
+    endif()
   endif()
 
   set(SWIFTLIB_INCORPORATED_OBJECT_LIBRARIES_EXPRESSIONS)
@@ -1408,7 +1413,7 @@
   endif()
 
   if(SWIFTLIB_TARGET_LIBRARY)
-    if(NOT SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER)
+    if(NOT SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER AND NOT BUILD_STANDALONE)
       list(APPEND SWIFTLIB_DEPENDS clang)
     endif()
 
@@ -1421,6 +1426,7 @@
           "${SWIFTLIB_TARGET_SDKS}" "${SWIFT_HOST_VARIANT_SDK}"
           SWIFTLIB_TARGET_SDKS)
     endif()
+
     foreach(sdk ${SWIFTLIB_TARGET_SDKS})
       set(THIN_INPUT_TARGETS)
 
@@ -1470,12 +1476,16 @@
         # linked libraries.  Find targets for both of these here.
         set(swiftlib_module_dependency_targets)
         set(swiftlib_private_link_libraries_targets)
-        foreach(mod ${swiftlib_module_depends_flattened})
-          list(APPEND swiftlib_module_dependency_targets
-              "swift${mod}${MODULE_VARIANT_SUFFIX}")
-          list(APPEND swiftlib_private_link_libraries_targets
-              "swift${mod}${VARIANT_SUFFIX}")
-        endforeach()
+
+        if(NOT BUILD_STANDALONE)
+          foreach(mod ${swiftlib_module_depends_flattened})
+            list(APPEND swiftlib_module_dependency_targets
+                "swift${mod}${MODULE_VARIANT_SUFFIX}")
+
+            list(APPEND swiftlib_private_link_libraries_targets
+                "swift${mod}${VARIANT_SUFFIX}")
+          endforeach()
+        endif()
 
         foreach(lib ${SWIFTLIB_PRIVATE_LINK_LIBRARIES})
           if("${lib}" STREQUAL "ICU_UC")
@@ -2082,7 +2092,7 @@
       TARGETS ${executable}
       RUNTIME DESTINATION bin)
 
-     swift_is_installing_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
+    swift_is_installing_component(${ADDSWIFTHOSTTOOL_SWIFT_COMPONENT}
       is_installing)
   
     if(NOT is_installing)
diff --git a/cmake/modules/DarwinSDKs.cmake b/cmake/modules/DarwinSDKs.cmake
new file mode 100644
index 0000000..8e680e6
--- /dev/null
+++ b/cmake/modules/DarwinSDKs.cmake
@@ -0,0 +1,78 @@
+is_sdk_requested(OSX swift_build_osx)
+if(swift_build_osx)
+  configure_sdk_darwin(
+      OSX "OS X" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_OSX}"
+      macosx macosx macosx "x86_64")
+  configure_target_variant(OSX-DA "OS X Debug+Asserts"   OSX DA "Debug+Asserts")
+  configure_target_variant(OSX-RA "OS X Release+Asserts" OSX RA "Release+Asserts")
+  configure_target_variant(OSX-R  "OS X Release"         OSX R  "Release")
+endif()
+
+# Compatible cross-compile SDKS for Darwin OSes: IOS, IOS_SIMULATOR, TVOS,
+#   TVOS_SIMULATOR, WATCHOS, WATCHOS_SIMULATOR (archs hardcoded below).
+
+is_sdk_requested(IOS swift_build_ios)
+if(swift_build_ios)
+  configure_sdk_darwin(
+      IOS "iOS" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_IOS}"
+      iphoneos ios ios "armv7;armv7s;arm64")
+  configure_target_variant(IOS-DA "iOS Debug+Asserts"   IOS DA "Debug+Asserts")
+  configure_target_variant(IOS-RA "iOS Release+Asserts" IOS RA "Release+Asserts")
+  configure_target_variant(IOS-R  "iOS Release"         IOS R "Release")
+endif()
+
+is_sdk_requested(IOS_SIMULATOR swift_build_ios_simulator)
+if(swift_build_ios_simulator)
+  configure_sdk_darwin(
+      IOS_SIMULATOR "iOS Simulator" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_IOS}"
+      iphonesimulator ios-simulator ios "i386;x86_64")
+  configure_target_variant(
+      IOS_SIMULATOR-DA "iOS Debug+Asserts"   IOS_SIMULATOR DA "Debug+Asserts")
+  configure_target_variant(
+      IOS_SIMULATOR-RA "iOS Release+Asserts" IOS_SIMULATOR RA "Release+Asserts")
+  configure_target_variant(
+      IOS_SIMULATOR-R  "iOS Release"         IOS_SIMULATOR R "Release")
+endif()
+
+is_sdk_requested(TVOS swift_build_tvos)
+if(swift_build_tvos)
+  configure_sdk_darwin(
+      TVOS "tvOS" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS}"
+      appletvos tvos tvos "arm64")
+  configure_target_variant(TVOS-DA "tvOS Debug+Asserts"   TVOS DA "Debug+Asserts")
+  configure_target_variant(TVOS-RA "tvOS Release+Asserts" TVOS RA "Release+Asserts")
+  configure_target_variant(TVOS-R  "tvOS Release"         TVOS R "Release")
+endif()
+
+is_sdk_requested(TVOS_SIMULATOR swift_build_tvos_simulator)
+if(swift_build_tvos_simulator)
+  configure_sdk_darwin(
+      TVOS_SIMULATOR "tvOS Simulator" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS}"
+      appletvsimulator tvos-simulator tvos "x86_64")
+  configure_target_variant(
+    TVOS_SIMULATOR-DA "tvOS Debug+Asserts"   TVOS_SIMULATOR DA "Debug+Asserts")
+  configure_target_variant(
+    TVOS_SIMULATOR-RA "tvOS Release+Asserts" TVOS_SIMULATOR RA "Release+Asserts")
+  configure_target_variant(
+    TVOS_SIMULATOR-R  "tvOS Release"         TVOS_SIMULATOR R "Release")
+endif()
+
+is_sdk_requested(WATCHOS swift_build_watchos)
+if(swift_build_watchos)
+  configure_sdk_darwin(
+      WATCHOS "watchOS" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS}"
+      watchos watchos watchos "armv7k")
+  configure_target_variant(WATCHOS-DA "watchOS Debug+Asserts"   WATCHOS DA "Debug+Asserts")
+  configure_target_variant(WATCHOS-RA "watchOS Release+Asserts" WATCHOS RA "Release+Asserts")
+  configure_target_variant(WATCHOS-R  "watchOS Release"         WATCHOS R "Release")
+endif()
+
+is_sdk_requested(WATCHOS_SIMULATOR swift_build_watchos_simulator)
+if(swift_build_watchos_simulator)
+  configure_sdk_darwin(
+      WATCHOS_SIMULATOR "watchOS Simulator" "${SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS}"
+      watchsimulator watchos-simulator watchos "i386")
+  configure_target_variant(WATCHOS_SIMULATOR-DA "watchOS Debug+Asserts"   WATCHOS_SIMULATOR DA "Debug+Asserts")
+  configure_target_variant(WATCHOS_SIMULATOR-RA "watchOS Release+Asserts" WATCHOS_SIMULATOR RA "Release+Asserts")
+  configure_target_variant(WATCHOS_SIMULATOR-R  "watchOS Release"         WATCHOS_SIMULATOR R "Release")
+endif()
diff --git a/cmake/modules/StandaloneOverlay.cmake b/cmake/modules/StandaloneOverlay.cmake
new file mode 100644
index 0000000..0082a6a
--- /dev/null
+++ b/cmake/modules/StandaloneOverlay.cmake
@@ -0,0 +1,68 @@
+# CMAKE_SOURCE_DIR is the directory that cmake got initially invoked on.
+# CMAKE_CURRENT_SOURCE_DIR is the current directory. If these are equal, it's
+# a top-level build of the CMAKE_SOURCE_DIR. Otherwise, define a guard variable
+# and return.
+if(DEFINED SWIFT_MASTER_LOADED
+  OR NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR})
+  message(STATUS "returning from StandaloneOverlay.cmake")
+  set(SWIFT_MASTER_LOADED TRUE)
+  return()
+endif()
+
+set(CMAKE_INSTALL_PREFIX "${SWIFT_DEST_ROOT}${TOOLCHAIN_DIR}/usr")
+
+# Only happens if it's called from a top-level cmake invocation.
+set(BUILD_STANDALONE TRUE)
+set(SWIFT_STDLIB_BUILD_TYPE "Release")
+set(SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES "SHARED")
+set(SWIFT_INSTALL_COMPONENTS "sdk-overlay" CACHE STRING "")
+set(SWIFT_DARWIN_DEPLOYMENT_VERSION_OSX "10.9")
+set(SWIFT_DARWIN_DEPLOYMENT_VERSION_IOS "7.0")
+set(SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS "9.0")
+set(SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS "2.0")
+
+set(SWIFT_SOURCE_DIR "${SWIFT_SOURCE_ROOT}/src/swift" CACHE PATH "")
+set(SWIFT_PATH_TO_LLVM_SOURCE "${SWIFT_SOURCE_ROOT}/src/llvm" CACHE PATH "")
+set(SWIFT_NATIVE_SWIFT_TOOLS_PATH "${TOOLCHAIN_DIR}/usr/bin" CACHE PATH "")
+set(SWIFT_SDKS ${SWIFT_HOST_VARIANT_SDK})
+
+set(LLVM_CMAKE_MODULES_PATH "${SWIFT_PATH_TO_LLVM_SOURCE}/cmake/modules")
+
+list(APPEND CMAKE_MODULE_PATH
+  "${PROJECT_SOURCE_DIR}/../../../../cmake/modules"
+  ${LLVM_CMAKE_MODULES_PATH}
+)
+
+message(STATUS "FINDING LIPO")
+  execute_process(
+  COMMAND "xcrun" "-find" "lipo"
+  OUTPUT_VARIABLE LIPO
+  OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+include(AddLLVM)
+include(SwiftUtils)
+include(SwiftSharedCMakeConfig)
+include(AddSwift)
+include(SwiftHandleGybSources)
+include(SwiftConfigureSDK)
+include(SwiftSource)
+include(SwiftComponents)
+include(DarwinSDKs)
+
+# These variables should be passed as -D variables to cmake.
+# e.g. cmake -G Ninja -DSWIFT_HOST_VARIANT_SDK=OSX ..
+precondition(CMAKE_INSTALL_PREFIX)
+precondition(SWIFT_SOURCE_ROOT)
+precondition(SWIFT_DEST_ROOT)
+precondition(SWIFT_HOST_VARIANT_SDK)
+precondition(TOOLCHAIN_DIR)
+
+# Without this line, installing components is broken. This needs refactoring.
+swift_configure_components()
+
+precondition(unknown_sdks NEGATE MESSAGE "Unknown SDKs: ${unknown_sdks}")
+precondition(SWIFT_CONFIGURED_SDKS MESSAGE "No SDKs selected.")
+precondition(SWIFT_HOST_VARIANT_SDK MESSAGE "No SDK for host tools.")
+
+# ARCH is set somewhere later.
+#precondition(SWIFT_HOST_VARIANT_ARCH MESSAGE "No arch for host tools")
diff --git a/cmake/modules/SwiftComponents.cmake b/cmake/modules/SwiftComponents.cmake
index 98addd6..faa8b94 100644
--- a/cmake/modules/SwiftComponents.cmake
+++ b/cmake/modules/SwiftComponents.cmake
@@ -91,6 +91,7 @@
   endforeach()
 endmacro()
 
+# Sets the is_installing variable.
 function(swift_is_installing_component component result_var_name)
   precondition(component MESSAGE "Component name is required")
 
diff --git a/cmake/modules/SwiftSource.cmake b/cmake/modules/SwiftSource.cmake
index 532a7e1..1724fff 100644
--- a/cmake/modules/SwiftSource.cmake
+++ b/cmake/modules/SwiftSource.cmake
@@ -329,9 +329,12 @@
     endif()
   endif()
 
-  swift_install_in_component("${SWIFTFILE_INSTALL_IN_COMPONENT}"
-      FILES "${module_file}" "${module_doc_file}"
-      DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${library_subdir}")
+  # If we want to build a single overlay, don't install the swiftmodule and swiftdoc files.
+  if(NOT BUILD_STANDALONE)
+    swift_install_in_component("${SWIFTFILE_INSTALL_IN_COMPONENT}"
+        FILES "${module_file}" "${module_doc_file}"
+        DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/${library_subdir}")
+  endif()
 
   set(line_directive_tool "${SWIFT_SOURCE_DIR}/utils/line-directive")
   set(swift_compiler_tool "${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swiftc")
diff --git a/cmake/modules/SwiftUtils.cmake b/cmake/modules/SwiftUtils.cmake
index 4b0b7dc..19f1722 100644
--- a/cmake/modules/SwiftUtils.cmake
+++ b/cmake/modules/SwiftUtils.cmake
@@ -151,3 +151,26 @@
     WORKING_DIRECTORY "${CS_WORKING_DIRECTORY}"
     COMMENT "${CS_COMMENT}")
 endfunction()
+
+function(dump_swift_vars)
+  set(SWIFT_STDLIB_GLOBAL_CMAKE_CACHE)
+  get_cmake_property(variableNames VARIABLES)
+  foreach(variableName ${variableNames})
+    if(variableName MATCHES "^SWIFT")
+      set(SWIFT_STDLIB_GLOBAL_CMAKE_CACHE "${SWIFT_STDLIB_GLOBAL_CMAKE_CACHE}set(${variableName} \"${${variableName}}\")\n")
+      message("set(${variableName} \"${${variableName}}\")")
+    endif()
+  endforeach()
+endfunction()
+
+function(is_sdk_requested name result_var_name)
+  if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${name}")
+    set("${result_var_name}" "TRUE" PARENT_SCOPE)
+  else()
+    if("${name}" IN_LIST SWIFT_SDKS)
+      set("${result_var_name}" "TRUE" PARENT_SCOPE)
+    else()
+      set("${result_var_name}" "FALSE" PARENT_SCOPE)
+    endif()
+  endif()
+endfunction()
diff --git a/docs/SIL.rst b/docs/SIL.rst
index b875014..be7c865 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -4489,9 +4489,14 @@
 ````````````````````````````````
 ::
 
-  sil-instruction ::= 'unconditional_checked_cast_value' sil-operand 'to' sil-type
+  sil-instruction ::= 'unconditional_checked_cast_value'
+                       sil-cast-consumption-kind
+                       sil-operand 'to' sil-type
+  sil-cast-consumption-kind ::= 'take_always'
+  sil-cast-consumption-kind ::= 'take_on_success'
+  sil-cast-consumption-kind ::= 'copy_on_success'
 
-  %1 = unconditional_checked_cast_value %0 : $A to $B
+  %1 = unconditional_checked_cast_value take_always %0 : $A to $B
   // $A must not be an address
   // $B must not be an address
   // %1 will be of type $B
diff --git a/include/swift/AST/Comment.h b/include/swift/AST/Comment.h
index 7cd7966..cc7a4e0 100644
--- a/include/swift/AST/Comment.h
+++ b/include/swift/AST/Comment.h
@@ -95,6 +95,10 @@
 Optional<DocComment *> getCascadingDocComment(swift::markup::MarkupContext &MC,
                                              const Decl *D);
 
+/// Extract comments parts from the given Markup node.
+swift::markup::CommentParts
+extractCommentParts(swift::markup::MarkupContext &MC,
+                    swift::markup::MarkupASTNode *Node);
 } // namespace swift
 
 #endif // LLVM_SWIFT_AST_COMMENT_H
diff --git a/include/swift/IDE/CommentConversion.h b/include/swift/IDE/CommentConversion.h
index fd7c98c..d2703a0 100644
--- a/include/swift/IDE/CommentConversion.h
+++ b/include/swift/IDE/CommentConversion.h
@@ -39,6 +39,9 @@
 /// Extract and normalize text from the given comment.
 std::string extractPlainTextFromComment(const StringRef Text);
 
+/// Given the raw text in markup format, convert its content to xml.
+bool convertMarkupToXML(StringRef Text, raw_ostream &OS);
+
 } // namespace ide
 } // namespace swift
 
diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h
index 633e77f..e640c22 100644
--- a/include/swift/IDE/Utils.h
+++ b/include/swift/IDE/Utils.h
@@ -267,8 +267,8 @@
                       DeclaredDecls(DeclaredDecls),
                       ReferencedDecls(ReferencedDecls),
                       RangeContext(RangeContext) {}
-  ResolvedRangeInfo() :
-  ResolvedRangeInfo(RangeKind::Invalid, Type(), StringRef(), nullptr,
+  ResolvedRangeInfo(StringRef Content) :
+  ResolvedRangeInfo(RangeKind::Invalid, Type(), Content, nullptr,
                     /*Single entry*/true, /*unhandled error*/false,
                     OrphanKind::None, {}, {}, {}) {}
   void print(llvm::raw_ostream &OS);
diff --git a/include/swift/Index/IndexSymbol.h b/include/swift/Index/IndexSymbol.h
index e1cd6f9..a4e9e85 100644
--- a/include/swift/Index/IndexSymbol.h
+++ b/include/swift/Index/IndexSymbol.h
@@ -79,6 +79,7 @@
 
 SymbolInfo getSymbolInfoForDecl(const Decl *D);
 SymbolSubKind getSubKindForAccessor(AccessorKind AK);
+bool isLocalSymbol(const Decl *D);
 
 using clang::index::printSymbolProperties;
 
diff --git a/include/swift/SIL/AbstractionPattern.h b/include/swift/SIL/AbstractionPattern.h
index 5aeb85d..dc082b5 100644
--- a/include/swift/SIL/AbstractionPattern.h
+++ b/include/swift/SIL/AbstractionPattern.h
@@ -893,9 +893,9 @@
   /// the abstraction pattern for its object type.
   AbstractionPattern getTupleElementType(unsigned index) const;
 
-  /// Given that the value being abstracted is an l-value type, return
-  /// the abstraction pattern for its object type.
-  AbstractionPattern getLValueObjectType() const;
+  /// Given that the value being abstracted is an l-value or inout type,
+  /// return the abstraction pattern for its object type.
+  AbstractionPattern getLValueOrInOutObjectType() const;
 
   /// Given that the value being abstracted is a function, return the
   /// abstraction pattern for its result type.
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index bf0e339..14d1ed0 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -801,10 +801,12 @@
   }
 
   UnconditionalCheckedCastValueInst *
-  createUnconditionalCheckedCastValue(SILLocation Loc, SILValue op,
-                                      SILType destTy) {
+  createUnconditionalCheckedCastValue(SILLocation Loc,
+                                      CastConsumptionKind consumption,
+                                      SILValue op, SILType destTy) {
     return insert(UnconditionalCheckedCastValueInst::create(
-        getSILDebugLocation(Loc), op, destTy, F, OpenedArchetypes));
+        getSILDebugLocation(Loc), consumption, op, destTy, F,
+        OpenedArchetypes));
   }
 
   RetainValueInst *createRetainValue(SILLocation Loc, SILValue operand,
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 0cccf8a..2ea0769 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -1165,7 +1165,7 @@
   SILType OpType = getOpType(Inst->getType());
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
   doPostProcess(Inst, getBuilder().createUnconditionalCheckedCastValue(
-                          OpLoc, OpValue, OpType));
+                          OpLoc, Inst->getConsumptionKind(), OpValue, OpType));
 }
 
 template <typename ImplClass>
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 327db93..db12dc6 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -2862,16 +2862,24 @@
           ValueKind::UnconditionalCheckedCastValueInst,
           UnconditionalCheckedCastValueInst, ConversionInst, true> {
   friend SILBuilder;
+  CastConsumptionKind ConsumptionKind;
 
-  UnconditionalCheckedCastValueInst(SILDebugLocation DebugLoc, SILValue Operand,
+  UnconditionalCheckedCastValueInst(SILDebugLocation DebugLoc,
+                                    CastConsumptionKind consumption,
+                                    SILValue Operand,
                                     ArrayRef<SILValue> TypeDependentOperands,
                                     SILType DestTy)
       : UnaryInstructionWithTypeDependentOperandsBase(
-            DebugLoc, Operand, TypeDependentOperands, DestTy) {}
+            DebugLoc, Operand, TypeDependentOperands, DestTy),
+        ConsumptionKind(consumption) {}
 
   static UnconditionalCheckedCastValueInst *
-  create(SILDebugLocation DebugLoc, SILValue Operand, SILType DestTy,
-         SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes);
+  create(SILDebugLocation DebugLoc, CastConsumptionKind consumption,
+         SILValue Operand, SILType DestTy, SILFunction &F,
+         SILOpenedArchetypesState &OpenedArchetypes);
+
+public:
+  CastConsumptionKind getConsumptionKind() const { return ConsumptionKind; }
 };
 
 /// StructInst - Represents a constructed loadable struct.
diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h
index dd42035..88d4aa0 100644
--- a/include/swift/SIL/TypeLowering.h
+++ b/include/swift/SIL/TypeLowering.h
@@ -653,24 +653,29 @@
   /// Returns the SILParameterInfo for the given declaration's `self` parameter.
   /// `constant` must refer to a method.
   SILParameterInfo getConstantSelfParameter(SILDeclRef constant);
-  
-  /// Returns the SILFunctionType the given declaration must use to override.
-  /// Will be the same as getConstantFunctionType if the declaration does
-  /// not override.
+
+  /// Returns the SILFunctionType that must be used to perform a vtable dispatch
+  /// to the given declaration.
+  ///
+  /// Will be the same as getConstantFunctionType() if the declaration does not
+  /// override anything.
   CanSILFunctionType getConstantOverrideType(SILDeclRef constant) {
-    // Fast path if the constant isn't overridden.
-    if (constant.getNextOverriddenVTableEntry().isNull())
-      return getConstantFunctionType(constant);
-    SILDeclRef base = constant;
-    while (SILDeclRef overridden = base.getOverridden())
-      base = overridden;
-    
-    return getConstantOverrideType(constant, base);
+    return getConstantOverrideInfo(constant).SILFnType;
   }
 
-  CanSILFunctionType getConstantOverrideType(SILDeclRef constant,
-                                             SILDeclRef base) {
-    return getConstantOverrideInfo(constant, base).SILFnType;
+  /// Returns the SILConstantInfo that must be used to perform a vtable dispatch
+  /// to the given declaration.
+  ///
+  /// Will be the same as getConstantInfo() if the declaration does not
+  /// override anything.
+  SILConstantInfo getConstantOverrideInfo(SILDeclRef constant) {
+    // Fast path if the constant does not override anything.
+    auto next = constant.getNextOverriddenVTableEntry();
+    if (next.isNull())
+      return getConstantInfo(constant);
+
+    auto base = constant.getBaseOverriddenVTableEntry();
+    return getConstantOverrideInfo(constant, base);
   }
 
   SILConstantInfo getConstantOverrideInfo(SILDeclRef constant,
@@ -678,7 +683,7 @@
 
   /// Get the empty tuple type as a SILType.
   SILType getEmptyTupleType() {
-    return getLoweredType(TupleType::getEmpty(Context));
+    return SILType::getPrimitiveObjectType(TupleType::getEmpty(Context));
   }
   
   /// Get a function type curried with its capture context.
diff --git a/include/swift/SILOptimizer/Utils/Generics.h b/include/swift/SILOptimizer/Utils/Generics.h
index 58406b6..da4efce 100644
--- a/include/swift/SILOptimizer/Utils/Generics.h
+++ b/include/swift/SILOptimizer/Utils/Generics.h
@@ -50,6 +50,10 @@
   /// to direct.
   llvm::SmallBitVector Conversions;
 
+  /// If set, indirect to direct conversions should be performned by the generic
+  /// specializer.
+  bool ConvertIndirectToDirect;
+
   /// The first NumResults bits in Conversions refer to formal indirect
   /// out-parameters.
   unsigned NumFormalIndirectResults;
@@ -130,7 +134,8 @@
   /// If specialization is not possible getSpecializedType() will return an
   /// invalid type.
   ReabstractionInfo(ApplySite Apply, SILFunction *Callee,
-                    SubstitutionList ParamSubs);
+                    SubstitutionList ParamSubs,
+                    bool ConvertIndirectToDirect = true);
 
   /// Constructs the ReabstractionInfo for generic function \p Orig with
   /// additional requirements. Requirements may contain new layout,
@@ -140,14 +145,15 @@
   /// Returns true if the \p ParamIdx'th (non-result) formal parameter is
   /// converted from indirect to direct.
   bool isParamConverted(unsigned ParamIdx) const {
-    return Conversions.test(ParamIdx + NumFormalIndirectResults);
+    return ConvertIndirectToDirect &&
+           Conversions.test(ParamIdx + NumFormalIndirectResults);
   }
 
   /// Returns true if the \p ResultIdx'th formal result is converted from
   /// indirect to direct.
   bool isFormalResultConverted(unsigned ResultIdx) const {
     assert(ResultIdx < NumFormalIndirectResults);
-    return Conversions.test(ResultIdx);
+    return ConvertIndirectToDirect && Conversions.test(ResultIdx);
   }
 
   /// Gets the total number of original function arguments.
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index a4370f7..4c84abd 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/ASTVisitor.h"
 #include "swift/AST/Initializer.h"
 #include "swift/AST/Module.h"
+#include "swift/AST/ParameterList.h"
 #include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Mangle.h"
 #include "swift/Demangling/ManglingUtils.h"
@@ -375,6 +376,29 @@
   return isInPrivateOrLocalContext(nominal);
 }
 
+static unsigned getUnnamedParamIndex(const Decl *D) {
+  unsigned UnnamedIndex = 0;
+  ArrayRef<ParameterList *> ParamLists;
+
+  if (auto AFD = dyn_cast<AbstractFunctionDecl>(D->getDeclContext())) {
+    ParamLists = AFD->getParameterLists();
+  } else if (auto ACE = dyn_cast<AbstractClosureExpr>(D->getDeclContext())) {
+    ParamLists = ACE->getParameterLists();
+  } else {
+    llvm_unreachable("unhandled param context");
+  }
+  for (auto ParamList : ParamLists) {
+    for (auto Param : *ParamList) {
+      if (!Param->hasName()) {
+        if (Param == D)
+          return UnnamedIndex;
+        ++UnnamedIndex;
+      }
+    }
+  }
+  llvm_unreachable("param not found");
+}
+
 void ASTMangler::appendDeclName(const ValueDecl *decl) {
   if (decl->isOperator()) {
     appendIdentifier(translateOperator(decl->getName().str()));
@@ -394,6 +418,10 @@
   }
 
   if (decl->getDeclContext()->isLocalContext()) {
+    if (isa<ParamDecl>(decl) && !decl->hasName()) {
+      // Mangle unnamed params with their ordering.
+      return appendOperator("L", Index(getUnnamedParamIndex(decl)));
+    }
     // Mangle local declarations with a numeric discriminator.
     return appendOperator("L", Index(decl->getLocalDiscriminator()));
   }
diff --git a/lib/AST/DocComment.cpp b/lib/AST/DocComment.cpp
index 03b778d..a181759 100644
--- a/lib/AST/DocComment.cpp
+++ b/lib/AST/DocComment.cpp
@@ -287,8 +287,8 @@
   return NormalItems.size() == 0;
 }
 
-static swift::markup::CommentParts
-extractCommentParts(swift::markup::MarkupContext &MC,
+swift::markup::CommentParts
+swift::extractCommentParts(swift::markup::MarkupContext &MC,
                     swift::markup::MarkupASTNode *Node) {
 
   swift::markup::CommentParts Parts;
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 23e0068..56cbac9 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -3200,6 +3200,13 @@
                                               LazyResolver *resolver) {
   auto subs = SubstitutionMap::getOverrideSubstitutions(
       baseDecl, derivedDecl, /*derivedSubs=*/None, resolver);
+
+  if (auto *genericMemberType = memberType->getAs<GenericFunctionType>()) {
+    memberType = FunctionType::get(genericMemberType->getInput(),
+                                   genericMemberType->getResult(),
+                                   genericMemberType->getExtInfo());
+  }
+
   auto type = memberType.subst(subs);
 
   if (isa<AbstractFunctionDecl>(baseDecl)) {
diff --git a/lib/AST/USRGeneration.cpp b/lib/AST/USRGeneration.cpp
index bcfd3bf..56cfe51 100644
--- a/lib/AST/USRGeneration.cpp
+++ b/lib/AST/USRGeneration.cpp
@@ -144,7 +144,9 @@
 bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) {
   using namespace Mangle;
 
-  if (!D->hasName() && (!isa<FuncDecl>(D) || cast<FuncDecl>(D)->getAccessorKind() == AccessorKind::NotAccessor))
+  if (!D->hasName() && !isa<ParamDecl>(D) &&
+      (!isa<FuncDecl>(D) ||
+       cast<FuncDecl>(D)->getAccessorKind() == AccessorKind::NotAccessor))
     return true; // Ignore.
   if (D->getModuleContext()->isBuiltinModule())
     return true; // Ignore.
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index c1d3754..5eb5113 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -2045,7 +2045,9 @@
       if (llvm::sys::fs::is_regular_file(OutputPath))
         llvm::sys::fs::remove(OutputPath);
     }
+  }
 
+  if (isa<CompileJobAction>(JA)) {
     // Choose the dependencies file output path.
     if (C.getArgs().hasArg(options::OPT_emit_dependencies)) {
       addAuxiliaryOutput(C, *Output, types::TY_Dependencies, OI, OutputMap);
diff --git a/lib/IDE/CommentConversion.cpp b/lib/IDE/CommentConversion.cpp
index d997fb3..9b0ca54 100644
--- a/lib/IDE/CommentConversion.cpp
+++ b/lib/IDE/CommentConversion.cpp
@@ -397,7 +397,7 @@
     OS << Doc;
 }
 
-std::string ide::extractPlainTextFromComment(const StringRef Text) {
+static LineList getLineListFromComment(const StringRef Text) {
   LangOptions LangOpts;
   SourceManager SourceMgr;
   auto Tokens = swift::tokenize(LangOpts, SourceMgr,
@@ -414,7 +414,11 @@
 
   RawComment Comment(Comments);
   swift::markup::MarkupContext MC;
-  return MC.getLineList(Comment).str();
+  return MC.getLineList(Comment);
+}
+
+std::string ide::extractPlainTextFromComment(const StringRef Text) {
+  return getLineListFromComment(Text).str();
 }
 
 bool ide::getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS) {
@@ -457,6 +461,23 @@
   return false;
 }
 
+bool ide::convertMarkupToXML(StringRef Text, raw_ostream &OS) {
+  std::string Comment;
+  {
+    llvm::raw_string_ostream OS(Comment);
+    OS << "/**\n" << Text << "\n" << "*/";
+  }
+  LineList LL = getLineListFromComment(Comment);
+  MarkupContext MC;
+  if (auto *Doc = swift::markup::parseDocument(MC, LL)) {
+    CommentToXMLConverter Converter(OS);
+    Converter.visitCommentParts(extractCommentParts(MC, Doc));
+    OS.flush();
+    return false;
+  }
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // Conversion to Doxygen.
 //===----------------------------------------------------------------------===//
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index 981f0ba..14d6ee9 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -342,6 +342,37 @@
     std::vector<ASTNode> EndMatches;
     ContextInfo(ASTNode Parent, bool ContainedInRange) : Parent(Parent),
       ContainedInRange(ContainedInRange) {}
+private:
+    bool hasStmtlikeNode(ArrayRef<ASTNode> Nodes) {
+      for (auto N : Nodes) {
+        if (N.is<Stmt*>())
+          return true;
+        // Expression with void type is statement-like.
+        else if (N.is<Expr*>()) {
+          auto *E = N.get<Expr*>();
+          if (auto T = E->getType()) {
+            if (T->isVoid())
+              return true;
+          }
+        } else {
+          // Decls are statement like.
+          return true;
+        }
+      }
+      return false;
+    }
+public:
+    bool hasStmtMatch(RangeMatchKind Kind) {
+      switch(Kind) {
+      case RangeMatchKind::NoneMatch:
+      case RangeMatchKind::RangeMatch:
+        llvm_unreachable("cannot answer these.");
+      case RangeMatchKind::StartMatch:
+        return hasStmtlikeNode(StartMatches);
+      case RangeMatchKind::EndMatch:
+        return hasStmtlikeNode(EndMatches);
+      }
+    }
   };
 
   std::vector<Token> AllTokens;
@@ -654,7 +685,11 @@
       }
     }
 
-    if (!DCInfo.StartMatches.empty() && !DCInfo.EndMatches.empty()) {
+    // Check if the start and end matches have statement-like entities; this
+    // can avoid picking expressions like "a == b" in a list of selected
+    // multi-statement at the start (or the end).
+    if (DCInfo.hasStmtMatch(RangeMatchKind::StartMatch) &&
+        DCInfo.hasStmtMatch(RangeMatchKind::EndMatch)) {
       postAnalysis(DCInfo.EndMatches.back());
       Result = {RangeKind::MultiStatement,
                 /* Last node has the type */
@@ -682,7 +717,7 @@
   ResolvedRangeInfo getResult() {
     if (Result.hasValue())
       return Result.getValue();
-    return ResolvedRangeInfo();
+    return ResolvedRangeInfo(Content);
   }
 
   void analyzeDeclRef(ValueDecl *VD, CharSourceRange Range, Type Ty,
@@ -784,7 +819,7 @@
 
 ResolvedRangeInfo RangeResolver::resolve() {
   if (!Impl)
-    return ResolvedRangeInfo();
+    return ResolvedRangeInfo(StringRef());
   Impl->enter(ASTNode());
   walk(Impl->File);
   return Impl->getResult();
diff --git a/lib/IRGen/GenArchetype.h b/lib/IRGen/GenArchetype.h
index 6baa977..7ef63cf 100644
--- a/lib/IRGen/GenArchetype.h
+++ b/lib/IRGen/GenArchetype.h
@@ -35,10 +35,6 @@
   using GetTypeParameterInContextFn =
     llvm::function_ref<CanType(CanType type)>;
 
-  void bindArchetypeAccessPaths(IRGenFunction &IGF,
-                                GenericSignature *generics,
-                                GetTypeParameterInContextFn getInContext);
-
   /// Emit a type metadata reference for an archetype.
   llvm::Value *emitArchetypeTypeMetadataRef(IRGenFunction &IGF,
                                             CanArchetypeType archetype);
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 51f6397..8786695 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -70,8 +70,8 @@
     case DeclKind::Struct:
       break;
     default:
-      // Keep all metadata for classes, because a class can be instanciated by
-      // using the library function _typeByName.
+      // Keep all metadata for classes, because a class can be instantiated by
+      // using the library function _typeByName or NSClassFromString.
       return false;
   }
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index c22f9d5..93f5a8b 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -2789,18 +2789,6 @@
   // use it to provide metadata for generic parameters in field types.
   IGF.bindLocalTypeDataFromTypeMetadata(formalType, IsExact, metadata);
   
-  // Bind archetype access paths if the type is generic.
-  if (type->isGenericContext()) {
-    auto declCtxt = type;
-    if (auto generics = declCtxt->getGenericSignatureOfContext()) {
-      auto getInContext = [&](CanType type) -> CanType {
-        return declCtxt->mapTypeIntoContext(type)
-            ->getCanonicalType();
-      };
-      bindArchetypeAccessPaths(IGF, generics, getInContext);
-    }
-  }
-
   // Allocate storage for the field vector.
   unsigned allocSize = fieldTypes.size() * IGM.getPointerSize().getValue();
   auto allocSizeVal = llvm::ConstantInt::get(IGM.IntPtrTy, allocSize);
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 923b9db..29879f8 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -1222,16 +1222,6 @@
       }
       return *Fulfillments;
     }
-
-    void bindArchetypeAccessPathsInConformance(IRGenFunction &IGF) {
-      auto declCtx = Conformance.getDeclContext();
-      if (auto generics = declCtx->getGenericSignatureOfContext()) {
-        auto getInContext = [&](CanType type) -> CanType {
-          return declCtx->mapTypeIntoContext(type)->getCanonicalType();
-        };
-        bindArchetypeAccessPaths(IGF, generics, getInContext);
-      }
-    }
   };
 } // end anonymous namespace
 
@@ -1286,9 +1276,6 @@
   // Bind local type data from the metadata argument.
   IGF.bindLocalTypeDataFromTypeMetadata(ConcreteType, IsExact, self);
 
-  // Bind archetype access paths.
-  bindArchetypeAccessPathsInConformance(IGF);
-
   // For now, assume that an associated type is cheap enough to access
   // that it doesn't need a new cache entry.
   if (auto archetype = dyn_cast<ArchetypeType>(associatedType)) {
@@ -1426,9 +1413,6 @@
                                         associatedTypeMetadata);
   IGF.bindLocalTypeDataFromTypeMetadata(ConcreteType, IsExact, self);
 
-  // Bind archetype access paths.
-  bindArchetypeAccessPathsInConformance(IGF);
-
   // For now, assume that finding an abstract conformance is always
   // fast enough that it's not worth caching.
   // TODO: provide an API to find the best metadata path to the conformance
@@ -1787,58 +1771,6 @@
   llvm_unreachable("Not a valid SILFunctionTypeRepresentation.");
 }
 
-static
-void addPotentialArchetypeAccessPath(IRGenFunction &IGF,
-                                     CanType targetDepType,
-                                     CanType sourceDepType,
-                                     GetTypeParameterInContextFn getInContext) {
-  assert(targetDepType->isTypeParameter());
-  assert(sourceDepType->isTypeParameter());
-
-  // We can only break down an associated-type path.
-  auto sourceDepMemberType = dyn_cast<DependentMemberType>(sourceDepType);
-  if (!sourceDepMemberType) return;
-
-  // We only really need to do this when there's a non-trivial set of
-  // conformances, but we can't determine that just from this decl:
-  // the associated type might gain conformances in a refining protocol.
-  auto association = sourceDepMemberType->getAssocType();
-
-  // These can end up as non-archetypes because of multiple levels of
-  // equality.
-  auto destArchetype =
-    dyn_cast<ArchetypeType>(getInContext(targetDepType));
-  if (!destArchetype) return;
-  auto srcBaseArchetype =
-    dyn_cast<ArchetypeType>(getInContext(sourceDepMemberType.getBase()));
-  if (!srcBaseArchetype) return;
-
-  IGF.addArchetypeAccessPath(destArchetype,
-                             {srcBaseArchetype, association});
-}
-
-void irgen::bindArchetypeAccessPaths(IRGenFunction &IGF, GenericSignature *Generics,
-                              GetTypeParameterInContextFn getInContext) {
-  // Remember all the extra ways we have of reaching the parameter
-  // archetypes due to type equality constraints.
-  for (auto reqt : Generics->getRequirements()) {
-    // Ignore non-same-type requirements in this pass.
-    if (reqt.getKind() != RequirementKind::SameType) continue;
-
-    // Ignore equality constraints to concrete types.  This is really
-    // just a fast-path; we still have to handle this case later.
-    // TODO: This might be a faster / better-cached way to materialize
-    // local type data for the concrete type.
-    if (!reqt.getSecondType()->isTypeParameter()) continue;
-
-    auto firstType = reqt.getFirstType()->getCanonicalType();
-    auto secondType = reqt.getSecondType()->getCanonicalType();
-
-    addPotentialArchetypeAccessPath(IGF, firstType, secondType, getInContext);
-    addPotentialArchetypeAccessPath(IGF, secondType, firstType, getInContext);
-  }
-}
-
 /// Emit a polymorphic parameters clause, binding all the metadata necessary.
 void EmitPolymorphicParameters::emit(Explosion &in,
                                      WitnessMetadata *witnessMetadata,
@@ -1860,29 +1792,8 @@
 
   // Bind all the fulfillments we can from the formal parameters.
   bindParameterSources(getParameter);
-
-  if (!Generics) return;
-  
-  // Bind all the archetype access paths.
-  bindArchetypeAccessPaths(IGF, Generics, getInContext);
 }
 
-void IRGenFunction::addArchetypeAccessPath(CanArchetypeType targetArchetype,
-                                           ArchetypeAccessPath accessPath) {
-  ArchetypeAccessPaths[targetArchetype].push_back(accessPath);
-}
-
-ArrayRef<IRGenFunction::ArchetypeAccessPath>
-IRGenFunction::getArchetypeAccessPaths(CanArchetypeType targetArchetype) {
-  auto it = ArchetypeAccessPaths.find(targetArchetype);
-  if (it == ArchetypeAccessPaths.end()) {
-    return {};
-  } else {
-    return it->second;
-  }
-}
-
-
 llvm::Value *
 MetadataPath::followFromTypeMetadata(IRGenFunction &IGF,
                                      CanType sourceType,
@@ -2716,12 +2627,6 @@
                                              Address buffer,
                                     GetTypeParameterInContextFn getInContext) {
   bindFromGenericRequirementsBuffer(IGF, Requirements, buffer, getInContext);
-
-  auto Generics = TheDecl->getGenericSignature();
-  if (!Generics) return;
-
-  // Bind all the archetype access paths in the signature's requirements.
-  bindArchetypeAccessPaths(IGF, Generics, getInContext);
 }
 
 void irgen::bindFromGenericRequirementsBuffer(IRGenFunction &IGF,
diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h
index ed80d20..b7d636f 100644
--- a/lib/IRGen/IRGenFunction.h
+++ b/lib/IRGen/IRGenFunction.h
@@ -394,23 +394,6 @@
                      llvm::Value *metadata,
                      ArrayRef<llvm::Value*> wtables);
 
-  struct ArchetypeAccessPath {
-    CanArchetypeType BaseType;
-    AssociatedTypeDecl *Association;
-  };
-
-  /// Register an additional access path to the given archetype besides
-  /// (if applicable) just drilling down from its parent.
-  ///
-  /// This is necessary when an archetype gains conformances from an
-  /// associated type that it's been constrained to be equal to
-  /// but which is not simply its parent.
-  void addArchetypeAccessPath(CanArchetypeType targetArchetype,
-                              ArchetypeAccessPath accessPath);
-
-  ArrayRef<ArchetypeAccessPath>
-  getArchetypeAccessPaths(CanArchetypeType targetArchetype);
-
 //--- Type emission ------------------------------------------------------------
 public:
   /// Look up a local type data reference, returning null if no entry was
@@ -581,9 +564,6 @@
   llvm::Value *LocalSelf = nullptr;
   
   LocalSelfKind SelfKind;
-
-  llvm::DenseMap<CanType, std::vector<ArchetypeAccessPath>>
-  ArchetypeAccessPaths;
 };
 
 using ConditionalDominanceScope = IRGenFunction::ConditionalDominanceScope;
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 43462fb..68b2f01 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -727,14 +727,24 @@
 }
 
 bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {
-  bool isWholeModule = PrimaryIGM->getSILModule().isWholeModule();
-  if (isPossiblyUsedExternally(wt->getLinkage(), isWholeModule))
-    return false;
-
   if (Opts.UseJIT)
     return false;
 
-  return true;
+  NominalTypeDecl *ConformingTy =
+    wt->getConformance()->getType()->getNominalOrBoundGenericNominal();
+
+  switch (ConformingTy->getEffectiveAccess()) {
+    case Accessibility::Private:
+    case Accessibility::FilePrivate:
+      return true;
+
+    case Accessibility::Internal:
+      return PrimaryIGM->getSILModule().isWholeModule();
+
+    default:
+      return false;
+  }
+  llvm_unreachable("switch does not handle all cases");
 }
 
 void IRGenerator::addLazyWitnessTable(const ProtocolConformance *Conf) {
diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp
index 821cde6..4ba1480 100644
--- a/lib/Index/Index.cpp
+++ b/lib/Index/Index.cpp
@@ -56,7 +56,7 @@
 }
 
 static bool printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS) {
-  if (!D->hasName()) {
+  if (!D->hasName() && !isa<ParamDecl>(D)) {
     auto *FD = dyn_cast<FuncDecl>(D);
     if (!FD || FD->getAccessorKind() == AccessorKind::NotAccessor)
       return true;
@@ -401,10 +401,10 @@
     return SrcMgr.getLineAndColumn(Loc, BufferID);
   }
 
-  bool shouldIndex(ValueDecl *D) const {
+  bool shouldIndex(ValueDecl *D, bool IsRef) const {
     if (D->isImplicit())
       return false;
-    if (isLocal(D))
+    if (isLocalSymbol(D) && (!isa<ParamDecl>(D) || IsRef))
       return false;
     if (D->isPrivateStdlibDecl())
       return false;
@@ -412,11 +412,6 @@
     return true;
   }
 
-  bool isLocal(ValueDecl *D) const {
-    return D->getDeclContext()->getLocalContext() &&
-      (!isa<ParamDecl>(D) || cast<ParamDecl>(D)->getArgumentNameLoc().isValid());
-  }
-
   void getModuleHash(SourceFileOrModule SFOrMod, llvm::raw_ostream &OS);
   llvm::hash_code hashModule(llvm::hash_code code, SourceFileOrModule SFOrMod);
   llvm::hash_code hashFileReference(llvm::hash_code code,
@@ -578,7 +573,7 @@
 }
 
 bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
-  if (!shouldIndex(D))
+  if (!shouldIndex(D, /*IsRef=*/false))
     return false;
 
   SourceLoc Loc = D->getLoc();
@@ -631,7 +626,7 @@
 
 bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit,
                                            SymbolRoleSet Relations, Decl *Related) {
-  if (!shouldIndex(D))
+  if (!shouldIndex(D, /*IsRef=*/true))
     return true;
 
   IndexSymbol Info;
@@ -697,7 +692,7 @@
 bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
                                                AccessorKind AccKind, bool IsRef,
                                                SourceLoc Loc) {
-  if (!shouldIndex(D))
+  if (!shouldIndex(D, IsRef))
     return true; // continue walking.
 
   auto updateInfo = [this, D, AccKind](IndexSymbol &Info) {
@@ -765,7 +760,7 @@
   NominalTypeDecl *NTD = D->getExtendedType()->getAnyNominal();
   if (!NTD)
     return true;
-  if (!shouldIndex(NTD))
+  if (!shouldIndex(NTD, /*IsRef=*/false))
     return true;
 
   IndexSymbol Info;
@@ -850,7 +845,7 @@
 
 bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
                                     IndexSymbol &Info) {
-  if (!shouldIndex(D))
+  if (!shouldIndex(D, /*IsRef=*/true))
     return true; // keep walking
 
   if (isa<AbstractFunctionDecl>(D)) {
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index 38a9555..3f19c21 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -208,6 +208,10 @@
       break;
   }
 
+  if (isLocalSymbol(D)) {
+    info.Properties |= SymbolProperty::Local;
+  }
+
   return info;
 }
 
@@ -227,3 +231,8 @@
 
   llvm_unreachable("Unhandled AccessorKind in switch.");
 }
+
+bool index::isLocalSymbol(const swift::Decl *D) {
+  return D->getDeclContext()->getLocalContext() &&
+    (!isa<ParamDecl>(D) || cast<ParamDecl>(D)->getArgumentNameLoc().isValid());
+}
diff --git a/lib/Parse/ParseSIL.cpp b/lib/Parse/ParseSIL.cpp
index b4cb238..dc92668 100644
--- a/lib/Parse/ParseSIL.cpp
+++ b/lib/Parse/ParseSIL.cpp
@@ -2481,9 +2481,34 @@
     break;
   }
 
+  case ValueKind::UnconditionalCheckedCastValueInst: {
+    CastConsumptionKind consumptionKind;
+    Identifier consumptionKindToken;
+    SourceLoc consumptionKindLoc;
+    SILType ty;
+    SILValue destVal;
+    Identifier toToken;
+    SourceLoc toLoc;
+    if (parseSILIdentifier(consumptionKindToken, consumptionKindLoc,
+                           diag::expected_tok_in_sil_instr,
+                           "cast consumption kind") ||
+        parseCastConsumptionKind(consumptionKindToken, consumptionKindLoc,
+                                 consumptionKind))
+      return true;
+
+    if (parseTypedValueRef(Val, B) || parseVerbatim("to") || parseSILType(ty))
+      return true;
+
+    if (parseSILDebugLocation(InstLoc, B))
+      return true;
+
+    ResultVal = B.createUnconditionalCheckedCastValue(InstLoc, consumptionKind,
+                                                      Val, ty);
+    break;
+  }
+
   // Checked Conversion instructions.
   case ValueKind::UnconditionalCheckedCastInst:
-  case ValueKind::UnconditionalCheckedCastValueInst:
   case ValueKind::CheckedCastValueBranchInst:
   case ValueKind::CheckedCastBranchInst: {
     SILType ty;
@@ -2507,11 +2532,6 @@
         return true;
       ResultVal = B.createUnconditionalCheckedCast(InstLoc, Val, ty);
       break;
-    } else if (Opcode == ValueKind::UnconditionalCheckedCastValueInst) {
-      if (parseSILDebugLocation(InstLoc, B))
-        return true;
-      ResultVal = B.createUnconditionalCheckedCastValue(InstLoc, Val, ty);
-      break;
     }
     // The conditional cast still needs its branch destinations.
     Identifier successBBName, failureBBName;
diff --git a/lib/SIL/AbstractionPattern.cpp b/lib/SIL/AbstractionPattern.cpp
index f55df92..d007a0f 100644
--- a/lib/SIL/AbstractionPattern.cpp
+++ b/lib/SIL/AbstractionPattern.cpp
@@ -587,7 +587,7 @@
   llvm_unreachable("bad kind");  
 }
 
-AbstractionPattern AbstractionPattern::getLValueObjectType() const {
+AbstractionPattern AbstractionPattern::getLValueOrInOutObjectType() const {
   switch (getKind()) {
   case Kind::Invalid:
     llvm_unreachable("querying invalid abstraction pattern!");
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 3246a39..d31ec6f 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -1818,7 +1818,7 @@
   // is concrete) but the derived member is generic (because the derived
   // class is generic).
   if (auto derivedInterfaceFnTy = derivedInterfaceTy->getAs<GenericFunctionType>()) {
-    auto overrideInterfaceFnTy = overrideInterfaceTy->castTo<AnyFunctionType>();
+    auto overrideInterfaceFnTy = overrideInterfaceTy->castTo<FunctionType>();
     overrideInterfaceTy =
         GenericFunctionType::get(derivedInterfaceFnTy->getGenericSignature(),
                                  overrideInterfaceFnTy->getInput(),
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 7f8c834..e325f2e 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -1775,7 +1775,8 @@
 }
 
 UnconditionalCheckedCastValueInst *UnconditionalCheckedCastValueInst::create(
-    SILDebugLocation DebugLoc, SILValue Operand, SILType DestTy, SILFunction &F,
+    SILDebugLocation DebugLoc, CastConsumptionKind consumption,
+    SILValue Operand, SILType DestTy, SILFunction &F,
     SILOpenedArchetypesState &OpenedArchetypes) {
   SILModule &Mod = F.getModule();
   SmallVector<SILValue, 8> TypeDependentOperands;
@@ -1786,7 +1787,7 @@
   void *Buffer =
       Mod.allocateInst(size, alignof(UnconditionalCheckedCastValueInst));
   return ::new (Buffer) UnconditionalCheckedCastValueInst(
-      DebugLoc, Operand, TypeDependentOperands, DestTy);
+      DebugLoc, consumption, Operand, TypeDependentOperands, DestTy);
 }
 
 CheckedCastBranchInst *CheckedCastBranchInst::create(
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index c93d2f1..8289d99 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -1224,7 +1224,8 @@
 
   void visitUnconditionalCheckedCastValueInst(
       UnconditionalCheckedCastValueInst *CI) {
-    *this << getIDAndType(CI->getOperand()) << " to " << CI->getType();
+    *this << getCastConsumptionKindName(CI->getConsumptionKind()) << ' '
+          << getIDAndType(CI->getOperand()) << " to " << CI->getType();
   }
 
   void visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CI) {
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index 9d5d511..9af8d21 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -1414,7 +1414,7 @@
 
     CanType loweredSubstEltType;
     if (auto substLV = dyn_cast<InOutType>(substEltType)) {
-      SILType silType = tc.getLoweredType(origType.getLValueObjectType(),
+      SILType silType = tc.getLoweredType(origType.getLValueOrInOutObjectType(),
                                           substLV.getObjectType());
       loweredSubstEltType = CanInOutType::get(silType.getSwiftRValueType());
 
@@ -1498,7 +1498,7 @@
   if (isa<InOutType>(substType)) {
     // Derive SILType for InOutType from the object type.
     CanType substObjectType = substType.getLValueOrInOutObjectType();
-    AbstractionPattern origObjectType = origType.getLValueObjectType();
+    AbstractionPattern origObjectType = origType.getLValueOrInOutObjectType();
 
     SILType loweredType = getLoweredType(origObjectType, substObjectType)
       .getAddressType();
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 38aac04..3d1d391 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -188,35 +188,50 @@
     SILDeclRef Constant;
   };
   SILValue SelfValue;
-  SubstitutionList Substitutions;
   CanAnyFunctionType OrigFormalInterfaceType;
+  CanFunctionType SubstFormalInterfaceType;
+  SubstitutionList Substitutions;
   Optional<SmallVector<ManagedValue, 2>> Captures;
 
   // The pointer back to the AST node that produced the callee.
   SILLocation Loc;
 
-private:
+  static CanFunctionType
+  getSubstFormalInterfaceType(CanAnyFunctionType substFormalType,
+                              SubstitutionList subs) {
+    if (auto *gft = substFormalType->getAs<GenericFunctionType>()) {
+      return cast<FunctionType>(
+        gft->substGenericArgs(subs)
+          ->getCanonicalType());
+    }
 
-  Callee(ManagedValue indirectValue,
-         CanAnyFunctionType origFormalType,
-         SILLocation L)
-    : kind(Kind::IndirectValue),
-      IndirectValue(indirectValue),
-      OrigFormalInterfaceType(origFormalType),
-      Loc(L)
-  {}
+    return cast<FunctionType>(substFormalType);
+  }
 
   static CanAnyFunctionType getConstantFormalInterfaceType(SILGenFunction &SGF,
                                                            SILDeclRef fn) {
-    return SGF.SGM.Types.getConstantInfo(fn.atUncurryLevel(0))
-             .FormalInterfaceType;
+    return SGF.SGM.Types.getConstantInfo(fn).FormalInterfaceType;
   }
 
-  Callee(SILGenFunction &SGF, SILDeclRef standaloneFunction,
+  Callee(ManagedValue indirectValue,
+         CanAnyFunctionType origFormalType,
          SILLocation l)
+    : kind(Kind::IndirectValue),
+      IndirectValue(indirectValue),
+      OrigFormalInterfaceType(origFormalType),
+      SubstFormalInterfaceType(cast<FunctionType>(origFormalType)),
+      Loc(l)
+  {}
+
+  Callee(SILGenFunction &SGF, SILDeclRef standaloneFunction,
+         CanAnyFunctionType origFormalType,
+         CanAnyFunctionType substFormalType,
+         SubstitutionList subs, SILLocation l)
     : kind(Kind::StandaloneFunction), Constant(standaloneFunction),
-      OrigFormalInterfaceType(getConstantFormalInterfaceType(SGF,
-                                                           standaloneFunction)),
+      OrigFormalInterfaceType(origFormalType),
+      SubstFormalInterfaceType(getSubstFormalInterfaceType(substFormalType,
+                                                           subs)),
+      Substitutions(subs),
       Loc(l)
   {
   }
@@ -225,36 +240,19 @@
          SILGenFunction &SGF,
          SILValue selfValue,
          SILDeclRef methodName,
+         CanAnyFunctionType origFormalType,
+         CanAnyFunctionType substFormalType,
+         SubstitutionList subs,
          SILLocation l)
     : kind(methodKind), Constant(methodName), SelfValue(selfValue),
-      OrigFormalInterfaceType(getConstantFormalInterfaceType(SGF, methodName)),
+      OrigFormalInterfaceType(origFormalType),
+      SubstFormalInterfaceType(getSubstFormalInterfaceType(substFormalType,
+                                                           subs)),
+      Substitutions(subs),
       Loc(l)
   {
   }
 
-  CanArchetypeType getWitnessMethodSelfType() const {
-    return cast<ArchetypeType>(getSubstFormalType().getInput()
-        ->getRValueInstanceType()
-        ->getCanonicalType());
-  }
-
-  CanSILFunctionType getSubstFunctionType(SILGenModule &SGM,
-                                          CanSILFunctionType origFnType) const {
-    return origFnType->substGenericArgs(SGM.M, Substitutions);
-  }
-
-  /// Add the 'self' type to the substituted function type of this
-  /// dynamic callee.
-  void addDynamicCalleeSelfToFormalType(Type substFormalType) {
-    assert(kind == Kind::DynamicMethod);
-
-    OrigFormalInterfaceType
-      = getDynamicMethodFormalType(SelfValue,
-                                   Constant.getDecl(),
-                                   substFormalType);
-    assert(!OrigFormalInterfaceType->hasTypeParameter());
-  }
-
 public:
 
   static Callee forIndirect(ManagedValue indirectValue,
@@ -263,50 +261,64 @@
     return Callee(indirectValue, origFormalType, l);
   }
   static Callee forDirect(SILGenFunction &SGF, SILDeclRef c,
+                          SubstitutionList subs,
                           SILLocation l) {
-    return Callee(SGF, c, l);
+    auto formalType = getConstantFormalInterfaceType(SGF, c);
+    return Callee(SGF, c, formalType, formalType, subs, l);
   }
   static Callee forEnumElement(SILGenFunction &SGF, SILDeclRef c,
+                               SubstitutionList subs,
                                SILLocation l) {
     assert(isa<EnumElementDecl>(c.getDecl()));
-    return Callee(Kind::EnumElement, SGF, SILValue(), c, l);
+    auto formalType = getConstantFormalInterfaceType(SGF, c);
+    return Callee(Kind::EnumElement, SGF, SILValue(), c,
+                  formalType, formalType, subs, l);
   }
   static Callee forClassMethod(SILGenFunction &SGF, SILValue selfValue,
-                               SILDeclRef name,
+                               SILDeclRef c,
+                               SubstitutionList subs,
                                SILLocation l) {
-    return Callee(Kind::ClassMethod, SGF, selfValue, name, l);
+    auto base = c.getBaseOverriddenVTableEntry();
+    auto formalType = getConstantFormalInterfaceType(SGF, base);
+    auto substType = getConstantFormalInterfaceType(SGF, c);
+    return Callee(Kind::ClassMethod, SGF, selfValue, c,
+                  formalType, substType, subs, l);
   }
   static Callee forSuperMethod(SILGenFunction &SGF, SILValue selfValue,
-                               SILDeclRef name,
+                               SILDeclRef c,
+                               SubstitutionList subs,
                                SILLocation l) {
     while (auto *UI = dyn_cast<UpcastInst>(selfValue))
       selfValue = UI->getOperand();
 
-    return Callee(Kind::SuperMethod, SGF, selfValue, name, l);
+    auto formalType = getConstantFormalInterfaceType(SGF, c);
+    return Callee(Kind::SuperMethod, SGF, selfValue, c,
+                  formalType, formalType, subs, l);
   }
   static Callee forArchetype(SILGenFunction &SGF,
                              SILValue optOpeningInstruction,
                              CanType protocolSelfType,
-                             SILDeclRef name,
+                             SILDeclRef c,
+                             SubstitutionList subs,
                              SILLocation l) {
-    Callee callee(Kind::WitnessMethod, SGF, optOpeningInstruction, name, l);
-    return callee;
+    auto formalType = getConstantFormalInterfaceType(SGF, c);
+    return Callee(Kind::WitnessMethod, SGF, optOpeningInstruction, c,
+                  formalType, formalType, subs, l);
   }
   static Callee forDynamic(SILGenFunction &SGF, SILValue proto,
-                           SILDeclRef name, Type substFormalType,
+                           SILDeclRef c,
+                           Type substFormalType,
+                           SubstitutionList subs,
                            SILLocation l) {
-    Callee callee(Kind::DynamicMethod, SGF, proto, name, l);
-    callee.addDynamicCalleeSelfToFormalType(substFormalType);
-    return callee;
+    auto formalType = getDynamicMethodFormalType(proto,
+                                                 c.getDecl(),
+                                                 substFormalType);
+    return Callee(Kind::DynamicMethod, SGF, proto, c,
+                  formalType, formalType, subs, l);
   }
   Callee(Callee &&) = default;
   Callee &operator=(Callee &&) = default;
 
-  void setSubstitutions(SubstitutionList newSubs) {
-    assert(Substitutions.empty() && "Already have substitutions?");
-    Substitutions = newSubs;
-  }
-  
   void setCaptures(SmallVectorImpl<ManagedValue> &&captures) {
     Captures = std::move(captures);
   }
@@ -321,18 +333,12 @@
     return Captures.hasValue();
   }
 
-  CanAnyFunctionType getOrigFormalType() const {
-    return OrigFormalInterfaceType;
+  AbstractionPattern getOrigFormalType() const {
+    return AbstractionPattern(OrigFormalInterfaceType);
   }
 
   CanFunctionType getSubstFormalType() const {
-    if (auto *gft = OrigFormalInterfaceType->getAs<GenericFunctionType>()) {
-      return cast<FunctionType>(
-        gft->substGenericArgs(getSubstitutions())
-          ->getCanonicalType());
-    }
-
-    return cast<FunctionType>(OrigFormalInterfaceType);
+    return SubstFormalInterfaceType;
   }
 
   unsigned getNaturalUncurryLevel() const {
@@ -459,13 +465,13 @@
         break;
       }
 
-      // Look up the witness for the archetype.
       auto proto = Constant.getDecl()->getDeclContext()
-                                     ->getAsProtocolOrProtocolExtensionContext();
-      auto archetype = getWitnessMethodSelfType();
+        ->getAsProtocolOrProtocolExtensionContext();
+      auto lookupType = getSubstFormalType().getInput()
+        ->getRValueInstanceType()->getCanonicalType();
 
       SILValue fn = SGF.B.createWitnessMethod(Loc,
-                                  archetype,
+                                  lookupType,
                                   ProtocolConformanceRef(proto),
                                   *constant,
                                   constantInfo.getSILType(),
@@ -512,8 +518,9 @@
       foreignSelf = func->getImportAsMemberStatus();
     }
 
-    CanSILFunctionType substFnType =
-      getSubstFunctionType(SGF.SGM, mv.getType().castTo<SILFunctionType>());
+    auto substFnType =
+      mv.getType().castTo<SILFunctionType>()->substGenericArgs(
+        SGF.SGM.M, Substitutions);
 
     return std::make_tuple(mv, substFnType, foreignError, foreignSelf, options);
   }
@@ -570,17 +577,22 @@
 
 class ArchetypeCalleeBuilder {
   SILGenFunction &SGF;
-  SILLocation loc;
   ArgumentSource &selfValue;
+  SubstitutionList subs;
+  SILLocation loc;
   SILParameterInfo selfParam;
   AbstractFunctionDecl *fd;
   ProtocolDecl *protocol;
   SILDeclRef constant;
 
 public:
-  ArchetypeCalleeBuilder(SILGenFunction &SGF, SILLocation loc,
-                         SILDeclRef inputConstant, ArgumentSource &selfValue)
-      : SGF(SGF), loc(loc), selfValue(selfValue),
+  ArchetypeCalleeBuilder(SILGenFunction &SGF,
+                         SILDeclRef inputConstant,
+                         SubstitutionList subs,
+                         SILLocation loc,
+                         ArgumentSource &selfValue)
+      : SGF(SGF), selfValue(selfValue),
+        subs(subs), loc(loc),
         selfParam(), fd(cast<AbstractFunctionDecl>(inputConstant.getDecl())),
         protocol(cast<ProtocolDecl>(fd->getDeclContext())),
         constant(inputConstant.asForeign(protocol->isObjC())) {}
@@ -590,7 +602,7 @@
     // an opened type.
     SILValue openingSite;
     auto archetype =
-        cast<ArchetypeType>(CanType(getSelfType()->getRValueInstanceType()));
+        getSelfType()->getRValueInstanceType()->castTo<ArchetypeType>();
     if (archetype->getOpenedExistentialType()) {
       openingSite = SGF.getArchetypeOpeningSite(archetype);
     }
@@ -602,7 +614,8 @@
       setSelfValueToAddress(selfLoc, address);
     }
 
-    return Callee::forArchetype(SGF, openingSite, getSelfType(), constant, loc);
+    return Callee::forArchetype(SGF, openingSite, getSelfType(), constant,
+                                subs, loc);
   }
 
 private:
@@ -646,7 +659,7 @@
     if (!fd->isInstanceMember() ||
         protocol->requiresClass() ||
         selfValue.hasLValueType() ||
-        !cast<ArchetypeType>(selfValue.getSubstRValueType())->requiresClass())
+        !cast<ArchetypeType>(getSelfType())->requiresClass())
       return false;
 
     assert(SGF.silConv.useLoweredAddresses() ==
@@ -681,11 +694,13 @@
 
 } // end anonymous namespace
 
-static Callee prepareArchetypeCallee(SILGenFunction &SGF, SILLocation loc,
+static Callee prepareArchetypeCallee(SILGenFunction &SGF,
                                      SILDeclRef constant,
+                                     SubstitutionList subs,
+                                     SILLocation loc,
                                      ArgumentSource &selfValue) {
   // Construct an archetype call.
-  ArchetypeCalleeBuilder Builder{SGF, loc, constant, selfValue};
+  ArchetypeCalleeBuilder Builder{SGF, constant, subs, loc, selfValue};
   return Builder.build();
 }
 
@@ -894,17 +909,13 @@
         SILDeclRef constant = SILDeclRef(afd, kind);
 
         // Prepare the callee.  This can modify both selfValue and subs.
-        Callee theCallee = prepareArchetypeCallee(SGF, e, constant, selfValue);
+        Callee theCallee = prepareArchetypeCallee(SGF, constant, subs, e, selfValue);
         AssumedPlusZeroSelf = selfValue.isRValue()
           && selfValue.forceAndPeekRValue(SGF).peekIsPlusZeroRValueOrTrivial();
 
         setSelfParam(std::move(selfValue), thisCallSite);
         setCallee(std::move(theCallee));
 
-        // If there are substitutions, add them now.
-        if (!subs.empty())
-          ApplyCallee->setSubstitutions(subs);
-
         return;
       }
 
@@ -982,13 +993,8 @@
                             SILDeclRef::ConstructAtNaturalUncurryLevel,
                             requiresForeignEntryPoint(afd));
 
-        setCallee(Callee::forClassMethod(SGF, selfValue, constant, e));
-
-        // If there are substitutions, add them.
-        if (e->getDeclRef().isSpecialized()) {
-          ApplyCallee->setSubstitutions(e->getDeclRef().getSubstitutions());
-        }
-
+        auto subs = e->getDeclRef().getSubstitutions();
+        setCallee(Callee::forClassMethod(SGF, selfValue, constant, subs, e));
         return;
       }
     }
@@ -1006,24 +1012,24 @@
                         !isConstructorWithGeneratedAllocatorThunk(e->getDecl())
                           && requiresForeignEntryPoint(e->getDecl()));
 
+    auto afd = dyn_cast<AbstractFunctionDecl>(e->getDecl());
+
     // Otherwise, we have a statically-dispatched call.
     SubstitutionList subs;
-    if (e->getDeclRef().isSpecialized())
+    if (e->getDeclRef().isSpecialized() &&
+        (!afd ||
+         !afd->getDeclContext()->isLocalContext() ||
+         afd->getCaptureInfo().hasGenericParamCaptures()))
       subs = e->getDeclRef().getSubstitutions();
 
     // Enum case constructor references are open-coded.
     if (isa<EnumElementDecl>(e->getDecl()))
-      setCallee(Callee::forEnumElement(SGF, constant, e));
+      setCallee(Callee::forEnumElement(SGF, constant, subs, e));
     else
-      setCallee(Callee::forDirect(SGF, constant, e));
+      setCallee(Callee::forDirect(SGF, constant, subs, e));
     
     // If the decl ref requires captures, emit the capture params.
-    auto afd = dyn_cast<AbstractFunctionDecl>(e->getDecl());
     if (afd) {
-      // FIXME: We should be checking hasLocalCaptures() on the lowered
-      // captures in the constant info too, to generate more efficient
-      // code for mutually recursive local functions which otherwise
-      // capture no state.
       if (SGF.SGM.M.Types.hasLoweredLocalCaptures(afd)) {
         SmallVector<ManagedValue, 4> captures;
         SGF.emitCaptures(e, afd, CaptureEmission::ImmediateApplication,
@@ -1031,13 +1037,6 @@
         ApplyCallee->setCaptures(std::move(captures));
       }
     }
-
-    // If there are substitutions, add them.
-    if (!subs.empty() &&
-        (!afd ||
-         !afd->getDeclContext()->isLocalContext() ||
-         afd->getCaptureInfo().hasGenericParamCaptures()))
-      ApplyCallee->setSubstitutions(subs);
   }
   
   void visitAbstractClosureExpr(AbstractClosureExpr *e) {
@@ -1059,7 +1058,7 @@
     if (e->getCaptureInfo().hasGenericParamCaptures())
       subs = SGF.getForwardingSubstitutions();
 
-    setCallee(Callee::forDirect(SGF, constant, e));
+    setCallee(Callee::forDirect(SGF, constant, subs, e));
     
     // If the closure requires captures, emit them.
     bool hasCaptures = SGF.SGM.M.Types.hasLoweredLocalCaptures(e);
@@ -1069,21 +1068,16 @@
                        captures);
       ApplyCallee->setCaptures(std::move(captures));
     }
-    // If there are substitutions, add them.
-    if (!subs.empty())
-      ApplyCallee->setSubstitutions(subs);
   }
   
   void visitOtherConstructorDeclRefExpr(OtherConstructorDeclRefExpr *e) {
+    auto subs = e->getDeclRef().getSubstitutions();
+
     // FIXME: We might need to go through ObjC dispatch for references to
     // constructors imported from Clang (which won't have a direct entry point)
     // or to delegate to a designated initializer.
     setCallee(Callee::forDirect(SGF,
-                SILDeclRef(e->getDecl(), SILDeclRef::Kind::Initializer), e));
-
-    // If there are substitutions, add them.
-    if (e->getDeclRef().isSpecialized())
-      ApplyCallee->setSubstitutions(e->getDeclRef().getSubstitutions());
+                SILDeclRef(e->getDecl(), SILDeclRef::Kind::Initializer), subs, e));
   }
   void visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *e) {
     setSideEffect(e->getLHS());
@@ -1165,15 +1159,13 @@
 
     if (!canUseStaticDispatch(SGF, constant)) {
       // ObjC super calls require dynamic dispatch.
-      setCallee(Callee::forSuperMethod(SGF, super.getValue(), constant, fn));
+      setCallee(Callee::forSuperMethod(SGF, super.getValue(), constant,
+                                       substitutions, fn));
     } else {
       // Native Swift super calls to final methods are direct.
-      setCallee(Callee::forDirect(SGF, constant, fn));
+      setCallee(Callee::forDirect(SGF, constant,
+                                  substitutions, fn));
     }
-
-    // If there are any substitutions for the callee, apply them now.
-    if (!substitutions.empty())
-      ApplyCallee->setSubstitutions(substitutions);
   }
 
   /// Walk the given \c selfArg expression that produces the appropriate
@@ -1316,6 +1308,8 @@
     setSelfParam(ArgumentSource(arg, RValue(SGF, expr, selfFormalType, self)),
                  expr);
 
+    auto subs = ctorRef->getDeclRef().getSubstitutions();
+
     // Determine the callee. For structs and enums, this is the allocating
     // constructor (because there is no initializing constructor). For protocol
     // default implementations, we also use the allocating constructor, because
@@ -1334,7 +1328,9 @@
                              SILDeclRef::ConstructAtNaturalUncurryLevel,
                              requiresForeignEntryPoint(ctorRef->getDecl()));
       setCallee(Callee::forArchetype(SGF, SILValue(),
-                     self.getType().getSwiftRValueType(), constant, expr));
+                                     self.getType().getSwiftRValueType(),
+                                     constant, subs,
+                                     expr));
     } else if (getMethodDispatch(ctorRef->getDecl())
                  == MethodDispatch::Class) {
       // Dynamic dispatch to the initializer.
@@ -1348,6 +1344,7 @@
                              SILDeclRef::ConstructAtBestResilienceExpansion,
                              SILDeclRef::ConstructAtNaturalUncurryLevel,
                              requiresForeignEntryPoint(ctorRef->getDecl())),
+                  subs,
                   fn));
     } else {
       // Directly call the peer constructor.
@@ -1361,13 +1358,10 @@
                      SILDeclRef::ConstructAtBestResilienceExpansion,
                      SILDeclRef::ConstructAtNaturalUncurryLevel,
                      requiresForeignEntryPoint(ctorRef->getDecl())),
-            fn));
+          subs,
+          fn));
     }
 
-    // Set up the substitutions, if we have any.
-    if (ctorRef->getDeclRef().isSpecialized())
-      ApplyCallee->setSubstitutions(ctorRef->getDeclRef().getSubstitutions());
-
     return true;
   }
 
@@ -1460,7 +1454,7 @@
       auto substFormalType = dynamicMemberRef->getType()
           ->getAnyOptionalObjectType();
       setCallee(Callee::forDynamic(SGF, base.getValue(), member,
-                                   substFormalType, e));
+                                   substFormalType, {}, e));
     };
 
     // When we have an open existential, open it and then emit the
@@ -3823,7 +3817,7 @@
   ApplyOptions initialOptions = ApplyOptions::None;
 
   formalType = callee.getSubstFormalType();
-  origFormalType = AbstractionPattern(callee.getOrigFormalType());
+  origFormalType = callee.getOrigFormalType();
 
   // Get the callee type information.
   std::tie(mv, substFnType, foreignError, foreignSelf, initialOptions) =
@@ -3879,7 +3873,7 @@
   // pattern, to ensure that function types in payloads are re-abstracted
   // correctly.
   formalType = callee.getSubstFormalType();
-  origFormalType = AbstractionPattern(callee.getOrigFormalType());
+  origFormalType = callee.getOrigFormalType();
   substFnType = SGF.getSILFunctionType(origFormalType.getValue(), formalType,
                                        uncurryLevel);
 
@@ -4276,11 +4270,9 @@
   if (auto *genericSig = fn->getGenericSignature())
     genericSig->getSubstitutions(subMap, subs);
 
-  auto callee = Callee::forDirect(*this, SILDeclRef(fn), loc);
-  callee.setSubstitutions(subs);
+  auto callee = Callee::forDirect(*this, SILDeclRef(fn), subs, loc);
 
-  auto origFormalType =
-    cast<AnyFunctionType>(fn->getInterfaceType()->getCanonicalType());
+  auto origFormalType = callee.getOrigFormalType();
   auto substFormalType = callee.getSubstFormalType();
 
   ManagedValue mv;
@@ -4297,7 +4289,7 @@
            == SILFunctionLanguage::Swift);
 
   CalleeTypeInfo calleeTypeInfo(
-      substFnType, AbstractionPattern(origFormalType).getFunctionResultType(),
+      substFnType, origFormalType.getFunctionResultType(),
       substFormalType.getResult());
   ResultPlanPtr resultPlan =
       ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, ctx);
@@ -4376,12 +4368,10 @@
                               RValue(SGF, loc,
                                      selfMetaVal.getType().getSwiftRValueType(),
                                      selfMetaVal));
-    callee.emplace(prepareArchetypeCallee(SGF, loc, initRef, selfSource));
+    callee.emplace(prepareArchetypeCallee(SGF, initRef, subs, loc, selfSource));
   } else {
-    callee.emplace(Callee::forDirect(SGF, initRef, loc));
+    callee.emplace(Callee::forDirect(SGF, initRef, subs, loc));
   }
-  if (!subs.empty())
-    callee->setSubstitutions(subs);
 
   auto substFormalType = callee->getSubstFormalType();
 
@@ -4592,7 +4582,8 @@
                                          SILDeclRef constant,
                                          ArgumentSource &selfValue,
                                          bool isSuper,
-                                         bool isDirectUse) {
+                                         bool isDirectUse,
+                                         SubstitutionList subs) {
   auto *decl = cast<AbstractFunctionDecl>(constant.getDecl());
 
   // If this is a method in a protocol, generate it as a protocol call.
@@ -4600,7 +4591,7 @@
     assert(!isDirectUse && "direct use of protocol accessor?");
     assert(!isSuper && "super call to protocol method?");
 
-    return prepareArchetypeCallee(SGF, loc, constant, selfValue);
+    return prepareArchetypeCallee(SGF, constant, subs, loc, selfValue);
   }
 
   bool isClassDispatch = false;
@@ -4617,20 +4608,20 @@
 
   // Dispatch in a struct/enum or to a final method is always direct.
   if (!isClassDispatch || decl->isFinal())
-    return Callee::forDirect(SGF, constant, loc);
+    return Callee::forDirect(SGF, constant, subs, loc);
 
   // Otherwise, if we have a non-final class dispatch to a normal method,
   // perform a dynamic dispatch.
   auto self = selfValue.forceAndPeekRValue(SGF).peekScalarValue();
   if (!isSuper)
-    return Callee::forClassMethod(SGF, self, constant, loc);
+    return Callee::forClassMethod(SGF, self, constant, subs, loc);
 
   // If this is a "super." dispatch, we do a dynamic dispatch for objc methods
   // or non-final native Swift methods.
   if (!canUseStaticDispatch(SGF, constant))
-    return Callee::forSuperMethod(SGF, self, constant, loc);
+    return Callee::forSuperMethod(SGF, self, constant, subs, loc);
 
-  return Callee::forDirect(SGF, constant, loc);
+  return Callee::forDirect(SGF, constant, subs, loc);
 }
 
 static Callee
@@ -4645,7 +4636,8 @@
   // Get the accessor function. The type will be a polymorphic function if
   // the Self type is generic.
   Callee callee = getBaseAccessorFunctionRef(SGF, loc, constant, selfValue,
-                                             isSuper, isDirectUse);
+                                             isSuper, isDirectUse,
+                                             substitutions);
   
   // Collect captures if the accessor has them.
   auto accessorFn = cast<AbstractFunctionDecl>(constant.getDecl());
@@ -4657,10 +4649,6 @@
     callee.setCaptures(std::move(captures));
   }
 
-  // If there are substitutions, specialize the generic accessor.
-  if (!substitutions.empty()) {
-    callee.setSubstitutions(substitutions);
-  }
   return callee;
 }
 
@@ -4988,8 +4976,7 @@
                                                      isSuper, isDirectUse);
   bool hasCaptures = callee.hasCaptures();
   bool hasSelf = (bool)selfValue;
-  CanAnyFunctionType accessType = callee.getSubstFormalType();
-  CanAnyFunctionType origAccessType = callee.getOrigFormalType();
+  auto accessType = callee.getSubstFormalType();
 
   CallEmission emission(*this, std::move(callee), std::move(writebackScope));
   // Self ->
@@ -4998,7 +4985,7 @@
   }
   // TODO: Have Callee encapsulate the captures better.
   if (hasSelf || hasCaptures) {
-    accessType = cast<AnyFunctionType>(accessType.getResult());
+    accessType = cast<FunctionType>(accessType.getResult());
   }
 
   // (buffer, callbackStorage)  or (buffer, callbackStorage, indices) ->
@@ -5034,9 +5021,13 @@
   // Project out the optional callback.
   SILValue optionalCallback = results[1].getUnmanagedValue();
 
-  CanType origSelfType = origAccessType->getInput()
+  auto origAccessType = SGM.Types.getConstantInfo(materializeForSet)
+      .FormalInterfaceType;
+
+  auto origSelfType = origAccessType->getInput()
       ->getInOutObjectType()
       ->getCanonicalType();
+
   CanGenericSignature genericSig;
   if (auto genericFnType = dyn_cast<GenericFunctionType>(origAccessType))
     genericSig = genericFnType.getGenericSignature();
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index 733bbb7..fa4768e 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -546,9 +546,10 @@
 }
 
 ManagedValue SILGenBuilder::createUnconditionalCheckedCastValue(
-    SILLocation loc, ManagedValue operand, SILType type) {
+    SILLocation loc, CastConsumptionKind consumption, ManagedValue operand,
+    SILType type) {
   SILValue result = SILBuilder::createUnconditionalCheckedCastValue(
-      loc, operand.forward(SGF), type);
+      loc, consumption, operand.forward(SGF), type);
   return SGF.emitManagedRValueWithCleanup(result);
 }
 
diff --git a/lib/SILGen/SILGenBuilder.h b/lib/SILGen/SILGenBuilder.h
index 2bafb16..8ee5a32 100644
--- a/lib/SILGen/SILGenBuilder.h
+++ b/lib/SILGen/SILGenBuilder.h
@@ -224,9 +224,10 @@
       SGFContext context, std::function<void(SILValue)> rvalueEmitter);
 
   using SILBuilder::createUnconditionalCheckedCastValue;
-  ManagedValue createUnconditionalCheckedCastValue(SILLocation loc,
-                                                   ManagedValue operand,
-                                                   SILType type);
+  ManagedValue
+  createUnconditionalCheckedCastValue(SILLocation loc,
+                                      CastConsumptionKind consumption,
+                                      ManagedValue operand, SILType type);
   using SILBuilder::createUnconditionalCheckedCast;
   ManagedValue createUnconditionalCheckedCast(SILLocation loc,
                                               ManagedValue operand,
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index fc45cd9..42cf6b4 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -88,7 +88,7 @@
 
   // Emit the indirect return argument, if any.
   SILValue resultSlot;
-  if (selfTy.isAddressOnly(gen.SGM.M)) {
+  if (selfTy.isAddressOnly(gen.SGM.M) && gen.silConv.useLoweredAddresses()) {
     auto &AC = gen.getASTContext();
     auto VD = new (AC) ParamDecl(/*IsLet*/ false, SourceLoc(), SourceLoc(),
                                  AC.getIdentifier("$return_value"),
diff --git a/lib/SILGen/SILGenConvert.cpp b/lib/SILGen/SILGenConvert.cpp
index 09154f5..ceb049c 100644
--- a/lib/SILGen/SILGenConvert.cpp
+++ b/lib/SILGen/SILGenConvert.cpp
@@ -760,7 +760,7 @@
 SILGenFunction::emitOpenExistential(
        SILLocation loc,
        ManagedValue existentialValue,
-       CanArchetypeType openedArchetype,
+       ArchetypeType *openedArchetype,
        SILType loweredOpenedType,
        AccessKind accessKind) {
   // Open the existential value into the opened archetype value.
diff --git a/lib/SILGen/SILGenDynamicCast.cpp b/lib/SILGen/SILGenDynamicCast.cpp
index 36efd7c..f6dd0ee 100644
--- a/lib/SILGen/SILGenDynamicCast.cpp
+++ b/lib/SILGen/SILGenDynamicCast.cpp
@@ -102,7 +102,8 @@
       ManagedValue result;
       if (Strategy == CastStrategy::Address) {
         result = SGF.B.createUnconditionalCheckedCastValue(
-            Loc, operand, origTargetTL.getLoweredType());
+            Loc, CastConsumptionKind::TakeAlways, operand,
+            origTargetTL.getLoweredType());
       } else {
         result = SGF.B.createUnconditionalCheckedCast(
             Loc, operand, origTargetTL.getLoweredType());
@@ -388,7 +389,8 @@
       SILValue resultScalar;
       if (Strategy == CastStrategy::Address) {
         resultScalar = SGF.B.createUnconditionalCheckedCastValue(
-            Loc, operand.forward(SGF), origTargetTL.getLoweredType());
+            Loc, CastConsumptionKind::TakeAlways, operand.forward(SGF),
+            origTargetTL.getLoweredType());
       } else {
         resultScalar = SGF.B.createUnconditionalCheckedCast(
             Loc, operand.forward(SGF), origTargetTL.getLoweredType());
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 4a7796b..0c8f157 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -3548,7 +3548,7 @@
   
   Type opaqueValueType = E->getOpaqueValue()->getType()->getRValueType();
   SILGenFunction::OpaqueValueState state = emitOpenExistential(
-      E, existentialValue, CanArchetypeType(E->getOpenedArchetype()),
+      E, existentialValue, E->getOpenedArchetype(),
       getLoweredType(opaqueValueType), accessKind);
 
   // Register the opaque value for the projected existential.
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index d103771..2649e24 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -884,16 +884,16 @@
 
   /// OpenedArchetypes - Mappings of opened archetypes back to the
   /// instruction which opened them.
-  llvm::DenseMap<CanType, SILValue> ArchetypeOpenings;
+  llvm::DenseMap<ArchetypeType *, SILValue> ArchetypeOpenings;
 
-  SILValue getArchetypeOpeningSite(CanArchetypeType archetype) const {
+  SILValue getArchetypeOpeningSite(ArchetypeType *archetype) const {
     auto it = ArchetypeOpenings.find(archetype);
     assert(it != ArchetypeOpenings.end() &&
            "opened archetype was not registered with SILGenFunction");
     return it->second;
   }
 
-  void setArchetypeOpeningSite(CanArchetypeType archetype, SILValue site) {
+  void setArchetypeOpeningSite(ArchetypeType *archetype, SILValue site) {
     ArchetypeOpenings.insert({archetype, site});
   }
 
@@ -916,7 +916,7 @@
   SILGenFunction::OpaqueValueState
   emitOpenExistential(SILLocation loc,
                       ManagedValue existentialValue,
-                      CanArchetypeType openedArchetype,
+                      ArchetypeType *openedArchetype,
                       SILType loweredOpenedType,
                       AccessKind accessKind);
 
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index fb3ea52..5577666 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -176,10 +176,10 @@
   return M->getASTContext().AllocateCopy(conformances);
 }
 
-static CanArchetypeType getOpenedArchetype(Type openedType) {
-  while (auto metatypeTy = openedType->getAs<MetatypeType>())
-    openedType = metatypeTy->getInstanceType();
-  return cast<ArchetypeType>(openedType->getCanonicalType());
+static ArchetypeType *getOpenedArchetype(CanType openedType) {
+  while (auto metatypeTy = dyn_cast<MetatypeType>(openedType))
+    openedType = metatypeTy.getInstanceType();
+  return cast<ArchetypeType>(openedType);
 }
 
 static ManagedValue emitTransformExistential(SILGenFunction &SGF,
@@ -191,7 +191,7 @@
   assert(inputType != outputType);
 
   SILGenFunction::OpaqueValueState state;
-  CanArchetypeType openedArchetype;
+  ArchetypeType *openedArchetype = nullptr;
 
   if (inputType->isAnyExistentialType()) {
     CanType openedType = ArchetypeType::getAnyOpened(inputType);
diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp
index acfa77a..3665886 100644
--- a/lib/SILOptimizer/IPO/CapturePropagation.cpp
+++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp
@@ -11,12 +11,15 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "capture-prop"
+#include "swift/AST/GenericEnvironment.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SILOptimizer/Utils/Generics.h"
 #include "swift/SILOptimizer/Utils/SpecializationMangler.h"
 #include "swift/Demangling/Demangle.h"
 #include "swift/SIL/Mangle.h"
 #include "swift/SIL/SILCloner.h"
 #include "swift/SIL/SILInstruction.h"
+#include "swift/SIL/TypeSubstCloner.h"
 #include "swift/SILOptimizer/Analysis/ColdBlockInfo.h"
 #include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
@@ -99,16 +102,17 @@
 /// caller, so the cloned function will have a mix of locations from different
 /// functions.
 class CapturePropagationCloner
-  : public SILClonerWithScopes<CapturePropagationCloner> {
-  using SuperTy = SILClonerWithScopes<CapturePropagationCloner>;
+  : public TypeSubstCloner<CapturePropagationCloner> {
+  using SuperTy = TypeSubstCloner<CapturePropagationCloner>;
   friend class SILVisitor<CapturePropagationCloner>;
   friend class SILCloner<CapturePropagationCloner>;
 
   SILFunction *OrigF;
   bool IsCloningConstant;
 public:
-  CapturePropagationCloner(SILFunction *OrigF, SILFunction *NewF)
-    : SuperTy(*NewF), OrigF(OrigF), IsCloningConstant(false) {}
+  CapturePropagationCloner(SILFunction *OrigF, SILFunction *NewF,
+                           SubstitutionList Subs)
+      : SuperTy(*NewF, *OrigF, Subs), OrigF(OrigF), IsCloningConstant(false) {}
 
   void cloneBlocks(OperandValueArrayRef Args);
 
@@ -219,6 +223,20 @@
   }
 }
 
+CanSILFunctionType getPartialApplyInterfaceResultType(PartialApplyInst *PAI) {
+  SILFunction *OrigF = PAI->getReferencedFunction();
+  // The new partial_apply will no longer take any arguments--they are all
+  // expressed as literals. So its callee signature will be the same as its
+  // return signature.
+  auto FTy = PAI->getType().castTo<SILFunctionType>();
+  CanGenericSignature CanGenericSig;
+  assert(!PAI->hasSubstitutions() || !hasArchetypes(PAI->getSubstitutions()));
+  FTy = cast<SILFunctionType>(
+    OrigF->mapTypeOutOfContext(FTy)->getCanonicalType());
+  auto NewFTy = FTy;
+  return NewFTy;
+}
+
 /// Given a partial_apply instruction, create a specialized callee by removing
 /// all constant arguments and adding constant literals to the specialized
 /// function body.
@@ -243,12 +261,16 @@
   // The new partial_apply will no longer take any arguments--they are all
   // expressed as literals. So its callee signature will be the same as its
   // return signature.
-  CanSILFunctionType NewFTy =
-    Lowering::adjustFunctionType(PAI->getType().castTo<SILFunctionType>(),
-                                 SILFunctionType::Representation::Thin);
+  auto NewFTy = getPartialApplyInterfaceResultType(PAI);
+  NewFTy = Lowering::adjustFunctionType(NewFTy,
+                                        SILFunctionType::Representation::Thin);
+
+  GenericEnvironment *GenericEnv = nullptr;
+  if (NewFTy->getGenericSignature())
+    GenericEnv = OrigF->getGenericEnvironment();
   SILFunction *NewF = OrigF->getModule().createFunction(
       SILLinkage::Shared, Name, NewFTy,
-      OrigF->getGenericEnvironment(), OrigF->getLocation(), OrigF->isBare(),
+      GenericEnv, OrigF->getLocation(), OrigF->isBare(),
       OrigF->isTransparent(), Fragile, OrigF->isThunk(),
       OrigF->getClassVisibility(), OrigF->getInlineStrategy(),
       OrigF->getEffectsKind(),
@@ -259,7 +281,11 @@
   DEBUG(llvm::dbgs() << "  Specialize callee as ";
         NewF->printName(llvm::dbgs()); llvm::dbgs() << " " << NewFTy << "\n");
 
-  CapturePropagationCloner cloner(OrigF, NewF);
+  DEBUG(if (PAI->hasSubstitutions()) {
+    llvm::dbgs() << "CapturePropagation of generic partial_apply:\n";
+    PAI->dumpInContext();
+  });
+  CapturePropagationCloner cloner(OrigF, NewF, PAI->getSubstitutions());
   cloner.cloneBlocks(PAI->getArguments());
   assert(OrigF->getDebugScope()->Parent != NewF->getDebugScope()->Parent);
   return NewF;
@@ -267,10 +293,16 @@
 
 void CapturePropagation::rewritePartialApply(PartialApplyInst *OrigPAI,
                                              SILFunction *SpecialF) {
+  DEBUG(llvm::dbgs() << "\n  Rewriting a partial apply:\n";
+        OrigPAI->dumpInContext(); llvm::dbgs() << "   with special function: "
+                                               << SpecialF->getName() << "\n";
+        llvm::dbgs() << "\nThe function being rewritten is:\n";
+        OrigPAI->getFunction()->dump());
+
   SILBuilderWithScope Builder(OrigPAI);
   auto FuncRef = Builder.createFunctionRef(OrigPAI->getLoc(), SpecialF);
-  auto *T2TF = Builder.createThinToThickFunction(OrigPAI->getLoc(),
-                                                 FuncRef, OrigPAI->getType());
+  auto *T2TF = Builder.createThinToThickFunction(OrigPAI->getLoc(), FuncRef,
+                                                 OrigPAI->getType());
   OrigPAI->replaceAllUsesWith(T2TF);
   recursivelyDeleteTriviallyDeadInstructions(OrigPAI, true);
   DEBUG(llvm::dbgs() << "  Rewrote caller:\n" << *T2TF);
@@ -311,12 +343,16 @@
 
 /// Checks if \p Orig is a thunk which calls another function but without
 /// passing the trailing \p numDeadParams dead parameters.
-static SILFunction *getSpecializedWithDeadParams(SILFunction *Orig,
-                                                 int numDeadParams) {
+/// If a generic specialization was performed for a generic capture,
+/// GenericSpecialized contains a tuple:
+/// (new specialized function, old function)
+static SILFunction *getSpecializedWithDeadParams(
+    PartialApplyInst *PAI, SILFunction *Orig, int numDeadParams,
+    std::pair<SILFunction *, SILFunction *> &GenericSpecialized) {
   SILBasicBlock &EntryBB = *Orig->begin();
   unsigned NumArgs = EntryBB.getNumArguments();
   SILModule &M = Orig->getModule();
-  
+
   // Check if all dead parameters have trivial types. We don't support non-
   // trivial types because it's very hard to find places where we can release
   // those parameters (as a replacement for the removed partial_apply).
@@ -328,20 +364,20 @@
   }
   SILFunction *Specialized = nullptr;
   SILValue RetValue;
-  
+
   // Check all instruction of the entry block.
   for (SILInstruction &I : EntryBB) {
     if (auto FAS = FullApplySite::isa(&I)) {
-      
       // Check if this is the call of the specialized function.
-      // As the original function is not generic, also the specialized function
-      // must be not generic.
-      if (FAS.hasSubstitutions())
+      // If the original partial_apply didn't have substitutions,
+      // also the specialized function must be not generic.
+      if (!PAI->hasSubstitutions() && FAS.hasSubstitutions())
         return nullptr;
+
       // Is it the only call?
       if (Specialized)
         return nullptr;
-      
+
       Specialized = FAS.getReferencedFunction();
       if (!Specialized)
         return nullptr;
@@ -376,29 +412,54 @@
     if (I.mayHaveSideEffects() || isa<TermInst>(&I))
       return nullptr;
   }
+
+  GenericSpecialized = std::make_pair(nullptr, nullptr);
+
+  if (PAI->hasSubstitutions()) {
+    if (Specialized->isExternalDeclaration())
+      return nullptr;
+    // Perform a generic specialization of the Specialized function.
+    ReabstractionInfo ReInfo(ApplySite(), Specialized, PAI->getSubstitutions(),
+                             /* ConvertIndirectToDirect */ false);
+    GenericFuncSpecializer FuncSpecializer(Specialized,
+                                           ReInfo.getClonerParamSubstitutions(),
+                                           Specialized->isFragile(), ReInfo);
+
+    SILFunction *GenericSpecializedFunc = FuncSpecializer.trySpecialization();
+    if (!GenericSpecializedFunc)
+      return nullptr;
+    GenericSpecialized = std::make_pair(GenericSpecializedFunc, Specialized);
+    return GenericSpecializedFunc;
+  }
   return Specialized;
 }
 
 bool CapturePropagation::optimizePartialApply(PartialApplyInst *PAI) {
-  // Check if the partial_apply has generic substitutions.
-  // FIXME: We could handle generic thunks if it's worthwhile.
-  if (PAI->hasSubstitutions())
-    return false;
-
   SILFunction *SubstF = PAI->getReferencedFunction();
   if (!SubstF)
     return false;
   if (SubstF->isExternalDeclaration())
     return false;
 
-  assert(!SubstF->getLoweredFunctionType()->isPolymorphic() &&
-         "cannot specialize generic partial apply");
+  if (PAI->hasSubstitutions() && hasArchetypes(PAI->getSubstitutions())) {
+    DEBUG(llvm::dbgs()
+              << "CapturePropagation: cannot handle partial specialization "
+                 "of partial_apply:\n";
+          PAI->dumpInContext());
+    return false;
+  }
+
 
   // First possibility: Is it a partial_apply where all partially applied
   // arguments are dead?
-  if (SILFunction *NewFunc = getSpecializedWithDeadParams(SubstF,
-                                                    PAI->getNumArguments())) {
+  std::pair<SILFunction *, SILFunction *> GenericSpecialized;
+  if (auto *NewFunc = getSpecializedWithDeadParams(
+          PAI, SubstF, PAI->getNumArguments(), GenericSpecialized)) {
     rewritePartialApply(PAI, NewFunc);
+    if (GenericSpecialized.first) {
+      // Notify the pass manager about the new function.
+      notifyAddFunction(GenericSpecialized.first, GenericSpecialized.second);
+    }
     return true;
   }
 
@@ -411,7 +472,8 @@
     return false;
 
   DEBUG(llvm::dbgs() << "Specializing closure for constant arguments:\n"
-        << "  " << SubstF->getName() << "\n" << *PAI);
+                     << "  " << SubstF->getName() << "\n"
+                     << *PAI);
   ++NumCapturesPropagated;
   SILFunction *NewF = specializeConstClosure(PAI, SubstF);
   rewritePartialApply(PAI, NewF);
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index b02d39f..f886a9c 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -290,10 +290,13 @@
 }
 
 ReabstractionInfo::ReabstractionInfo(ApplySite Apply, SILFunction *Callee,
-                                     ArrayRef<Substitution> ParamSubs) {
+                                     ArrayRef<Substitution> ParamSubs,
+                                     bool ConvertIndirectToDirect) {
   if (!prepareAndCheck(Apply, Callee, ParamSubs))
     return;
 
+  this->ConvertIndirectToDirect = ConvertIndirectToDirect;
+
   if (SpecializeGenericSubstitutions) {
     specializeConcreteAndGenericSubstitutions(Apply, Callee, ParamSubs);
   } else {
diff --git a/lib/SILOptimizer/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp
index 4c2ee80..f1f6c55 100644
--- a/lib/SILOptimizer/Utils/Local.cpp
+++ b/lib/SILOptimizer/Utils/Local.cpp
@@ -2046,7 +2046,7 @@
 
       if (!CastedValue)
         CastedValue = Builder.createUnconditionalCheckedCastValue(
-            Loc, Op, LoweredTargetType);
+            Loc, CastConsumptionKind::TakeAlways, Op, LoweredTargetType);
     } else {
       CastedValue = SILUndef::get(LoweredTargetType, Mod);
     }
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 01ecf13..4a148fdc 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -1412,7 +1412,7 @@
       // Wrap in covariant `Self` return if needed.
       if (selfTy->hasReferenceSemantics()) {
         auto covariantTy = resultTy
-          ->replaceCovariantResultType(base->getType()
+          ->replaceCovariantResultType(cs.getType(base)
                                            ->getLValueOrInOutObjectType(),
                                        ctor->getNumParameterLists());
         if (!covariantTy->isEqual(resultTy))
@@ -7300,9 +7300,11 @@
                             /*implicit=*/true, getType);
   }
 
+  cs.cacheSubExprTypes(call);
+
   // Add the conversion from the argument to the function parameter type.
   cs.addConstraint(ConstraintKind::ArgumentTupleConversion,
-                   call->getArg()->getType(),
+                   cs.getType(call->getArg()),
                    openedType->castTo<FunctionType>()->getInput(),
                    cs.getConstraintLocator(call,
                                            ConstraintLocator::ApplyArgument));
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 0a8851b..5941116 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1820,7 +1820,7 @@
         unsigned index = 0;
         for (auto element : expr->getElements()) {
           CS.addConstraint(ConstraintKind::Conversion,
-                           element->getType(),
+                           CS.getType(element),
                            contextualDictionaryElementType,
                            CS.getConstraintLocator(expr,
                                                    LocatorPathElt::
@@ -1862,8 +1862,8 @@
             if (element1 == element2)
               continue;
 
-            auto tty1 = element1->getType()->getAs<TupleType>();
-            auto tty2 = element2->getType()->getAs<TupleType>();
+            auto tty1 = CS.getType(element1)->getAs<TupleType>();
+            auto tty2 = CS.getType(element2)->getAs<TupleType>();
 
             if (tty1 && tty2) {
               auto mergedKey = false;
@@ -1911,7 +1911,7 @@
       for (auto element : expr->getElements()) {
         if (!mergedElements.count(element))
           CS.addConstraint(ConstraintKind::Conversion,
-                           element->getType(),
+                           CS.getType(element),
                            elementTy,
                            CS.getConstraintLocator(
                              expr,
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 56aa695..4320fe3 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -1161,8 +1161,10 @@
         : RootExpr(expr), CS(cs), ExcludeRoot(excludeRoot) {}
 
     Expr *walkToExprPost(Expr *expr) override {
-      if (ExcludeRoot && expr == RootExpr)
+      if (ExcludeRoot && expr == RootExpr) {
+        assert(!expr->getType() && "Unexpected type in root of expression!");
         return expr;
+      }
 
       if (expr->getType())
         CS.cacheType(expr);
@@ -1428,14 +1430,12 @@
   void setType(Expr *E, Type T) {
     assert(T && "Expected non-null type!");
 
-    // FIXME: Ideally this would be enabled but there are currently at
-    // least a few places where we set types to different values. We
-    // should track down and fix those places.
-
+    // FIXME: We sometimes set the type and then later set it to a
+    //        value that is slightly different, e.g. not an lvalue.
     // assert((ExprTypes.find(E) == ExprTypes.end() ||
     //         ExprTypes.find(E)->second->isEqual(T) ||
     //         ExprTypes.find(E)->second->hasTypeVariable()) &&
-    //        "Expected type to be set exactly once!");
+    //        "Expected type to be invariant!");
 
     ExprTypes[E] = T.getPointer();
 
@@ -1452,9 +1452,10 @@
   /// Get the type for an expression.
   Type getType(const Expr *E) const {
     assert(hasType(E) && "Expected type to have been set!");
-    assert((!E->getType() ||
-            E->getType()->isEqual(ExprTypes.find(E)->second)) &&
-           "Mismatched types!");
+    // FIXME: lvalue differences
+    //    assert((!E->getType() ||
+    //            E->getType()->isEqual(ExprTypes.find(E)->second)) &&
+    //           "Mismatched types!");
     return ExprTypes.find(E)->second;
   }
 
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 491a423..7fc4f61 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -5153,9 +5153,9 @@
     bool emittedError = false;
     Type plainParentTy = owningTy->adjustSuperclassMemberDeclType(
         parentMember, member, parentMember->getInterfaceType(), &TC);
-    const auto *parentTy = plainParentTy->castTo<AnyFunctionType>();
+    const auto *parentTy = plainParentTy->castTo<FunctionType>();
     if (isa<AbstractFunctionDecl>(parentMember))
-      parentTy = parentTy->getResult()->castTo<AnyFunctionType>();
+      parentTy = parentTy->getResult()->castTo<FunctionType>();
 
     // Check the parameter types.
     auto checkParam = [&](const ParamDecl *decl, Type parentParamTy) {
@@ -5600,14 +5600,8 @@
         parentDeclTy = parentDeclTy->getUnlabeledType(TC.Context);
         if (method) {
           // For methods, strip off the 'Self' type.
-          parentDeclTy = parentDeclTy->castTo<AnyFunctionType>()->getResult();
+          parentDeclTy = parentDeclTy->castTo<FunctionType>()->getResult();
           adjustFunctionTypeForOverride(parentDeclTy);
-        } else if (subscript) {
-          // For subscripts, we don't have a 'Self' type, but turn it
-          // into a monomorphic function type.
-          auto parentFuncTy = parentDeclTy->castTo<AnyFunctionType>();
-          parentDeclTy = FunctionType::get(parentFuncTy->getInput(),
-                                           parentFuncTy->getResult());
         } else {
           // For properties, strip off ownership.
           parentDeclTy = parentDeclTy->getReferenceStorageReferent();
@@ -7171,7 +7165,8 @@
 
     validateAttributes(*this, D);
 
-    proto->computeRequirementSignature();
+    if (!proto->isRequirementSignatureComputed())
+      proto->computeRequirementSignature();
 
     // If the protocol is @objc, it may only refine other @objc protocols.
     // FIXME: Revisit this restriction.
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 0080ba9..f4b8fac 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1930,10 +1930,12 @@
     break;
   }
   case ValueKind::UnconditionalCheckedCastValueInst: {
+    CastConsumptionKind consumption = getCastConsumptionKind(Attr);
     SILValue Val = getLocalValue(
         ValID, getSILType(MF->getType(TyID2), (SILValueCategory)TyCategory2));
     SILType Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory);
-    ResultVal = Builder.createUnconditionalCheckedCastValue(Loc, Val, Ty);
+    ResultVal =
+        Builder.createUnconditionalCheckedCastValue(Loc, consumption, Val, Ty);
     break;
   }
   case ValueKind::UnconditionalCheckedCastAddrInst:
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index ea68efa..acc304d 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -1313,7 +1313,8 @@
     auto CI = cast<UnconditionalCheckedCastValueInst>(&SI);
     SILInstCastLayout::emitRecord(
         Out, ScratchRecord, SILAbbrCodes[SILInstCastLayout::Code],
-        (unsigned)SI.getKind(), /*attr*/ 0,
+        (unsigned)SI.getKind(),
+        toStableCastConsumptionKind(CI->getConsumptionKind()),
         S.addTypeRef(CI->getType().getSwiftRValueType()),
         (unsigned)CI->getType().getCategory(),
         S.addTypeRef(CI->getOperand()->getType().getSwiftRValueType()),
diff --git a/stdlib/public/SDK/AVFoundation/CMakeLists.txt b/stdlib/public/SDK/AVFoundation/CMakeLists.txt
index e4be115..adeb2c0 100644
--- a/stdlib/public/SDK/AVFoundation/CMakeLists.txt
+++ b/stdlib/public/SDK/AVFoundation/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftAVFoundation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   AVError.swift
   NSValue.swift.gyb
diff --git a/stdlib/public/SDK/AppKit/CMakeLists.txt b/stdlib/public/SDK/AppKit/CMakeLists.txt
index c6b5c07..222a0e4 100644
--- a/stdlib/public/SDK/AppKit/CMakeLists.txt
+++ b/stdlib/public/SDK/AppKit/CMakeLists.txt
@@ -1,7 +1,11 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftAppKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   AppKit.swift
   AppKit_FoundationExtensions.swift
   NSError.swift
+
   SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   TARGET_SDKS OSX
diff --git a/stdlib/public/SDK/AssetsLibrary/CMakeLists.txt b/stdlib/public/SDK/AssetsLibrary/CMakeLists.txt
index bcef824..ab388d6 100644
--- a/stdlib/public/SDK/AssetsLibrary/CMakeLists.txt
+++ b/stdlib/public/SDK/AssetsLibrary/CMakeLists.txt
@@ -1,5 +1,9 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftAssetsLibrary ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   ALAssetsLibrary.swift
+
   SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   TARGET_SDKS IOS IOS_SIMULATOR
diff --git a/stdlib/public/SDK/CallKit/CMakeLists.txt b/stdlib/public/SDK/CallKit/CMakeLists.txt
index 3f147c2..497531c 100644
--- a/stdlib/public/SDK/CallKit/CMakeLists.txt
+++ b/stdlib/public/SDK/CallKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCallKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CXProviderConfiguration.swift
 
diff --git a/stdlib/public/SDK/CloudKit/CMakeLists.txt b/stdlib/public/SDK/CloudKit/CMakeLists.txt
index 4e0403d..a8243d3 100644
--- a/stdlib/public/SDK/CloudKit/CMakeLists.txt
+++ b/stdlib/public/SDK/CloudKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCloudKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CKError.swift
 
diff --git a/stdlib/public/SDK/Contacts/CMakeLists.txt b/stdlib/public/SDK/Contacts/CMakeLists.txt
index a1d1d33..67a45a9 100644
--- a/stdlib/public/SDK/Contacts/CMakeLists.txt
+++ b/stdlib/public/SDK/Contacts/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftContacts ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CNError.swift
 
diff --git a/stdlib/public/SDK/CoreAudio/CMakeLists.txt b/stdlib/public/SDK/CoreAudio/CMakeLists.txt
index 0a9eaa3..b3f8c66 100644
--- a/stdlib/public/SDK/CoreAudio/CMakeLists.txt
+++ b/stdlib/public/SDK/CoreAudio/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCoreAudio ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CoreAudio.swift
   ../../../public/core/WriteBackMutableSlice.swift
diff --git a/stdlib/public/SDK/CoreData/CMakeLists.txt b/stdlib/public/SDK/CoreData/CMakeLists.txt
index 3f60b46..4079769 100644
--- a/stdlib/public/SDK/CoreData/CMakeLists.txt
+++ b/stdlib/public/SDK/CoreData/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCoreData ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CocoaError.swift
   NSManagedObjectContext.swift
diff --git a/stdlib/public/SDK/CoreGraphics/CMakeLists.txt b/stdlib/public/SDK/CoreGraphics/CMakeLists.txt
index 92fecf6..c0ca2f8 100644
--- a/stdlib/public/SDK/CoreGraphics/CMakeLists.txt
+++ b/stdlib/public/SDK/CoreGraphics/CMakeLists.txt
@@ -1,7 +1,11 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCoreGraphics ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CoreGraphics.swift
   CGFloat.swift.gyb
   Private.swift
+
   # rdar://problem/20891746
   # SWIFT_COMPILE_FLAGS ${STDLIB_SIL_SERIALIZE_ALL}
   SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
diff --git a/stdlib/public/SDK/CoreImage/CMakeLists.txt b/stdlib/public/SDK/CoreImage/CMakeLists.txt
index f08ee64..9e1c822 100644
--- a/stdlib/public/SDK/CoreImage/CMakeLists.txt
+++ b/stdlib/public/SDK/CoreImage/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCoreImage ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CoreImage.swift
 
diff --git a/stdlib/public/SDK/CoreLocation/CMakeLists.txt b/stdlib/public/SDK/CoreLocation/CMakeLists.txt
index c8deb20..2170918 100644
--- a/stdlib/public/SDK/CoreLocation/CMakeLists.txt
+++ b/stdlib/public/SDK/CoreLocation/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCoreLocation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CLError.swift
   NSValue.swift.gyb
diff --git a/stdlib/public/SDK/CoreMedia/CMakeLists.txt b/stdlib/public/SDK/CoreMedia/CMakeLists.txt
index 2a2a748..c848124 100644
--- a/stdlib/public/SDK/CoreMedia/CMakeLists.txt
+++ b/stdlib/public/SDK/CoreMedia/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCoreMedia ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   CMTime.swift
   CMTimeRange.swift
diff --git a/stdlib/public/SDK/CryptoTokenKit/CMakeLists.txt b/stdlib/public/SDK/CryptoTokenKit/CMakeLists.txt
index d8b526e..fb43caa 100644
--- a/stdlib/public/SDK/CryptoTokenKit/CMakeLists.txt
+++ b/stdlib/public/SDK/CryptoTokenKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftCryptoTokenKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   TKSmartCard.swift
 
diff --git a/stdlib/public/SDK/Dispatch/CMakeLists.txt b/stdlib/public/SDK/Dispatch/CMakeLists.txt
index 0658516..e7f55d4 100644
--- a/stdlib/public/SDK/Dispatch/CMakeLists.txt
+++ b/stdlib/public/SDK/Dispatch/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftDispatch ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   Dispatch.swift
   Dispatch.mm
@@ -9,6 +12,7 @@
   Queue.swift
   Source.swift
   Time.swift
+
   SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   SWIFT_MODULE_DEPENDS_OSX Darwin ObjectiveC # auto-updated
diff --git a/stdlib/public/SDK/Foundation/CMakeLists.txt b/stdlib/public/SDK/Foundation/CMakeLists.txt
index 0e1781e..e04c119 100644
--- a/stdlib/public/SDK/Foundation/CMakeLists.txt
+++ b/stdlib/public/SDK/Foundation/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftFoundation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   AffineTransform.swift
   Boxing.swift
diff --git a/stdlib/public/SDK/GLKit/CMakeLists.txt b/stdlib/public/SDK/GLKit/CMakeLists.txt
index 313c7d8..eb12e0a 100644
--- a/stdlib/public/SDK/GLKit/CMakeLists.txt
+++ b/stdlib/public/SDK/GLKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftGLKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   GLKMath.swift.gyb
 
diff --git a/stdlib/public/SDK/GameplayKit/CMakeLists.txt b/stdlib/public/SDK/GameplayKit/CMakeLists.txt
index 98ae393..8b61a99 100644
--- a/stdlib/public/SDK/GameplayKit/CMakeLists.txt
+++ b/stdlib/public/SDK/GameplayKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftGameplayKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   GameplayKit.swift
 
diff --git a/stdlib/public/SDK/HomeKit/CMakeLists.txt b/stdlib/public/SDK/HomeKit/CMakeLists.txt
index b2fc7215..e4dd0ac 100644
--- a/stdlib/public/SDK/HomeKit/CMakeLists.txt
+++ b/stdlib/public/SDK/HomeKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftHomeKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   HomeKit.swift
 
diff --git a/stdlib/public/SDK/IOKit/CMakeLists.txt b/stdlib/public/SDK/IOKit/CMakeLists.txt
index 14afb21..f2a15cb 100644
--- a/stdlib/public/SDK/IOKit/CMakeLists.txt
+++ b/stdlib/public/SDK/IOKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftIOKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   IOReturn.swift
 
diff --git a/stdlib/public/SDK/Intents/CMakeLists.txt b/stdlib/public/SDK/Intents/CMakeLists.txt
index 40464a1..a275355 100644
--- a/stdlib/public/SDK/Intents/CMakeLists.txt
+++ b/stdlib/public/SDK/Intents/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftIntents ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   INBooleanResolutionResult.swift
   INDoubleResolutionResult.swift
diff --git a/stdlib/public/SDK/MapKit/CMakeLists.txt b/stdlib/public/SDK/MapKit/CMakeLists.txt
index f858ccc..6413362 100644
--- a/stdlib/public/SDK/MapKit/CMakeLists.txt
+++ b/stdlib/public/SDK/MapKit/CMakeLists.txt
@@ -1,5 +1,9 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftMapKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   NSValue.swift.gyb
+
   SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   SWIFT_MODULE_DEPENDS_OSX Darwin AppKit CoreData CoreGraphics CoreImage CoreLocation Dispatch Foundation IOKit ObjectiveC QuartzCore XPC # auto-updated
diff --git a/stdlib/public/SDK/ObjectiveC/CMakeLists.txt b/stdlib/public/SDK/ObjectiveC/CMakeLists.txt
index 7e4dc7d..847ad34 100644
--- a/stdlib/public/SDK/ObjectiveC/CMakeLists.txt
+++ b/stdlib/public/SDK/ObjectiveC/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftObjectiveC ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   ObjectiveC.swift
 
diff --git a/stdlib/public/SDK/OpenCL/CMakeLists.txt b/stdlib/public/SDK/OpenCL/CMakeLists.txt
index edba768..f46a5ab 100644
--- a/stdlib/public/SDK/OpenCL/CMakeLists.txt
+++ b/stdlib/public/SDK/OpenCL/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftOpenCL ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   OpenCL.swift
 
diff --git a/stdlib/public/SDK/Photos/CMakeLists.txt b/stdlib/public/SDK/Photos/CMakeLists.txt
index 83b6434..959831b 100644
--- a/stdlib/public/SDK/Photos/CMakeLists.txt
+++ b/stdlib/public/SDK/Photos/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftPhotos ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   PHChange.swift
 
diff --git a/stdlib/public/SDK/QuartzCore/CMakeLists.txt b/stdlib/public/SDK/QuartzCore/CMakeLists.txt
index 77c55a6..4485328 100644
--- a/stdlib/public/SDK/QuartzCore/CMakeLists.txt
+++ b/stdlib/public/SDK/QuartzCore/CMakeLists.txt
@@ -1,5 +1,9 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftQuartzCore ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   NSValue.swift.gyb
+
   SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
   TARGET_SDKS OSX IOS IOS_SIMULATOR TVOS TVOS_SIMULATOR
diff --git a/stdlib/public/SDK/SafariServices/CMakeLists.txt b/stdlib/public/SDK/SafariServices/CMakeLists.txt
index 6ef0afd..2a10837 100644
--- a/stdlib/public/SDK/SafariServices/CMakeLists.txt
+++ b/stdlib/public/SDK/SafariServices/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftSafariServices ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   SafariServices.swift
 
diff --git a/stdlib/public/SDK/SceneKit/CMakeLists.txt b/stdlib/public/SDK/SceneKit/CMakeLists.txt
index 8235716..63633bb 100644
--- a/stdlib/public/SDK/SceneKit/CMakeLists.txt
+++ b/stdlib/public/SDK/SceneKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftSceneKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   SceneKit.swift.gyb
 
diff --git a/stdlib/public/SDK/SpriteKit/CMakeLists.txt b/stdlib/public/SDK/SpriteKit/CMakeLists.txt
index 18e3fb0..8174db7 100644
--- a/stdlib/public/SDK/SpriteKit/CMakeLists.txt
+++ b/stdlib/public/SDK/SpriteKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftSpriteKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   SpriteKit.swift
   SpriteKitQuickLooks.swift.gyb
diff --git a/stdlib/public/SDK/UIKit/CMakeLists.txt b/stdlib/public/SDK/UIKit/CMakeLists.txt
index caf59d5..401c8b1 100644
--- a/stdlib/public/SDK/UIKit/CMakeLists.txt
+++ b/stdlib/public/SDK/UIKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftUIKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   DesignatedInitializers.mm
   UIKit.swift
diff --git a/stdlib/public/SDK/WatchKit/CMakeLists.txt b/stdlib/public/SDK/WatchKit/CMakeLists.txt
index 3489d15..f10c5b0 100644
--- a/stdlib/public/SDK/WatchKit/CMakeLists.txt
+++ b/stdlib/public/SDK/WatchKit/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftWatchKit ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   WKInterfaceController.swift
 
diff --git a/stdlib/public/SDK/XCTest/CMakeLists.txt b/stdlib/public/SDK/XCTest/CMakeLists.txt
index f12ed99..a1f38db 100644
--- a/stdlib/public/SDK/XCTest/CMakeLists.txt
+++ b/stdlib/public/SDK/XCTest/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 set(DISABLE_APPLICATION_EXTENSION ON)
 
 add_swift_library(swiftXCTest ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
diff --git a/stdlib/public/SDK/XPC/CMakeLists.txt b/stdlib/public/SDK/XPC/CMakeLists.txt
index ccf37f9..5b400fd 100644
--- a/stdlib/public/SDK/XPC/CMakeLists.txt
+++ b/stdlib/public/SDK/XPC/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftXPC ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   XPC.swift
 
diff --git a/stdlib/public/SDK/os/CMakeLists.txt b/stdlib/public/SDK/os/CMakeLists.txt
index b9b5916..7f7e84d 100644
--- a/stdlib/public/SDK/os/CMakeLists.txt
+++ b/stdlib/public/SDK/os/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftos ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   os_log.swift
   os_log.m
diff --git a/stdlib/public/SDK/simd/CMakeLists.txt b/stdlib/public/SDK/simd/CMakeLists.txt
index e853c79..f0555bf 100644
--- a/stdlib/public/SDK/simd/CMakeLists.txt
+++ b/stdlib/public/SDK/simd/CMakeLists.txt
@@ -1,3 +1,6 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
 add_swift_library(swiftsimd ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
   simd.swift.gyb
 
diff --git a/test/Driver/bridging-pch.swift b/test/Driver/bridging-pch.swift
index f2f7ea9..8059f96 100644
--- a/test/Driver/bridging-pch.swift
+++ b/test/Driver/bridging-pch.swift
@@ -15,3 +15,5 @@
 // RUN: %swiftc_driver -typecheck -disable-bridging-pch  -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB
 // NOPCHJOB: {{.*}}swift -frontend {{.*}} -import-objc-header {{.*}}Inputs/bridging-header.h
 
+// RUN: echo "{\"\": {\"swift-dependencies\": \"master.swiftdeps\"}}" > %t.json
+// RUN: %swiftc_driver -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-objc-header %S/Inputs/bridging-header.h %s
diff --git a/test/IDE/range_info_basics.swift b/test/IDE/range_info_basics.swift
index 9483408..22cd59c 100644
--- a/test/IDE/range_info_basics.swift
+++ b/test/IDE/range_info_basics.swift
@@ -105,6 +105,13 @@
   } while i < 100
 }
 
+func foo9(a: Int, b: Int) -> Int {
+  if a == b {
+    return 0
+  }
+  return 0
+}
+
 // RUN: %target-swift-ide-test -range -pos=8:1 -end-pos 8:32 -source-filename %s | %FileCheck %s -check-prefix=CHECK1
 // RUN: %target-swift-ide-test -range -pos=9:1 -end-pos 9:26 -source-filename %s | %FileCheck %s -check-prefix=CHECK2
 // RUN: %target-swift-ide-test -range -pos=10:1 -end-pos 10:27 -source-filename %s | %FileCheck %s -check-prefix=CHECK3
@@ -131,6 +138,9 @@
 // RUN: %target-swift-ide-test -range -pos=102:1 -end-pos=104:6 -source-filename %s | %FileCheck %s -check-prefix=CHECK24
 // RUN: %target-swift-ide-test -range -pos=87:1 -end-pos=92:6 -source-filename %s | %FileCheck %s -check-prefix=CHECK25
 // RUN: %target-swift-ide-test -range -pos=97:1 -end-pos=104:6 -source-filename %s | %FileCheck %s -check-prefix=CHECK26
+// RUN: %target-swift-ide-test -range -pos=109:6 -end-pos=111:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK-INVALID
+
+// CHECK-INVALID: <Kind>Invalid</Kind>
 
 // CHECK1: <Kind>SingleDecl</Kind>
 // CHECK1-NEXT: <Content>func foo1() -> Int { return 0 }</Content>
diff --git a/test/IRGen/lazy_metadata.swift b/test/IRGen/lazy_metadata.swift
index fceff58..869f46a 100644
--- a/test/IRGen/lazy_metadata.swift
+++ b/test/IRGen/lazy_metadata.swift
@@ -4,60 +4,79 @@
 
 // protocol descriptor for test.Proto
 // CHECK-DAG: @_T04test5ProtoMp =
+// CHECK-DAG: @_T04test12PrivateProto{{[_A-Z0-9]*}}Mp =
 
 // reflection metadata field descriptors
 // CHECK-DAG: @_T04test7StructAVMF =
 // CHECK-DAG: @_T04test7StructBVMF =
 // CHECK-DAG: @_T04test7StructCVMF =
 // CHECK-DAG: @_T04test7StructDVMF =
+// CHECK-DAG: @_T04test7StructEVMF =
 
 // value witness tables
 // CHECK-DAG: @_T04test7StructAVWV =
 // CHECK-DAG: @_T04test7StructBVWV =
 // CHECK-DAG: @_T04test7StructCVWV =
 // CHECK-DEAD-NOT: @_T04test7StructDVWV
+// CHECK-DAG: @_T04test7StructEVWV =
 
 // nominal type descriptors
 // CHECK-DAG: @_T04test7StructAVMn =
 // CHECK-DAG: @_T04test7StructBVMn =
 // CHECK-DAG: @_T04test7StructCVMn =
 // CHECK-DEAD-NOT: @_T04test7StructDVMn
+// CHECK-DAG: @_T04test7StructEVMn =
 
 // full type metadata
 // CHECK-DAG: @_T04test7StructAVMf =
 // CHECK-DAG: @_T04test7StructBVMf =
 // CHECK-DAG: @_T04test7StructCVMf =
 // CHECK-DEAD-NOT: @_T04test7StructDVMf
+// CHECK-DAG: @_T04test7StructEVMf =
 
 // protocol witness tables
 // CHECK-DAG: @_T04test7StructAVAA5ProtoAAWP =
 // CHECK-DAG: @_T04test7StructBVAA5ProtoAAWP =
 // CHECK-DAG: @_T04test7StructCVAA5ProtoAAWP =
 // CHECK-DEAD-NOT: @_T04test7StructDVAA5ProtoAAWP =
+// CHECK-DAG: @_T04test7StructEVAA12PrivateProto{{[_A-Z0-9]*}}AAWP =
 
 public protocol Proto {
-	func abc()
+  func abc()
 }
 
 struct StructA : Proto {
-	func abc() {
-	}
+  func abc() {
+  }
 }
 
 struct StructB : Proto {
-	func abc() {
-	}
+  func abc() {
+  }
 }
 
 struct StructC : Proto {
-	func abc() {
-	}
+  func abc() {
+  }
 }
 
 // This is the only struct for which no metadata and conformances are needed.
 struct StructD : Proto {
-	func abc() {
-	}
+  func abc() {
+  }
+}
+
+private protocol PrivateProto {
+  func xyz()
+}
+
+public struct StructE : PrivateProto {
+  func xyz() {
+  }
+}
+
+public func needPrivateConformance(_ x: Any) -> Bool {
+  return x is PrivateProto
 }
 
 @inline(never)
@@ -68,12 +87,12 @@
 @inline(never)
 @_semantics("optimize.sil.never")
 func consume2<T: Proto>(_ t: T) {
-	t.abc()
+  t.abc()
 }
 @inline(never)
 @_semantics("optimize.sil.never")
 func consume3(_ p: Proto) {
-	p.abc()
+  p.abc()
 }
 @inline(never)
 @_semantics("optimize.sil.never")
@@ -87,18 +106,18 @@
 var d = StructD()
 
 public func callfuncA() {
-	consume1(a)
+  consume1(a)
 }
 
 public func callfuncB() {
-	consume2(b)
+  consume2(b)
 }
 
 public func callfuncC() {
-	consume3(c)
+  consume3(c)
 }
 
 public func callfuncD() {
-	consume4(d)
+  consume4(d)
 }
 
diff --git a/test/IRGen/protocol_resilience.sil b/test/IRGen/protocol_resilience.sil
index 4858833..5582a80 100644
--- a/test/IRGen/protocol_resilience.sil
+++ b/test/IRGen/protocol_resilience.sil
@@ -11,13 +11,6 @@
 
 import resilient_protocol
 
-// Witness table for conformance with resilient associated type
-
-// CHECK: @_T019protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWP = {{(protected )?}}constant [2 x i8*] [
-// CHECK-SAME:   i8* bitcast (%swift.type* ()* @_T019protocol_resilience23ResilientConformingTypeVMa to i8*),
-// CHECK-SAME:   i8* bitcast (i8** ()* @_T019protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWa to i8*)
-// CHECK-SAME: ]
-
 
 // Protocol is public -- needs resilient witness table
 
@@ -57,6 +50,13 @@
 }
 
 
+// Witness table for conformance with resilient associated type
+
+// CHECK: @_T019protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWP = {{(protected )?}}constant [2 x i8*] [
+// CHECK-SAME:   i8* bitcast (%swift.type* ()* @_T019protocol_resilience23ResilientConformingTypeVMa to i8*),
+// CHECK-SAME:   i8* bitcast (i8** ()* @_T019protocol_resilience23ResilientConformingTypeV010resilient_A005OtherC8ProtocolAAWa to i8*)
+// CHECK-SAME: ]
+
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @defaultC(%swift.opaque* noalias nocapture swiftself, %swift.type* %Self, i8** %SelfWitnessTable)
 // CHECK-NEXT:  entry:
 
diff --git a/test/Index/kinds.swift b/test/Index/kinds.swift
index a8de882..98fd06d 100644
--- a/test/Index/kinds.swift
+++ b/test/Index/kinds.swift
@@ -44,15 +44,23 @@
   // CHECK: [[@LINE-1]]:7 | class/Swift | AClass | s:14swift_ide_test6AClassC | Def | rel: 0
 
   // InstanceMethod + Parameters
-  func instanceMethod(a: Int, b b: Int, _ c: Int, d _: Int, _: Int) {}
+  func instanceMethod(a: Int, b b: Int, _ c: Int, d _: Int, _: Int) {
   // CHECK: [[@LINE-1]]:8 | instance-method/Swift | instanceMethod(a:b:_:d:_:) | s:14swift_ide_test6AClassC14instanceMethodySi1a_Si1bS2i1dSitF | Def,RelChild | rel: 1
   // CHECK-NEXT: RelChild | class/Swift | AClass | s:14swift_ide_test6AClassC
   // CHECK: [[@LINE-3]]:23 | param/Swift | a | s:14swift_ide_test6AClassC14instanceMethodySi1a_Si1bS2i1dSitFAEL_Siv | Def,RelChild | rel: 1
   // CHECK-NEXT: RelChild | instance-method/Swift | instanceMethod(a:b:_:d:_:) | s:14swift_ide_test6AClassC14instanceMethodySi1a_Si1bS2i1dSitF
-  // CHECK-NOT: [[@LINE-5]]:33 | param/Swift | b | s:{{.*}} | Def,RelChild | rel: 1
-  // CHECK-NOT: [[@LINE-6]]:43 | param/Swift | c | s:{{.*}} | Def,RelChild | rel: 1
-  // CHECK-NOT: [[@LINE-7]]:53 | param/Swift | d | s:{{.*}} | Def,RelChild | rel: 1
-  // CHECK-NOT: [[@LINE-8]]:61 | param/Swift | _ | s:{{.*}} | Def,RelChild | rel: 1
+  // CHECK: [[@LINE-5]]:33 | param(local)/Swift | b | s:{{.*}} | Def,RelChild | rel: 1
+  // CHECK: [[@LINE-6]]:43 | param(local)/Swift | c | s:{{.*}} | Def,RelChild | rel: 1
+  // CHECK: [[@LINE-7]]:53 | param(local)/Swift | _ | s:{{.*}} | Def,RelChild | rel: 1
+  // CHECK: [[@LINE-8]]:61 | param/Swift | _ | s:{{.*}} | Def,RelChild | rel: 1
+
+    _ = a
+    // CHECK: [[@LINE-1]]:9 | param/Swift | a | s:{{.*}} | Ref,Read,RelCont | rel: 1
+    _ = b
+    // CHECK-NOT: [[@LINE-1]]:9 | param(local)/Swift | b | s:{{.*}} | Ref,Read,RelCont | rel: 1
+    _ = c
+    // CHECK-NOT: [[@LINE-1]]:9 | param(local)/Swift | c | s:{{.*}} | Ref,Read,RelCont | rel: 1
+  }
 
   // ClassMethod
   class func classMethod() {}
diff --git a/test/Interpreter/SDK/libc.swift b/test/Interpreter/SDK/libc.swift
index 8824568..ee2412d 100644
--- a/test/Interpreter/SDK/libc.swift
+++ b/test/Interpreter/SDK/libc.swift
@@ -36,22 +36,32 @@
   open(sourcePath, O_RDONLY | O_CREAT | O_EXCL)
 if errFile != -1 { 
   print("O_CREAT|O_EXCL failed to return an error") 
-} else { 
-  print("O_CREAT|O_EXCL returned errno *\(errno)*") 
+} else {
+  let e = errno
+  print("O_CREAT|O_EXCL returned errno *\(e)*") 
 }
 
 // CHECK-NOT: error
 // CHECK: created mode *33216* *33216*
 let tempFile = 
   open(tempPath, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IXUSR)
+if tempFile == -1 {
+  let e = errno
+  print("error: open(tempPath \(tempPath)) returned -1, errno \(e)")
+  abort()
+}
 let written = write(tempFile, bytes, 11)
-assert(written == 11)
+if (written != 11) {
+  print("error: write(tempFile) returned \(written), errno \(errno)")
+  abort()
+}
 
 var err: Int32
 var statbuf1 = stat()
 err = fstat(tempFile, &statbuf1)
-if err != 0 { 
-  print("error: fstat returned \(err), errno \(errno)")
+if err != 0 {
+  let e = errno
+  print("error: fstat returned \(err), errno \(e)")
   abort()
 }
 
@@ -59,8 +69,9 @@
 
 var statbuf2 = stat()
 err = stat(tempPath, &statbuf2)
-if err != 0 { 
-  print("error: stat returned \(err), errno \(errno)")
+if err != 0 {
+  let e = errno
+  print("error: stat returned \(err), errno \(e)")
   abort()
 }
 
diff --git a/test/SIL/Parser/opaque_values_parse.sil b/test/SIL/Parser/opaque_values_parse.sil
index 797fb70..d57b3f9 100644
--- a/test/SIL/Parser/opaque_values_parse.sil
+++ b/test/SIL/Parser/opaque_values_parse.sil
@@ -16,11 +16,11 @@
 
 // CHECK-LABEL: sil @castOpaque : $@convention(thin) (Int) -> () {
 // CHECK: bb0([[ARG:%.*]] : $Int):
-// CHECK:  unconditional_checked_cast_value [[ARG]] : $Int to $Foo
+// CHECK:  unconditional_checked_cast_value take_always [[ARG]] : $Int to $Foo
 // CHECK-LABEL: } // end sil function 'castOpaque'
 sil @castOpaque : $@convention(thin) (Int) -> () {
 bb0(%0 : $Int):
-  %c = unconditional_checked_cast_value %0 : $Int to $Foo
+  %c = unconditional_checked_cast_value take_always %0 : $Int to $Foo
   %t = tuple ()
   return %t : $()
 }
diff --git a/test/SIL/Serialization/opaque_values_serialize.sil b/test/SIL/Serialization/opaque_values_serialize.sil
index 8d0cfc6..ee020bd 100644
--- a/test/SIL/Serialization/opaque_values_serialize.sil
+++ b/test/SIL/Serialization/opaque_values_serialize.sil
@@ -22,11 +22,11 @@
 
 // CHECK-LABEL: sil @castOpaque : $@convention(thin) (Int) -> () {
 // CHECK: bb0([[ARG:%.*]] : $Int):
-// CHECK:  unconditional_checked_cast_value [[ARG]] : $Int to $Foo
+// CHECK:  unconditional_checked_cast_value take_always [[ARG]] : $Int to $Foo
 // CHECK-LABEL: } // end sil function 'castOpaque'
 sil @castOpaque : $@convention(thin) (Int) -> () {
 bb0(%0 : $Int):
-  %c = unconditional_checked_cast_value %0 : $Int to $Foo
+  %c = unconditional_checked_cast_value take_always %0 : $Int to $Foo
   %t = tuple ()
   return %t : $()
 }
diff --git a/test/SIL/ownership-verifier/opaque_use_verifier.sil b/test/SIL/ownership-verifier/opaque_use_verifier.sil
index a2e801b..23f767a 100644
--- a/test/SIL/ownership-verifier/opaque_use_verifier.sil
+++ b/test/SIL/ownership-verifier/opaque_use_verifier.sil
@@ -11,6 +11,6 @@
 
 sil @unconditional_checked_cast_value_test : $@convention(thin) <T> (Builtin.Int32) -> @out T {
 bb0(%0 : @trivial $Builtin.Int32):
-  %1 = unconditional_checked_cast_value %0 : $Builtin.Int32 to $T
+  %1 = unconditional_checked_cast_value take_always %0 : $Builtin.Int32 to $T
   return %1 : $T
 }
diff --git a/test/SILGen/concrete_subclass.swift b/test/SILGen/concrete_subclass.swift
new file mode 100644
index 0000000..ed08629
--- /dev/null
+++ b/test/SILGen/concrete_subclass.swift
@@ -0,0 +1,38 @@
+// RUN: %target-swift-frontend -Xllvm -new-mangling-for-tests -Xllvm -sil-full-demangle -emit-silgen %s
+
+class BaseClass<T> {
+  func inAndOut(_ t: T) -> T { return t }
+  var property: T
+
+  init(_ t: T) {
+    self.property = t
+  }
+}
+
+class DerivedClass : BaseClass<(Int, Int)> {
+  override func inAndOut(_ t: (Int, Int)) -> (Int, Int) {
+    let fn = super.inAndOut
+    return fn(t)
+  }
+
+  override var property: (Int, Int) {
+    get {
+      return super.property
+    }
+    set {
+      super.property = newValue
+    }
+  }
+
+  override init(_ t: (Int, Int)) {
+    super.init(t)
+  }
+}
+
+let d = DerivedClass((1, 2))
+_ = d.inAndOut((1, 2))
+
+let value = d.property
+d.property = value
+
+d.property.0 += 1
diff --git a/test/SILGen/opaque_values_silgen.swift b/test/SILGen/opaque_values_silgen.swift
index f2d7cd4..63e16f7 100644
--- a/test/SILGen/opaque_values_silgen.swift
+++ b/test/SILGen/opaque_values_silgen.swift
@@ -10,6 +10,10 @@
   var x : Int { get }
 }
 
+struct Box<T> {
+  let t: T
+}
+
 func s010_hasVarArg(_ args: Any...) {}
 
 // Test that we still use addresses when dealing with array initialization
@@ -258,7 +262,7 @@
 // CHECK:   [[INT_TYPE:%.*]] = metatype $@thin Int.Type
 // CHECK:   [[INT_LIT:%.*]] = integer_literal $Builtin.Int2048, 42
 // CHECK:   [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
-// CHECK:   [[INT_CAST:%.*]] = unconditional_checked_cast_value [[INT_ARG]] : $Int to $T
+// CHECK:   [[INT_CAST:%.*]] = unconditional_checked_cast_value take_always [[INT_ARG]] : $Int to $T
 // CHECK:   [[CAST_BORROW:%.*]] = begin_borrow [[INT_CAST]] : $T
 // CHECK:   [[RETURN_VAL:%.*]] = copy_value [[CAST_BORROW]] : $T
 // CHECK:   end_borrow [[CAST_BORROW]] from [[INT_CAST]] : $T, $T
@@ -276,7 +280,7 @@
 // CHECK: bb0:
 // CHECK:   [[INT_LIT:%.*]] = integer_literal $Builtin.Int2048, 42
 // CHECK:   [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
-// CHECK:   [[INT_CAST:%.*]] = unconditional_checked_cast_value [[INT_ARG]] : $Int to $Foo
+// CHECK:   [[INT_CAST:%.*]] = unconditional_checked_cast_value take_always [[INT_ARG]] : $Int to $Foo
 // CHECK:   return [[INT_CAST]] : $Foo
 // CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s180_______return_fooAA3Foo_pyF'
 func s180_______return_foo() -> Foo {
@@ -392,9 +396,24 @@
   return x._domain
 }
 
+// Tests Implicit Value Construction under Opaque value mode
+// ---
+// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s250_________testBoxTyyF : $@convention(thin) () -> () {
+// CHECK: bb0:
+// CHECK:   [[BOX_MTYPE:%.*]] = metatype $@thin Box<Int>.Type
+// CHECK:   [[MTYPE:%.*]] = metatype $@thin Int.Type
+// CHECK:   [[INTLIT:%.*]] = integer_literal $Builtin.Int2048, 42
+// CHECK:   [[AINT:%.*]] = apply {{.*}}([[INTLIT]], [[MTYPE]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
+// CHECK:   apply {{.*}}<Int>([[AINT]], [[BOX_MTYPE]]) : $@convention(method) <τ_0_0> (@in τ_0_0, @thin Box<τ_0_0>.Type) -> @out Box<τ_0_0>
+// CHECK:   return %{{.*}} : $()
+// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s250_________testBoxTyyF'
+func s250_________testBoxT() {
+  let _ = Box(t: 42)
+}
+
 // Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
 // ---
-// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s250_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {
+// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {
 // CHECK: bb0([[ARG0:%.*]] : $Any, [[ARG1:%.*]] : $T):
 // CHECK:   [[BORROWED_ARG:%.*]] = begin_borrow [[ARG0]]
 // CHECK:   [[COPY__ARG:%.*]] = copy_value [[BORROWED_ARG]]
@@ -404,12 +423,21 @@
 // CHECK:   partial_apply [[THUNK_REF]]<T>([[THUNK_PARAM]])
 // CHECK: bb6:
 // CHECK:   return %{{.*}} : $()
-// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s250_____condTFromAnyyyp_xtlF'
-func s250_____condTFromAny<T>(_ x: Any, _ y: T) {
+// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF'
+func s999_____condTFromAny<T>(_ x: Any, _ y: T) {
   if let f = x as? (Int, T) -> (Int, T) {
     f(42, y)
   }
 }
+
+// s250_________testBoxT continued Tests Implicit Value Construction under Opaque value mode
+// ---
+// CHECK-LABEL: sil hidden @_T020opaque_values_silgen3BoxVACyxGx1t_tcfC : $@convention(method) <T> (@in T, @thin Box<T>.Type) -> @out Box<T> {
+// CHECK: bb0([[ARG0:%.*]] : $T, [[ARG1:%.*]] : $@thin Box<T>.Type):
+// CHECK:   [[RETVAL:%.*]] = struct $Box<T> ([[ARG0]] : $T)
+// CHECK:   return [[RETVAL]] : $Box<T>
+// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen3BoxVACyxGx1t_tcfC'
+
 // CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @{{.*}} : $@convention(thin) (Int, Int, Int, Int, Int, @owned @callee_owned (@in (Int, (Int, (Int, Int)), Int)) -> @out (Int, (Int, (Int, Int)), Int)) -> (Int, Int, Int, Int, Int)
 // CHECK: bb0([[ARG0:%.*]] : $Int, [[ARG1:%.*]] : $Int, [[ARG2:%.*]] : $Int, [[ARG3:%.*]] : $Int, [[ARG4:%.*]] : $Int, [[ARG5:%.*]] : $@callee_owned (@in (Int, (Int, (Int, Int)), Int)) -> @out (Int, (Int, (Int, Int)), Int)):
 // CHECK:   [[TUPLE_TO_APPLY0:%.*]] = tuple ([[ARG2]] : $Int, [[ARG3]] : $Int)
diff --git a/test/SILGen/vtable_thunks_reabstraction.swift b/test/SILGen/vtable_thunks_reabstraction.swift
index e1edd14..78feb52 100644
--- a/test/SILGen/vtable_thunks_reabstraction.swift
+++ b/test/SILGen/vtable_thunks_reabstraction.swift
@@ -86,12 +86,10 @@
   override func variantOptionality(x: C.Type?) -> C.Type { return x! }
 }
 
-/*
 class ConcreteOptional<X>: Opaque<S?> {
   override func inAndOut(x: S?) -> S? { return x }
-  override func variantOptionality(x: S??) -> S? { return x! }
+  // override func variantOptionality(x: S??) -> S? { return x! }
 }
- */
 
 // Make sure we remap the method's innermost generic parameters
 // to the correct depth
@@ -122,3 +120,16 @@
     super.doStuff(t: t, u: u)
   }
 }
+
+// Issue with generic parameter index
+class MoreGenericSub1<T, TT> : GenericBase<T> {
+  override func doStuff<U>(t: T, u: U) {
+    super.doStuff(t: t, u: u)
+  }
+}
+
+class MoreGenericSub2<TT, T> : GenericBase<T> {
+  override func doStuff<U>(t: T, u: U) {
+    super.doStuff(t: t, u: u)
+  }
+}
diff --git a/test/SILOptimizer/capture_propagation.sil b/test/SILOptimizer/capture_propagation.sil
index b0317c9..d8dce48 100644
--- a/test/SILOptimizer/capture_propagation.sil
+++ b/test/SILOptimizer/capture_propagation.sil
@@ -378,3 +378,75 @@
   return %2 : $@callee_owned (Int32, Int32) -> (Bool, @error Error)
 }
 
+// Test generic capture propagation
+
+sil @_TFtest_generic_capture_propagation2_closure : $@convention(thin) <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> () {
+bb0(%0 : $Builtin.Int32, %1 : $Builtin.FPIEEE32, %2 : $Builtin.RawPointer, %3 : $*T):
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @test_generic_capture_propagation2_caller
+// CHECK: %[[CALLEE:[0-9]+]] = function_ref @test_generic_capture_propagation2_callee 
+// CHECK: %[[FR:[0-9]+]] = function_ref @{{.*}}test_generic_capture_propagation2_thunk : $@convention(thin) () -> () 
+// CHECK: %[[CONVERTED:[0-9]+]] = thin_to_thick_function %[[FR]] : $@convention(thin) () -> () to $@callee_owned () -> ()
+// CHECK-NOT: partial_apply
+// CHECK: apply %[[CALLEE]](%[[CONVERTED]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+// CHECL-NOT: partial_apply
+// CHECK: return
+sil @test_generic_capture_propagation2_caller : $@convention(thin) () -> () {
+  %0 = integer_literal $Builtin.Int32, 0
+  %1 = float_literal $Builtin.FPIEEE32, 0
+  %2 = string_literal utf8 "123"
+  %3 = global_addr @globalinit_33_06E7F1D906492AE070936A9B58CBAE1C_token8 : $*Builtin.Word
+  %4 = function_ref @_TFtest_generic_capture_propagation2_closure : $@convention(thin) <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()
+  %5 = thin_to_thick_function %4 : $@convention(thin) <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> () to $@callee_owned <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()
+  %6 = function_ref @test_generic_capture_propagation2_callee : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %7 = function_ref @test_generic_capture_propagation2_thunk : $@convention(thin) <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T, @owned @callee_owned <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()) -> ()
+  %8 = partial_apply %7<Builtin.Word>(%0, %1, %2, %3, %5) : $@convention(thin) <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T, @owned @callee_owned <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()) -> ()
+  apply %6(%8) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil shared @test_generic_capture_propagation2_thunk : $@convention(thin) <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T, @owned @callee_owned <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()) -> () {
+bb0(%0 : $Builtin.Int32, %1 : $Builtin.FPIEEE32, %2 : $Builtin.RawPointer, %3 : $*T, %4 : $@callee_owned <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()):
+  apply %4<T>(%0, %1, %2, %3) : $@callee_owned <T> (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in T) -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil shared @test_generic_capture_propagation2_callee : $@convention(thin) (@owned @callee_owned () -> ()) -> () {
+bb0(%0 : $@callee_owned () -> ()):
+  apply %0() : $@callee_owned () -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// Test dead partial applied arguments when using generics
+
+sil @specialized_generic_nonthrowing_closure : $@convention(thin) <T> (@in T, @in T) -> Bool {
+bb0(%0 : $*T, %1 : $*T):
+  %10 = integer_literal $Builtin.Int1, -1
+  %9999 = struct $Bool (%10 : $Builtin.Int1)
+  return %9999 : $Bool
+}
+
+sil @nonthrowing_generic_closure : $@convention(method) <T> (@in T, @in T, @thin T.Type) -> Bool {
+bb0(%0 : $*T, %1 : $*T, %2 : $@thin T.Type):
+  %3 = function_ref @specialized_generic_nonthrowing_closure : $@convention(thin) <T> (@in T, @in T) -> Bool
+  %4 = apply %3<T>(%0, %1) : $@convention(thin) <T> (@in T, @in T) -> Bool
+  return %4 : $Bool
+}
+
+// CHECK-LABEL: sil @return_generic_nonthrowing_closure
+// CHECK: [[F:%[0-9]+]] = function_ref @_TTSg5Vs5Int32__specialized_generic_nonthrowing_closure
+// CHECK: [[R:%[0-9]+]] = thin_to_thick_function [[F]]
+// CHECK: return [[R]]
+sil @return_generic_nonthrowing_closure : $@convention(thin) () -> @owned @callee_owned (@in Int32, @in Int32) -> Bool {
+bb0:
+  %0 = metatype $@thin Int32.Type
+  %1 = function_ref @nonthrowing_generic_closure : $@convention(method) <T> (@in T, @in T, @thin T.Type) -> Bool
+  %2 = partial_apply %1<Int32>(%0) : $@convention(method) <T>(@in T, @in T, @thin T.Type) -> Bool
+  return %2 : $@callee_owned (@in Int32, @in Int32) -> Bool
+}
\ No newline at end of file
diff --git a/test/SourceKit/MarkupXML/Input/DocComment1.md b/test/SourceKit/MarkupXML/Input/DocComment1.md
new file mode 100644
index 0000000..38d9717
--- /dev/null
+++ b/test/SourceKit/MarkupXML/Input/DocComment1.md
@@ -0,0 +1,4 @@
+Another useful function
+- parameters:
+- alpha: Describe the alpha param
+- beta: Describe the beta param
diff --git a/test/SourceKit/MarkupXML/basic.swift b/test/SourceKit/MarkupXML/basic.swift
new file mode 100644
index 0000000..22cf3e4
--- /dev/null
+++ b/test/SourceKit/MarkupXML/basic.swift
@@ -0,0 +1,2 @@
+// RUN: %sourcekitd-test -req=markup-xml -pass-as-sourcetext %S/Input/DocComment1.md > %t.DocComment1.response
+// RUN: diff -u %s.DocComment1.response %t.DocComment1.response
diff --git a/test/SourceKit/MarkupXML/basic.swift.DocComment1.response b/test/SourceKit/MarkupXML/basic.swift.DocComment1.response
new file mode 100644
index 0000000..e70d529
--- /dev/null
+++ b/test/SourceKit/MarkupXML/basic.swift.DocComment1.response
@@ -0,0 +1 @@
+"<Abstract><Para>Another useful function</Para></Abstract><Discussion><List-Bullet><Item><Para>parameters:</Para></Item><Item><Para>alpha: Describe the alpha param</Para></Item><Item><Para>beta: Describe the beta param</Para></Item></List-Bullet></Discussion>"
diff --git a/test/attr/attr_override.swift b/test/attr/attr_override.swift
index 2831aea..596e5d6 100644
--- a/test/attr/attr_override.swift
+++ b/test/attr/attr_override.swift
@@ -407,3 +407,12 @@
   override init<U>(t: Int, u: U) {}
   override func doStuff<U>(t: Int, u: U) {}
 }
+
+// Issue with generic parameter index
+class MoreGenericSub1<T, TT> : GenericBase<T> {
+  override func doStuff<U>(t: T, u: U) {}
+}
+
+class MoreGenericSub2<TT, T> : GenericBase<T> {
+  override func doStuff<U>(t: T, u: U) {}
+}
diff --git a/test/multifile/Inputs/requirement-signature.swift b/test/multifile/Inputs/requirement-signature.swift
new file mode 100644
index 0000000..430d942
--- /dev/null
+++ b/test/multifile/Inputs/requirement-signature.swift
@@ -0,0 +1,7 @@
+protocol ObservableType {
+  func subscribe<O>(_: O)
+}
+
+protocol ConnectableObservableType : ObservableType {
+  func connect()
+}
diff --git a/test/multifile/requirement-signature.swift b/test/multifile/requirement-signature.swift
new file mode 100644
index 0000000..b2f2d2e
--- /dev/null
+++ b/test/multifile/requirement-signature.swift
@@ -0,0 +1,5 @@
+// RUN: %target-swift-frontend -typecheck -primary-file %s %S/Inputs/requirement-signature.swift
+
+func run<CO: ConnectableObservableType, O>(co: CO, o: O) {
+  co.subscribe(o)
+}
diff --git a/tools/SourceKit/include/SourceKit/Core/LangSupport.h b/tools/SourceKit/include/SourceKit/Core/LangSupport.h
index 9baaeb0..fce5664 100644
--- a/tools/SourceKit/include/SourceKit/Core/LangSupport.h
+++ b/tools/SourceKit/include/SourceKit/Core/LangSupport.h
@@ -463,6 +463,9 @@
   virtual void editorExtractTextFromComment(StringRef Source,
                                             EditorConsumer &Consumer) = 0;
 
+  virtual void editorConvertMarkupToXML(StringRef Source,
+                                        EditorConsumer &Consumer) = 0;
+
   virtual void editorExpandPlaceholder(StringRef Name, unsigned Offset,
                                        unsigned Length,
                                        EditorConsumer &Consumer) = 0;
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
index fefce90..ac9ca49 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
@@ -2128,6 +2128,17 @@
   Consumer.handleSourceText(extractPlainTextFromComment(Source));
 }
 
+void SwiftLangSupport::editorConvertMarkupToXML(StringRef Source,
+                                                EditorConsumer &Consumer) {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  if (convertMarkupToXML(Source, OS)) {
+    Consumer.handleRequestError("Conversion failed.");
+    return;
+  }
+  Consumer.handleSourceText(Result);
+}
+
 //===----------------------------------------------------------------------===//
 // EditorExpandPlaceholder
 //===----------------------------------------------------------------------===//
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
index 874e659..f64435b 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
@@ -380,6 +380,9 @@
   void editorExtractTextFromComment(StringRef Source,
                                     EditorConsumer &Consumer) override;
 
+  void editorConvertMarkupToXML(StringRef Source,
+                                EditorConsumer &Consumer) override;
+
   void editorExpandPlaceholder(StringRef Name, unsigned Offset, unsigned Length,
                                EditorConsumer &Consumer) override;
 
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
index c5cb232..d19bcb3 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
@@ -132,6 +132,7 @@
         .Case("module-groups", SourceKitRequest::ModuleGroups)
         .Case("range", SourceKitRequest::RangeInfo)
         .Case("translate", SourceKitRequest::NameTranslation)
+        .Case("markup-xml", SourceKitRequest::MarkupToXML)
         .Default(SourceKitRequest::None);
       if (Request == SourceKitRequest::None) {
         llvm::errs() << "error: invalid request, expected one of "
@@ -139,7 +140,8 @@
                "complete.update/complete.cache.ondisk/complete.cache.setpopularapi/"
                "cursor/related-idents/syntax-map/structure/format/expand-placeholder/"
                "doc-info/sema/interface-gen/interface-gen-openfind-usr/find-interface/"
-               "open/edit/print-annotations/print-diags/extract-comment/module-groups/range\n";
+               "open/edit/print-annotations/print-diags/extract-comment/module-groups/"
+               "range/translate/markup-xml\n";
         return true;
       }
       break;
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
index 1024540..acb8e70 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
@@ -51,6 +51,7 @@
   ExtractComment,
   ModuleGroups,
   NameTranslation,
+  MarkupToXML,
 };
 
 struct TestOptions {
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index 0da572f..8424d46 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -166,6 +166,7 @@
 static sourcekitd_uid_t RequestDocInfo;
 static sourcekitd_uid_t RequestModuleGroups;
 static sourcekitd_uid_t RequestNameTranslation;
+static sourcekitd_uid_t RequestMarkupToXML;
 
 static sourcekitd_uid_t SemaDiagnosticStage;
 
@@ -297,6 +298,7 @@
   RequestDocInfo = sourcekitd_uid_get_from_cstr("source.request.docinfo");
   RequestModuleGroups = sourcekitd_uid_get_from_cstr("source.request.module.groups");
   RequestNameTranslation = sourcekitd_uid_get_from_cstr("source.request.name.translation");
+  RequestMarkupToXML = sourcekitd_uid_get_from_cstr("source.request.convert.markup.xml");
   KindNameObjc = sourcekitd_uid_get_from_cstr("source.lang.name.kind.objc");
   KindNameSwift = sourcekitd_uid_get_from_cstr("source.lang.name.kind.swift");
 
@@ -578,7 +580,10 @@
     sourcekitd_request_dictionary_set_int64(Req, KeyLength, Length);
     break;
   }
-
+  case SourceKitRequest::MarkupToXML: {
+    sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestMarkupToXML);
+    break;
+  }
   case SourceKitRequest::NameTranslation: {
     sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestNameTranslation);
     sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
@@ -932,6 +937,7 @@
       break;
 
     case SourceKitRequest::ExtractComment:
+    case SourceKitRequest::MarkupToXML:
       printNormalizedDocComment(Info);
       break;
 
diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h
index 8a9bed6..3532c0f 100644
--- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h
+++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h
@@ -34,15 +34,13 @@
   class UIdent;
 }
 
-SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL bool
-sourcekitd_variant_dictionary_apply_impl(
-  sourcekitd_variant_t dict,
-  llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier);
+bool sourcekitd_variant_dictionary_apply_impl(
+    sourcekitd_variant_t dict,
+    llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier);
 
-SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL bool
-sourcekitd_variant_array_apply_impl(
-  sourcekitd_variant_t array,
-  llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier);
+bool sourcekitd_variant_array_apply_impl(
+    sourcekitd_variant_t array,
+    llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier);
 
 namespace sourcekitd {
 
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp
index 0fdb125..050de20 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp
@@ -90,7 +90,6 @@
                              sourcekitd_uid_t,
                              uint8_t> CompactArrayReaderTy;
 
-
   static bool
   dictionary_apply(void *Buf, size_t Index,
                    llvm::function_ref<bool(sourcekitd_uid_t,
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
index 9f2b905..9388e04 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
@@ -110,6 +110,7 @@
 static LazySKDUID RequestModuleGroups(
     "source.request.module.groups");
 static LazySKDUID RequestNameTranslation("source.request.name.translation");
+static LazySKDUID RequestMarkupToXML("source.request.convert.markup.xml");
 
 static LazySKDUID KindExpr("source.lang.swift.expr");
 static LazySKDUID KindStmt("source.lang.swift.stmt");
@@ -231,6 +232,8 @@
 
 static sourcekitd_response_t editorExtractTextFromComment(StringRef Source);
 
+static sourcekitd_response_t editorConvertMarkupToXML(StringRef Source);
+
 static sourcekitd_response_t
 editorClose(StringRef Name, bool RemoveCache);
 
@@ -543,6 +546,13 @@
     return Rec(editorExtractTextFromComment(Source.getValue()));
   }
 
+  if (ReqUID == RequestMarkupToXML) {
+    Optional<StringRef> Source = Req.getString(KeySourceText);
+    if (!Source.hasValue())
+      return Rec(createErrorRequestInvalid("missing 'key.sourcetext'"));
+    return Rec(editorConvertMarkupToXML(Source.getValue()));
+  }
+
   if (ReqUID == RequestEditorFindUSR) {
     Optional<StringRef> Name = Req.getString(KeySourceFile);
     if (!Name.hasValue())
@@ -1984,6 +1994,16 @@
   return EditC.createResponse();
 }
 
+static sourcekitd_response_t editorConvertMarkupToXML(StringRef Source) {
+  SKEditorConsumer EditC(/*EnableSyntaxMap=*/false,
+                         /*EnableStructure=*/false,
+                         /*EnableDiagnostics=*/false,
+                         /*SyntacticOnly=*/true);
+  LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
+  Lang.editorConvertMarkupToXML(Source, EditC);
+  return EditC.createResponse();
+}
+
 static sourcekitd_response_t
 editorOpenHeaderInterface(StringRef Name, StringRef HeaderName,
                           ArrayRef<const char *> Args,
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp
index e7574cf..cc4fa29 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp
@@ -704,8 +704,7 @@
 }
 #endif
 
-SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL bool
-  sourcekitd_variant_array_apply_impl(
+bool sourcekitd_variant_array_apply_impl(
     sourcekitd_variant_t array,
     llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier) {
   if (auto fn = VAR_FN(array, array_apply))
diff --git a/utils/build-overlay b/utils/build-overlay
new file mode 100755
index 0000000..5c3d418
--- /dev/null
+++ b/utils/build-overlay
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+function usage {
+  echo "usage: $0 OVERLAY SDK TARGET"
+  echo "SDK: OSX,IOS,IOS_SIMULATOR,TVOS,TVOS_SIMULATOR,WATCHOS,WATCHOS_SIMULATOR"
+  echo "TARGET: macosx,iphoneos,iphonesimulator,appletvos,appletvsimulator,watchos,watchsimulator"
+  echo "example: ./utils/build-overlay AVFoundation OSX macosx"
+  exit 1
+}
+
+OVERLAY=$1; SDK=$2; TARGET=$3
+if [ ! "$OVERLAY" ]; then echo "Overlay param required"; usage; fi
+if [ ! "$SDK" ]; then echo "SDK param required"; usage; fi
+if [ ! "$TARGET" ]; then echo "TARGET param required"; usage; fi
+
+function absolute_path { if [[ "$1" == /* ]]; then echo "$1"; else echo "$PWD/$1"; fi }
+function dir_name { echo "${1%/*}"; }
+function file_name { echo "${1##*/}"; }
+script_absolute_path=$(absolute_path "${BASH_SOURCE[@]}")
+script_dir_name=$(dir_name "${script_absolute_path}")
+script_file_name=$(file_name "${script_absolute_path}")
+overlay_source_path="${script_dir_name}/../stdlib/public/SDK/$OVERLAY"
+build_dir="${script_dir_name}/../../build/${OVERLAY}-${SDK}"
+swift_source_root="${script_dir_name}/../../../"
+
+mkdir -p "$build_dir" && cd "$build_dir"
+
+echo "OVERLAY: ${OVERLAY}"
+echo "SDK: ${SDK}"
+echo "TARGET: ${TARGET}"
+echo "script_absolute_path: ${script_absolute_path}"
+echo "script_dir_name: ${script_dir_name}"
+echo "script_file_name: ${script_file_name}"
+echo "overlay_source_path: ${overlay_source_path}"
+echo "swift_source_root: ${swift_source_root}"
+echo "build_dir: ${build_dir}"
+
+toolchain=`xcode-select -p`
+cmake -G Ninja -DSWIFT_SOURCE_ROOT="${swift_source_root}" -DSWIFT_DEST_ROOT="${build_dir}/root" -DSWIFT_HOST_VARIANT_SDK="${SDK}" -DTOOLCHAIN_DIR="${toolchain}/Toolchains/XcodeDefault.xctoolchain" "${overlay_source_path}"
+NINJA_TARGET="swift${OVERLAY}-${TARGET}"
+ninja "${NINJA_TARGET}"
diff --git a/utils/build-script b/utils/build-script
index d758668..044c892 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -57,6 +57,12 @@
     SWIFT_SOURCE_ROOT, "swift", "utils", "build-script-impl")
 
 
+def exit_rejecting_arguments(message, parser = None):
+    print(message, file=sys.stderr)
+    if parser:
+        parser.print_usage(sys.stderr)
+    sys.exit(2)  # 2 is the same as `argparse` error exit code.
+
 def call_without_sleeping(command, env=None, dry_run=False, echo=False):
     """
     Execute a command during which system sleep is disabled.
@@ -303,6 +309,22 @@
         if args.cmake_generator is None:
             args.cmake_generator = "Ninja"
 
+        # --ios-all etc are not supported by open-source Swift.
+        if args.ios_all:
+            exit_rejecting_arguments("error: --ios-all is unavailable in " +
+                                     "open-source Swift.\nUse --ios to " +
+                                     "skip iOS device tests.")
+
+        if args.tvos_all:
+            exit_rejecting_arguments("error: --tvos-all is unavailable in " +
+                                     "open-source Swift.\nUse --tvos to " +
+                                     "skip tvOS device tests.")
+
+        if args.watchos_all:
+            exit_rejecting_arguments("error: --watchos-all is unavailable in " +
+                                     "open-source Swift.\nUse --watchos to " +
+                                     "skip watchOS device tests.")
+
         ninja_required = (
             args.cmake_generator == 'Ninja' or args.build_foundation)
         if ninja_required and toolchain.ninja is None:
@@ -489,18 +511,27 @@
             self.platforms_to_skip_test.add(StdlibDeploymentTarget.Cygwin)
         if args.skip_test_osx:
             self.platforms_to_skip_test.add(StdlibDeploymentTarget.OSX)
-        # iOS device tests are not supported.
-        self.platforms_to_skip_test.add(StdlibDeploymentTarget.iOS)
+        if args.skip_test_ios_host:
+            self.platforms_to_skip_test.add(StdlibDeploymentTarget.iOS)
+        else:
+            exit_rejecting_arguments("error: iOS device tests are not " +
+                                     "supported in open-source Swift.")
         if args.skip_test_ios_simulator:
             self.platforms_to_skip_test.add(
                 StdlibDeploymentTarget.iOSSimulator)
-        # tvOS device tests are not supported.
-        self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleTV)
+        if args.skip_test_tvos_host:
+            self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleTV)
+        else:
+            exit_rejecting_arguments("error: tvOS device tests are not " +
+                                     "supported in open-source Swift.")
         if args.skip_test_tvos_simulator:
             self.platforms_to_skip_test.add(
                 StdlibDeploymentTarget.AppleTVSimulator)
-        # watchOS device tests are not supported.
-        self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleWatch)
+        if args.skip_test_watchos_host:
+            self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleWatch)
+        else:
+            exit_rejecting_arguments("error: watchOS device tests are not " +
+                                     "supported in open-source Swift.")
         if args.skip_test_watchos_simulator:
             self.platforms_to_skip_test.add(
                 StdlibDeploymentTarget.AppleWatchSimulator)
@@ -1795,6 +1826,10 @@
         help="also build for iOS, but disallow tests that require an iOS "
              "device",
         action="store_true")
+    parser.add_argument("-I", "--ios-all",
+        help="also build for iOS, and allow all iOS tests",
+        action="store_true",
+        dest="ios_all")
     parser.add_argument(
         "--skip-ios",
         help="set to skip everything iOS-related",
@@ -1806,6 +1841,10 @@
         help="also build for tvOS, but disallow tests that require a tvos "
              "device",
         action=arguments.action.optional_bool)
+    parser.add_argument("--tvos-all",
+        help="also build for tvOS, and allow all tvOS tests",
+        action=arguments.action.optional_bool,
+        dest="tvos_all")
     parser.add_argument(
         "--skip-tvos",
         help="set to skip everything tvOS-related",
@@ -1817,6 +1856,10 @@
         help="also build for watchOS, but disallow tests that require an "
              "watchOS device",
         action=arguments.action.optional_bool)
+    parser.add_argument("--watchos-all",
+        help="also build for Apple watchOS, and allow all Apple watchOS tests",
+        action=arguments.action.optional_bool,
+        dest="watchos_all")
     parser.add_argument(
         "--skip-watchos",
         help="set to skip everything watchOS-related",
@@ -2116,9 +2159,7 @@
             migration.check_impl_args(build_script_impl,
                                       args.build_script_impl_args)
         except ValueError as e:
-            parser.print_usage(sys.stderr)
-            print(e, file=sys.stderr)
-            sys.exit(2)  # 2 is the same as `argparse` error exit code.
+            exit_rejecting_arguments(e, parser)
 
         if '--check-args-only' in args.build_script_impl_args:
             return 0