@@ -783,6 +783,7 @@ namespace {
783
783
// We don't need to do any further adjustment once we've built the
784
784
// curry thunk.
785
785
return buildSingleCurryThunk (result, fnDecl,
786
+ adjustedFullType->castTo <FunctionType>(),
786
787
adjustedFullType->castTo <FunctionType>(),
787
788
locator);
788
789
}
@@ -1342,6 +1343,7 @@ namespace {
1342
1343
AutoClosureExpr *buildSingleCurryThunk (Expr *baseExpr, Expr *fnExpr,
1343
1344
DeclContext *declOrClosure,
1344
1345
FunctionType *thunkTy,
1346
+ FunctionType *refTy,
1345
1347
ConstraintLocatorBuilder locator) {
1346
1348
const OptionSet<ParameterList::CloneFlags> options =
1347
1349
(ParameterList::Implicit | ParameterList::NamedArguments);
@@ -1404,24 +1406,10 @@ namespace {
1404
1406
if (baseExpr) {
1405
1407
if (auto *fnDecl = dyn_cast<AbstractFunctionDecl>(declOrClosure)) {
1406
1408
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));
1425
1413
}
1426
1414
}
1427
1415
}
@@ -1460,15 +1448,19 @@ namespace {
1460
1448
// / \param thunkTy The type of the resulting thunk. This should be the
1461
1449
// / type of the \c fnExpr, with any potential adjustments for things like
1462
1450
// / 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.
1463
1454
// / \param locator The locator pinned on the function reference carried
1464
1455
// / by \p fnExpr. If the function has associated applied property wrappers,
1465
1456
// / the locator is used to pull them in.
1466
1457
AutoClosureExpr *buildSingleCurryThunk (Expr *fnExpr,
1467
1458
DeclContext *declOrClosure,
1468
1459
FunctionType *thunkTy,
1460
+ FunctionType *refTy,
1469
1461
ConstraintLocatorBuilder locator) {
1470
1462
return buildSingleCurryThunk (/* baseExpr=*/ nullptr , fnExpr, declOrClosure,
1471
- thunkTy, locator);
1463
+ thunkTy, refTy, locator);
1472
1464
}
1473
1465
1474
1466
// / Build a "{ self in { args in self.fn(args) } }" nested curry thunk.
@@ -1478,12 +1470,16 @@ namespace {
1478
1470
// / the parameters of the inner thunk.
1479
1471
// / \param member The underlying function declaration to be called.
1480
1472
// / \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.
1481
1476
// / \param memberLocator The locator pinned on the member reference. If the
1482
1477
// / function has associated applied property wrappers, the locator is used
1483
1478
// / to pull them in.
1484
1479
AutoClosureExpr *
1485
1480
buildDoubleCurryThunk (DeclRefExpr *memberRef, ValueDecl *member,
1486
1481
FunctionType *outerThunkTy,
1482
+ FunctionType *outerRefTy,
1487
1483
ConstraintLocatorBuilder memberLocator,
1488
1484
DeclNameLoc memberLoc, bool isDynamicLookup) {
1489
1485
const auto selfThunkParam = outerThunkTy->getParams ().front ();
@@ -1596,7 +1592,9 @@ namespace {
1596
1592
} else {
1597
1593
auto *innerThunk = buildSingleCurryThunk (
1598
1594
selfOpenedRef, memberRef, cast<DeclContext>(member),
1599
- outerThunkTy->getResult ()->castTo <FunctionType>(), memberLocator);
1595
+ outerThunkTy->getResult ()->castTo <FunctionType>(),
1596
+ outerRefTy->getResult ()->castTo <FunctionType>(),
1597
+ memberLocator);
1600
1598
assert ((!outerActorIsolation ||
1601
1599
innerThunk->getActorIsolation ().getKind () ==
1602
1600
outerActorIsolation->getKind ()) &&
@@ -1635,7 +1633,8 @@ namespace {
1635
1633
1636
1634
Expr *buildStaticCurryThunk (Expr *base, Expr *declRefExpr,
1637
1635
AbstractFunctionDecl *member,
1638
- FunctionType *adjustedOpenedType,
1636
+ FunctionType *curryThunkTy,
1637
+ FunctionType *curryRefTy,
1639
1638
ConstraintLocatorBuilder locator,
1640
1639
ConstraintLocatorBuilder memberLocator,
1641
1640
bool openedExistential) {
@@ -1650,7 +1649,7 @@ namespace {
1650
1649
// built is the curried reference.
1651
1650
return buildSingleCurryThunk (
1652
1651
base, declRefExpr, member,
1653
- adjustedOpenedType ,
1652
+ curryThunkTy, curryRefTy ,
1654
1653
memberLocator);
1655
1654
} else {
1656
1655
// Add a useless ".self" to avoid downstream diagnostics, in case
@@ -1682,7 +1681,7 @@ namespace {
1682
1681
1683
1682
auto *closure = buildSingleCurryThunk (
1684
1683
baseRef, declRefExpr, member,
1685
- adjustedOpenedType ,
1684
+ curryThunkTy, curryRefTy ,
1686
1685
memberLocator);
1687
1686
1688
1687
// Wrap the closure in a capture list.
@@ -1955,12 +1954,15 @@ namespace {
1955
1954
1956
1955
// If we opened up an existential when referencing this member, update
1957
1956
// the base accordingly.
1957
+ Type baseOpenedTy = baseTy;
1958
1958
bool openedExistential = false ;
1959
1959
1960
1960
auto knownOpened = solution.OpenedExistentialTypes .find (
1961
1961
getConstraintSystem ().getConstraintLocator (
1962
1962
memberLocator));
1963
1963
if (knownOpened != solution.OpenedExistentialTypes .end ()) {
1964
+ baseOpenedTy = knownOpened->second ;
1965
+
1964
1966
// Determine if we're going to have an OpenExistentialExpr around
1965
1967
// this member reference.
1966
1968
//
@@ -1982,7 +1984,7 @@ namespace {
1982
1984
baseIsInstance && member->isInstanceMember ())) {
1983
1985
// Open the existential before performing the member reference.
1984
1986
base = openExistentialReference (base, knownOpened->second , member);
1985
- baseTy = knownOpened-> second ;
1987
+ baseTy = baseOpenedTy ;
1986
1988
selfTy = baseTy;
1987
1989
openedExistential = true ;
1988
1990
} else {
@@ -2064,7 +2066,7 @@ namespace {
2064
2066
// Now replace DynamicSelfType with the actual base type
2065
2067
// of the call.
2066
2068
auto replacementTy = getDynamicSelfReplacementType (
2067
- baseTy , member, memberLocator.getBaseLocator ());
2069
+ baseOpenedTy , member, memberLocator.getBaseLocator ());
2068
2070
refTy = simplifyType (
2069
2071
overload.openedFullType
2070
2072
->replaceDynamicSelfType (replacementTy));
@@ -2127,6 +2129,8 @@ namespace {
2127
2129
ref = buildSingleCurryThunk (
2128
2130
base, declRefExpr, cast<AbstractFunctionDecl>(member),
2129
2131
adjustedOpenedType->castTo <FunctionType>(),
2132
+ adjustedRefTy->castTo <FunctionType>()
2133
+ ->getResult ()->castTo <FunctionType>(),
2130
2134
memberLocator);
2131
2135
} else if (needsCurryThunk) {
2132
2136
// Another case where we want to build a single closure is when
@@ -2140,10 +2144,14 @@ namespace {
2140
2144
return buildStaticCurryThunk (
2141
2145
base, declRefExpr, cast<AbstractFunctionDecl>(member),
2142
2146
adjustedOpenedType->castTo <FunctionType>(),
2147
+ adjustedRefTy->castTo <FunctionType>()
2148
+ ->getResult ()->castTo <FunctionType>(),
2143
2149
locator, memberLocator, openedExistential);
2144
2150
}
2145
2151
2146
2152
FunctionType *curryThunkTy = nullptr ;
2153
+ FunctionType *curryRefTy = nullptr ;
2154
+
2147
2155
if (isUnboundInstanceMember) {
2148
2156
// For an unbound reference to a method, all conversions, including
2149
2157
// dynamic 'Self' handling, are done within the thunk to support
@@ -2153,12 +2161,12 @@ namespace {
2153
2161
// subclass existential to cope with the expectations placed
2154
2162
// on 'CovariantReturnConversionExpr'.
2155
2163
curryThunkTy = adjustedOpenedType->castTo <FunctionType>();
2164
+ curryRefTy = adjustedRefTy->castTo <FunctionType>();
2156
2165
} else {
2157
2166
curryThunkTy = adjustedRefTySelf->castTo <FunctionType>();
2167
+ curryRefTy = curryThunkTy;
2158
2168
2159
2169
// Check if we need to open an existential stored inside 'self'.
2160
- auto knownOpened = solution.OpenedExistentialTypes .find (
2161
- getConstraintSystem ().getConstraintLocator (memberLocator));
2162
2170
if (knownOpened != solution.OpenedExistentialTypes .end ()) {
2163
2171
curryThunkTy =
2164
2172
typeEraseOpenedArchetypesFromEnvironment (
@@ -2169,8 +2177,10 @@ namespace {
2169
2177
2170
2178
// Replace the DeclRefExpr with a closure expression which SILGen
2171
2179
// 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);
2174
2184
}
2175
2185
2176
2186
// If the member is a method with a dynamic 'Self' result type, wrap an
@@ -2182,20 +2192,8 @@ namespace {
2182
2192
if (!isUnboundInstanceMember &&
2183
2193
member->getDeclContext ()->getSelfClassDecl ()) {
2184
2194
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;
2199
2197
if (isSuperPartialApplication) {
2200
2198
conversionTy =
2201
2199
conversionTy->castTo <FunctionType>()->getResult ();
@@ -9143,7 +9141,7 @@ namespace {
9143
9141
if (AnyFunctionRef (closure).hasExternalPropertyWrapperParameters ()) {
9144
9142
auto *thunkTy = Rewriter.cs .getType (closure)->castTo <FunctionType>();
9145
9143
return Action::SkipNode (Rewriter.buildSingleCurryThunk (
9146
- closure, closure, thunkTy,
9144
+ closure, closure, thunkTy, thunkTy,
9147
9145
Rewriter.cs .getConstraintLocator (closure)));
9148
9146
}
9149
9147
0 commit comments