Skip to content

Commit ab4e754

Browse files
committed
Sema: Don't stick CovariantReturnConversionExpr around property access with DynamicSelfType base
It could be that refTy->hasDynamicSelfType() is true whereas varDecl->getValueInterfaceType()->hasDynamicSelfType() is false. This happens if the base of the access is dynamic Self, so the refTy is (Self) -> @lvalue Int or whatever. Note that replaceDynamicSelfType() behaves correctly in this case; it leaves that Self in place, because it's in contravariant position. However, the other place where we check the condition would then form a nonsensical CovariantReturnConversionExpr around the result of the access, even though no conversion was necessary here; the type of the returned value does not involve Self. Simplify this logic further with the correct condition. Fixes rdar://159531634.
1 parent e5f9ffc commit ab4e754

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,23 +1789,23 @@ namespace {
17891789
base->setImplicit();
17901790
}
17911791

1792-
const auto hasDynamicSelf = refTy->hasDynamicSelfType();
1793-
17941792
auto memberRefExpr
17951793
= new (ctx) MemberRefExpr(base, dotLoc, memberRef,
17961794
memberLoc, Implicit, semantics);
17971795
memberRefExpr->setIsSuper(isSuper);
17981796

1797+
auto resultTy = resultType(refTy);
1798+
bool hasDynamicSelf = resultTy->hasDynamicSelfType();
17991799
if (hasDynamicSelf) {
18001800
refTy = refTy->replaceDynamicSelfType(containerTy);
18011801
adjustedRefTy = adjustedRefTy->replaceDynamicSelfType(
18021802
containerTy);
18031803
}
18041804

1805-
cs.setType(memberRefExpr, resultType(refTy));
1805+
cs.setType(memberRefExpr, resultTy);
18061806

18071807
Expr *result = memberRefExpr;
1808-
result = adjustTypeForDeclReference(result, resultType(refTy),
1808+
result = adjustTypeForDeclReference(result, resultTy,
18091809
resultType(adjustedRefTy),
18101810
locator);
18111811
closeExistentials(result, locator);
@@ -1815,10 +1815,9 @@ namespace {
18151815
// type having 'Self' swapped for the appropriate replacement
18161816
// type -- usually the base object type.
18171817
if (hasDynamicSelf) {
1818-
const auto conversionTy = adjustedOpenedType;
1819-
if (!containerTy->isEqual(conversionTy)) {
1818+
if (!resultTy->isEqual(adjustedOpenedType)) {
18201819
result = cs.cacheType(new (ctx) CovariantReturnConversionExpr(
1821-
result, conversionTy));
1820+
result, adjustedOpenedType));
18221821
}
18231822
}
18241823

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %target-swift-emit-silgen %s
2+
3+
class C: P1, P2 {
4+
public func f(_ n: Int) -> Self {
5+
self.x = n
6+
self.y = n
7+
self.z = n
8+
return self
9+
}
10+
11+
public var x: Int? {
12+
get { fatalError() }
13+
set { }
14+
}
15+
}
16+
17+
protocol P1: AnyObject {}
18+
protocol P2 {}
19+
20+
extension P1 {
21+
public var y: Int? {
22+
get { fatalError() }
23+
set { }
24+
}
25+
}
26+
27+
extension P2 {
28+
public var z: Int? {
29+
get { fatalError() }
30+
nonmutating set { }
31+
}
32+
}

0 commit comments

Comments
 (0)