Skip to content

Commit 59b7599

Browse files
committed
Sema: Simplify handling of DynamicSelfType in buildSingleCurryThunk()
1 parent 30fc84c commit 59b7599

File tree

1 file changed

+42
-44
lines changed

1 file changed

+42
-44
lines changed

lib/Sema/CSApply.cpp

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ namespace {
783783
// We don't need to do any further adjustment once we've built the
784784
// curry thunk.
785785
return buildSingleCurryThunk(result, fnDecl,
786+
adjustedFullType->castTo<FunctionType>(),
786787
adjustedFullType->castTo<FunctionType>(),
787788
locator);
788789
}
@@ -1342,6 +1343,7 @@ namespace {
13421343
AutoClosureExpr *buildSingleCurryThunk(Expr *baseExpr, Expr *fnExpr,
13431344
DeclContext *declOrClosure,
13441345
FunctionType *thunkTy,
1346+
FunctionType *refTy,
13451347
ConstraintLocatorBuilder locator) {
13461348
const OptionSet<ParameterList::CloneFlags> options =
13471349
(ParameterList::Implicit | ParameterList::NamedArguments);
@@ -1404,24 +1406,10 @@ namespace {
14041406
if (baseExpr) {
14051407
if (auto *fnDecl = dyn_cast<AbstractFunctionDecl>(declOrClosure)) {
14061408
if (fnDecl->getDeclContext()->getSelfClassDecl()) {
1407-
if (fnDecl->hasDynamicSelfResult()) {
1408-
Type convTy;
1409-
1410-
if (cs.getType(baseExpr)->hasOpenedExistential()) {
1411-
// FIXME: Sometimes we need to convert to an opened existential
1412-
// first, because CovariantReturnConversionExpr does not support
1413-
// direct conversions from a class C to an existential C & P.
1414-
convTy = cs.getType(baseExpr)->getMetatypeInstanceType();
1415-
if (thunkTy->getResult()->getOptionalObjectType())
1416-
convTy = OptionalType::get(thunkTy);
1417-
} else {
1418-
convTy = thunkTy->getResult();
1419-
}
1420-
1421-
if (!thunkBody->getType()->isEqual(convTy)) {
1422-
thunkBody = cs.cacheType(
1423-
new (ctx) CovariantReturnConversionExpr(thunkBody, convTy));
1424-
}
1409+
auto convTy = refTy->getResult();
1410+
if (!thunkBody->getType()->isEqual(convTy)) {
1411+
thunkBody = cs.cacheType(
1412+
new (ctx) CovariantReturnConversionExpr(thunkBody, convTy));
14251413
}
14261414
}
14271415
}
@@ -1460,15 +1448,19 @@ namespace {
14601448
/// \param thunkTy The type of the resulting thunk. This should be the
14611449
/// type of the \c fnExpr, with any potential adjustments for things like
14621450
/// concurrency.
1451+
/// \param refTy The type of the declaration reference inside the thunk.
1452+
/// This might involve opened existentials or a covariant
1453+
/// Self result.
14631454
/// \param locator The locator pinned on the function reference carried
14641455
/// by \p fnExpr. If the function has associated applied property wrappers,
14651456
/// the locator is used to pull them in.
14661457
AutoClosureExpr *buildSingleCurryThunk(Expr *fnExpr,
14671458
DeclContext *declOrClosure,
14681459
FunctionType *thunkTy,
1460+
FunctionType *refTy,
14691461
ConstraintLocatorBuilder locator) {
14701462
return buildSingleCurryThunk(/*baseExpr=*/nullptr, fnExpr, declOrClosure,
1471-
thunkTy, locator);
1463+
thunkTy, refTy, locator);
14721464
}
14731465

14741466
/// Build a "{ self in { args in self.fn(args) } }" nested curry thunk.
@@ -1478,12 +1470,16 @@ namespace {
14781470
/// the parameters of the inner thunk.
14791471
/// \param member The underlying function declaration to be called.
14801472
/// \param outerThunkTy The type of the outer thunk.
1473+
/// \param outerRefTy The type of the declaration reference inside the thunk.
1474+
/// This might involve opened existentials or a covariant
1475+
/// Self result.
14811476
/// \param memberLocator The locator pinned on the member reference. If the
14821477
/// function has associated applied property wrappers, the locator is used
14831478
/// to pull them in.
14841479
AutoClosureExpr *
14851480
buildDoubleCurryThunk(DeclRefExpr *memberRef, ValueDecl *member,
14861481
FunctionType *outerThunkTy,
1482+
FunctionType *outerRefTy,
14871483
ConstraintLocatorBuilder memberLocator,
14881484
DeclNameLoc memberLoc, bool isDynamicLookup) {
14891485
const auto selfThunkParam = outerThunkTy->getParams().front();
@@ -1596,7 +1592,9 @@ namespace {
15961592
} else {
15971593
auto *innerThunk = buildSingleCurryThunk(
15981594
selfOpenedRef, memberRef, cast<DeclContext>(member),
1599-
outerThunkTy->getResult()->castTo<FunctionType>(), memberLocator);
1595+
outerThunkTy->getResult()->castTo<FunctionType>(),
1596+
outerRefTy->getResult()->castTo<FunctionType>(),
1597+
memberLocator);
16001598
assert((!outerActorIsolation ||
16011599
innerThunk->getActorIsolation().getKind() ==
16021600
outerActorIsolation->getKind()) &&
@@ -1635,7 +1633,8 @@ namespace {
16351633

16361634
Expr *buildStaticCurryThunk(Expr *base, Expr *declRefExpr,
16371635
AbstractFunctionDecl *member,
1638-
FunctionType *adjustedOpenedType,
1636+
FunctionType *curryThunkTy,
1637+
FunctionType *curryRefTy,
16391638
ConstraintLocatorBuilder locator,
16401639
ConstraintLocatorBuilder memberLocator,
16411640
bool openedExistential) {
@@ -1650,7 +1649,7 @@ namespace {
16501649
// built is the curried reference.
16511650
return buildSingleCurryThunk(
16521651
base, declRefExpr, member,
1653-
adjustedOpenedType,
1652+
curryThunkTy, curryRefTy,
16541653
memberLocator);
16551654
} else {
16561655
// Add a useless ".self" to avoid downstream diagnostics, in case
@@ -1682,7 +1681,7 @@ namespace {
16821681

16831682
auto *closure = buildSingleCurryThunk(
16841683
baseRef, declRefExpr, member,
1685-
adjustedOpenedType,
1684+
curryThunkTy, curryRefTy,
16861685
memberLocator);
16871686

16881687
// Wrap the closure in a capture list.
@@ -1955,12 +1954,15 @@ namespace {
19551954

19561955
// If we opened up an existential when referencing this member, update
19571956
// the base accordingly.
1957+
Type baseOpenedTy = baseTy;
19581958
bool openedExistential = false;
19591959

19601960
auto knownOpened = solution.OpenedExistentialTypes.find(
19611961
getConstraintSystem().getConstraintLocator(
19621962
memberLocator));
19631963
if (knownOpened != solution.OpenedExistentialTypes.end()) {
1964+
baseOpenedTy = knownOpened->second;
1965+
19641966
// Determine if we're going to have an OpenExistentialExpr around
19651967
// this member reference.
19661968
//
@@ -1982,7 +1984,7 @@ namespace {
19821984
baseIsInstance && member->isInstanceMember())) {
19831985
// Open the existential before performing the member reference.
19841986
base = openExistentialReference(base, knownOpened->second, member);
1985-
baseTy = knownOpened->second;
1987+
baseTy = baseOpenedTy;
19861988
selfTy = baseTy;
19871989
openedExistential = true;
19881990
} else {
@@ -2064,7 +2066,7 @@ namespace {
20642066
// Now replace DynamicSelfType with the actual base type
20652067
// of the call.
20662068
auto replacementTy = getDynamicSelfReplacementType(
2067-
baseTy, member, memberLocator.getBaseLocator());
2069+
baseOpenedTy, member, memberLocator.getBaseLocator());
20682070
refTy = simplifyType(
20692071
overload.openedFullType
20702072
->replaceDynamicSelfType(replacementTy));
@@ -2127,6 +2129,8 @@ namespace {
21272129
ref = buildSingleCurryThunk(
21282130
base, declRefExpr, cast<AbstractFunctionDecl>(member),
21292131
adjustedOpenedType->castTo<FunctionType>(),
2132+
adjustedRefTy->castTo<FunctionType>()
2133+
->getResult()->castTo<FunctionType>(),
21302134
memberLocator);
21312135
} else if (needsCurryThunk) {
21322136
// Another case where we want to build a single closure is when
@@ -2140,10 +2144,14 @@ namespace {
21402144
return buildStaticCurryThunk(
21412145
base, declRefExpr, cast<AbstractFunctionDecl>(member),
21422146
adjustedOpenedType->castTo<FunctionType>(),
2147+
adjustedRefTy->castTo<FunctionType>()
2148+
->getResult()->castTo<FunctionType>(),
21432149
locator, memberLocator, openedExistential);
21442150
}
21452151

21462152
FunctionType *curryThunkTy = nullptr;
2153+
FunctionType *curryRefTy = nullptr;
2154+
21472155
if (isUnboundInstanceMember) {
21482156
// For an unbound reference to a method, all conversions, including
21492157
// dynamic 'Self' handling, are done within the thunk to support
@@ -2153,12 +2161,12 @@ namespace {
21532161
// subclass existential to cope with the expectations placed
21542162
// on 'CovariantReturnConversionExpr'.
21552163
curryThunkTy = adjustedOpenedType->castTo<FunctionType>();
2164+
curryRefTy = adjustedRefTy->castTo<FunctionType>();
21562165
} else {
21572166
curryThunkTy = adjustedRefTySelf->castTo<FunctionType>();
2167+
curryRefTy = curryThunkTy;
21582168

21592169
// Check if we need to open an existential stored inside 'self'.
2160-
auto knownOpened = solution.OpenedExistentialTypes.find(
2161-
getConstraintSystem().getConstraintLocator(memberLocator));
21622170
if (knownOpened != solution.OpenedExistentialTypes.end()) {
21632171
curryThunkTy =
21642172
typeEraseOpenedArchetypesFromEnvironment(
@@ -2169,8 +2177,10 @@ namespace {
21692177

21702178
// Replace the DeclRefExpr with a closure expression which SILGen
21712179
// knows how to emit.
2172-
ref = buildDoubleCurryThunk(declRefExpr, member, curryThunkTy,
2173-
memberLocator, memberLoc, isDynamic);
2180+
ref = buildDoubleCurryThunk(declRefExpr, member,
2181+
curryThunkTy, curryRefTy,
2182+
memberLocator, memberLoc,
2183+
isDynamic);
21742184
}
21752185

21762186
// If the member is a method with a dynamic 'Self' result type, wrap an
@@ -2182,20 +2192,8 @@ namespace {
21822192
if (!isUnboundInstanceMember &&
21832193
member->getDeclContext()->getSelfClassDecl()) {
21842194
if (overload.adjustedOpenedFullType->hasDynamicSelfType()) {
2185-
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)) {
2195+
if (!adjustedRefTy->isEqual(adjustedRefTySelf)) {
2196+
Type conversionTy = adjustedRefTy;
21992197
if (isSuperPartialApplication) {
22002198
conversionTy =
22012199
conversionTy->castTo<FunctionType>()->getResult();
@@ -9143,7 +9141,7 @@ namespace {
91439141
if (AnyFunctionRef(closure).hasExternalPropertyWrapperParameters()) {
91449142
auto *thunkTy = Rewriter.cs.getType(closure)->castTo<FunctionType>();
91459143
return Action::SkipNode(Rewriter.buildSingleCurryThunk(
9146-
closure, closure, thunkTy,
9144+
closure, closure, thunkTy, thunkTy,
91479145
Rewriter.cs.getConstraintLocator(closure)));
91489146
}
91499147

0 commit comments

Comments
 (0)