Skip to content

Commit 0a28307

Browse files
committed
[CS] Use The Full Opened Type When Forming Subscripts
The "opened type" of a subscript reference has all references to Self immediately substituted out, which destroys the link between Self and the opened existential type we form for the "fully opened type". This means, in general, we cannot use this type when rewriting subscript applies, or we'll miss closing opened existentials. Use the "fully opened type" everywhere except the AnyObject subscript path. Then, add an assertion that AnyObject subscripts never involve opened archetypes that we would have to close. Resolves SR-11748, rdar://57092093
1 parent 686bbc7 commit 0a28307

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,13 +1408,12 @@ namespace {
14081408
// Compute the concrete reference to the subscript.
14091409
auto subscriptRef = resolveConcreteDeclRef(subscript, memberLoc);
14101410

1411-
// Figure out the index and result types.
1412-
auto subscriptTy = simplifyType(selected.openedType);
1413-
auto *subscriptFnTy = subscriptTy->castTo<FunctionType>();
1414-
auto resultTy = subscriptFnTy->getResult();
1415-
14161411
// Coerce the index argument.
1417-
index = coerceCallArguments(index, subscriptFnTy, subscriptRef, nullptr,
1412+
auto openedFullFnType = simplifyType(selected.openedFullType)
1413+
->castTo<FunctionType>();
1414+
auto fullSubscriptTy = openedFullFnType->getResult()
1415+
->castTo<FunctionType>();
1416+
index = coerceCallArguments(index, fullSubscriptTy, subscriptRef, nullptr,
14181417
argLabels, hasTrailingClosure,
14191418
locator.withPathElement(
14201419
ConstraintLocator::ApplyArgument));
@@ -1436,14 +1435,18 @@ namespace {
14361435
// TODO: diagnose if semantics != AccessSemantics::Ordinary?
14371436
auto subscriptExpr = DynamicSubscriptExpr::create(
14381437
ctx, base, index, subscriptRef, isImplicit, getType);
1438+
auto resultTy = simplifyType(selected.openedType)
1439+
->castTo<FunctionType>()
1440+
->getResult();
1441+
assert(!selected.openedFullType->hasOpenedExistential()
1442+
&& "open existential archetype in AnyObject subscript type?");
14391443
cs.setType(subscriptExpr, resultTy);
14401444
Expr *result = subscriptExpr;
14411445
closeExistential(result, locator);
14421446
return result;
14431447
}
14441448

14451449
// Convert the base.
1446-
auto openedFullFnType = selected.openedFullType->castTo<FunctionType>();
14471450
auto openedBaseType =
14481451
getBaseType(openedFullFnType, /*wantsRValue*/ false);
14491452
auto containerTy = solution.simplifyType(openedBaseType);
@@ -1469,7 +1472,7 @@ namespace {
14691472
// Form the subscript expression.
14701473
auto subscriptExpr = SubscriptExpr::create(
14711474
ctx, base, index, subscriptRef, isImplicit, semantics, getType);
1472-
cs.setType(subscriptExpr, resultTy);
1475+
cs.setType(subscriptExpr, fullSubscriptTy->getResult());
14731476
subscriptExpr->setIsSuper(isSuper);
14741477

14751478
Expr *result = subscriptExpr;

test/SILGen/protocols.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,22 @@ public func test(_ p: Proto) {
429429
// CHECK: end_apply [[TOKEN]]
430430
// CHECK: return
431431

432+
// SR-11748
433+
434+
protocol SelfReturningSubscript {
435+
subscript(b: Int) -> Self { get }
436+
}
437+
438+
public func testSelfReturningSubscript() {
439+
// CHECK-LABEL: sil private [ossa] @$s9protocols26testSelfReturningSubscriptyyFAA0cdE0_pAaC_pXEfU_
440+
// CHECK: [[OPEN:%.*]] = open_existential_addr immutable_access
441+
// CHECK: [[OPEN_ADDR:%.*]] = alloc_stack $@opened("{{.*}}") SelfReturningSubscript
442+
// CHECK: copy_addr [[OPEN]] to [initialization] [[OPEN_ADDR]] : $*@opened("{{.*}}") SelfReturningSubscript
443+
// CHECK: [[WIT_M:%.*]] = witness_method $@opened("{{.*}}") SelfReturningSubscript, #SelfReturningSubscript.subscript!getter.1
444+
// CHECK: apply [[WIT_M]]<@opened("{{.*}}") SelfReturningSubscript>({{%.*}}, {{%.*}}, [[OPEN_ADDR]])
445+
_ = [String: SelfReturningSubscript]().mapValues { $0[2] }
446+
}
447+
432448
// CHECK-LABEL: sil_witness_table hidden ClassWithGetter: PropertyWithGetter module protocols {
433449
// CHECK-NEXT: method #PropertyWithGetter.a!getter.1: {{.*}} : @$s9protocols15ClassWithGetterCAA08PropertycD0A2aDP1aSivgTW
434450
// CHECK-NEXT: }

0 commit comments

Comments
 (0)