@@ -1743,6 +1743,93 @@ namespace {
1743
1743
return forceUnwrapIfExpected (ref, memberLocator);
1744
1744
}
1745
1745
1746
+ Expr *buildVarMemberRef (Expr *base, SourceLoc dotLoc,
1747
+ bool baseIsInstance,
1748
+ ConcreteDeclRef memberRef,
1749
+ DeclNameLoc memberLoc,
1750
+ Type containerTy,
1751
+ Type refTy,
1752
+ Type adjustedRefTy,
1753
+ Type adjustedOpenedType,
1754
+ AccessSemantics semantics,
1755
+ ConstraintLocatorBuilder locator,
1756
+ ConstraintLocatorBuilder memberLocator,
1757
+ bool isSuper,
1758
+ bool isUnboundInstanceMember,
1759
+ bool Implicit) {
1760
+ auto *varDecl = cast<VarDecl>(memberRef.getDecl ());
1761
+
1762
+ bool loadImmediately = false ;
1763
+ auto resultType = [&loadImmediately](Type fnTy) -> Type {
1764
+ Type resultTy = fnTy->castTo <FunctionType>()->getResult ();
1765
+ if (loadImmediately)
1766
+ return LValueType::get (resultTy);
1767
+ return resultTy;
1768
+ };
1769
+
1770
+ // If we have an instance property that's treated as an rvalue
1771
+ // but allows assignment (for initialization) in the current
1772
+ // context, treat it as an rvalue that we immediately load.
1773
+ // This is the AST that's expected by SILGen.
1774
+ if (baseIsInstance && !resultType (refTy)->hasLValueType () &&
1775
+ varDecl->mutability (dc, dyn_cast<DeclRefExpr>(base))
1776
+ == StorageMutability::Initializable) {
1777
+ loadImmediately = true ;
1778
+ }
1779
+
1780
+ if (isUnboundInstanceMember) {
1781
+ assert (memberLocator.getBaseLocator () &&
1782
+ cs.UnevaluatedRootExprs .count (
1783
+ getAsExpr (memberLocator.getBaseLocator ()->getAnchor ())) &&
1784
+ " Attempt to reference an instance member of a metatype" );
1785
+ auto baseInstanceTy = cs.getType (base)
1786
+ ->getInOutObjectType ()->getMetatypeInstanceType ();
1787
+ base = new (ctx) UnevaluatedInstanceExpr (base, baseInstanceTy);
1788
+ cs.cacheType (base);
1789
+ base->setImplicit ();
1790
+ }
1791
+
1792
+ const auto hasDynamicSelf = refTy->hasDynamicSelfType ();
1793
+
1794
+ auto memberRefExpr
1795
+ = new (ctx) MemberRefExpr (base, dotLoc, memberRef,
1796
+ memberLoc, Implicit, semantics);
1797
+ memberRefExpr->setIsSuper (isSuper);
1798
+
1799
+ if (hasDynamicSelf) {
1800
+ refTy = refTy->replaceDynamicSelfType (containerTy);
1801
+ adjustedRefTy = adjustedRefTy->replaceDynamicSelfType (
1802
+ containerTy);
1803
+ }
1804
+
1805
+ cs.setType (memberRefExpr, resultType (refTy));
1806
+
1807
+ Expr *result = memberRefExpr;
1808
+ result = adjustTypeForDeclReference (result, resultType (refTy),
1809
+ resultType (adjustedRefTy),
1810
+ locator);
1811
+ closeExistentials (result, locator);
1812
+
1813
+ // If the property is of dynamic 'Self' type, wrap an implicit
1814
+ // conversion around the resulting expression, with the destination
1815
+ // type having 'Self' swapped for the appropriate replacement
1816
+ // 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
+ }
1823
+ }
1824
+
1825
+ // If we need to load, do so now.
1826
+ if (loadImmediately) {
1827
+ result = cs.addImplicitLoadExpr (result);
1828
+ }
1829
+
1830
+ return forceUnwrapIfExpected (result, memberLocator);
1831
+ }
1832
+
1746
1833
// / Build a new member reference with the given base and member.
1747
1834
Expr *buildMemberRef (Expr *base, SourceLoc dotLoc,
1748
1835
SelectedOverload overload, DeclNameLoc memberLoc,
@@ -1974,79 +2061,17 @@ namespace {
1974
2061
}
1975
2062
1976
2063
// For properties, build member references.
1977
- if (auto *varDecl = dyn_cast<VarDecl>(member)) {
1978
- // \returns result of the given function type
1979
- bool loadImmediately = false ;
1980
- auto resultType = [&loadImmediately](Type fnTy) -> Type {
1981
- Type resultTy = fnTy->castTo <FunctionType>()->getResult ();
1982
- if (loadImmediately)
1983
- return LValueType::get (resultTy);
1984
- return resultTy;
1985
- };
1986
-
1987
- // If we have an instance property that's treated as an rvalue
1988
- // but allows assignment (for initialization) in the current
1989
- // context, treat it as an rvalue that we immediately load.
1990
- // This is the AST that's expected by SILGen.
1991
- if (baseIsInstance && !resultType (refTy)->hasLValueType () &&
1992
- varDecl->mutability (dc, dyn_cast<DeclRefExpr>(base))
1993
- == StorageMutability::Initializable) {
1994
- loadImmediately = true ;
1995
- }
1996
-
1997
- if (isUnboundInstanceMember) {
1998
- assert (memberLocator.getBaseLocator () &&
1999
- cs.UnevaluatedRootExprs .count (
2000
- getAsExpr (memberLocator.getBaseLocator ()->getAnchor ())) &&
2001
- " Attempt to reference an instance member of a metatype" );
2002
- auto baseInstanceTy = cs.getType (base)
2003
- ->getInOutObjectType ()->getMetatypeInstanceType ();
2004
- base = new (ctx) UnevaluatedInstanceExpr (base, baseInstanceTy);
2005
- cs.cacheType (base);
2006
- base->setImplicit ();
2007
- }
2008
-
2009
- const auto hasDynamicSelf = refTy->hasDynamicSelfType ();
2010
-
2011
- auto memberRefExpr
2012
- = new (ctx) MemberRefExpr (base, dotLoc, memberRef,
2013
- memberLoc, Implicit, semantics);
2014
- memberRefExpr->setIsSuper (isSuper);
2015
-
2016
- if (hasDynamicSelf) {
2017
- refTy = refTy->replaceDynamicSelfType (containerTy);
2018
- adjustedRefTy = adjustedRefTy->replaceDynamicSelfType (
2019
- containerTy);
2020
- }
2021
-
2022
- cs.setType (memberRefExpr, resultType (refTy));
2023
-
2024
- Expr *result = memberRefExpr;
2025
- result = adjustTypeForDeclReference (result, resultType (refTy),
2026
- resultType (adjustedRefTy),
2027
- locator);
2028
- closeExistentials (result, locator);
2029
-
2030
- // If the property is of dynamic 'Self' type, wrap an implicit
2031
- // conversion around the resulting expression, with the destination
2032
- // type having 'Self' swapped for the appropriate replacement
2033
- // type -- usually the base object type.
2034
- if (hasDynamicSelf) {
2035
- const auto conversionTy = adjustedOpenedType;
2036
- if (!containerTy->isEqual (conversionTy)) {
2037
- result = cs.cacheType (new (ctx) CovariantReturnConversionExpr (
2038
- result, conversionTy));
2039
- }
2040
- }
2041
-
2042
- // If we need to load, do so now.
2043
- if (loadImmediately) {
2044
- result = cs.addImplicitLoadExpr (result);
2045
- }
2046
-
2047
- return forceUnwrapIfExpected (result, memberLocator);
2064
+ if (isa<VarDecl>(member)) {
2065
+ return buildVarMemberRef (base, dotLoc, baseIsInstance,
2066
+ memberRef, memberLoc, containerTy,
2067
+ refTy, adjustedRefTy, adjustedOpenedType,
2068
+ semantics, locator, memberLocator,
2069
+ isSuper, isUnboundInstanceMember, Implicit);
2048
2070
}
2049
2071
2072
+ ASSERT (isa<AbstractFunctionDecl>(member) ||
2073
+ isa<EnumElementDecl>(member));
2074
+
2050
2075
Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
2051
2076
2052
2077
auto *func = dyn_cast<FuncDecl>(member);
0 commit comments