Skip to content

Commit 1d4497a

Browse files
committed
SILVerifier: Fix keypath verification involving opaque return types
The SIL type of the keypath instruction is lowered in the function's type expansion context, the various types involved in patterns are unlowered AST types. When verifying that the types matchup apply the type expansion to both sides. rdar://72134937
1 parent 6a5eb3c commit 1d4497a

File tree

2 files changed

+76
-22
lines changed

2 files changed

+76
-22
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ namespace {
130130

131131
/// Verify invariants on a key path component.
132132
void verifyKeyPathComponent(SILModule &M,
133-
ResilienceExpansion expansion,
133+
TypeExpansionContext typeExpansionContext,
134134
llvm::function_ref<void(bool, StringRef)> require,
135135
CanType &baseTy,
136136
CanType leafTy,
@@ -141,16 +141,17 @@ void verifyKeyPathComponent(SILModule &M,
141141
bool forPropertyDescriptor,
142142
bool hasIndices) {
143143
auto &C = M.getASTContext();
144-
auto typeExpansionContext =
145-
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(expansion);
144+
auto expansion = typeExpansionContext.getResilienceExpansion();
146145
auto opaque = AbstractionPattern::getOpaque();
147146
auto loweredBaseTy =
148147
M.Types.getLoweredType(opaque, baseTy, typeExpansionContext);
149148
auto componentTy = component.getComponentType().subst(patternSubs)
150149
->getCanonicalType();
151150
auto loweredComponentTy =
152151
M.Types.getLoweredType(opaque, componentTy, typeExpansionContext);
153-
152+
auto getTypeInExpansionContext = [&](CanType ty) -> CanType {
153+
return M.Types.getLoweredType(opaque, ty, typeExpansionContext).getASTType();
154+
};
154155
auto checkIndexEqualsAndHash = [&]{
155156
if (!component.getSubscriptIndices().empty()) {
156157
// Equals should be
@@ -236,7 +237,8 @@ void verifyKeyPathComponent(SILModule &M,
236237
auto fieldTy = baseTy->getTypeOfMember(M.getSwiftModule(), property)
237238
->getReferenceStorageReferent()
238239
->getCanonicalType();
239-
require(fieldTy == componentTy,
240+
require(getTypeInExpansionContext(fieldTy) ==
241+
getTypeInExpansionContext(componentTy),
240242
"property decl should be a member of the base with the same type "
241243
"as the component");
242244
require(property->hasStorage(), "property must be stored");
@@ -289,10 +291,11 @@ void verifyKeyPathComponent(SILModule &M,
289291
auto baseParam = substGetterType->getParameters()[0];
290292
require(baseParam.getConvention() == normalArgConvention,
291293
"getter base parameter should have normal arg convention");
292-
require(baseParam.getArgumentType(M, substGetterType, typeExpansionContext)
293-
== loweredBaseTy.getASTType(),
294+
require(getTypeInExpansionContext(baseParam.getArgumentType(
295+
M, substGetterType, typeExpansionContext)) ==
296+
loweredBaseTy.getASTType(),
294297
"getter base parameter should match base of component");
295-
298+
296299
if (hasIndices) {
297300
auto indicesParam = substGetterType->getParameters()[1];
298301
require(indicesParam.getConvention()
@@ -310,11 +313,11 @@ void verifyKeyPathComponent(SILModule &M,
310313
auto result = substGetterType->getResults()[0];
311314
require(result.getConvention() == ResultConvention::Indirect,
312315
"getter result should be @out");
313-
require(
314-
result.getReturnValueType(M, substGetterType, typeExpansionContext) ==
315-
loweredComponentTy.getASTType(),
316-
"getter result should match the maximal abstraction of the "
317-
"formal component type");
316+
require(getTypeInExpansionContext(result.getReturnValueType(
317+
M, substGetterType, typeExpansionContext)) ==
318+
getTypeInExpansionContext(loweredComponentTy.getASTType()),
319+
"getter result should match the maximal abstraction of the "
320+
"formal component type");
318321
}
319322

320323
if (kind == KeyPathPatternComponent::Kind::SettableProperty) {
@@ -363,9 +366,9 @@ void verifyKeyPathComponent(SILModule &M,
363366
"indices pointer should be an UnsafeRawPointer");
364367
}
365368

366-
require(newValueParam.getArgumentType(M, substSetterType,
367-
typeExpansionContext) ==
368-
loweredComponentTy.getASTType(),
369+
require(getTypeInExpansionContext(newValueParam.getArgumentType(
370+
M, substSetterType, typeExpansionContext)) ==
371+
getTypeInExpansionContext(loweredComponentTy.getASTType()),
369372
"setter value should match the maximal abstraction of the "
370373
"formal component type");
371374

@@ -4736,12 +4739,17 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
47364739
auto pattern = KPI->getPattern();
47374740
SubstitutionMap patternSubs = KPI->getSubstitutions();
47384741
requireSameType(
4739-
baseTy, pattern->getRootType().subst(patternSubs)->getCanonicalType(),
4742+
F.getLoweredType(baseTy).getASTType(),
4743+
F.getLoweredType(
4744+
pattern->getRootType().subst(patternSubs)->getCanonicalType()).getASTType(),
47404745
"keypath root type should match root type of keypath pattern");
47414746

47424747
auto leafTy = CanType(kpBGT->getGenericArgs()[1]);
47434748
requireSameType(
4744-
leafTy, pattern->getValueType().subst(patternSubs)->getCanonicalType(),
4749+
F.getLoweredType(leafTy).getASTType(),
4750+
F.getLoweredType(
4751+
pattern->getValueType().subst(patternSubs)->getCanonicalType())
4752+
.getASTType(),
47454753
"keypath value type should match value type of keypath pattern");
47464754

47474755
{
@@ -4762,7 +4770,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
47624770
break;
47634771
}
47644772

4765-
verifyKeyPathComponent(F.getModule(), F.getResilienceExpansion(),
4773+
verifyKeyPathComponent(F.getModule(), F.getTypeExpansionContext(),
47664774
[&](bool reqt, StringRef message) { _require(reqt, message); },
47674775
baseTy,
47684776
leafTy,
@@ -4775,7 +4783,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
47754783
}
47764784
}
47774785
requireSameType(
4778-
CanType(baseTy), CanType(leafTy),
4786+
F.getLoweredType(CanType(baseTy)).getASTType(),
4787+
F.getLoweredType(CanType(leafTy)).getASTType(),
47794788
"final component should match leaf value type of key path type");
47804789
}
47814790

@@ -5595,8 +5604,11 @@ void SILProperty::verify(const SILModule &M) const {
55955604
};
55965605

55975606
if (auto &component = getComponent()) {
5607+
auto typeExpansionContext =
5608+
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(
5609+
ResilienceExpansion::Maximal);
55985610
verifyKeyPathComponent(const_cast<SILModule&>(M),
5599-
ResilienceExpansion::Maximal,
5611+
typeExpansionContext,
56005612
require,
56015613
baseTy,
56025614
leafTy,

test/SILGen/keypaths.swift

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-emit-silgen -parse-stdlib -module-name keypaths %s | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen -disable-availability-checking -parse-stdlib -module-name keypaths %s | %FileCheck %s
22

33
import Swift
44

@@ -587,3 +587,45 @@ func tuples_generic<T, U, V>(_: T, _: U, _: V) {
587587
// CHECK: keypath $KeyPath<(T, U, C<V>), String>, <τ_0_0, τ_0_1, τ_0_2> (root $(τ_0_0, τ_0_1, C<τ_0_2>); tuple_element #2 : $C<τ_0_2>; stored_property #C.y : $String) <T, U, V>
588588
let _: KeyPath<TUC, String> = \TUC.2.y
589589
}
590+
591+
protocol DefineSomeType {
592+
associatedtype SomeType
593+
func defineSome() -> SomeType
594+
}
595+
596+
protocol A {}
597+
extension Int : A {}
598+
599+
struct TestKeyPathWithSomeType : DefineSomeType {
600+
func defineSome() -> some A {
601+
return 0
602+
}
603+
604+
func testKeyPathWithSome() {
605+
_ = \S<SomeType>.y
606+
_ = \S<SomeType>.z.x
607+
_ = \C<SomeType>.x
608+
_ = \C<SomeType>.y
609+
_ = \C<SomeType>.z.x
610+
_ = \C<SomeType>.z.z.y
611+
_ = \C<SomeType>.nonfinal
612+
_ = \C<SomeType>.computed
613+
_ = \C<SomeType>.observed
614+
_ = \C<SomeType>.nonfinal.x
615+
_ = \C<SomeType>.computed.x
616+
_ = \C<SomeType>.observed.x
617+
_ = \C<SomeType>.z.computed
618+
_ = \C<SomeType>.z.observed
619+
_ = \C<SomeType>.observed.x
620+
_ = \C<SomeType>.reabstracted
621+
_ = \S<SomeType>.computed
622+
_ = \S<SomeType>.observed
623+
_ = \S<SomeType>.z.nonfinal
624+
_ = \S<SomeType>.z.computed
625+
_ = \S<SomeType>.z.observed
626+
_ = \S<SomeType>.computed.x
627+
_ = \S<SomeType>.computed.y
628+
_ = \S<SomeType>.reabstracted
629+
630+
}
631+
}

0 commit comments

Comments
 (0)