Skip to content

Commit d07ed46

Browse files
authored
Merge pull request swiftlang#30221 from CodaFi/existaxis
[CS] Use The Full Opened Type When Forming Subscripts
2 parents 36fb9c9 + 0a28307 commit d07ed46

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)