Skip to content

Commit 9e2d4c5

Browse files
committed
Sema: More DynamicSelfType cleanup
1 parent 45e3f1b commit 9e2d4c5

File tree

2 files changed

+91
-47
lines changed

2 files changed

+91
-47
lines changed

lib/Sema/CSApply.cpp

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,14 +1743,16 @@ namespace {
17431743
return forceUnwrapIfExpected(ref, memberLocator);
17441744
}
17451745

1746+
/// FIXME: Simplify this horrible parameter list.
17461747
Expr *buildVarMemberRef(Expr *base, SourceLoc dotLoc,
17471748
bool baseIsInstance,
17481749
ConcreteDeclRef memberRef,
17491750
DeclNameLoc memberLoc,
17501751
Type containerTy,
17511752
Type refTy,
1753+
Type refTySelf,
17521754
Type adjustedRefTy,
1753-
Type adjustedOpenedType,
1755+
Type adjustedRefTySelf,
17541756
AccessSemantics semantics,
17551757
ConstraintLocatorBuilder locator,
17561758
ConstraintLocatorBuilder memberLocator,
@@ -1794,31 +1796,23 @@ namespace {
17941796
memberLoc, Implicit, semantics);
17951797
memberRefExpr->setIsSuper(isSuper);
17961798

1797-
auto resultTy = resultType(refTy);
1798-
bool hasDynamicSelf = resultTy->hasDynamicSelfType();
1799-
if (hasDynamicSelf) {
1800-
refTy = refTy->replaceDynamicSelfType(containerTy);
1801-
adjustedRefTy = adjustedRefTy->replaceDynamicSelfType(
1802-
containerTy);
1803-
}
1804-
1805-
cs.setType(memberRefExpr, resultTy);
1799+
auto resultTySelf = resultType(refTySelf);
1800+
cs.setType(memberRefExpr, resultTySelf);
18061801

18071802
Expr *result = memberRefExpr;
1808-
result = adjustTypeForDeclReference(result, resultTy,
1809-
resultType(adjustedRefTy),
1803+
result = adjustTypeForDeclReference(result, resultTySelf,
1804+
resultType(adjustedRefTySelf),
18101805
locator);
18111806
closeExistentials(result, locator);
18121807

18131808
// If the property is of dynamic 'Self' type, wrap an implicit
18141809
// conversion around the resulting expression, with the destination
18151810
// type having 'Self' swapped for the appropriate replacement
18161811
// type -- usually the base object type.
1817-
if (hasDynamicSelf) {
1818-
if (!resultTy->isEqual(adjustedOpenedType)) {
1819-
result = cs.cacheType(new (ctx) CovariantReturnConversionExpr(
1820-
result, adjustedOpenedType));
1821-
}
1812+
auto resultTy = resultType(refTy);
1813+
if (!resultTy->isEqual(resultTySelf)) {
1814+
result = cs.cacheType(new (ctx) CovariantReturnConversionExpr(
1815+
result, resultTy));
18221816
}
18231817

18241818
// If we need to load, do so now.
@@ -1942,7 +1936,8 @@ namespace {
19421936
Expr *ref = cs.cacheType(new (ctx) DotSyntaxBaseIgnoredExpr(
19431937
base, dotLoc, dre, refTy));
19441938

1945-
ref = adjustTypeForDeclReference(ref, refTy, adjustedRefTy, locator);
1939+
ref = adjustTypeForDeclReference(ref, refTy, adjustedRefTy,
1940+
locator);
19461941
return forceUnwrapIfExpected(ref, memberLocator);
19471942
}
19481943

@@ -2050,6 +2045,34 @@ namespace {
20502045
}
20512046
assert(base && "Unable to convert base?");
20522047

2048+
// This is the type of the DeclRefExpr, where DynamicSelfType has
2049+
// been replaced with the static Self type of the member, ie the
2050+
// base class it is declared in.
2051+
Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
2052+
2053+
// Now, deal with DynamicSelfType.
2054+
if (overload.openedFullType->hasDynamicSelfType()) {
2055+
// We look at the original opened type with unsimplified type
2056+
// variables, because we only want to erase DynamicSelfType
2057+
// that appears in the original type of the member, and not
2058+
// one introduced by substitution.
2059+
refTySelf = simplifyType(
2060+
overload.openedFullType->eraseDynamicSelfType());
2061+
adjustedRefTySelf = simplifyType(
2062+
overload.adjustedOpenedFullType->eraseDynamicSelfType());
2063+
2064+
// Now replace DynamicSelfType with the actual base type
2065+
// of the call.
2066+
auto replacementTy = getDynamicSelfReplacementType(
2067+
baseTy, member, memberLocator.getBaseLocator());
2068+
refTy = simplifyType(
2069+
overload.openedFullType
2070+
->replaceDynamicSelfType(replacementTy));
2071+
adjustedRefTy = simplifyType(
2072+
overload.adjustedOpenedFullType
2073+
->replaceDynamicSelfType(replacementTy));
2074+
}
2075+
20532076
// Handle dynamic references.
20542077
if (!needsCurryThunk &&
20552078
(isDynamic || member->getAttrs().hasAttribute<OptionalAttr>())) {
@@ -2063,22 +2086,14 @@ namespace {
20632086
if (isa<VarDecl>(member)) {
20642087
return buildVarMemberRef(base, dotLoc, baseIsInstance,
20652088
memberRef, memberLoc, containerTy,
2066-
refTy, adjustedRefTy, adjustedOpenedType,
2089+
refTy, refTySelf, adjustedRefTy, adjustedRefTySelf,
20672090
semantics, locator, memberLocator,
20682091
isSuper, isUnboundInstanceMember, Implicit);
20692092
}
20702093

20712094
ASSERT(isa<AbstractFunctionDecl>(member) ||
20722095
isa<EnumElementDecl>(member));
20732096

2074-
Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
2075-
2076-
if (refTy->hasDynamicSelfType()) {
2077-
refTySelf = refTy->replaceDynamicSelfType(containerTy);
2078-
adjustedRefTySelf = adjustedRefTy->replaceDynamicSelfType(
2079-
containerTy);
2080-
}
2081-
20822097
// Handle all other references.
20832098
auto declRefExpr = new (ctx) DeclRefExpr(memberRef, memberLoc,
20842099
Implicit, semantics);
@@ -2166,27 +2181,28 @@ namespace {
21662181
// Note: For unbound references this is handled inside the thunk.
21672182
if (!isUnboundInstanceMember &&
21682183
member->getDeclContext()->getSelfClassDecl()) {
2169-
if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
2170-
if (func->hasDynamicSelfResult()) {
2171-
// FIXME: Once CovariantReturnConversionExpr (unchecked_ref_cast)
2172-
// supports a class existential dest., consider using the opened
2173-
// type directly to avoid recomputing the 'Self' replacement and
2174-
// substituting.
2175-
const Type replacementTy = getDynamicSelfReplacementType(
2176-
baseTy, member, memberLocator.getBaseLocator());
2177-
if (!replacementTy->isEqual(containerTy)) {
2178-
ASSERT(adjustedRefTy->hasDynamicSelfType());
2179-
2180-
Type conversionTy =
2181-
adjustedRefTy->replaceDynamicSelfType(replacementTy);
2182-
if (isSuperPartialApplication) {
2183-
conversionTy =
2184-
conversionTy->castTo<FunctionType>()->getResult();
2185-
}
2184+
if (overload.adjustedOpenedFullType->hasDynamicSelfType()) {
21862185

2187-
ref = cs.cacheType(new (ctx) CovariantFunctionConversionExpr(
2188-
ref, conversionTy));
2186+
// Now, replace DynamicSelfType with the actual base type of
2187+
// the call.
2188+
//
2189+
// We look at the original opened type with unsimplified type
2190+
// variables, because we only want to replace DynamicSelfType
2191+
// that appears in the original type of the member, and not
2192+
// one introduced by substitution.
2193+
auto replacementTy = getDynamicSelfReplacementType(
2194+
baseTy, member, memberLocator.getBaseLocator());
2195+
auto conversionTy = simplifyType(
2196+
overload.adjustedOpenedFullType
2197+
->replaceDynamicSelfType(replacementTy));
2198+
if (!conversionTy->isEqual(adjustedRefTySelf)) {
2199+
if (isSuperPartialApplication) {
2200+
conversionTy =
2201+
conversionTy->castTo<FunctionType>()->getResult();
21892202
}
2203+
2204+
ref = cs.cacheType(new (ctx) CovariantFunctionConversionExpr(
2205+
ref, conversionTy));
21902206
}
21912207
}
21922208
}
@@ -2542,7 +2558,6 @@ namespace {
25422558
// Form the subscript expression.
25432559
auto subscriptExpr = SubscriptExpr::create(
25442560
ctx, base, args, subscriptRef, isImplicit, semantics);
2545-
cs.setType(subscriptExpr, fullSubscriptTy->getResult());
25462561
subscriptExpr->setIsSuper(isSuper);
25472562

25482563
if (!hasDynamicSelf) {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-emit-silgen %s
2+
3+
class C {
4+
func f1() -> Self? {
5+
return D<Self>().g(self)
6+
}
7+
8+
func f2() -> Self? {
9+
return D<Self>()[self]
10+
}
11+
12+
func f3() -> Self? {
13+
return D<Self>().x
14+
}
15+
}
16+
17+
class D<T> {
18+
func g(_ t: T) -> T? {
19+
return t
20+
}
21+
22+
subscript(_ t: T) -> T? {
23+
return t
24+
}
25+
26+
var x: T? {
27+
fatalError()
28+
}
29+
}

0 commit comments

Comments
 (0)