@@ -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,
@@ -1789,37 +1791,28 @@ namespace {
1789
1791
base->setImplicit ();
1790
1792
}
1791
1793
1792
- const auto hasDynamicSelf = refTy->hasDynamicSelfType ();
1793
-
1794
1794
auto memberRefExpr
1795
1795
= new (ctx) MemberRefExpr (base, dotLoc, memberRef,
1796
1796
memberLoc, Implicit, semantics);
1797
1797
memberRefExpr->setIsSuper (isSuper);
1798
1798
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);
1806
1801
1807
1802
Expr *result = memberRefExpr;
1808
- result = adjustTypeForDeclReference (result, resultType (refTy) ,
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
- 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));
1823
1816
}
1824
1817
1825
1818
// If we need to load, do so now.
@@ -1943,7 +1936,8 @@ namespace {
1943
1936
Expr *ref = cs.cacheType (new (ctx) DotSyntaxBaseIgnoredExpr (
1944
1937
base, dotLoc, dre, refTy));
1945
1938
1946
- ref = adjustTypeForDeclReference (ref, refTy, adjustedRefTy, locator);
1939
+ ref = adjustTypeForDeclReference (ref, refTy, adjustedRefTy,
1940
+ locator);
1947
1941
return forceUnwrapIfExpected (ref, memberLocator);
1948
1942
}
1949
1943
@@ -2051,6 +2045,34 @@ namespace {
2051
2045
}
2052
2046
assert (base && " Unable to convert base?" );
2053
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
+
2054
2076
// Handle dynamic references.
2055
2077
if (!needsCurryThunk &&
2056
2078
(isDynamic || member->getAttrs ().hasAttribute <OptionalAttr>())) {
@@ -2064,24 +2086,14 @@ namespace {
2064
2086
if (isa<VarDecl>(member)) {
2065
2087
return buildVarMemberRef (base, dotLoc, baseIsInstance,
2066
2088
memberRef, memberLoc, containerTy,
2067
- refTy, adjustedRefTy, adjustedOpenedType ,
2089
+ refTy, refTySelf, adjustedRefTy, adjustedRefTySelf ,
2068
2090
semantics, locator, memberLocator,
2069
2091
isSuper, isUnboundInstanceMember, Implicit);
2070
2092
}
2071
2093
2072
2094
ASSERT (isa<AbstractFunctionDecl>(member) ||
2073
2095
isa<EnumElementDecl>(member));
2074
2096
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
-
2085
2097
// Handle all other references.
2086
2098
auto declRefExpr = new (ctx) DeclRefExpr (memberRef, memberLoc,
2087
2099
Implicit, semantics);
@@ -2169,30 +2181,28 @@ namespace {
2169
2181
// Note: For unbound references this is handled inside the thunk.
2170
2182
if (!isUnboundInstanceMember &&
2171
2183
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 ()) {
2192
2185
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 ();
2195
2202
}
2203
+
2204
+ ref = cs.cacheType (new (ctx) CovariantFunctionConversionExpr (
2205
+ ref, conversionTy));
2196
2206
}
2197
2207
}
2198
2208
}
@@ -2548,7 +2558,6 @@ namespace {
2548
2558
// Form the subscript expression.
2549
2559
auto subscriptExpr = SubscriptExpr::create (
2550
2560
ctx, base, args, subscriptRef, isImplicit, semantics);
2551
- cs.setType (subscriptExpr, fullSubscriptTy->getResult ());
2552
2561
subscriptExpr->setIsSuper (isSuper);
2553
2562
2554
2563
if (!hasDynamicSelf) {
@@ -2587,30 +2596,36 @@ namespace {
2587
2596
bool implicit) {
2588
2597
// The constructor was opened with the allocating type, not the
2589
2598
// 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
+ };
2598
2612
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 ());
2602
2615
2603
2616
// Build the constructor reference.
2604
2617
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 ()));
2606
2623
2607
2624
// 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));
2614
2629
}
2615
2630
2616
2631
return ctorRef;
0 commit comments