Skip to content

Commit 7609c22

Browse files
authored
Merge pull request #84594 from slavapestov/fix-rdar160816868
Fix malformed AST with property or subscript returning dynamic Self on an opened existential
2 parents 2fdb1a8 + 5be227a commit 7609c22

File tree

3 files changed

+72
-19
lines changed

3 files changed

+72
-19
lines changed

lib/Sema/CSApply.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,7 +1809,6 @@ namespace {
18091809
result = adjustTypeForDeclReference(result, resultTySelf,
18101810
resultType(adjustedRefTySelf),
18111811
locator);
1812-
closeExistentials(result, locator);
18131812

18141813
// If the property is of dynamic 'Self' type, wrap an implicit
18151814
// conversion around the resulting expression, with the destination
@@ -1821,6 +1820,8 @@ namespace {
18211820
result, resultTy));
18221821
}
18231822

1823+
closeExistentials(result, locator);
1824+
18241825
// If we need to load, do so now.
18251826
if (loadImmediately) {
18261827
result = cs.addImplicitLoadExpr(result);
@@ -2509,8 +2510,27 @@ namespace {
25092510
// Coerce the index argument.
25102511
auto openedFullFnType = simplifyType(selected.adjustedOpenedFullType)
25112512
->castTo<FunctionType>();
2513+
2514+
auto openedFullFnTypeSelf = openedFullFnType;
2515+
2516+
// Now, deal with DynamicSelfType.
2517+
if (selected.adjustedOpenedFullType->hasDynamicSelfType()) {
2518+
openedFullFnTypeSelf = simplifyType(
2519+
selected.adjustedOpenedFullType->eraseDynamicSelfType())
2520+
->castTo<FunctionType>();
2521+
auto replacementTy = getDynamicSelfReplacementType(
2522+
baseTy, subscript, memberLoc);
2523+
openedFullFnType = simplifyType(
2524+
selected.adjustedOpenedFullType
2525+
->replaceDynamicSelfType(replacementTy))
2526+
->castTo<FunctionType>();
2527+
}
2528+
25122529
auto fullSubscriptTy = openedFullFnType->getResult()
25132530
->castTo<FunctionType>();
2531+
auto fullSubscriptTySelf = openedFullFnTypeSelf->getResult()
2532+
->castTo<FunctionType>();
2533+
25142534
auto appliedWrappers =
25152535
solution.getAppliedPropertyWrappers(memberLoc->getAnchor());
25162536
args = coerceCallArguments(
@@ -2564,38 +2584,28 @@ namespace {
25642584
if (!base)
25652585
return nullptr;
25662586

2567-
bool hasDynamicSelf = fullSubscriptTy->hasDynamicSelfType();
2568-
25692587
// Form the subscript expression.
25702588
auto subscriptExpr = SubscriptExpr::create(
25712589
ctx, base, args, subscriptRef, isImplicit, semantics);
25722590
subscriptExpr->setIsSuper(isSuper);
25732591

2574-
if (!hasDynamicSelf) {
2575-
cs.setType(subscriptExpr, fullSubscriptTy->getResult());
2576-
} else {
2577-
cs.setType(subscriptExpr,
2578-
fullSubscriptTy->getResult()
2579-
->replaceDynamicSelfType(containerTy));
2580-
}
2592+
cs.setType(subscriptExpr, fullSubscriptTySelf->getResult());
25812593

25822594
Expr *result = subscriptExpr;
2583-
closeExistentials(result, locator);
25842595

25852596
// If the element is of dynamic 'Self' type, wrap an implicit conversion
25862597
// around the resulting expression, with the destination type having
25872598
// 'Self' swapped for the appropriate replacement type -- usually the
25882599
// base object type.
2589-
if (hasDynamicSelf) {
2590-
const auto conversionTy = simplifyType(
2591-
selected.adjustedOpenedType->castTo<FunctionType>()->getResult());
2592-
2593-
if (!containerTy->isEqual(conversionTy)) {
2594-
result = cs.cacheType(
2595-
new (ctx) CovariantReturnConversionExpr(result, conversionTy));
2596-
}
2600+
if (!fullSubscriptTy->getResult()->isEqual(
2601+
fullSubscriptTySelf->getResult())) {
2602+
result = cs.cacheType(
2603+
new (ctx) CovariantReturnConversionExpr(
2604+
result, fullSubscriptTy->getResult()));
25972605
}
25982606

2607+
closeExistentials(result, locator);
2608+
25992609
return result;
26002610
}
26012611

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-emit-silgen %s
2+
3+
public class C {
4+
public func f() -> Self { return self }
5+
public var v: Self { return self }
6+
public subscript() -> Self { return self }
7+
8+
public func g1() {}
9+
}
10+
11+
public protocol P {
12+
func g2()
13+
}
14+
15+
func f(_ p: any P & C) {
16+
p.f().g1()
17+
p.f().g2()
18+
19+
p.v.g1()
20+
p.v.g2()
21+
22+
p[].g1()
23+
p[].g2()
24+
}
25+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-swift-emit-silgen %s
2+
3+
class AA {
4+
subscript<T>(_: T.Type) -> T? {
5+
get { fatalError() }
6+
set {}
7+
}
8+
}
9+
10+
class C {
11+
typealias A = AA
12+
13+
func f() {
14+
let a = AA()
15+
guard let result = a[Self.A.self] else { return }
16+
_ = result
17+
}
18+
}

0 commit comments

Comments
 (0)