@@ -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,
@@ -1789,37 +1791,28 @@ namespace {
17891791 base->setImplicit ();
17901792 }
17911793
1792- const auto hasDynamicSelf = refTy->hasDynamicSelfType ();
1793-
17941794 auto memberRefExpr
17951795 = new (ctx) MemberRefExpr (base, dotLoc, memberRef,
17961796 memberLoc, Implicit, semantics);
17971797 memberRefExpr->setIsSuper (isSuper);
17981798
1799- if (hasDynamicSelf) {
1800- refTy = refTy->replaceDynamicSelfType (containerTy);
1801- adjustedRefTy = adjustedRefTy->replaceDynamicSelfType (
1802- containerTy);
1803- }
1804-
1805- cs.setType (memberRefExpr, resultType (refTy));
1799+ auto resultTySelf = resultType (refTySelf);
1800+ cs.setType (memberRefExpr, resultTySelf);
18061801
18071802 Expr *result = memberRefExpr;
1808- result = adjustTypeForDeclReference (result, resultType (refTy) ,
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- const auto conversionTy = adjustedOpenedType;
1819- if (!containerTy->isEqual (conversionTy)) {
1820- result = cs.cacheType (new (ctx) CovariantReturnConversionExpr (
1821- result, conversionTy));
1822- }
1812+ auto resultTy = resultType (refTy);
1813+ if (!resultTy->isEqual (resultTySelf)) {
1814+ result = cs.cacheType (new (ctx) CovariantReturnConversionExpr (
1815+ result, resultTy));
18231816 }
18241817
18251818 // If we need to load, do so now.
@@ -1943,7 +1936,8 @@ namespace {
19431936 Expr *ref = cs.cacheType (new (ctx) DotSyntaxBaseIgnoredExpr (
19441937 base, dotLoc, dre, refTy));
19451938
1946- ref = adjustTypeForDeclReference (ref, refTy, adjustedRefTy, locator);
1939+ ref = adjustTypeForDeclReference (ref, refTy, adjustedRefTy,
1940+ locator);
19471941 return forceUnwrapIfExpected (ref, memberLocator);
19481942 }
19491943
@@ -2051,6 +2045,34 @@ namespace {
20512045 }
20522046 assert (base && " Unable to convert base?" );
20532047
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+
20542076 // Handle dynamic references.
20552077 if (!needsCurryThunk &&
20562078 (isDynamic || member->getAttrs ().hasAttribute <OptionalAttr>())) {
@@ -2064,24 +2086,14 @@ namespace {
20642086 if (isa<VarDecl>(member)) {
20652087 return buildVarMemberRef (base, dotLoc, baseIsInstance,
20662088 memberRef, memberLoc, containerTy,
2067- refTy, adjustedRefTy, adjustedOpenedType ,
2089+ refTy, refTySelf, adjustedRefTy, adjustedRefTySelf ,
20682090 semantics, locator, memberLocator,
20692091 isSuper, isUnboundInstanceMember, Implicit);
20702092 }
20712093
20722094 ASSERT (isa<AbstractFunctionDecl>(member) ||
20732095 isa<EnumElementDecl>(member));
20742096
2075- Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
2076-
2077- auto *func = dyn_cast<FuncDecl>(member);
2078- if (func && func->getResultInterfaceType ()->hasDynamicSelfType ()) {
2079- ASSERT (refTy->hasDynamicSelfType ());
2080- refTySelf = refTy->replaceDynamicSelfType (containerTy);
2081- adjustedRefTySelf = adjustedRefTy->replaceDynamicSelfType (
2082- containerTy);
2083- }
2084-
20852097 // Handle all other references.
20862098 auto declRefExpr = new (ctx) DeclRefExpr (memberRef, memberLoc,
20872099 Implicit, semantics);
@@ -2169,30 +2181,28 @@ namespace {
21692181 // Note: For unbound references this is handled inside the thunk.
21702182 if (!isUnboundInstanceMember &&
21712183 member->getDeclContext ()->getSelfClassDecl ()) {
2172- if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
2173- if (func->hasDynamicSelfResult ()) {
2174- // FIXME: Once CovariantReturnConversionExpr (unchecked_ref_cast)
2175- // supports a class existential dest., consider using the opened
2176- // type directly to avoid recomputing the 'Self' replacement and
2177- // substituting.
2178- const Type replacementTy = getDynamicSelfReplacementType (
2179- baseTy, member, memberLocator.getBaseLocator ());
2180- if (!replacementTy->isEqual (containerTy)) {
2181- if (isa<ConstructorDecl>(member)) {
2182- adjustedRefTy = adjustedRefTy->withCovariantResultType ();
2183- } else {
2184- ASSERT (adjustedRefTy->hasDynamicSelfType ());
2185- }
2186- Type conversionTy =
2187- adjustedRefTy->replaceDynamicSelfType (replacementTy);
2188- if (isSuperPartialApplication) {
2189- conversionTy =
2190- conversionTy->castTo <FunctionType>()->getResult ();
2191- }
2184+ if (overload.adjustedOpenedFullType ->hasDynamicSelfType ()) {
21922185
2193- ref = cs.cacheType (new (ctx) CovariantFunctionConversionExpr (
2194- 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 ();
21952202 }
2203+
2204+ ref = cs.cacheType (new (ctx) CovariantFunctionConversionExpr (
2205+ ref, conversionTy));
21962206 }
21972207 }
21982208 }
@@ -2548,7 +2558,6 @@ namespace {
25482558 // Form the subscript expression.
25492559 auto subscriptExpr = SubscriptExpr::create (
25502560 ctx, base, args, subscriptRef, isImplicit, semantics);
2551- cs.setType (subscriptExpr, fullSubscriptTy->getResult ());
25522561 subscriptExpr->setIsSuper (isSuper);
25532562
25542563 if (!hasDynamicSelf) {
@@ -2587,30 +2596,36 @@ namespace {
25872596 bool implicit) {
25882597 // The constructor was opened with the allocating type, not the
25892598 // initializer type. Map the former into the latter.
2590- auto *resultTy =
2591- solution.simplifyType (openedFullType)->castTo <FunctionType>();
2592-
2593- const auto selfTy = getBaseType (resultTy);
2594-
2595- ParameterTypeFlags flags;
2596- if (!selfTy->hasReferenceSemantics ())
2597- flags = flags.withInOut (true );
2599+ auto getOpenedInitializerType = [&](Type ty) -> FunctionType * {
2600+ auto *resultTy = solution.simplifyType (ty)->castTo <FunctionType>();
2601+ auto selfTy = getBaseType (resultTy);
2602+
2603+ ParameterTypeFlags flags;
2604+ if (!selfTy->hasReferenceSemantics ())
2605+ flags = flags.withInOut (true );
2606+
2607+ auto selfParam = AnyFunctionType::Param (selfTy, Identifier (), flags);
2608+ return FunctionType::get ({selfParam},
2609+ resultTy->getResult (),
2610+ resultTy->getExtInfo ());
2611+ };
25982612
2599- auto selfParam = AnyFunctionType::Param (selfTy, Identifier (), flags);
2600- resultTy = FunctionType::get ({selfParam}, resultTy->getResult (),
2601- resultTy->getExtInfo ());
2613+ auto *resultTySelf = getOpenedInitializerType (
2614+ openedFullType->eraseDynamicSelfType ());
26022615
26032616 // Build the constructor reference.
26042617 Expr *ctorRef = cs.cacheType (
2605- new (ctx) OtherConstructorDeclRefExpr (ref, loc, implicit, resultTy));
2618+ new (ctx) OtherConstructorDeclRefExpr (ref, loc, implicit, resultTySelf));
2619+
2620+ auto *resultTy = getOpenedInitializerType (
2621+ openedFullType->replaceDynamicSelfType (
2622+ cs.getType (base)->getWithoutSpecifierType ()));
26062623
26072624 // Wrap in covariant `Self` return if needed.
2608- if (ref.getDecl ()->getDeclContext ()->getSelfClassDecl ()) {
2609- auto covariantTy = resultTy->withCovariantResultType ()
2610- ->replaceDynamicSelfType (cs.getType (base)->getWithoutSpecifierType ());
2611- if (!covariantTy->isEqual (resultTy))
2612- ctorRef = cs.cacheType (
2613- new (ctx) CovariantFunctionConversionExpr (ctorRef, covariantTy));
2625+ if (!resultTy->isEqual (resultTySelf)) {
2626+ ASSERT (ref.getDecl ()->getDeclContext ()->getSelfClassDecl ());
2627+ ctorRef = cs.cacheType (
2628+ new (ctx) CovariantFunctionConversionExpr (ctorRef, resultTy));
26142629 }
26152630
26162631 return ctorRef;
0 commit comments