Merge pull request #21604 from aschwaighofer/fix_keypath_stored_property_subclass-5.0

[5.0] IRGen: Don't assert on keypaths that use a subclass as root
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 64254fb..39dd6ce 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -865,15 +865,17 @@
                          .getReferenceStorageReferentType();
 
   auto storage = accessor->getStorage();
-  auto valueType = storage->getValueInterfaceType()
-                          ->getReferenceStorageReferent();
+  auto valueType = storage->getValueInterfaceType();
   if (reqtSubs) {
     valueType = valueType.subst(*reqtSubs);
   }
 
+  auto canValueType = valueType->getCanonicalType(
+    accessor->getGenericSignature());
+
   // 'modify' yields an inout of the target type.
   if (accessor->getAccessorKind() == AccessorKind::Modify) {
-    auto loweredValueTy = M.Types.getLoweredType(origType, valueType);
+    auto loweredValueTy = M.Types.getLoweredType(origType, canValueType);
     yields.push_back(SILYieldInfo(loweredValueTy.getASTType(),
                                   ParameterConvention::Indirect_Inout));
     return;
@@ -882,8 +884,7 @@
   // 'read' yields a borrowed value of the target type, destructuring
   // tuples as necessary.
   assert(accessor->getAccessorKind() == AccessorKind::Read);
-  destructureYieldsForReadAccessor(M, origType, valueType->getCanonicalType(),
-                                   yields);
+  destructureYieldsForReadAccessor(M, origType, canValueType, yields);
 }
 
 /// Create the appropriate SIL function type for the given formal type
diff --git a/test/SILGen/subscript_accessor.swift b/test/SILGen/subscript_accessor.swift
index ca460b8..71e4a61 100644
--- a/test/SILGen/subscript_accessor.swift
+++ b/test/SILGen/subscript_accessor.swift
@@ -12,7 +12,20 @@
   }
 }
 
-  // CHECK: sil{{.*}}s18subscript_accessor9testXRead1xxAA1XVyxG_tlF
+// Don't crash dealing with T? in a non-generic context.
+// rdar://44762116
+struct WillBeConcretelyConstrained<T> {}
+extension WillBeConcretelyConstrained where T == Int {
+  subscript(key: Int) -> T? {
+    get { return nil }
+    set {}
+  }
+}
+
+// CHECK-LABEL: sil hidden [transparent] @$s18subscript_accessor27WillBeConcretelyConstrainedVAASiRszlEySiSgSiciM
+// CHECK-SAME: $@yield_once @convention(method) (Int, @inout WillBeConcretelyConstrained<Int>) -> @yields @inout Optional<Int>
+
+// CHECK: sil{{.*}}s18subscript_accessor9testXRead1xxAA1XVyxG_tlF
 @_specialize(where T == (Int, Int))
 func testXRead<T>(x: X<T>) -> T {
   return x[]!