@@ -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