mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SILGen: Fix verifier error when forming keypath to subscript with resilient index type
emitKeyPathSubscriptOperands() uses the ArgEmitter to collect index arguments, which uses ResilienceExpansion::Minimal when lowering parameter types. For this reason, lowerKeyPathSubscriptIndexTypes() should also use ResilienceExpansion::Minimal when lowering parameter types. Otherwise, we crash in the SIL verifier due to a loadable vs address-only mismatch, if the index type is resilient. Fixes rdar://problem/144654366. Fixes https://github.com/swiftlang/swift/issues/79304.
This commit is contained in:
@@ -4098,7 +4098,6 @@ lowerKeyPathSubscriptIndexTypes(
|
||||
SmallVectorImpl<IndexTypePair> &indexPatterns,
|
||||
SubscriptDecl *subscript,
|
||||
SubstitutionMap subscriptSubs,
|
||||
ResilienceExpansion expansion,
|
||||
bool &needsGenericContext) {
|
||||
// Capturing an index value dependent on the generic context means we
|
||||
// need the generic context captured in the key path.
|
||||
@@ -4118,7 +4117,8 @@ lowerKeyPathSubscriptIndexTypes(
|
||||
|
||||
auto indexLoweredTy = SGM.Types.getLoweredType(
|
||||
AbstractionPattern::getOpaque(), indexTy,
|
||||
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(expansion));
|
||||
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(
|
||||
ResilienceExpansion::Minimal));
|
||||
indexLoweredTy = indexLoweredTy.mapTypeOutOfContext();
|
||||
indexPatterns.push_back({indexTy->mapTypeOutOfContext()
|
||||
->getCanonicalType(),
|
||||
@@ -4347,7 +4347,6 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
|
||||
SmallVector<IndexTypePair, 4> indexTypes;
|
||||
lowerKeyPathSubscriptIndexTypes(*this, indexTypes,
|
||||
decl, subs,
|
||||
expansion,
|
||||
needsGenericContext);
|
||||
|
||||
SmallVector<KeyPathPatternComponent::Index, 4> indexPatterns;
|
||||
|
||||
19
test/SILGen/keypaths_resilient.swift
Normal file
19
test/SILGen/keypaths_resilient.swift
Normal file
@@ -0,0 +1,19 @@
|
||||
// RUN: %target-swift-emit-silgen %s -enable-library-evolution | %FileCheck %s
|
||||
|
||||
public enum E: Hashable {
|
||||
case e
|
||||
}
|
||||
|
||||
public struct S {
|
||||
public var dict: [E: Int] = [:]
|
||||
}
|
||||
|
||||
public func f() {
|
||||
let _ = \S.dict[.e]
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil [ossa] @$s18keypaths_resilient1fyyF : $@convention(thin) () -> () {
|
||||
// CHECK: [[ARG:%.*]] = alloc_stack $E
|
||||
// CHECK: store %1 to [trivial] [[ARG]]
|
||||
// CHECK: {{%.*}} = keypath $WritableKeyPath<S, Optional<Int>>, (root $S; stored_property #S.dict : $Dictionary<E, Int>; settable_property $Optional<Int>, id @$sSDyq_Sgxcig : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in_guaranteed τ_0_0, @guaranteed Dictionary<τ_0_0, τ_0_1>) -> @out Optional<τ_0_1>, getter @$sSDyq_SgxcipSDy18keypaths_resilient1EOSiGADSiTK : $@convention(keypath_accessor_getter) (@in_guaranteed Dictionary<E, Int>, @in_guaranteed E) -> @out Optional<Int>, setter @$sSDyq_SgxcipSDy18keypaths_resilient1EOSiGADSiTk : $@convention(keypath_accessor_setter) (@in_guaranteed Optional<Int>, @inout Dictionary<E, Int>, @in_guaranteed E) -> (), indices [%$0 : $E : $*E], indices_equals @$s18keypaths_resilient1EOTH : $@convention(keypath_accessor_equals) (@in_guaranteed E, @in_guaranteed E) -> Bool, indices_hash @$s18keypaths_resilient1EOTh : $@convention(keypath_accessor_hash) (@in_guaranteed E) -> Int, external #Dictionary.subscript<E, Int>) ([[ARG]])
|
||||
// CHECK: return
|
||||
Reference in New Issue
Block a user