Merge pull request #9996 from rudkx/fix-keypath-subscript-score-kind

Update SK_LastScoreKind to SK_KeyPathSubscript.
diff --git a/README.md b/README.md
index a29b10e..36ecd79 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@
 
 For Ubuntu, you'll need the following development dependencies:
 
-    sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-dev
+    sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libblocksruntime-dev libcurl4-openssl-dev autoconf libtool systemtap-sdt-dev tzdata
 
 **Note:** LLDB currently requires at least `swig-1.3.40` but will successfully build
 with version 2 shipped with Ubuntu.
diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
index 68dd2f6..969994d 100644
--- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
+++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
@@ -48,7 +48,6 @@
       "-target" "${target}"
       "-F" "${sdk}/../../../Developer/Library/Frameworks"
       "-${BENCH_COMPILE_ARCHOPTS_OPT}"
-      "-D" "INTERNAL_CHECKS_ENABLED"
       "-no-link-objc-runtime"
       "-I" "${srcdir}/utils/ObjectiveCTests")
 
@@ -63,7 +62,6 @@
       "-target" "${target}"
       "-F" "${sdk}/../../../Developer/Library/Frameworks"
       "-${driver_opt}"
-      "-D" "INTERNAL_CHECKS_ENABLED"
       "-no-link-objc-runtime")
 
   set(bench_library_objects)
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 292c69f..75fc706 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -11,7 +11,7 @@
 
 SET(SPHINX_ARGS
   -W
-  -D latex_paper_size=${SWIFT_SPHINX_PAPER_SIZE}
+  -D latex_elements.papersize=${SWIFT_SPHINX_PAPER_SIZE}
   -d ${CMAKE_BINARY_DIR}/doctrees)
 
 if(SPHINX_EXECUTABLE)
diff --git a/docs/Makefile b/docs/Makefile
index 8998fb1..a3100e6 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -8,8 +8,8 @@
 BUILDDIR      = _build
 
 # Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
+PAPEROPT_a4     = -D latex_elements.papersize=a4
+PAPEROPT_letter = -D latex_elements.papersize=letter
 ALLSPHINXOPTS   = -W -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
 # the i18n builder cannot share the environment and doctrees with the others
 I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
diff --git a/include/swift/AST/DebuggerClient.h b/include/swift/AST/DebuggerClient.h
index e5bcf39..2341102 100644
--- a/include/swift/AST/DebuggerClient.h
+++ b/include/swift/AST/DebuggerClient.h
@@ -48,16 +48,16 @@
   /// be consulted first.  Return true if results have been added
   /// to RV.
   /// FIXME: I don't think this ever does anything useful.
-  virtual bool lookupOverrides(Identifier Name, DeclContext *DC,
+  virtual bool lookupOverrides(DeclBaseName Name, DeclContext *DC,
                                SourceLoc Loc, bool IsTypeLookup,
                                ResultVector &RV) = 0;
- 
+
   /// This is the second time DebuggerClient is consulted:
   /// after all names in external Modules are checked, the client
   /// gets a chance to add names to the list of candidates that
-  /// have been found in the external module lookup.  
+  /// have been found in the external module lookup.
 
-  virtual bool lookupAdditions(Identifier Name, DeclContext *DC,
+  virtual bool lookupAdditions(DeclBaseName Name, DeclContext *DC,
                                SourceLoc Loc, bool IsTypeLookup,
                                ResultVector &RV) = 0;
 
diff --git a/include/swift/IDE/APIDigesterData.h b/include/swift/IDE/APIDigesterData.h
index ead967c..cd96487 100644
--- a/include/swift/IDE/APIDigesterData.h
+++ b/include/swift/IDE/APIDigesterData.h
@@ -231,6 +231,7 @@
   StringRef newPrintedName;
   Optional<uint8_t> selfIndex;
   Optional<uint8_t> removedIndex;
+  StringRef oldTypeName;
   StringRef oldPrintedName;
 
 private:
@@ -243,10 +244,10 @@
 public:
   TypeMemberDiffItem(StringRef usr, StringRef newTypeName,
                      StringRef newPrintedName, Optional<uint8_t> selfIndex,
-                     Optional<uint8_t> removedIndex,
+                     Optional<uint8_t> removedIndex, StringRef oldTypeName,
                      StringRef oldPrintedName) : usr(usr),
     newTypeName(newTypeName), newPrintedName(newPrintedName),
-    selfIndex(selfIndex), removedIndex(removedIndex),
+    selfIndex(selfIndex), removedIndex(removedIndex), oldTypeName(oldTypeName),
     oldPrintedName(oldPrintedName), OldNameViewer(oldPrintedName),
     NewNameViewer(newPrintedName), Subkind(getSubKind()) {}
   static StringRef head();
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 66965a6..064b24f 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -120,6 +120,7 @@
 DIFF_ITEM_KEY_KIND_STRING(ModuleName)
 DIFF_ITEM_KEY_KIND_STRING(NewTypeName)
 DIFF_ITEM_KEY_KIND_STRING(NewPrintedName)
+DIFF_ITEM_KEY_KIND_STRING(OldTypeName)
 DIFF_ITEM_KEY_KIND_STRING(OldPrintedName)
 DIFF_ITEM_KEY_KIND_STRING(SpecialCaseId)
 
diff --git a/lib/IDE/APIDigesterData.cpp b/lib/IDE/APIDigesterData.cpp
index 09e998d..0a1dc9c 100644
--- a/lib/IDE/APIDigesterData.cpp
+++ b/lib/IDE/APIDigesterData.cpp
@@ -325,7 +325,7 @@
       RemovedIndexShort = RemovedIndex.getValue();
     return new (Alloc.Allocate<TypeMemberDiffItem>())
       TypeMemberDiffItem(Usr, NewTypeName, NewPrintedName, SelfIndexShort,
-                         RemovedIndexShort, OldPrintedName);
+                         RemovedIndexShort, OldTypeName, OldPrintedName);
   }
   case APIDiffItemKind::ADK_NoEscapeFuncParam: {
     return new (Alloc.Allocate<NoEscapeFuncParam>())
@@ -393,6 +393,8 @@
       out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Usr), Item->usr);
       out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldPrintedName),
                       Item->oldPrintedName);
+      out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldTypeName),
+                      Item->oldTypeName);
       out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewPrintedName),
                       Item->newPrintedName);
       out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewTypeName),
diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp
index bf5ff05..792d2bb 100644
--- a/lib/IDE/Utils.cpp
+++ b/lib/IDE/Utils.cpp
@@ -798,6 +798,10 @@
     return;
   assert(Labels.back().empty());
   Labels.pop_back();
+  std::transform(Labels.begin(), Labels.end(), Labels.begin(),
+      [](StringRef Label) {
+    return Label == "_" ? StringRef() : Label;
+  });
 }
 
 unsigned DeclNameViewer::commonPartsCount(DeclNameViewer &Other) const {
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index d620895..677c30b 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -334,7 +334,7 @@
       if (Idx < NewName.argSize()) {
         auto Label = NewName.args()[Idx++];
 
-        if (Label != "_") {
+        if (!Label.empty()) {
           if (LR.getByteLength())
             Editor.replace(LR, Label);
           else
diff --git a/lib/SIL/SILOpenedArchetypesTracker.cpp b/lib/SIL/SILOpenedArchetypesTracker.cpp
index d94795b..1046efd 100644
--- a/lib/SIL/SILOpenedArchetypesTracker.cpp
+++ b/lib/SIL/SILOpenedArchetypesTracker.cpp
@@ -159,7 +159,8 @@
   // First perform a quick check.
   for (auto &Op : OpenedArchetypeOperands) {
     auto Def = Op.get();
-    if (getOpenedArchetypeOf(cast<SILInstruction>(Def)) == archetypeTy)
+    if (isa<SILInstruction>(Def) &&
+        getOpenedArchetypeOf(cast<SILInstruction>(Def)) == archetypeTy)
       return Def;
   }
   // Then use a regular lookup.
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 9ccab94..d8283c1 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -49,9 +49,9 @@
 ///    that the release occurs in the epilog after any retains associated with
 ///    @owned return values.
 ///
-/// 3. Handling addresses. We currently do not handle address types. We can in
-///    the future by introducing alloc_stacks.
-///
+/// 3. We do not support specialization of closures with arguments passed using
+///    any indirect calling conventions besides @inout and @inout_aliasable.
+///    This is a temporary limitation.
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "closure-specialization"
@@ -247,7 +247,8 @@
   }
 
   /// Extend the lifetime of 'Arg' to the lifetime of the closure.
-  void extendArgumentLifetime(SILValue Arg) const;
+  void extendArgumentLifetime(SILValue Arg,
+                              SILArgumentConvention ArgConvention) const;
 };
 } // end anonymous namespace
 
@@ -268,6 +269,13 @@
   return CInfo->Closure;
 }
 
+static bool isNonInoutIndirectSILArgument(SILValue Arg,
+                                          SILArgumentConvention ArgConvention) {
+  return !Arg->getType().isObject() && ArgConvention.isIndirectConvention() &&
+         ArgConvention != SILArgumentConvention::Indirect_Inout &&
+         ArgConvention != SILArgumentConvention::Indirect_InoutAliasable;
+}
+
 /// Update the callsite to pass in the correct arguments.
 static void rewriteApplyInst(const CallSiteDescriptor &CSDesc,
                              SILFunction *NewF) {
@@ -290,14 +298,33 @@
   // implicit release of all captured arguments that occurs when the partial
   // apply is destroyed.
   SILModule &M = NewF->getModule();
+  unsigned ClosureArgIdx = 0;
+  auto ClosureCalleeConv = CSDesc.getClosureCallee()->getConventions();
   for (auto Arg : CSDesc.getArguments()) {
-    NewArgs.push_back(Arg);
-
     SILType ArgTy = Arg->getType();
 
     // If our argument is of trivial type, continue...
-    if (ArgTy.isTrivial(M))
+    if (ArgTy.isTrivial(M)) {
+      NewArgs.push_back(Arg);
+      ++ClosureArgIdx;
       continue;
+    }
+
+    auto ArgConvention =
+        ClosureCalleeConv.getSILArgumentConvention(ClosureArgIdx);
+
+    // Non-inout indirect arguments are not supported yet.
+    assert(ArgTy.isObject() ||
+           !isNonInoutIndirectSILArgument(Arg, ArgConvention));
+
+    // If argument is not an object and it is an inout parameter,
+    // continue...
+    if (!ArgTy.isObject() &&
+        !isNonInoutIndirectSILArgument(Arg, ArgConvention)) {
+      NewArgs.push_back(Arg);
+      ++ClosureArgIdx;
+      continue;
+    }
 
     // TODO: When we support address types, this code path will need to be
     // updated.
@@ -340,15 +367,21 @@
     if (AI.getParent() != Closure->getParent()) {
       // Emit the retain and release that keeps the argument life across the
       // callee using the closure.
-      CSDesc.extendArgumentLifetime(Arg);
+      CSDesc.extendArgumentLifetime(Arg, ArgConvention);
 
-      // Emit the retain that matches the captured argument by the partial_apply
+      // Emit the retain that matches the captured argument by the
+      // partial_apply
       // in the callee that is consumed by the partial_apply.
       Builder.setInsertionPoint(AI.getInstruction());
-      Builder.createRetainValue(Closure->getLoc(), Arg, Builder.getDefaultAtomicity());
+      Builder.createRetainValue(Closure->getLoc(), Arg,
+                                Builder.getDefaultAtomicity());
     } else {
-      Builder.createRetainValue(Closure->getLoc(), Arg, Builder.getDefaultAtomicity());
+      Builder.createRetainValue(Closure->getLoc(), Arg,
+                                Builder.getDefaultAtomicity());
     }
+
+    NewArgs.push_back(Arg);
+    ++ClosureArgIdx;
   }
 
   Builder.setInsertionPoint(AI.getInstruction());
@@ -409,16 +442,27 @@
   return Mangler.mangle();
 }
 
-void CallSiteDescriptor::extendArgumentLifetime(SILValue Arg) const {
+void CallSiteDescriptor::extendArgumentLifetime(
+    SILValue Arg, SILArgumentConvention ArgConvention) const {
   assert(!CInfo->LifetimeFrontier.empty() &&
          "Need a post-dominating release(s)");
 
+  auto ArgTy = Arg->getType();
+
   // Extend the lifetime of a captured argument to cover the callee.
   SILBuilderWithScope Builder(getClosure());
-  Builder.createRetainValue(getClosure()->getLoc(), Arg, Builder.getDefaultAtomicity());
-  for (auto *I : CInfo->LifetimeFrontier) {
-    Builder.setInsertionPoint(I);
-    Builder.createReleaseValue(getClosure()->getLoc(), Arg, Builder.getDefaultAtomicity());
+
+  // Indirect non-inout arguments are not supported yet.
+  assert(!isNonInoutIndirectSILArgument(Arg, ArgConvention));
+
+  if (ArgTy.isObject()) {
+    Builder.createRetainValue(getClosure()->getLoc(), Arg,
+                              Builder.getDefaultAtomicity());
+    for (auto *I : CInfo->LifetimeFrontier) {
+      Builder.setInsertionPoint(I);
+      Builder.createReleaseValue(getClosure()->getLoc(), Arg,
+                                 Builder.getDefaultAtomicity());
+    }
   }
 }
 
@@ -437,12 +481,6 @@
     if (PAI->hasSubstitutions())
       return false;
 
-    // If any arguments are not objects, return false. This is a temporary
-    // limitation.
-    for (SILValue Arg : PAI->getArguments())
-      if (!Arg->getType().isObject())
-        return false;
-
     // Ok, it is a closure we support, set Callee.
     Callee = PAI->getCallee();
 
@@ -459,6 +497,30 @@
   if (!FRI)
     return false;
 
+  if (auto *PAI = dyn_cast<PartialApplyInst>(Closure)) {
+    // Bail if any of the arguments are passed by address and
+    // are not @inout.
+    // This is a temporary limitation.
+    auto ClosureCallee = FRI->getReferencedFunction();
+    assert(ClosureCallee);
+    auto ClosureCalleeConv = ClosureCallee->getConventions();
+    unsigned ClosureArgIdx = 0;
+    for (auto Arg : PAI->getArguments()) {
+      SILType ArgTy = Arg->getType();
+      // If our argument is an object, continue...
+      if (ArgTy.isObject()) {
+        ++ClosureArgIdx;
+        continue;
+      }
+      auto ArgConvention =
+          ClosureCalleeConv.getSILArgumentConvention(ClosureArgIdx);
+      if (ArgConvention != SILArgumentConvention::Indirect_Inout &&
+          ArgConvention != SILArgumentConvention::Indirect_InoutAliasable)
+        return false;
+      ++ClosureArgIdx;
+    }
+  }
+
   // Otherwise, we do support specializing this closure.
   return true;
 }
@@ -503,23 +565,29 @@
   SILModule &M = ClosureUser->getModule();
 
   // Captured parameters are always appended to the function signature. If the
-  // type of the captured argument is trivial, pass the argument as
-  // Direct_Unowned. Otherwise pass it as Direct_Owned.
+  // type of the captured argument is:
+  // - direct and trivial, pass the argument as Direct_Unowned.
+  // - direct and non-trivial, pass the argument as Direct_Owned.
+  // - indirect, pass the argument using the same parameter convention as in the
+  // original closure.
   //
   // We use the type of the closure here since we allow for the closure to be an
   // external declaration.
   unsigned NumTotalParams = ClosedOverFunConv.getNumParameters();
   unsigned NumNotCaptured = NumTotalParams - CallSiteDesc.getNumArguments();
   for (auto &PInfo : ClosedOverFunConv.getParameters().slice(NumNotCaptured)) {
-    if (ClosedOverFunConv.getSILType(PInfo).isTrivial(M)) {
-      SILParameterInfo NewPInfo(PInfo.getType(),
-                                ParameterConvention::Direct_Unowned);
-      NewParameterInfoList.push_back(NewPInfo);
-      continue;
+    ParameterConvention ParamConv;
+    if (PInfo.isFormalIndirect()) {
+      ParamConv = PInfo.getConvention();
+      assert(ParamConv == ParameterConvention::Indirect_Inout ||
+             ParamConv == ParameterConvention::Indirect_InoutAliasable);
+    } else {
+      ParamConv = ClosedOverFunConv.getSILType(PInfo).isTrivial(M)
+                      ? ParameterConvention::Direct_Unowned
+                      : ParameterConvention::Direct_Owned;
     }
 
-    SILParameterInfo NewPInfo(PInfo.getType(),
-                              ParameterConvention::Direct_Owned);
+    SILParameterInfo NewPInfo(PInfo.getType(), ParamConv);
     NewParameterInfoList.push_back(NewPInfo);
   }
 
diff --git a/test/SILGen/collection_cast_crash.swift b/test/SILGen/collection_cast_crash.swift
index 1eb55ed..08ddd49 100644
--- a/test/SILGen/collection_cast_crash.swift
+++ b/test/SILGen/collection_cast_crash.swift
@@ -10,28 +10,28 @@
 }
 func ==(lhs: KeyClass, rhs: KeyClass) -> Bool { return true }
 
-// CHECK-LABEL: sil shared @{{.*}}arrayUpCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}arrayUpCast{{.*}} <Ct where Ct : MyClass>
 func arrayUpCast<Ct: MyClass>(_ arr: [Ct]) -> [MyClass] {
-  // CHECK: apply %{{[0-9]*}}<Ct, MyClass>(%{{[0-9]*}})
+  // CHECK: apply %{{[0-9]*}}<Ct{{.*}}>(%{{[0-9]*}})
   return arr
   // CHECK: return	  
 }
 
-// CHECK-LABEL: sil shared @{{.*}}arrayDownCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}arrayDownCast{{.*}} <Ct where Ct : MyClass>
 func arrayDownCast<Ct: MyClass>(_ arr: [MyClass]) -> [Ct] {
-  // CHECK: apply %{{[0-9]*}}<MyClass, Ct>(%{{[0-9]*}})
+  // CHECK: apply %{{[0-9]*}}<{{.*}}Ct>(%{{[0-9]*}})
   return arr as! [Ct]
   // CHECK: return	  
 }
 
-// CHECK-LABEL: sil shared @{{.*}}dictUpCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}dictUpCast{{.*}} <Ct where Ct : MyClass>
 func dictUpCast<Ct: MyClass>(_ dict: [KeyClass:Ct]) -> [KeyClass:MyClass] {
-  // CHECK: apply %{{[0-9]*}}<KeyClass, Ct, KeyClass, MyClass>(%{{[0-9]*}})
+  // CHECK: apply %{{[0-9]*}}<{{.*}}Ct{{.*}}>(%{{[0-9]*}})
   return dict as [KeyClass:MyClass]
   // CHECK: return	  
 }
 
-// CHECK-LABEL: sil shared @{{.*}}dictDownCast{{.*}} <Ct where Ct : MyClass>
+// CHECK-LABEL: sil{{.*}}@{{.*}}dictDownCast{{.*}} <Ct where Ct : MyClass>
 func dictDownCast<Ct: MyClass>(_ dict: [KeyClass:MyClass]) -> [KeyClass:Ct] {
   // CHECK: apply %{{[0-9]*}}<KeyClass, MyClass, KeyClass, Ct>(%{{[0-9]*}})
   return dict as! [KeyClass:Ct]
diff --git a/test/SILOptimizer/closure_specialize.sil b/test/SILOptimizer/closure_specialize.sil
index d8609ac..35aa8b1 100644
--- a/test/SILOptimizer/closure_specialize.sil
+++ b/test/SILOptimizer/closure_specialize.sil
@@ -127,7 +127,9 @@
 }
 
 // We don't handle closures that close over address types (*NOTE* this includes
-// address and non-address only types). This is a temporary limitation.
+// address and non-address only types) taken as @in or @in_guaranteed.
+
+// This is a temporary limitation.
 // CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int) -> () {
 sil @address_closure : $@convention(thin) (@in Int) -> () {
 bb0(%0 : $*Int):
diff --git a/test/SILOptimizer/closure_specialize_consolidated.sil b/test/SILOptimizer/closure_specialize_consolidated.sil
index 775616e..a35705d 100644
--- a/test/SILOptimizer/closure_specialize_consolidated.sil
+++ b/test/SILOptimizer/closure_specialize_consolidated.sil
@@ -12,6 +12,17 @@
   func foo(f: (Int32)->Int32, _ j: Int32) -> Int32
 }
 
+public class C {
+  @sil_stored var c: C? { get set }
+  init()
+}
+
+public struct S {
+  @sil_stored var c: C? { get set }
+  init(c: C?)
+  init()
+}
+
 // = Test Summary =
 // We test the following things here:
 //
@@ -28,19 +39,73 @@
 // Address Argument Tests //
 ////////////////////////////
 //
-// Make sure that we do not specialize if we have address arguments. We do not
-// handle them correctly so there is a special check to not perform any action.
+// Make sure that we can specialize even if we have address arguments.
 //
-
-// We don't handle closures that close over address types (*NOTE* this includes
-// address and non-address only types). This is a temporary limitation.
-// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int) -> () {
-sil @address_closure : $@convention(thin) (@in Int) -> () {
-bb0(%0 : $*Int):
+// But we don't handle closures that close over address types passed as @in or
+// @in_guaranteed.
+// (*NOTE* this includes address and non-address only types).
+// This is a temporary limitation.
+// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int32) -> () {
+sil @address_closure : $@convention(thin) (@in Int32) -> () {
+bb0(%0 : $*Int32):
   %6 = tuple()
   return %6 : $()
 }
 
+sil @address_closure_struct_complex : $@convention(thin) (@in S) -> () {
+bb0(%0 : $*S):
+  %6 = tuple()
+  return %6 : $()
+}
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: function_ref @address_closure_trivial : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: function_ref @address_closure_trivial_mutating : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: function_ref @address_closure_existential : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: function_ref @address_closure_struct1 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: function_ref @address_closure_struct2 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+// CHECK: apply
+// CHECK: return
+
+// Check that a specialization of address_closure_user was generated which does not
+// take a closure as a parameter anymore.
+// CHECK-LABEL: sil shared @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: function_ref @address_closure_class1 : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: partial_apply %{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: apply
+// CHECK: return
+
 // CHECK-LABEL: sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () {
 sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () {
 bb0(%0 : $@callee_owned () -> ()):
@@ -49,18 +114,282 @@
   return %9999 : $()
 }
 
-// CHECK-LABEL: sil @address_caller : $@convention(thin) (@in Int) -> () {
+// CHECK-LABEL: sil @address_caller : $@convention(thin) (@in Int32) -> () {
 // CHECK-NOT: _TTSf1cl15address_closureSi__address_closure_user
-sil @address_caller : $@convention(thin) (@in Int) -> () {
-bb0(%0 : $*Int):
-  %1 = function_ref @address_closure : $@convention(thin) (@in Int) -> ()
-  %2 = partial_apply %1(%0) : $@convention(thin) (@in Int) -> ()
+sil @address_caller : $@convention(thin) (@in Int32) -> () {
+bb0(%0 : $*Int32):
+  %1 = function_ref @address_closure : $@convention(thin) (@in Int32) -> ()
+  %2 = partial_apply %1(%0) : $@convention(thin) (@in Int32) -> ()
   %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
   %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
   %9999 = tuple()
   return %9999 : $()
 }
 
+// We don't handle closures that close over address types passed as @in or
+// @in_guaranteed.
+// (*NOTE* this includes address and non-address only types).
+// This is a temporary limitation.
+//
+// CHECK-LABEL: sil @address_caller_complex : $@convention(thin) (@in Int32) -> ()
+// CHECK-NOT: function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in Int32) -> ()
+// CHECK: partial_apply
+// CHECK-NOT: function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in Int32) -> ()
+// CHECK: return
+sil @address_caller_complex : $@convention(thin) (@in Int32) -> () {
+bb0(%0 : $*Int32):
+  %00 = alloc_stack $Int32
+  %01 = load %0 : $*Int32
+  store %01 to %00 : $*Int32
+  %1 = function_ref @address_closure : $@convention(thin) (@in Int32) -> ()
+  %2 = partial_apply %1(%00) : $@convention(thin) (@in Int32) -> ()
+  %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  dealloc_stack %00 : $*Int32
+  br bb1
+
+bb1:
+  %6 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We don't handle closures that close over address types passed as @in or
+// @in_guaranteed.
+// (*NOTE* this includes address and non-address only types).
+// This is a temporary limitation.
+//
+// CHECK-LABEL: sil @address_caller_struct_complex : $@convention(thin) (@in S) -> ()
+// CHECK-NOT:  [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in S) -> ()
+// CHECK: partial_apply 
+// CHECK-NOT:  [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@in S) -> ()
+// CHECK: return
+sil @address_caller_struct_complex : $@convention(thin) (@in S) -> () {
+bb0(%0 : $*S):
+  %00 = alloc_stack $S
+  %01 = load %0 : $*S
+  retain_value %01 : $S
+  store %01 to %00 : $*S
+  %1 = function_ref @address_closure_struct_complex : $@convention(thin) (@in S) -> ()
+  %2 = partial_apply %1(%00) : $@convention(thin) (@in S) -> ()
+  %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %5  = load %00 : $*S
+  release_value %5 : $S
+  dealloc_stack %00 : $*S
+  br bb1
+
+bb1:
+  %6 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// More complex tests involving address arguments.
+
+sil @address_closure_trivial : $@convention(thin) (Int32, @inout_aliasable Int32) -> () {
+bb0(%0 : $Int32, %1 : $*Int32):
+  %9 = integer_literal $Builtin.Int32, 42
+  %10 = struct $Int32 (%9 : $Builtin.Int32)
+  store %10 to %1 : $*Int32
+  %12 = tuple ()
+  return %12 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_trivial
+// CHECK-NOT: partial_apply
+// CHECK:  [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_trivial: $@convention(thin) (Int32) -> Int32 {
+bb0(%0 : $Int32):
+  %2 = alloc_stack $Int32, var, name "xx"
+  store %0 to %2 : $*Int32
+  // function_ref address_closure_user(f:)
+  %4 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  // function_ref address_closure_trivial(x:)
+  %5 = function_ref @address_closure_trivial : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+  %6 = partial_apply %5(%0, %2) : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
+  %7 = apply %4(%6) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %8 = load %2 : $*Int32
+  dealloc_stack %2 : $*Int32
+  return %8 : $Int32
+}
+
+sil @address_closure_trivial_mutating : $@convention(thin) (@inout_aliasable Int32) -> () {
+bb0(%0 : $*Int32):
+  %2 = struct_element_addr %0 : $*Int32, #Int32._value
+  %3 = load %2 : $*Builtin.Int32
+  %4 = integer_literal $Builtin.Int32, 1
+  %5 = integer_literal $Builtin.Int1, -1
+  %6 = builtin "sadd_with_overflow_Int32"(%3 : $Builtin.Int32, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
+  %7 = tuple_extract %6 : $(Builtin.Int32, Builtin.Int1), 0
+  %8 = tuple_extract %6 : $(Builtin.Int32, Builtin.Int1), 1
+  cond_fail %8 : $Builtin.Int1
+  %10 = struct $Int32 (%7 : $Builtin.Int32)
+  store %10 to %0 : $*Int32
+  %12 = tuple ()
+  return %12 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_trivial_mutating
+// CHECK-NOT: partial_apply
+// CHECK:  [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable Int32) -> ()
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_trivial_mutating: $@convention(thin) (Int32) -> Int32 {
+bb0(%0 : $Int32):
+  %2 = alloc_stack $Int32, var, name "xx"
+  store %0 to %2 : $*Int32
+  %4 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %5 = function_ref @address_closure_trivial_mutating : $@convention(thin) (@inout_aliasable Int32) -> () // user: %6
+  %6 = partial_apply %5(%2) : $@convention(thin) (@inout_aliasable Int32) -> () // user: %7
+  %7 = apply %4(%6) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %8 = load %2 : $*Int32
+  dealloc_stack %2 : $*Int32
+  return %8 : $Int32
+}
+
+// CHECK-LABEL: sil @address_caller_existential
+// CHECK-NOT: partial_apply
+// CHECK:  [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK:  [[SPECIALIZED_FN2:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable P) -> ()
+// CHECK: apply [[SPECIALIZED_FN2]]{{.*}}
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_existential : $@convention(thin) (@in P, @in P, Int32) -> @out P {
+bb0(%0 : $*P, %1 : $*P, %2 : $*P, %3 : $Int32):
+  %7 = alloc_stack $P
+  copy_addr %1 to [initialization] %7 : $*P
+  %9 = function_ref @address_closure_existential : $@convention(thin) (@inout_aliasable P) -> ()
+  %10 = partial_apply %9(%7) : $@convention(thin) (@inout_aliasable P) -> ()
+  %12 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  strong_retain %10 : $@callee_owned () -> ()
+  %14 = apply %12(%10) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  strong_retain %10 : $@callee_owned () -> ()
+  %16 = apply %12(%10) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %17 = integer_literal $Builtin.Int32, 10
+  %18 = struct_extract %3 : $Int32, #Int32._value
+  %19 = builtin "cmp_slt_Int32"(%17 : $Builtin.Int32, %18 : $Builtin.Int32) : $Builtin.Int1
+  cond_br %19, bb1, bb2
+
+bb1:
+  destroy_addr %2 : $*P
+  copy_addr %1 to [initialization] %0 : $*P
+  destroy_addr %1 : $*P
+  strong_release %10 : $@callee_owned () -> ()
+  br bb3
+
+bb2:
+  destroy_addr %1 : $*P
+  copy_addr %2 to [initialization] %0 : $*P
+  destroy_addr %2 : $*P
+  strong_release %10 : $@callee_owned () -> ()
+  br bb3
+
+bb3:
+  destroy_addr %7 : $*P
+  dealloc_stack %7 : $*P
+  %33 = tuple ()
+  return %33 : $()
+}
+
+sil shared @address_closure_existential : $@convention(thin) (@inout_aliasable P) -> () {
+bb0(%0 : $*P):
+  %7 = tuple ()                                   // user: %8
+  return %7 : $()                                 // id: %8
+}
+
+sil @address_closure_struct1 : $@convention(thin) (@inout_aliasable S, @owned S) -> () {
+bb0(%0 : $*S, %1 : $S):
+  %4 = struct_element_addr %0 : $*S, #S.c
+  %5 = load %4 : $*Optional<C>
+  store %1 to %0 : $*S
+  release_value %5 : $Optional<C>
+  %8 = tuple ()
+  return %8 : $()
+}
+
+sil @address_closure_struct2 : $@convention(thin) (@inout_aliasable S, @owned S) -> () {
+bb0(%0 : $*S, %1 : $S):
+  %4 = struct_element_addr %0 : $*S, #S.c
+  %5 = load %4 : $*Optional<C>
+  store %1 to %0 : $*S
+  release_value %5 : $Optional<C>
+  %8 = tuple ()
+  return %8 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_struct
+// CHECK-NOT: partial_apply
+// CHECK: [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> () 
+// CHECK: apply [[SPECIALIZED_FN1]]
+// CHECK: [[SPECIALIZED_FN2:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable S, @owned S) -> () 
+// CHECK: apply [[SPECIALIZED_FN2]]
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_struct : $@convention(thin) (@guaranteed S, @guaranteed S) -> @owned S {
+bb0(%0 : $S, %1 : $S):
+  %4 = alloc_stack $S, var, name "xx"
+  %5 = struct_extract %0 : $S, #S.c
+  store %0 to %4 : $*S
+  %7 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %8 = function_ref @address_closure_struct1 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+  %9 = partial_apply %8(%4, %1) : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+  retain_value %0 : $S
+  retain_value %1 : $S
+  %12 = apply %7(%9) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %13 = function_ref @address_closure_struct2 : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+  %14 = partial_apply %13(%4, %0) : $@convention(thin) (@inout_aliasable S, @owned S) -> ()
+  retain_value %5 : $Optional<C>
+  %16 = apply %7(%14) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %17 = load %4 : $*S
+  dealloc_stack %4 : $*S
+  return %17 : $S
+}
+
+sil shared @address_closure_class1 : $@convention(thin) (@inout_aliasable C, @owned C) -> () {
+bb0(%0 : $*C, %1 : $C):
+  %4 = load %0 : $*C
+  store %1 to %0 : $*C
+  strong_release %4 : $C
+  %7 = tuple ()
+  return %7 : $()
+}
+
+// CHECK-LABEL: sil @address_caller_class1
+// CHECK-NOT: partial_apply
+// CHECK:  [[SPECIALIZED_FN1:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK:  [[SPECIALIZED_FN2:%.*]] = function_ref @{{.*}}address_closure_user{{.*}} : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+// CHECK: apply [[SPECIALIZED_FN2]]{{.*}}
+// CHECK: apply [[SPECIALIZED_FN1]]{{.*}}
+// CHECK-NOT: partial_apply
+// CHECK: return
+sil @address_caller_class1 : $@convention(thin) (@guaranteed C, @guaranteed C) -> @owned C {
+bb0(%0 : $C, %1 : $C):
+  %4 = alloc_stack $C, var, name "xx"
+  store %0 to %4 : $*C
+  %7 = function_ref @address_closure_class1 : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+  %8 = partial_apply %7(%4, %1) : $@convention(thin) (@inout_aliasable C, @owned C) -> ()
+  %10 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  strong_retain %0 : $C
+  strong_retain %1 : $C
+  strong_retain %8 : $@callee_owned () -> ()
+  %14 = apply %10(%8) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  strong_retain %8 : $@callee_owned () -> ()
+  %16 = apply %10(%8) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
+  %17 = load %4 : $*C
+  strong_retain %17 : $C
+  strong_release %8 : $@callee_owned () -> ()
+  %20 = load %4 : $*C
+  strong_release %20 : $C
+  dealloc_stack %4 : $*C
+  return %17 : $C
+}
+
 /////////////////////////////////////
 // Thin To Thick and Partial Apply //
 /////////////////////////////////////
diff --git a/test/SILOptimizer/closure_specialize_simple.sil b/test/SILOptimizer/closure_specialize_simple.sil
index f231a86..5dce016 100644
--- a/test/SILOptimizer/closure_specialize_simple.sil
+++ b/test/SILOptimizer/closure_specialize_simple.sil
@@ -190,7 +190,7 @@
 // CHECK: [[INLINEDCLOSURE_CALLER1:%.*]] = function_ref @_T040indirect_parameter_partial_apply_caller10a1_b1_c1_D4_funTf1c_n
 // CHECK-NOT: partial_apply [[CLOSUREFUN]]()
 
-// We don't handle captured indirect parameters yet.
+// We don't handle captured indirect @in and @in_guaranteed parameters yet.
 // CHECK: [[CLOSURE2:%.*]] = partial_apply [[CLOSUREFUN]](%{{.*}})
 // CHECK: [[CLOSURE3:%.*]] = partial_apply [[CLOSUREFUN]](%{{.*}})
 // CHECK: [[CLOSURE4:%.*]] = partial_apply [[CLOSUREFUN]](%{{.*}})
diff --git a/test/SILOptimizer/inline_self.swift b/test/SILOptimizer/inline_self.swift
index 31a1e82..79e657b 100644
--- a/test/SILOptimizer/inline_self.swift
+++ b/test/SILOptimizer/inline_self.swift
@@ -33,6 +33,12 @@
   fn()
 }
 
+protocol Use {
+  func use<T>(_ t: T)
+}
+
+var user: Use? = nil
+
 class BaseZ {
   final func baseCapturesSelf() -> Self {
     let fn = { [weak self] in _ = self }
@@ -41,11 +47,14 @@
   }
 }
 
-// Do not inline C.capturesSelf() into main either.
+// Do not inline C.capturesSelf() into main either. Doing so would lose the ability
+// to materialize local Self metadata.
 class Z : BaseZ {
+  @inline(__always)
   final func capturesSelf() -> Self {
     let fn = { [weak self] in _ = self }
     callIt(fn: fn)
+    user?.use(self)
     return self
   }
 
diff --git a/test/api-digester/Inputs/APINotesLeft/APINotesTest.apinotes b/test/api-digester/Inputs/APINotesLeft/APINotesTest.apinotes
new file mode 100644
index 0000000..3256892
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesLeft/APINotesTest.apinotes
@@ -0,0 +1,4 @@
+Name: APINotesTest
+Globals:
+  - Name: ANTGlobalValue
+    SwiftName: OldType.oldMember
diff --git a/test/api-digester/Inputs/APINotesLeft/APINotesTest.h b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
new file mode 100644
index 0000000..20d1c60
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
@@ -0,0 +1,6 @@
+extern int ANTGlobalValue;
+
+@interface NewType
+@end
+@interface OldType
+@end
diff --git a/test/api-digester/Inputs/APINotesLeft/module.modulemap b/test/api-digester/Inputs/APINotesLeft/module.modulemap
new file mode 100644
index 0000000..afd875a
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesLeft/module.modulemap
@@ -0,0 +1,3 @@
+module APINotesTest {
+  header "APINotesTest.h"
+}
diff --git a/test/api-digester/Inputs/APINotesRight/APINotesTest.apinotes b/test/api-digester/Inputs/APINotesRight/APINotesTest.apinotes
new file mode 100644
index 0000000..0a50e5e
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesRight/APINotesTest.apinotes
@@ -0,0 +1,4 @@
+Name: APINotesTest
+Globals:
+  - Name: ANTGlobalValue
+    SwiftName: NewType.newMember
diff --git a/test/api-digester/Inputs/APINotesRight/APINotesTest.h b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
new file mode 100644
index 0000000..5dc6d9e
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
@@ -0,0 +1,6 @@
+extern int ANTGlobalValue;
+
+@interface NewType
+@end
+@interface OldType
+@end
\ No newline at end of file
diff --git a/test/api-digester/Inputs/APINotesRight/module.modulemap b/test/api-digester/Inputs/APINotesRight/module.modulemap
new file mode 100644
index 0000000..afd875a
--- /dev/null
+++ b/test/api-digester/Inputs/APINotesRight/module.modulemap
@@ -0,0 +1,3 @@
+module APINotesTest {
+  header "APINotesTest.h"
+}
diff --git a/test/api-digester/Outputs/apinotes-migrator-gen.json b/test/api-digester/Outputs/apinotes-migrator-gen.json
new file mode 100644
index 0000000..09d2570
--- /dev/null
+++ b/test/api-digester/Outputs/apinotes-migrator-gen.json
@@ -0,0 +1,10 @@
+[
+  {
+    "DiffItemKind": "TypeMemberDiffItem",
+    "Usr": "c:@ANTGlobalValue",
+    "OldPrintedName": "oldMember",
+    "OldTypeName": "OldType",
+    "NewPrintedName": "newMember",
+    "NewTypeName": "NewType"
+  }
+]
\ No newline at end of file
diff --git a/test/api-digester/apinotes-migrator-gen.swift b/test/api-digester/apinotes-migrator-gen.swift
new file mode 100644
index 0000000..7210b91
--- /dev/null
+++ b/test/api-digester/apinotes-migrator-gen.swift
@@ -0,0 +1,8 @@
+// REQUIRES: OS=macosx
+// RUN: rm -rf %t.mod && mkdir -p %t.mod
+// RUN: rm -rf %t.sdk && mkdir -p %t.sdk
+// RUN: rm -rf %t.module-cache && mkdir -p %t.module-cache
+// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesLeft
+// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesRight
+// RUN: %api-digester -compare-sdk --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result -json
+// RUN: diff -u %S/Outputs/apinotes-migrator-gen.json %t.result
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index e21d589..64a53fc 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -2159,9 +2159,15 @@
     auto diffParent = diffNode->getParent();
     assert(nodeParent && diffParent && "trying to check Root?");
 
+    // Move from global variable to a member variable.
     if (nodeParent->getKind() == SDKNodeKind::TypeDecl &&
         diffParent->getKind() == SDKNodeKind::Root)
       TypeMemberDiffs.push_back({diffNode, node});
+    // Move from a member variable to another member variable
+    if (nodeParent->getKind() == SDKNodeKind::TypeDecl &&
+        diffParent->getKind() == SDKNodeKind::TypeDecl)
+      TypeMemberDiffs.push_back({diffNode, node});
+    // Move from a getter/setter function to a property
     else if (node->getKind() == SDKNodeKind::Getter &&
              diffNode->getKind() == SDKNodeKind::Function &&
              node->isNameValid()) {
@@ -2998,6 +3004,7 @@
   RenameDetectorForMemberDiff Detector;
   for (auto pair : diffFinder.getDiffs()) {
     auto left = pair.first;
+    auto leftParent = left->getParent();
     auto right = pair.second;
     auto rightParent = right->getParent();
 
@@ -3006,6 +3013,8 @@
     TypeMemberDiffItem item = {
         right->getAs<SDKNodeDecl>()->getUsr(), constructFullTypeName(rightParent),
         right->getPrintedName(), findSelfIndex(right), None,
+        leftParent->getKind() == SDKNodeKind::Root ?
+          StringRef() : constructFullTypeName(leftParent),
         left->getPrintedName()};
     out.emplace_back(item);
     Detector.workOn(left, right);
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 5280119..07bde7a 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -108,13 +108,13 @@
     return false;
   }
   void didGlobalize(Decl *D) override {}
-  bool lookupOverrides(Identifier Name, DeclContext *DC,
+  bool lookupOverrides(DeclBaseName Name, DeclContext *DC,
                        SourceLoc Loc, bool IsTypeLookup,
                        ResultVector &RV) override {
     return false;
   }
 
-  bool lookupAdditions(Identifier Name, DeclContext *DC,
+  bool lookupAdditions(DeclBaseName Name, DeclContext *DC,
                        SourceLoc Loc, bool IsTypeLookup,
                        ResultVector &RV) override {
     return false;