@@ -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) {
0 commit comments