@@ -1743,14 +1743,16 @@ namespace {
1743
1743
return forceUnwrapIfExpected (ref, memberLocator);
1744
1744
}
1745
1745
1746
+ // / FIXME: Simplify this horrible parameter list.
1746
1747
Expr *buildVarMemberRef (Expr *base, SourceLoc dotLoc,
1747
1748
bool baseIsInstance,
1748
1749
ConcreteDeclRef memberRef,
1749
1750
DeclNameLoc memberLoc,
1750
1751
Type containerTy,
1751
1752
Type refTy,
1753
+ Type refTySelf,
1752
1754
Type adjustedRefTy,
1753
- Type adjustedOpenedType ,
1755
+ Type adjustedRefTySelf ,
1754
1756
AccessSemantics semantics,
1755
1757
ConstraintLocatorBuilder locator,
1756
1758
ConstraintLocatorBuilder memberLocator,
@@ -1794,31 +1796,23 @@ namespace {
1794
1796
memberLoc, Implicit, semantics);
1795
1797
memberRefExpr->setIsSuper (isSuper);
1796
1798
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);
1806
1801
1807
1802
Expr *result = memberRefExpr;
1808
- result = adjustTypeForDeclReference (result, resultTy ,
1809
- resultType (adjustedRefTy ),
1803
+ result = adjustTypeForDeclReference (result, resultTySelf ,
1804
+ resultType (adjustedRefTySelf ),
1810
1805
locator);
1811
1806
closeExistentials (result, locator);
1812
1807
1813
1808
// If the property is of dynamic 'Self' type, wrap an implicit
1814
1809
// conversion around the resulting expression, with the destination
1815
1810
// type having 'Self' swapped for the appropriate replacement
1816
1811
// 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));
1822
1816
}
1823
1817
1824
1818
// If we need to load, do so now.
@@ -1942,7 +1936,8 @@ namespace {
1942
1936
Expr *ref = cs.cacheType (new (ctx) DotSyntaxBaseIgnoredExpr (
1943
1937
base, dotLoc, dre, refTy));
1944
1938
1945
- ref = adjustTypeForDeclReference (ref, refTy, adjustedRefTy, locator);
1939
+ ref = adjustTypeForDeclReference (ref, refTy, adjustedRefTy,
1940
+ locator);
1946
1941
return forceUnwrapIfExpected (ref, memberLocator);
1947
1942
}
1948
1943
@@ -2050,6 +2045,34 @@ namespace {
2050
2045
}
2051
2046
assert (base && " Unable to convert base?" );
2052
2047
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
+
2053
2076
// Handle dynamic references.
2054
2077
if (!needsCurryThunk &&
2055
2078
(isDynamic || member->getAttrs ().hasAttribute <OptionalAttr>())) {
@@ -2063,22 +2086,14 @@ namespace {
2063
2086
if (isa<VarDecl>(member)) {
2064
2087
return buildVarMemberRef (base, dotLoc, baseIsInstance,
2065
2088
memberRef, memberLoc, containerTy,
2066
- refTy, adjustedRefTy, adjustedOpenedType ,
2089
+ refTy, refTySelf, adjustedRefTy, adjustedRefTySelf ,
2067
2090
semantics, locator, memberLocator,
2068
2091
isSuper, isUnboundInstanceMember, Implicit);
2069
2092
}
2070
2093
2071
2094
ASSERT (isa<AbstractFunctionDecl>(member) ||
2072
2095
isa<EnumElementDecl>(member));
2073
2096
2074
- Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
2075
-
2076
- if (refTy->hasDynamicSelfType ()) {
2077
- refTySelf = refTy->replaceDynamicSelfType (containerTy);
2078
- adjustedRefTySelf = adjustedRefTy->replaceDynamicSelfType (
2079
- containerTy);
2080
- }
2081
-
2082
2097
// Handle all other references.
2083
2098
auto declRefExpr = new (ctx) DeclRefExpr (memberRef, memberLoc,
2084
2099
Implicit, semantics);
@@ -2166,27 +2181,28 @@ namespace {
2166
2181
// Note: For unbound references this is handled inside the thunk.
2167
2182
if (!isUnboundInstanceMember &&
2168
2183
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 ()) {
2186
2185
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 ();
2189
2202
}
2203
+
2204
+ ref = cs.cacheType (new (ctx) CovariantFunctionConversionExpr (
2205
+ ref, conversionTy));
2190
2206
}
2191
2207
}
2192
2208
}
@@ -2542,7 +2558,6 @@ namespace {
2542
2558
// Form the subscript expression.
2543
2559
auto subscriptExpr = SubscriptExpr::create (
2544
2560
ctx, base, args, subscriptRef, isImplicit, semantics);
2545
- cs.setType (subscriptExpr, fullSubscriptTy->getResult ());
2546
2561
subscriptExpr->setIsSuper (isSuper);
2547
2562
2548
2563
if (!hasDynamicSelf) {
0 commit comments