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[]!