@@ -1743,6 +1743,93 @@ namespace {
17431743 return forceUnwrapIfExpected (ref, memberLocator);
17441744 }
17451745
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+
17461833 // / Build a new member reference with the given base and member.
17471834 Expr *buildMemberRef (Expr *base, SourceLoc dotLoc,
17481835 SelectedOverload overload, DeclNameLoc memberLoc,
@@ -1974,79 +2061,17 @@ namespace {
19742061 }
19752062
19762063 // 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);
20482070 }
20492071
2072+ ASSERT (isa<AbstractFunctionDecl>(member) ||
2073+ isa<EnumElementDecl>(member));
2074+
20502075 Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
20512076
20522077 auto *func = dyn_cast<FuncDecl>(member);
0 commit comments