Merge pull request #7911 from practicalswift/remove-unused-variable-loweredMT

[gardening] Remove unused variable loweredMT
diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def
index a000471..678d17f 100644
--- a/include/swift/AST/DiagnosticsCommon.def
+++ b/include/swift/AST/DiagnosticsCommon.def
@@ -58,8 +58,6 @@
 // Generic disambiguation
 NOTE(while_parsing_as_left_angle_bracket,none,
      "while parsing this '<' as a type parameter bracket", ())
-NOTE(while_parsing_as_less_operator,none,
-     "while parsing this '<' as an operator", ())
 
 
 // FIXME: This is used both as a parse error (a literal "super" outside a
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 7adedf4..0cc1062 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -755,8 +755,6 @@
       "default arguments are not allowed in subscripts", ())
 ERROR(no_default_arg_curried,none,
       "default arguments are not allowed in curried parameter lists", ())
-WARNING(let_on_param_is_redundant, none,
-      "'let' keyword is unnecessary; function parameters are immutable by default", (unsigned))
 ERROR(var_pattern_in_var,none,
       "'%select{var|let}0' cannot appear nested inside another 'var' or "
       "'let' pattern", (unsigned))
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 42e442f..221461d 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -45,11 +45,6 @@
 NOTE(extended_type_declared_here,none,
      "extended type declared here", ())
 
-NOTE(while_converting_default_tuple_value,none,
-     "while converting default tuple value to element type %0", (Type))
-NOTE(while_converting_subscript_index,none,
-     "while converting subscript index to expected type %0", (Type))
-
 //------------------------------------------------------------------------------
 // Constraint solver diagnostics
 //------------------------------------------------------------------------------
@@ -915,8 +910,6 @@
       "%select{local function|closure}0 that captures "
       "%select{context|generic parameters|dynamic Self type}1",
       (bool, unsigned))
-NOTE(c_function_pointer_captures_here,none,
-     "%0 captured here", (Identifier))
 
 //------------------------------------------------------------------------------
 // Type Check Declarations
@@ -1508,8 +1501,6 @@
 
 ERROR(redundant_conformance,none,
       "redundant conformance of %0 to protocol %1", (Type, DeclName))
-NOTE(protocol_conformance_implied_here,none,
-     "implied protocol conformance %0 here can be made explicit", (Identifier))
 
 // "Near matches"
 WARNING(optional_req_near_match,none,
@@ -1517,9 +1508,6 @@
         (DescriptiveDeclKind, DeclName, DeclName, DeclName))
 NOTE(optional_req_nonobjc_near_match_add_objc,none,
      "add '@objc' to provide an Objective-C entrypoint", ())
-NOTE(optional_req_nonobjc_to_objc,none,
-     "rename to %0 to satisfy this requirement",
-     (DeclName))
 NOTE(optional_req_near_match_move,none,
      "move %0 to %select{an|another}1 extension to silence this warning",
      (DeclName, unsigned))
@@ -1775,8 +1763,6 @@
       "static declarations are already final", ())
 ERROR(open_decl_cannot_be_final,none,
       "%0 cannot be declared both 'final' and 'open'", (DescriptiveDeclKind))
-NOTE(decl_init_here,none,
-     "initial value is here", ())
 
 
 // Inheritance
@@ -2069,9 +2055,6 @@
 #define SELECT_APPLICATION_MAIN "select{'UIApplicationMain'|'NSApplicationMain'}"
 #define SELECT_APPLICATION_DELEGATE "select{'UIApplicationDelegate'|'NSApplicationDelegate'}"
 
-ERROR(attr_ApplicationMain_not_class,none,
-      "%" SELECT_APPLICATION_MAIN "0 attribute may only be used on classes",
-      (unsigned))
 ERROR(attr_ApplicationMain_not_ApplicationDelegate,none,
       "%" SELECT_APPLICATION_MAIN "0 class must conform to the %" SELECT_APPLICATION_DELEGATE "0 protocol",
       (unsigned))
@@ -2125,17 +2108,7 @@
      "found this candidate", ())
 NOTE(found_candidate_type,none,
      "found candidate with type %0", (Type))
-NOTE(first_declaration,none,
-     "first declaration", ())
-NOTE(second_declaration,none,
-     "second declaration", ())
 
-ERROR(no_IntegerLiteralType_found,none,
-      "standard library error: IntegerLiteralType not defined", ())
-ERROR(no_FloatLiteralType_found,none,
-      "standard library error: FloatLiteralType not defined", ())
-ERROR(no_StringLiteralType_found,none,
-      "standard library error: StringLiteralType not defined", ())
 ERROR(no_MaxBuiltinIntegerType_found,none,
    "standard library error: _MaxBuiltinIntegerType is not properly defined", ())
 ERROR(no_MaxBuiltinFloatType_found,none,
@@ -2241,9 +2214,6 @@
       "'" TRY_KIND_SELECT(0) "' following assignment operator does not cover "
       "everything to its right", (unsigned))
 
-NOTE(subscript_decl_here,none,
-     "subscript operator declared here", ())
-
 ERROR(broken_bool,none, "type 'Bool' is broken", ())
 
 WARNING(inject_forced_downcast,none,
@@ -3465,10 +3435,6 @@
         "%select{variable|parameter}1 %0 was written to, but never read",
         (Identifier, unsigned))
 
-WARNING(extraneous_default_args_in_call, none,
-        "call to %0 has extraneous arguments that could use defaults",
-        (DeclName))
-
 //------------------------------------------------------------------------------
 // Circular reference diagnostics
 //------------------------------------------------------------------------------
diff --git a/lib/IRGen/DebugTypeInfo.cpp b/lib/IRGen/DebugTypeInfo.cpp
index 551ea82..98f1546 100644
--- a/lib/IRGen/DebugTypeInfo.cpp
+++ b/lib/IRGen/DebugTypeInfo.cpp
@@ -50,16 +50,15 @@
                        Info.getBestKnownAlignment());
 }
 
-DebugTypeInfo DebugTypeInfo::getLocalVariable(DeclContext *DeclCtx,
+DebugTypeInfo DebugTypeInfo::getLocalVariable(DeclContext *DC,
                                               VarDecl *Decl, swift::Type Ty,
                                               const TypeInfo &Info,
                                               bool Unwrap) {
 
-  auto DeclType = Ty;
-  if (DeclCtx)
-    DeclType = (Decl->hasType()
-                    ? Decl->getType()
-                    : DeclCtx->mapTypeIntoContext(Decl->getInterfaceType()));
+  auto DeclType = (Decl->hasType()
+                   ? Decl->getType()
+                   : Decl->getDeclContext()->mapTypeIntoContext(
+                     Decl->getInterfaceType()));
   auto RealType = Ty;
   if (Unwrap) {
     DeclType = DeclType->getInOutObjectType();
@@ -75,7 +74,7 @@
   // the type hasn't been mucked with by an optimization pass.
   auto *Type = DeclSelfType->isEqual(RealType) ? DeclType.getPointer()
                                                : RealType.getPointer();
-  return getFromTypeInfo(DeclCtx, Type, Info);
+  return getFromTypeInfo(DC, Type, Info);
 }
 
 DebugTypeInfo DebugTypeInfo::getMetadata(swift::Type Ty, llvm::Type *StorageTy,
diff --git a/lib/IRGen/DebugTypeInfo.h b/lib/IRGen/DebugTypeInfo.h
index 87d389e..dc398e8 100644
--- a/lib/IRGen/DebugTypeInfo.h
+++ b/lib/IRGen/DebugTypeInfo.h
@@ -37,7 +37,8 @@
 /// for a type.
 class DebugTypeInfo {
 public:
-  /// The DeclContext if this is has an Archetype.
+  /// The DeclContext of the function. This might not be the DeclContext of
+  /// the variable if inlining took place.
   DeclContext *DeclCtx;
   /// The type we need to emit may be different from the type
   /// mentioned in the Decl, for example, stripped of qualifiers.
diff --git a/lib/Index/Index.cpp b/lib/Index/Index.cpp
index 52bf53c..dc07a83 100644
--- a/lib/Index/Index.cpp
+++ b/lib/Index/Index.cpp
@@ -355,7 +355,7 @@
   bool startEntity(Decl *D, IndexSymbol &Info);
   bool startEntityDecl(ValueDecl *D);
 
-  bool reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRoleSet Relations, Decl *Related);
+  bool reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit, SymbolRoleSet Relations, Decl *Related);
   bool reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related);
   bool reportInheritedTypeRefs(ArrayRef<TypeLoc> Inherited, Decl *Inheritee);
   NominalTypeDecl *getTypeLocAsNominalTypeDecl(const TypeLoc &Ty);
@@ -624,13 +624,16 @@
   return startEntity(D, Info);
 }
 
-bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, SymbolRoleSet Relations, Decl *Related) {
+bool IndexSwiftASTWalker::reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit,
+                                           SymbolRoleSet Relations, Decl *Related) {
   if (!shouldIndex(D))
     return true;
 
   IndexSymbol Info;
   if (addRelation(Info, Relations, Related))
     return true;
+  if (isImplicit)
+    Info.roles |= (unsigned)SymbolRole::Implicit;
 
   // don't report this ref again when visitDeclReference reports it
   repressRefAtLoc(Loc);
@@ -655,9 +658,24 @@
 
   if (IdentTypeRepr *T = dyn_cast_or_null<IdentTypeRepr>(Ty.getTypeRepr())) {
     auto Comps = T->getComponentRange();
-    if (auto NTD =
-            dyn_cast_or_null<NominalTypeDecl>(Comps.back()->getBoundDecl())) {
-      if (!reportRelatedRef(NTD, Comps.back()->getIdLoc(), Relations, Related))
+    SourceLoc IdLoc = Comps.back()->getIdLoc();
+    NominalTypeDecl *NTD = nullptr;
+    bool isImplicit = false;
+    if (auto *VD = Comps.back()->getBoundDecl()) {
+      if (auto *TAD = dyn_cast<TypeAliasDecl>(VD)) {
+        IndexSymbol Info;
+        if (!reportRef(TAD, IdLoc, Info))
+          return false;
+        if (auto Ty = TAD->getUnderlyingTypeLoc().getType()) {
+          NTD = Ty->getAnyNominal();
+          isImplicit = true;
+        }
+      } else {
+        NTD = dyn_cast<NominalTypeDecl>(VD);
+      }
+    }
+    if (NTD) {
+      if (!reportRelatedRef(NTD, IdLoc, isImplicit, Relations, Related))
         return false;
     }
     return true;
@@ -665,7 +683,7 @@
 
   if (Ty.getType()) {
     if (auto nominal = Ty.getType()->getAnyNominal())
-      if (!reportRelatedRef(nominal, Ty.getLoc(), Relations, Related))
+      if (!reportRelatedRef(nominal, Ty.getLoc(), /*isImplicit=*/false, Relations, Related))
         return false;
   }
   return true;
@@ -752,8 +770,8 @@
   if (!startEntity(D, Info))
     return false;
 
-  if (!reportRelatedRef(NTD, Loc, (SymbolRoleSet)SymbolRole::RelationExtendedBy,
-                        D))
+  if (!reportRelatedRef(NTD, Loc, /*isImplicit=*/false,
+                        (SymbolRoleSet)SymbolRole::RelationExtendedBy, D))
       return false;
   if (!reportInheritedTypeRefs(D->getInherited(), D))
       return false;
diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp
index b5c39b8..0a857f9 100644
--- a/lib/SILOptimizer/IPO/CapturePropagation.cpp
+++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp
@@ -248,7 +248,7 @@
                                  SILFunctionType::Representation::Thin);
   SILFunction *NewF = OrigF->getModule().createFunction(
       SILLinkage::Shared, Name, NewFTy,
-      /*contextGenericParams*/ nullptr, OrigF->getLocation(), OrigF->isBare(),
+      OrigF->getGenericEnvironment(), OrigF->getLocation(), OrigF->isBare(),
       OrigF->isTransparent(), Fragile, OrigF->isThunk(),
       OrigF->getClassVisibility(), OrigF->getInlineStrategy(),
       OrigF->getEffectsKind(),
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 21ce0d6..413bc8c 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -240,7 +240,8 @@
   auto LoweredType = SILFunctionType::get(nullptr, EInfo,
       ParameterConvention::Direct_Owned, { }, Results, None,
       Store->getModule().getASTContext());
-  auto *GetterF = Store->getModule().getOrCreateFunction(Store->getLoc(),
+  auto *GetterF = Store->getModule().getOrCreateFunction(
+      Store->getLoc(),
       getterName, SILLinkage::Private, LoweredType,
       IsBare_t::IsBare, IsTransparent_t::IsNotTransparent,
       IsFragile_t::IsFragile);
@@ -493,8 +494,9 @@
   auto LoweredType = SILFunctionType::get(nullptr, EInfo,
       ParameterConvention::Direct_Owned, { }, Results, None,
       InitF->getASTContext());
-  auto *GetterF = InitF->getModule().getOrCreateFunction(InitF->getLocation(),
-     getterName, SILLinkage::Private, LoweredType,
+  auto *GetterF = InitF->getModule().getOrCreateFunction(
+      InitF->getLocation(),
+      getterName, SILLinkage::Private, LoweredType,
       IsBare_t::IsBare, IsTransparent_t::IsNotTransparent,
       IsFragile_t::IsFragile);
   if (InitF->hasUnqualifiedOwnership())
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 3d8f05c..54b99d4 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -692,39 +692,26 @@
   // replaced by a concrete type.
   SmallVector<Substitution, 8> Substitutions;
   for (auto Subst : AI.getSubstitutions()) {
-    auto *A = Subst.getReplacement()->getAs<ArchetypeType>();
-    if (A && A == OpenedArchetype) {
-      auto Conformances = AI.getModule().getASTContext()
-                            .AllocateUninitialized<ProtocolConformanceRef>(1);
-      Conformances[0] = Conformance;
-      Substitution NewSubst(ConcreteType, Conformances);
-      Substitutions.push_back(NewSubst);
-    } else
-      Substitutions.push_back(Subst);
+    auto NewSubst = Subst.subst(
+      AI.getModule().getSwiftModule(),
+      [&](SubstitutableType *type) -> Type {
+        if (type == OpenedArchetype)
+          return ConcreteType;
+        return type;
+      },
+      [&](Type origTy, Type substTy, ProtocolType *protoType)
+        -> Optional<ProtocolConformanceRef> {
+        assert(origTy->isEqual(OpenedArchetype));
+        return Conformance;
+      });
+    Substitutions.push_back(NewSubst);
   }
 
-  SILType SubstCalleeType = AI.getSubstCalleeSILType();
-
-  SILType NewSubstCalleeType;
-
   auto FnTy = AI.getCallee()->getType().castTo<SILFunctionType>();
-  if (FnTy->isPolymorphic()) {
-    // Handle polymorphic functions by properly substituting
-    // their parameter types.
-    CanSILFunctionType SFT = FnTy->substGenericArgs(
-                                        AI.getModule(),
-                                        Substitutions);
-    NewSubstCalleeType = SILType::getPrimitiveObjectType(SFT);
-  } else {
-    NewSubstCalleeType =
-      SubstCalleeType.subst(AI.getModule(),
-                            [&](SubstitutableType *type) -> Type {
-                              if (type == OpenedArchetype)
-                                return ConcreteType;
-                              return type;
-                            },
-                            MakeAbstractConformanceForGenericType());
-  }
+  assert(FnTy->isPolymorphic());
+
+  auto SFT = FnTy->substGenericArgs(AI.getModule(), Substitutions);
+  auto NewSubstCalleeType = SILType::getPrimitiveObjectType(SFT);
 
   FullApplySite NewAI;
   Builder.setCurrentDebugScope(AI.getDebugScope());
@@ -732,14 +719,14 @@
 
   if (auto *TAI = dyn_cast<TryApplyInst>(AI))
     NewAI = Builder.createTryApply(AI.getLoc(), AI.getCallee(),
-                                    NewSubstCalleeType,
-                                    Substitutions, Args,
-                                    TAI->getNormalBB(), TAI->getErrorBB());
+                                   NewSubstCalleeType,
+                                   Substitutions, Args,
+                                   TAI->getNormalBB(), TAI->getErrorBB());
   else
     NewAI = Builder.createApply(AI.getLoc(), AI.getCallee(),
-                                 NewSubstCalleeType,
-                                 AI.getType(), Substitutions, Args,
-                                 cast<ApplyInst>(AI)->isNonThrowing());
+                                NewSubstCalleeType,
+                                AI.getType(), Substitutions, Args,
+                                cast<ApplyInst>(AI)->isNonThrowing());
 
   if (isa<ApplyInst>(NewAI))
     replaceInstUsesWith(*AI.getInstruction(), NewAI.getInstruction());
@@ -886,21 +873,6 @@
   if (WMI->getConformance().isConcrete())
     return nullptr;
 
-  // Don't specialize Apply instructions that return the Self type.
-  // Notice that it is sufficient to compare the return type to the
-  // substituted type because types that depend on the Self type are
-  // not allowed (for example [Self] is not allowed).
-  if (AI.getType().getSwiftRValueType() == WMI->getLookupType())
-    return nullptr;
-
-  // We need to handle the Self return type.
-  // In we find arguments that are not the 'self' argument and if
-  // they are of the Self type then we abort the optimization.
-  for (auto Arg : AI.getArgumentsWithoutSelf()) {
-    if (Arg->getType().getSwiftRValueType() == WMI->getLookupType())
-      return nullptr;
-  }
-
   // The lookup type is not an opened existential type,
   // thus it cannot be made more concrete.
   if (!WMI->getLookupType()->isOpenedExistential())
@@ -916,10 +888,10 @@
     // Keep around the dependence on the open instruction unless we've
     // actually eliminated the use.
     auto *NewWMI = Builder.createWitnessMethod(WMI->getLoc(),
-                                                ConcreteType,
-                                                Conformance, WMI->getMember(),
-                                                WMI->getType(),
-                                                WMI->isVolatile());
+                                               ConcreteType,
+                                               Conformance, WMI->getMember(),
+                                               WMI->getType(),
+                                               WMI->isVolatile());
     // Replace only uses of the witness_method in the apply that is going to
     // be changed.
     MutableArrayRef<Operand> Operands = AI.getInstruction()->getAllOperands();
@@ -957,15 +929,6 @@
   if (!Self)
     return nullptr;
 
-  // We need to handle the Self return type.
-  // In we find arguments that are not the 'self' argument and if
-  // they are of the Self type then we abort the optimization.
-  for (auto Arg : AI.getArgumentsWithoutSelf()) {
-    if (Arg->getType().getSwiftRValueType() ==
-        AI.getArguments().back()->getType().getSwiftRValueType())
-      return nullptr;
-  }
-
   // Obtain the protocol whose which should be used by the conformance.
   auto *AFD = dyn_cast<AbstractFunctionDecl>(Callee->getDeclContext());
   if (!AFD)
diff --git a/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
index ce6a1d1..73d41fb 100644
--- a/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
+++ b/lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp
@@ -488,10 +488,11 @@
   DEBUG(llvm::dbgs() << "  -> create specialized function " << Name << "\n");
 
   NewF = M.createFunction(linkage, Name, createOptimizedSILFunctionType(),
-                          nullptr, F->getLocation(), F->isBare(),
-                          F->isTransparent(), F->isFragile(), F->isThunk(),
-                          F->getClassVisibility(), F->getInlineStrategy(),
-                          F->getEffectsKind(), nullptr, F->getDebugScope());
+                          F->getGenericEnvironment(), F->getLocation(),
+                          F->isBare(), F->isTransparent(), F->isFragile(),
+                          F->isThunk(), F->getClassVisibility(),
+                          F->getInlineStrategy(), F->getEffectsKind(), nullptr,
+                          F->getDebugScope());
   if (F->hasUnqualifiedOwnership()) {
     NewF->setUnqualifiedOwnership();
   }
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index e2b0b7d..b78d05c 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -2507,8 +2507,13 @@
       if (!selfDecl->hasType())
         return ErrorType::get(tc.Context);
 
-      Type declaredType = selfDecl->getType()->getRValueInstanceType();
-      Type superclassTy = declaredType->getSuperclass(&tc);
+      // If the method returns 'Self', the type of 'self' is a
+      // DynamicSelfType. Unwrap it before getting the superclass.
+      auto selfTy = selfDecl->getType()->getRValueInstanceType();
+      if (auto *dynamicSelfTy = selfTy->getAs<DynamicSelfType>())
+        selfTy = dynamicSelfTy->getSelfType();
+
+      auto superclassTy = selfTy->getSuperclass(&tc);
 
       if (selfDecl->getType()->is<MetatypeType>())
         superclassTy = MetatypeType::get(superclassTy);
diff --git a/test/DebugInfo/inlined-generics.swift b/test/DebugInfo/inlined-generics.swift
index fc2c84c..3005ee3 100644
--- a/test/DebugInfo/inlined-generics.swift
+++ b/test/DebugInfo/inlined-generics.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -Xllvm -new-mangling-for-tests -Xllvm -sil-inline-generics=true %s -O -emit-sil -g -o - -emit-ir | %FileCheck %s
+// RUN: %target-swift-frontend -Xllvm -new-mangling-for-tests -Xllvm -sil-inline-generics=true %s -O -g -o - -emit-ir | %FileCheck %s
 public protocol P {
   associatedtype DT1
   func getDT() -> DT1
@@ -18,3 +18,38 @@
   // T.DT1 should get substituted with S.DT1.
   // CHECK: ![[META]] = !DILocalVariable(name: "$swift.type.S.DT1"
 }
+
+
+// More complex example -- we inline an alloc_stack that references a VarDecl
+// with generic type.
+
+public protocol Q : class {
+  associatedtype T : Equatable
+
+  var old: T? { get set }
+  var new: T? { get }
+}
+
+@inline(__always)
+public func update<S : Q>(_ s: S) -> (S.T?, S.T?)? {
+  let oldValue = s.old
+  let newValue = s.new
+
+  if oldValue != newValue {
+    s.old = newValue
+    return (oldValue, newValue)
+  } else {
+    return nil
+  }
+}
+
+public class C : Q {
+  public typealias T = String
+
+  public var old: String? = nil
+  public var new: T? = nil
+}
+
+public func updateC(_ c: C) {
+  update(c)
+}
diff --git a/test/Index/kinds.swift b/test/Index/kinds.swift
index 1ddd0bf..55d8d43 100644
--- a/test/Index/kinds.swift
+++ b/test/Index/kinds.swift
@@ -214,3 +214,13 @@
   @GKInspectable var gkString = "gk"
   // CHECK: [[@LINE-1]]:22 | instance-property(GKI)/Swift | gkString |
 }
+
+// CHECK: [[@LINE+1]]:7 | class/Swift | C1 | [[C1_USR:.*]] | Def | rel: 0
+class C1 {}
+// CHECK: [[@LINE+1]]:11 | type-alias/Swift | C1Alias | [[C1Alias_USR:.*]] | Def | rel: 0
+typealias C1Alias = C1
+// CHECK: [[@LINE+4]]:7 | class/Swift | SubC1 | [[SubC1_USR:.*]] | Def | rel: 0
+// CHECK: [[@LINE+3]]:15 | type-alias/Swift | C1Alias | [[C1Alias_USR]] | Ref | rel: 0
+// CHECK: [[@LINE+2]]:15 | class/Swift | C1 | [[C1_USR]] | Ref,Impl,RelBase | rel: 1
+// CHECK-NEXT: RelBase | SubC1 | [[SubC1_USR]]
+class SubC1 : C1Alias {}
diff --git a/test/SILGen/dynamic_self.swift b/test/SILGen/dynamic_self.swift
index e9e3708..516d34e 100644
--- a/test/SILGen/dynamic_self.swift
+++ b/test/SILGen/dynamic_self.swift
@@ -263,6 +263,61 @@
   }
 }
 
+// Super call to a method returning Self
+class Base {
+  required init() {}
+
+  func returnsSelf() -> Self {
+    return self
+  }
+
+  static func returnsSelfStatic() -> Self {
+    return self.init()
+  }
+}
+
+class Derived : Base {
+  // CHECK-LABEL: sil hidden @_T012dynamic_self7DerivedC9superCallyyF : $@convention(method) (@guaranteed Derived) -> ()
+  // CHECK: [[SELF:%.*]] = copy_value %0
+  // CHECK: [[SUPER:%.*]] = upcast [[SELF]] : $Derived to $Base
+  // CHECK: [[METHOD:%.*]] = function_ref @_T012dynamic_self4BaseC11returnsSelfACXDyF
+  // CHECK: apply [[METHOD]]([[SUPER]])
+  // CHECK: return
+  func superCall() {
+    super.returnsSelf()
+  }
+
+  // CHECK-LABEL: sil hidden @_T012dynamic_self7DerivedC15superCallStaticyyFZ : $@convention(method) (@thick Derived.Type) -> ()
+  // CHECK: [[SUPER:%.*]] = upcast %0 : $@thick Derived.Type to $@thick Base.Type
+  // CHECK: [[METHOD:%.*]] = function_ref @_T012dynamic_self4BaseC17returnsSelfStaticACXDyFZ
+  // CHECK: apply [[METHOD]]([[SUPER]])
+  // CHECK: return
+  static func superCallStatic() {
+    super.returnsSelfStatic()
+  }
+
+  // CHECK-LABEL: sil hidden @_T012dynamic_self7DerivedC32superCallFromMethodReturningSelfACXDyF : $@convention(method) (@guaranteed Derived) -> @owned Derived
+  // CHECK: [[SELF:%.*]] = copy_value %0
+  // CHECK: [[SUPER:%.*]] = upcast [[SELF]] : $Derived to $Base
+  // CHECK: [[METHOD:%.*]] = function_ref @_T012dynamic_self4BaseC11returnsSelfACXDyF
+  // CHECK: apply [[METHOD]]([[SUPER]])
+  // CHECK: return
+  func superCallFromMethodReturningSelf() -> Self {
+    super.returnsSelf()
+    return self
+  }
+
+  // CHECK-LABEL: sil hidden @_T012dynamic_self7DerivedC38superCallFromMethodReturningSelfStaticACXDyFZ : $@convention(method) (@thick Derived.Type) -> @owned Derived
+  // CHECK: [[SUPER:%.*]] = upcast %0 : $@thick Derived.Type to $@thick Base.Type
+  // CHECK: [[METHOD:%.*]] = function_ref @_T012dynamic_self4BaseC17returnsSelfStaticACXDyFZ
+  // CHECK: apply [[METHOD]]([[SUPER]])
+  // CHECK: return
+  static func superCallFromMethodReturningSelfStatic() -> Self {
+    super.returnsSelfStatic()
+    return self.init()
+  }
+}
+
 // CHECK-LABEL: sil_witness_table hidden X: P module dynamic_self {
 // CHECK: method #P.f!1: {{.*}} : @_T012dynamic_self1XCAA1PAaaDP1f{{[_0-9a-zA-Z]*}}FTW
 
diff --git a/test/SILOptimizer/devirtualize_existential.swift b/test/SILOptimizer/devirtualize_existential.swift
index 570460b..8072de8 100644
--- a/test/SILOptimizer/devirtualize_existential.swift
+++ b/test/SILOptimizer/devirtualize_existential.swift
@@ -8,12 +8,61 @@
 }
 
 // Everything gets devirtualized, inlined, and promoted to the stack.
-//CHECK: @_T024devirtualize_existential17interesting_stuffyyF
-//CHECK-NOT: init_existential_addr
-//CHECK-NOT: apply
-//CHECK: return
+// CHECK-LABEL: @_T024devirtualize_existential17interesting_stuffyyF
+// CHECK-NOT: init_existential_addr
+// CHECK-NOT: apply
+// CHECK: return
 public func interesting_stuff() {
- var x : Pingable = Foo()
+ var x: Pingable = Foo()
  x.ping(1)
 }
 
+protocol Cloneable {
+  func clone() -> Self
+  func maybeClone() -> Self?
+}
+
+struct Bar : Cloneable {
+  @inline(never)
+  func clone() -> Bar { return self }
+
+  @inline(never)
+  func maybeClone() -> Bar? { return self }
+}
+
+// In this example, we don't eliminate the init_existential_addr, because
+// of the stack allocated existential value used for the return.
+//
+// If the combiner was generalized to replace the opened existential type
+// with the concrete type in all instructions that use it, instead of just
+// special-casing witness_method and apply, we could eliminate the opened
+// existential type completely.
+//
+// However even though IRGen still performs more work at runtime than is
+// necessary here, the call is devirtualized.
+
+// CHECK-LABEL: sil @_T024devirtualize_existential22more_interesting_stuffyyF
+// CHECK: [[EXISTENTIAL:%.*]] = alloc_stack $Cloneable
+// CHECK: [[EXISTENTIAL_ADDR:%.*]] = init_existential_addr [[EXISTENTIAL]]
+// CHECK: [[VALUE:%.*]] = struct $Bar ()
+// CHECK: [[RESULT_ADDR:%.*]] = unchecked_addr_cast [[EXISTENTIAL_ADDR:%.*]]
+// CHECK: [[FN:%.*]] = function_ref @_T024devirtualize_existential3BarV5cloneACyF
+// CHECK: [[RETURN:%.*]] = apply [[FN]]([[VALUE]])
+// CHECK: store [[RETURN]] to [[RESULT_ADDR]]
+
+// CHECK: [[ENUM:%.*]] = alloc_stack $Optional<Cloneable>
+// CHECK: [[ENUM_ADDR:%.*]] = init_enum_data_addr [[ENUM]]
+// CHECK: [[EXISTENTIAL_ADDR:%.*]] = init_existential_addr [[ENUM_ADDR]]
+// CHECK: [[RESULT_ADDR:%.*]] = unchecked_addr_cast [[EXISTENTIAL_ADDR:%.*]]
+// CHECK: [[FN:%.*]] = function_ref @_T024devirtualize_existential3BarV10maybeCloneACSgyF
+// CHECK: [[RETURN:%.*]] = apply [[FN]]([[VALUE]])
+// CHECK: store [[RETURN]] to [[RESULT_ADDR]]
+
+// CHECK: return
+
+public func more_interesting_stuff() {
+  var x: Cloneable = Bar()
+
+  x.clone()
+  x.maybeClone()
+}
diff --git a/validation-test/compiler_crashers/28709-unreachable-executed-at-swift-lib-ast-type-cpp-1005.swift b/validation-test/compiler_crashers/28709-unreachable-executed-at-swift-lib-ast-type-cpp-1005.swift
new file mode 100644
index 0000000..4eb8150
--- /dev/null
+++ b/validation-test/compiler_crashers/28709-unreachable-executed-at-swift-lib-ast-type-cpp-1005.swift
@@ -0,0 +1,12 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+{
+class C{func o(UInt=1 + 1 + 1 + 1 + 1 as?Int){{
+{r
+p