Sema: Fix the same bug with subscripts as well

Fixes rdar://161588385.
This commit is contained in:
Slava Pestov
2025-09-30 13:41:38 -04:00
parent 782d68fc99
commit 5be227a9b9
3 changed files with 47 additions and 21 deletions

View File

@@ -2510,8 +2510,27 @@ namespace {
// Coerce the index argument.
auto openedFullFnType = simplifyType(selected.adjustedOpenedFullType)
->castTo<FunctionType>();
auto openedFullFnTypeSelf = openedFullFnType;
// Now, deal with DynamicSelfType.
if (selected.adjustedOpenedFullType->hasDynamicSelfType()) {
openedFullFnTypeSelf = simplifyType(
selected.adjustedOpenedFullType->eraseDynamicSelfType())
->castTo<FunctionType>();
auto replacementTy = getDynamicSelfReplacementType(
baseTy, subscript, memberLoc);
openedFullFnType = simplifyType(
selected.adjustedOpenedFullType
->replaceDynamicSelfType(replacementTy))
->castTo<FunctionType>();
}
auto fullSubscriptTy = openedFullFnType->getResult()
->castTo<FunctionType>();
auto fullSubscriptTySelf = openedFullFnTypeSelf->getResult()
->castTo<FunctionType>();
auto appliedWrappers =
solution.getAppliedPropertyWrappers(memberLoc->getAnchor());
args = coerceCallArguments(
@@ -2565,38 +2584,28 @@ namespace {
if (!base)
return nullptr;
bool hasDynamicSelf = fullSubscriptTy->hasDynamicSelfType();
// Form the subscript expression.
auto subscriptExpr = SubscriptExpr::create(
ctx, base, args, subscriptRef, isImplicit, semantics);
subscriptExpr->setIsSuper(isSuper);
if (!hasDynamicSelf) {
cs.setType(subscriptExpr, fullSubscriptTy->getResult());
} else {
cs.setType(subscriptExpr,
fullSubscriptTy->getResult()
->replaceDynamicSelfType(containerTy));
}
cs.setType(subscriptExpr, fullSubscriptTySelf->getResult());
Expr *result = subscriptExpr;
closeExistentials(result, locator);
// If the element is of dynamic 'Self' type, wrap an implicit conversion
// around the resulting expression, with the destination type having
// 'Self' swapped for the appropriate replacement type -- usually the
// base object type.
if (hasDynamicSelf) {
const auto conversionTy = simplifyType(
selected.adjustedOpenedType->castTo<FunctionType>()->getResult());
if (!containerTy->isEqual(conversionTy)) {
result = cs.cacheType(
new (ctx) CovariantReturnConversionExpr(result, conversionTy));
}
if (!fullSubscriptTy->getResult()->isEqual(
fullSubscriptTySelf->getResult())) {
result = cs.cacheType(
new (ctx) CovariantReturnConversionExpr(
result, fullSubscriptTy->getResult()));
}
closeExistentials(result, locator);
return result;
}

View File

@@ -19,8 +19,7 @@ func f(_ p: any P & C) {
p.v.g1()
p.v.g2()
// FIXME
// p[].g1()
// p[].g2()
p[].g1()
p[].g2()
}

View File

@@ -0,0 +1,18 @@
// RUN: %target-swift-emit-silgen %s
class AA {
subscript<T>(_: T.Type) -> T? {
get { fatalError() }
set {}
}
}
class C {
typealias A = AA
func f() {
let a = AA()
guard let result = a[Self.A.self] else { return }
_ = result
}
}