Skip to content

Commit e5e28ff

Browse files
committed
SILGen: avoid reusing the same opened archetype in keypath setter and getter functions.
1 parent df2a89f commit e5e28ff

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3521,6 +3521,14 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35213521
return storage->isSettable(storage->getDeclContext());
35223522
};
35233523

3524+
// We cannot use the same opened archetype in the getter and setter. Therefore
3525+
// we create a new one for both the getter and the setter.
3526+
auto renewOpenedArchetypes = [](SubstitutableType *type) -> Type {
3527+
if (auto *openedTy = dyn_cast<OpenedArchetypeType>(type))
3528+
return OpenedArchetypeType::get(openedTy->getOpenedExistentialType());
3529+
return type;
3530+
};
3531+
35243532
if (auto var = dyn_cast<VarDecl>(storage)) {
35253533
CanType componentTy;
35263534
if (!var->getDeclContext()->isTypeContext()) {
@@ -3544,13 +3552,15 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35443552
auto id = getIdForKeyPathComponentComputedProperty(*this, var,
35453553
strategy);
35463554
auto getter = getOrCreateKeyPathGetter(*this, loc,
3547-
var, subs,
3555+
var, subs.subst(renewOpenedArchetypes,
3556+
MakeAbstractConformanceForGenericType()),
35483557
needsGenericContext ? genericEnv : nullptr,
35493558
expansion, {}, baseTy, componentTy);
35503559

35513560
if (isSettableInComponent()) {
35523561
auto setter = getOrCreateKeyPathSetter(*this, loc,
3553-
var, subs,
3562+
var, subs.subst(renewOpenedArchetypes,
3563+
MakeAbstractConformanceForGenericType()),
35543564
needsGenericContext ? genericEnv : nullptr,
35553565
expansion, {}, baseTy, componentTy);
35563566
return KeyPathPatternComponent::forComputedSettableProperty(id,
@@ -3595,7 +3605,8 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
35953605

35963606
auto id = getIdForKeyPathComponentComputedProperty(*this, decl, strategy);
35973607
auto getter = getOrCreateKeyPathGetter(*this, loc,
3598-
decl, subs,
3608+
decl, subs.subst(renewOpenedArchetypes,
3609+
MakeAbstractConformanceForGenericType()),
35993610
needsGenericContext ? genericEnv : nullptr,
36003611
expansion,
36013612
indexTypes,
@@ -3604,7 +3615,8 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
36043615
auto indexPatternsCopy = getASTContext().AllocateCopy(indexPatterns);
36053616
if (isSettableInComponent()) {
36063617
auto setter = getOrCreateKeyPathSetter(*this, loc,
3607-
decl, subs,
3618+
decl, subs.subst(renewOpenedArchetypes,
3619+
MakeAbstractConformanceForGenericType()),
36083620
needsGenericContext ? genericEnv : nullptr,
36093621
expansion,
36103622
indexTypes,

test/stdlib/KeyPath.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,17 @@ class ABC: AB, ABCProtocol {
329329
var a = LifetimeTracked(1)
330330
var b = LifetimeTracked(2)
331331
var c = LifetimeTracked(3)
332+
subscript(x: Int) -> Int {
333+
get { return x + 27 }
334+
set { }
335+
}
332336
}
333337

334338
protocol ABCProtocol {
335339
var a: LifetimeTracked { get }
336340
var b: LifetimeTracked { get set }
337341
var c: LifetimeTracked { get nonmutating set }
342+
subscript(x: Int) -> Int { get set }
338343
}
339344

340345
keyPath.test("dynamically-typed application") {
@@ -369,6 +374,7 @@ keyPath.test("dynamically-typed application") {
369374
let protoErasedPathA = \ABCProtocol.a
370375
let protoErasedPathB = \ABCProtocol.b
371376
let protoErasedPathC = \ABCProtocol.c
377+
let protoErasedSubscript = \ABCProtocol[100]
372378

373379
do {
374380
expectTrue(protoErasedSubject.a ===
@@ -389,6 +395,8 @@ keyPath.test("dynamically-typed application") {
389395
expectTrue(protoErasedSubject.c ===
390396
protoErasedSubject[keyPath: protoErasedPathC])
391397
expectTrue(protoErasedSubject.c === newC)
398+
399+
expectTrue(protoErasedSubject[keyPath: protoErasedSubscript] == 127)
392400
}
393401
}
394402

0 commit comments

Comments
 (0)