Merge pull request #13945 from airspeedswift/array-protocol

diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 6747434..7d96782 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -3079,6 +3079,11 @@
     return result;
   }
 
+  /// If this enum has a unique element, return it. A unique element can
+  /// either hold a value or not, and the existence of one unique element does
+  /// not imply the existence or non-existence of the opposite unique element.
+  EnumElementDecl *getUniqueElement(bool hasValue) const;
+
   /// Return a range that iterates over all the cases of an enum.
   CaseRange getAllCases() const {
     return CaseRange(getMembers());
@@ -6522,6 +6527,20 @@
   }
 }
 
+inline EnumElementDecl *EnumDecl::getUniqueElement(bool hasValue) const {
+  EnumElementDecl *result = nullptr;
+  bool found = false;
+  for (auto elt : getAllElements()) {
+    if (elt->hasAssociatedValues() == hasValue) {
+      if (found)
+        return nullptr;
+      found = true;
+      result = elt;
+    }
+  }
+  return result;
+}
+
 } // end namespace swift
 
 #endif
diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def
index 16d2fd7..bb04564 100644
--- a/include/swift/AST/KnownIdentifiers.def
+++ b/include/swift/AST/KnownIdentifiers.def
@@ -72,7 +72,6 @@
 IDENTIFIER(Iterator)
 IDENTIFIER(load)
 IDENTIFIER(next)
-IDENTIFIER(none)
 IDENTIFIER_(nsErrorDomain)
 IDENTIFIER(objectAtIndexedSubscript)
 IDENTIFIER(objectForKeyedSubscript)
@@ -89,7 +88,6 @@
 IDENTIFIER(Self)
 IDENTIFIER(setObject)
 IDENTIFIER(simd)
-IDENTIFIER(some)
 IDENTIFIER(storage)
 IDENTIFIER(stringValue)
 IDENTIFIER(super)
diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h
index 185cbce..539f97a 100644
--- a/include/swift/SIL/SILDeclRef.h
+++ b/include/swift/SIL/SILDeclRef.h
@@ -114,10 +114,6 @@
     /// accessor for the global VarDecl in loc.
     GlobalAccessor,
 
-    /// GlobalGetter - this constant references the lazy-initializing
-    /// getter for the global VarDecl.
-    GlobalGetter,
-
     /// References the generator for a default argument of a function.
     DefaultArgGenerator,
 
@@ -245,7 +241,7 @@
   }
   /// True if the SILDeclRef references a global variable accessor.
   bool isGlobal() const {
-    return kind == Kind::GlobalAccessor || kind == Kind::GlobalGetter;
+    return kind == Kind::GlobalAccessor;
   }
   /// True if the SILDeclRef references the generator for a default argument of
   /// a function.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 585ce99..3bae3d0 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -651,14 +651,6 @@
   llvm_unreachable("Unhandled OptionalTypeKind in switch.");
 }
 
-static EnumElementDecl *findEnumElement(EnumDecl *e, Identifier name) {
-  for (auto elt : e->getAllElements()) {
-    if (elt->getName() == name)
-      return elt;
-  }
-  return nullptr;
-}
-
 EnumElementDecl *ASTContext::getOptionalSomeDecl(OptionalTypeKind kind) const {
   switch (kind) {
   case OTK_Optional:
@@ -685,27 +677,27 @@
 
 EnumElementDecl *ASTContext::getOptionalSomeDecl() const {
   if (!Impl.OptionalSomeDecl)
-    Impl.OptionalSomeDecl = findEnumElement(getOptionalDecl(), Id_some);
+    Impl.OptionalSomeDecl = getOptionalDecl()->getUniqueElement(/*hasVal*/true);
   return Impl.OptionalSomeDecl;
 }
 
 EnumElementDecl *ASTContext::getOptionalNoneDecl() const {
   if (!Impl.OptionalNoneDecl)
-    Impl.OptionalNoneDecl = findEnumElement(getOptionalDecl(), Id_none);
+    Impl.OptionalNoneDecl =getOptionalDecl()->getUniqueElement(/*hasVal*/false);
   return Impl.OptionalNoneDecl;
 }
 
 EnumElementDecl *ASTContext::getImplicitlyUnwrappedOptionalSomeDecl() const {
   if (!Impl.ImplicitlyUnwrappedOptionalSomeDecl)
     Impl.ImplicitlyUnwrappedOptionalSomeDecl =
-      findEnumElement(getImplicitlyUnwrappedOptionalDecl(), Id_some);
+      getImplicitlyUnwrappedOptionalDecl()->getUniqueElement(/*hasVal*/true);
   return Impl.ImplicitlyUnwrappedOptionalSomeDecl;
 }
 
 EnumElementDecl *ASTContext::getImplicitlyUnwrappedOptionalNoneDecl() const {
   if (!Impl.ImplicitlyUnwrappedOptionalNoneDecl)
     Impl.ImplicitlyUnwrappedOptionalNoneDecl =
-      findEnumElement(getImplicitlyUnwrappedOptionalDecl(), Id_none);
+      getImplicitlyUnwrappedOptionalDecl()->getUniqueElement(/*hasVal*/false);
   return Impl.ImplicitlyUnwrappedOptionalNoneDecl;
 }
 
diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp
index 8f02131..7151e6f 100644
--- a/lib/IRGen/GenObjC.cpp
+++ b/lib/IRGen/GenObjC.cpp
@@ -540,7 +540,6 @@
       case SILDeclRef::Kind::StoredPropertyInitializer:
       case SILDeclRef::Kind::EnumElement:
       case SILDeclRef::Kind::GlobalAccessor:
-      case SILDeclRef::Kind::GlobalGetter:
         llvm_unreachable("Method does not have a selector");
 
       case SILDeclRef::Kind::Destroyer:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index e9b6750..eb02d5a 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -143,7 +143,7 @@
       TheParser.setCodeCompletionCallbacks(CodeCompletion.get());
     }
     bool Parsed = false;
-    if (auto accessor = dyn_cast<AccessorDecl>(AFD)) {
+    if (isa<AccessorDecl>(AFD)) {
       TheParser.parseAccessorBodyDelayed(AFD);
       Parsed = true;
     }
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 50d7356..8507aa1 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -1310,9 +1310,6 @@
       } else if (!ParseState && Id.str() == "globalaccessor") {
         Kind = SILDeclRef::Kind::GlobalAccessor;
         ParseState = 1;
-      } else if (!ParseState && Id.str() == "globalgetter") {
-        Kind = SILDeclRef::Kind::GlobalGetter;
-        ParseState = 1;
       } else if (!ParseState && Id.str() == "ivardestroyer") {
         Kind = SILDeclRef::Kind::IVarDestroyer;
         ParseState = 1;
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index 10c12f5..a0da3fa 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -650,10 +650,6 @@
                                         /*isStatic*/ false,
                                         SKind);
 
-  case SILDeclRef::Kind::GlobalGetter:
-    assert(!isCurried);
-    return mangler.mangleGlobalGetterEntity(getDecl(), SKind);
-
   case SILDeclRef::Kind::DefaultArgGenerator:
     assert(!isCurried);
     return mangler.mangleDefaultArgumentEntity(
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 76ab8ef..9977c29 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -1267,7 +1267,6 @@
       LLVM_FALLTHROUGH;
     case SILDeclRef::Kind::Destroyer:
     case SILDeclRef::Kind::GlobalAccessor:
-    case SILDeclRef::Kind::GlobalGetter:
     case SILDeclRef::Kind::DefaultArgGenerator:
     case SILDeclRef::Kind::StoredPropertyInitializer:
     case SILDeclRef::Kind::IVarInitializer:
@@ -1796,7 +1795,6 @@
   case SILDeclRef::Kind::Destroyer:
   case SILDeclRef::Kind::Deallocator:
   case SILDeclRef::Kind::GlobalAccessor:
-  case SILDeclRef::Kind::GlobalGetter:
   case SILDeclRef::Kind::IVarDestroyer:
   case SILDeclRef::Kind::DefaultArgGenerator:
   case SILDeclRef::Kind::StoredPropertyInitializer:
@@ -2031,7 +2029,6 @@
 
   switch (c.kind) {
     case SILDeclRef::Kind::GlobalAccessor:
-    case SILDeclRef::Kind::GlobalGetter:
     case SILDeclRef::Kind::DefaultArgGenerator:
     case SILDeclRef::Kind::StoredPropertyInitializer:
       return SILFunctionTypeRepresentation::Thin;
@@ -2552,7 +2549,6 @@
   case SILDeclRef::Kind::Destroyer:
   case SILDeclRef::Kind::Deallocator:
   case SILDeclRef::Kind::GlobalAccessor:
-  case SILDeclRef::Kind::GlobalGetter:
   case SILDeclRef::Kind::DefaultArgGenerator:
   case SILDeclRef::Kind::StoredPropertyInitializer:
   case SILDeclRef::Kind::IVarInitializer:
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 6cd5e6c..3fcdc10 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -344,9 +344,6 @@
   case SILDeclRef::Kind::GlobalAccessor:
     OS << "!globalaccessor";
     break;
-  case SILDeclRef::Kind::GlobalGetter:
-    OS << "!globalgetter";
-    break;
   case SILDeclRef::Kind::DefaultArgGenerator:
     OS << "!defaultarg" << "." << defaultArgIndex;
     break;
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index a4ff6b0..4e4cf70 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -1720,12 +1720,6 @@
   return CanFunctionType::get(TupleType::getEmpty(C), C.TheRawPointerType);
 }
 
-/// Get the type of a global variable getter function.
-static CanAnyFunctionType getGlobalGetterType(CanType varType) {
-  ASTContext &C = varType->getASTContext();
-  return CanFunctionType::get(TupleType::getEmpty(C), varType);
-}
-
 /// Get the type of a default argument generator, () -> T.
 static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
                                                      TypeConverter &TC,
@@ -1920,12 +1914,6 @@
            "constant ref to computed global var");
     return getGlobalAccessorType(var->getInterfaceType()->getCanonicalType());
   }
-  case SILDeclRef::Kind::GlobalGetter: {
-    VarDecl *var = cast<VarDecl>(vd);
-    assert(var->hasStorage() &&
-           "constant ref to computed global var");
-    return getGlobalGetterType(var->getInterfaceType()->getCanonicalType());
-  }
   case SILDeclRef::Kind::DefaultArgGenerator:
     return getDefaultArgGeneratorInterfaceType(*this,
                                                cast<AbstractFunctionDecl>(vd),
@@ -1977,9 +1965,7 @@
     return getEffectiveGenericEnvironment(afd, captureInfo);
   }
   case SILDeclRef::Kind::GlobalAccessor:
-  case SILDeclRef::Kind::GlobalGetter: {
     return vd->getDeclContext()->getGenericEnvironmentOfContext();
-  }
   case SILDeclRef::Kind::IVarInitializer:
   case SILDeclRef::Kind::IVarDestroyer:
     return cast<ClassDecl>(vd)->getGenericEnvironmentOfContext();
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 602badb..ceb7e22 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -1038,20 +1038,6 @@
   });
 }
 
-void SILGenModule::emitGlobalGetter(VarDecl *global,
-                                    SILGlobalVariable *onceToken,
-                                    SILFunction *onceFunc) {
-  SILDeclRef accessor(global, SILDeclRef::Kind::GlobalGetter);
-  emitOrDelayFunction(*this, accessor,
-                      [this,accessor,global,onceToken,onceFunc](SILFunction *f){
-    preEmitFunction(accessor, global, f, global);
-    PrettyStackTraceSILFunction X("silgen emitGlobalGetter", f);
-    SILGenFunction(*this, *f)
-      .emitGlobalGetter(global, onceToken, onceFunc);
-    postEmitFunction(accessor, f);
-  });
-}
-
 void SILGenModule::emitDefaultArgGenerators(SILDeclRef::Loc decl,
                                             ParameterList *paramList) {
   unsigned index = 0;
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index d0a2001..71918f8 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -329,10 +329,6 @@
                           SILGlobalVariable *onceToken,
                           SILFunction *onceFunc);
 
-  void emitGlobalGetter(VarDecl *global,
-                        SILGlobalVariable *onceToken,
-                        SILFunction *onceFunc);
-  
   /// True if the given function requires an entry point for ObjC method
   /// dispatch.
   bool requiresObjCMethodEntryPoint(FuncDecl *method);
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index 79ca9ff..ddcbe04 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -108,7 +108,6 @@
   case SILDeclRef::Kind::Destroyer:
     return getMagicFunctionName(cast<DestructorDecl>(ref.getDecl()));
   case SILDeclRef::Kind::GlobalAccessor:
-  case SILDeclRef::Kind::GlobalGetter:
     return getMagicFunctionName(cast<VarDecl>(ref.getDecl())->getDeclContext());
   case SILDeclRef::Kind::DefaultArgGenerator:
     return getMagicFunctionName(cast<AbstractFunctionDecl>(ref.getDecl()));
@@ -432,8 +431,6 @@
     CanType NSStringTy = SGM.Types.getNSStringType();
     CanType OptNSStringTy
       = OptionalType::get(NSStringTy)->getCanonicalType();
-    CanType IUOptNSStringTy
-      = ImplicitlyUnwrappedOptionalType::get(NSStringTy)->getCanonicalType();
 
     // Look up UIApplicationMain.
     // FIXME: Doing an AST lookup here is gross and not entirely sound;
@@ -499,21 +496,9 @@
     assert(nameArgTy == fnConv.getSILArgumentType(2));
     auto managedName = ManagedValue::forUnmanaged(optName);
     SILValue nilValue;
-    if (optName->getType() == nameArgTy) {
-      nilValue = getOptionalNoneValue(mainClass,
-                                      getTypeLowering(OptNSStringTy));
-    } else {
-      assert(nameArgTy.getSwiftRValueType() == IUOptNSStringTy);
-      nilValue = getOptionalNoneValue(mainClass,
-                                      getTypeLowering(IUOptNSStringTy));
-      managedName = emitOptionalToOptional(
-          mainClass, managedName,
-          SILType::getPrimitiveObjectType(IUOptNSStringTy),
-          [](SILGenFunction &, SILLocation, ManagedValue input, SILType,
-             SGFContext) {
-        return input;
-      });
-    }
+    assert(optName->getType() == nameArgTy);
+    nilValue = getOptionalNoneValue(mainClass,
+                                    getTypeLowering(OptNSStringTy));
 
     // Fix up argv to have the right type.
     auto argvTy = fnConv.getSILArgumentType(1);
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index 94536ba..679ad1b 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -542,10 +542,6 @@
                           SILGlobalVariable *onceToken,
                           SILFunction *onceFunc);
 
-  void emitGlobalGetter(VarDecl *global,
-                        SILGlobalVariable *onceToken,
-                        SILFunction *onceFunc);
-  
   /// Generate a protocol witness entry point, invoking 'witness' at the
   /// abstraction level of 'requirement'.
   ///
diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp
index c373f0d..48f4c26 100644
--- a/lib/SILGen/SILGenGlobalVariable.cpp
+++ b/lib/SILGen/SILGenGlobalVariable.cpp
@@ -296,18 +296,3 @@
   assert(ret->getDebugScope() && "instruction without scope");
 }
 
-void SILGenFunction::emitGlobalGetter(VarDecl *global,
-                                      SILGlobalVariable *onceToken,
-                                      SILFunction *onceFunc) {
-  emitOnceCall(*this, global, onceToken, onceFunc);
-
-  auto *silG = SGM.getSILGlobalVariable(global, NotForDefinition);
-  SILValue addr = B.createGlobalAddr(global, silG);
-
-  auto refType = global->getInterfaceType()->getCanonicalType();
-  ManagedValue value = emitLoad(global, addr, getTypeLowering(refType),
-                                SGFContext(), IsNotTake);
-  SILValue result = value.forward(*this);
-  B.createReturn(global, result);
-}
-
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index aaa3f30..38af939 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -2191,7 +2191,9 @@
   }
   
   // Before the memory allocation, store zero in the control variable.
-  B.setInsertionPoint(&*std::next(TheMemory.MemoryInst->getIterator()));
+  auto *InsertPoint = &*std::next(TheMemory.MemoryInst->getIterator());
+  B.setInsertionPoint(InsertPoint);
+  B.setCurrentDebugScope(InsertPoint->getDebugScope());
   SILValue ControlVariableAddr = ControlVariableBox;
   auto Zero = B.createIntegerLiteral(Loc, IVType, 0);
   B.createStore(Loc, Zero, ControlVariableAddr,
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 0c912c3..b150808 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -3900,8 +3900,11 @@
       if (!choices[i].isDecl()) {
         return SolutionKind::Error;
       }
+      auto storage = dyn_cast<AbstractStorageDecl>(choices[i].getDecl());
+      if (!storage) {
+        return SolutionKind::Error;
+      }
       
-      auto storage = cast<AbstractStorageDecl>(choices[i].getDecl());
       if (!storage->isSettable(DC)) {
         // A non-settable component makes the key path read-only, unless
         // a reference-writable component shows up later.
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index 4f9db18..5571060 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -25,10 +25,10 @@
 
 FragileFunctionKind TypeChecker::getFragileFunctionKind(const DeclContext *DC) {
   for (; DC->isLocalContext(); DC = DC->getParent()) {
-    if (auto *DAI = dyn_cast<DefaultArgumentInitializer>(DC))
+    if (isa<DefaultArgumentInitializer>(DC))
       return FragileFunctionKind::DefaultArgument;
 
-    if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC))
+    if (isa<PatternBindingInitializer>(DC))
       return FragileFunctionKind::PropertyInitializer;
 
     if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 662071b..799e27d 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -1231,10 +1231,11 @@
     if (numExtraOptionals > 0) {
       Pattern *sub = IP;
       for (int i = 0; i < numExtraOptionals; ++i) {
+        auto some = Context.getOptionalDecl()->getUniqueElement(/*hasVal*/true);
         sub = new (Context) EnumElementPattern(TypeLoc(),
                                                IP->getStartLoc(),
                                                IP->getEndLoc(),
-                                               Context.Id_some,
+                                               some->getName(),
                                                nullptr, sub,
                                                /*Implicit=*/true);
       }
diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil
index d7428cd..276046e 100644
--- a/test/SIL/Parser/basic.sil
+++ b/test/SIL/Parser/basic.sil
@@ -1,7 +1,4 @@
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=false %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=false | %FileCheck %s
-//
-// FIXME: Enable sil-verify-all in both commands above:
-//        SIL Parsing fails on vtables: <rdar://problem/24060338> Identify problems with textual SIL and fix them.
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true | %FileCheck %s
 
 sil_stage raw // CHECK: sil_stage raw
 
@@ -1160,7 +1157,7 @@
   init()
 }
 
-sil @_TFC3tmp3Foog9subscriptFTVs5Int32S1__S1_ : $@convention(method) (Int32, Int32, Foo) -> Int32 {
+sil @Foo_subscript_getter : $@convention(method) (Int32, Int32, @guaranteed Foo) -> Int32 {
 bb0(%0 : $Int32, %1 : $Int32, %2 : $Foo):
   %3 = tuple ()
   %4 = alloc_stack $Int32  // var x               // users: %17, %6
@@ -1172,14 +1169,13 @@
   %10 = metatype $@thin Int32.Type
   %12 = integer_literal $Builtin.Int32, 0         // user: %13
   %13 = struct $Int32 (%12 : $Builtin.Int32)      // user: %18
-  destroy_addr %8 : $*Foo
   dealloc_stack %8 : $*Foo
   dealloc_stack %5 : $*Int32
   dealloc_stack %4 : $*Int32
   return %13 : $Int32
 }
 
-sil @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_ : $@convention(method) (Int32, Int32, Int32, Foo) -> () {
+sil @Foo_subscript_setter : $@convention(method) (Int32, Int32, Int32, @guaranteed Foo) -> () {
 bb0(%0 : $Int32, %1 : $Int32, %2 : $Int32, %3 : $Foo):
   %4 = alloc_stack $Int32  // var value           // users: %16, %5
   store %0 to %4 : $*Int32
@@ -1189,7 +1185,6 @@
   store %2 to %7 : $*Int32
   %10 = alloc_stack $Foo  // var self             // users: %13, %12, %11
   store %3 to %10 : $*Foo
-  destroy_addr %10 : $*Foo
   dealloc_stack %10 : $*Foo
   dealloc_stack %7 : $*Int32
   dealloc_stack %6 : $*Int32
@@ -1638,12 +1633,12 @@
 }
 
 // CHECK-LABEL: sil_vtable Foo {
-// CHECK: #Foo.subscript!getter.1: {{.*}} : hidden @_TFC3tmp3Foog9subscriptFTVs5Int32S1__S1_
-// CHECK: #Foo.subscript!setter.1: {{.*}} : @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_
+// CHECK: #Foo.subscript!getter.1: {{.*}} : hidden @Foo_subscript_getter
+// CHECK: #Foo.subscript!setter.1: {{.*}} : @Foo_subscript_setter
 // CHECK: }
 sil_vtable Foo {
-  // Override the linke to check if it is parsed correctly.
-  #Foo.subscript!getter.1: hidden @_TFC3tmp3Foog9subscriptFTVs5Int32S1__S1_
+  // Override the linkage to check if it is parsed correctly.
+  #Foo.subscript!getter.1: hidden @Foo_subscript_getter
   // The public linkage is the same as the function's linkage and should not be printed.
-  #Foo.subscript!setter.1: public @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_
+  #Foo.subscript!setter.1: public @Foo_subscript_setter
 }
diff --git a/test/SILOptimizer/definite-init-wrong-scope2.swift b/test/SILOptimizer/definite-init-wrong-scope2.swift
new file mode 100644
index 0000000..4e05133
--- /dev/null
+++ b/test/SILOptimizer/definite-init-wrong-scope2.swift
@@ -0,0 +1,26 @@
+// RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm -sil-print-debuginfo \
+// RUN:   -o /dev/null -Xllvm -sil-print-after=definite-init \
+// RUN:   -Xllvm -sil-print-only-functions=$S8patatino4BearC6before7before26during5afterACSb_S3btKcfc \
+// RUN:   2>&1 | %FileCheck %s
+// REQUIRES: executable_test
+
+import StdlibUnittest
+
+func unwrap(_ b: Bool) throws -> Int {
+  return 0
+}
+class Bear {
+  let x: LifetimeTracked
+  init(n: Int, before: Bool) throws {
+    self.x = LifetimeTracked(0)
+  }
+  init(n: Int, after: Bool) throws {
+    self.x = LifetimeTracked(0)
+  }
+  convenience init(before: Bool, before2: Bool, during: Bool, after: Bool) throws {
+    try self.init(n: unwrap(before2), after: during)
+  }
+}
+
+// CHECK: %7 = integer_literal $Builtin.Int1, 0, loc {{.*}}:20:15, scope 1
+// CHECK-NEXT:  store %7 to [trivial] %5 : $*Builtin.Int1, loc {{.*}}:20:15, scope 1
diff --git a/test/expr/unary/keypath/keypath.swift b/test/expr/unary/keypath/keypath.swift
index 2498292..e7e6f63 100644
--- a/test/expr/unary/keypath/keypath.swift
+++ b/test/expr/unary/keypath/keypath.swift
@@ -485,6 +485,20 @@
   }
 }
 
+// SR-6744
+func sr6744() {
+    struct ABC {
+        let value: Int
+        func value(adding i: Int) -> Int { return value + i }
+    }
+
+    let abc = ABC(value: 0)
+    func get<T>(for kp: KeyPath<ABC, T>) -> T {
+        return abc[keyPath: kp]
+    }
+    _ = get(for: \.value)
+}
+
 func testSyntaxErrors() { // expected-note{{}}
   _ = \.  ; // expected-error{{expected member name following '.'}}
   _ = \.a ;
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 943ae43..d4fddf9 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -302,7 +302,8 @@
   StringRef SuperclassUsr;
   SDKNodeInitInfo(SDKContext &Ctx) : Ctx(Ctx) {}
   SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD);
-  SDKNodeInitInfo(SDKContext &Ctx, Type Ty);
+  SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
+                  bool IsImplicitlyUnwrappedOptional =false);
   SDKNode* createSDKNode(SDKNodeKind Kind);
 };
 
@@ -1029,16 +1030,21 @@
   SDKNodeDumpVisitor() {};
 };
 
-static StringRef getPrintedName(SDKContext &Ctx, Type Ty) {
+static StringRef getPrintedName(SDKContext &Ctx, Type Ty,
+                                bool IsImplicitlyUnwrappedOptional) {
   std::string S;
   llvm::raw_string_ostream OS(S);
   PrintOptions PO;
   PO.SkipAttributes = true;
+  if (IsImplicitlyUnwrappedOptional)
+    PO.PrintOptionalAsImplicitlyUnwrapped = true;
+
   Ty.print(OS, PO);
   return Ctx.buffer(OS.str());
 }
 
-static StringRef getTypeName(SDKContext &Ctx, Type Ty) {
+static StringRef getTypeName(SDKContext &Ctx, Type Ty,
+                             bool IsImplicitlyUnwrappedOptional) {
   if (Ty->getKind() == TypeKind::Paren) {
     return Ctx.buffer("Paren");
   }
@@ -1049,6 +1055,10 @@
     return NAT->getDecl()->getNameStr();
   }
   if (Ty->getAnyNominal()) {
+    if (IsImplicitlyUnwrappedOptional) {
+      assert(Ty->getAnyOptionalObjectType());
+      return StringRef("ImplicitlyUnwrappedOptional");
+    }
     return Ty->getAnyNominal()->getNameStr();
   }
 #define TYPE(id, parent)                                                      \
@@ -1159,8 +1169,10 @@
   return Ownership::Strong;
 }
 
-SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty) :
-    Ctx(Ctx), Name(getTypeName(Ctx, Ty)), PrintedName(getPrintedName(Ctx, Ty)) {
+SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
+                                 bool IsImplicitlyUnwrappedOptional) :
+    Ctx(Ctx), Name(getTypeName(Ctx, Ty, IsImplicitlyUnwrappedOptional)),
+    PrintedName(getPrintedName(Ctx, Ty, IsImplicitlyUnwrappedOptional)) {
   if (isFunctionTypeNoEscape(Ty))
     TypeAttrs.push_back(TypeAttrKind::TAK_noescape);
 }
@@ -1196,8 +1208,10 @@
 
 // Recursively construct a node that represents a type, for instance,
 // representing the return value type of a function decl.
-static SDKNode *constructTypeNode(SDKContext &Ctx, Type T) {
-  SDKNode* Root = SDKNodeInitInfo(Ctx, T).createSDKNode(SDKNodeKind::TypeNominal);
+static SDKNode *constructTypeNode(SDKContext &Ctx, Type T,
+                                  bool IsImplicitlyUnwrappedOptional =false) {
+  SDKNode* Root = SDKNodeInitInfo(Ctx, T, IsImplicitlyUnwrappedOptional)
+    .createSDKNode(SDKNodeKind::TypeNominal);
 
   if (auto NAT = dyn_cast<NameAliasType>(T.getPointer())) {
     SDKNode* Root = SDKNodeInitInfo(Ctx, T).createSDKNode(SDKNodeKind::TypeNameAlias);
@@ -1245,11 +1259,20 @@
 static SDKNode *constructFunctionNode(SDKContext &Ctx, FuncDecl* FD,
                                       SDKNodeKind Kind) {
   auto Func = SDKNodeInitInfo(Ctx, FD).createSDKNode(Kind);
-  Func->addChild(constructTypeNode(Ctx, FD->getResultInterfaceType()));
+  bool resultIsImplicitlyUnwrappedOptional = false;
+  if (FD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+    resultIsImplicitlyUnwrappedOptional = true;
+  Func->addChild(constructTypeNode(Ctx, FD->getResultInterfaceType(),
+                                   resultIsImplicitlyUnwrappedOptional));
   for (auto *paramList : FD->getParameterLists()) {
     for (auto param : *paramList) {
+      bool paramIsImplicitlyUnwrappedOptional = false;
+      if (param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+        paramIsImplicitlyUnwrappedOptional = true;
+
       if (!param->isSelfParameter())
-        Func->addChild(constructTypeNode(Ctx, param->getInterfaceType()));
+        Func->addChild(constructTypeNode(Ctx, param->getInterfaceType(),
+                                         paramIsImplicitlyUnwrappedOptional));
     }
   }
   return Func;
@@ -1321,7 +1344,11 @@
 
 static SDKNode *constructVarNode(SDKContext &Ctx, ValueDecl *VD) {
   auto Var = SDKNodeInitInfo(Ctx, VD).createSDKNode(SDKNodeKind::Var);
-  Var->addChild(constructTypeNode(Ctx, VD->getInterfaceType()));
+  auto isImplicitlyUnwrappedOptional = false;
+  if (VD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
+    isImplicitlyUnwrappedOptional = true;
+  Var->addChild(constructTypeNode(Ctx, VD->getInterfaceType(),
+                                  isImplicitlyUnwrappedOptional));
   if (auto VAD = dyn_cast<AbstractStorageDecl>(VD)) {
     if (auto Getter = VAD->getGetter())
       Var->addChild(constructFunctionNode(Ctx, Getter, SDKNodeKind::Getter));
diff --git a/utils/rth b/utils/rth
index 287011a..87aabfe 100755
--- a/utils/rth
+++ b/utils/rth
@@ -70,9 +70,12 @@
             for emit_flag in ['-emit-library', '-emit-module']:
                 output_obj = os.path.join(self.config_dir_map[config],
                                           self.lib_obj_name)
-                compiler_flags = [emit_flag, '-Xfrontend',
-                                  '-enable-resilience', '-D', config, '-c',
-                                  self.lib_src, '-o', output_obj]
+                compiler_flags = [emit_flag,
+                                  '-swift-version', '4',
+                                  '-Xfrontend', '-enable-resilience',
+                                  '-D', config,
+                                  '-c', self.lib_src,
+                                  '-o', output_obj]
                 command = self.target_build_swift + \
                     self.additional_compile_flags_library + compiler_flags
                 verbose_print_command(command)