@@ -411,18 +411,57 @@ FunctionType *ConstraintSystem::openFunctionType(
411411 return funcType->castTo <FunctionType>();
412412}
413413
414+ static bool isInLeftHandSideOfAssignment (ConstraintSystem &cs, Expr *expr) {
415+ // Walk up the parent tree.
416+ auto parent = cs.getParentExpr (expr);
417+ if (!parent)
418+ return false ;
419+
420+ // If the parent is an assignment expression, check whether we are
421+ // the left-hand side.
422+ if (auto assignParent = dyn_cast<AssignExpr>(parent)) {
423+ return expr == assignParent->getDest ();
424+ }
425+
426+ // Always look up through these parent kinds.
427+ if (isa<TupleExpr>(parent) || isa<IdentityExpr>(parent) ||
428+ isa<AnyTryExpr>(parent) || isa<BindOptionalExpr>(parent)) {
429+ return isInLeftHandSideOfAssignment (cs, parent);
430+ }
431+
432+ // If the parent is a lookup expression, only follow from the base.
433+ if (auto lookupParent = dyn_cast<LookupExpr>(parent)) {
434+ if (lookupParent->getBase () == expr)
435+ return isInLeftHandSideOfAssignment (cs, parent);
414436
437+ // The expression wasn't in the base, so this isn't part of the
438+ // left-hand side.
439+ return false ;
440+ }
441+
442+ // If the parent is an unresolved member reference a.b, only follow
443+ // from the base.
444+ if (auto dotParent = dyn_cast<UnresolvedDotExpr>(parent)) {
445+ if (dotParent->getBase () == expr)
446+ return isInLeftHandSideOfAssignment (cs, parent);
447+
448+ // The expression wasn't in the base, so this isn't part of the
449+ // left-hand side.
450+ return false ;
451+ }
452+
453+ return false ;
454+ }
415455
416456// / Does a var or subscript produce an l-value?
417457// /
418458// / \param baseType - the type of the base on which this object
419459// / is being accessed; must be null if and only if this is not
420460// / a type member
421- static bool
422- doesStorageProduceLValue (
461+ static bool doesStorageProduceLValue (
423462 AbstractStorageDecl *storage, Type baseType,
424463 DeclContext *useDC,
425- llvm::function_ref< bool (Expr *)> isAssignTarget ,
464+ ConstraintSystem &cs ,
426465 ConstraintLocator *locator) {
427466 const DeclRefExpr *base = nullptr ;
428467 if (locator) {
@@ -456,7 +495,7 @@ doesStorageProduceLValue(
456495
457496 // If the anchor isn't known to be the target of an assignment,
458497 // treat as immutable.
459- if (!isAssignTarget ( anchor))
498+ if (!isInLeftHandSideOfAssignment (cs, anchor))
460499 return false ;
461500
462501 break ;
@@ -541,9 +580,7 @@ Type ConstraintSystem::getUnopenedTypeOfReference(
541580
542581 // Qualify storage declarations with an lvalue when appropriate.
543582 // Otherwise, they yield rvalues (and the access must be a load).
544- if (doesStorageProduceLValue (value, baseType, UseDC,
545- IsInLeftHandSideOfAssignment{*this },
546- locator) &&
583+ if (doesStorageProduceLValue (value, baseType, UseDC, *this , locator) &&
547584 !requestedType->hasError ()) {
548585 return LValueType::get (requestedType);
549586 }
@@ -1391,48 +1428,6 @@ Type ConstraintSystem::getMemberReferenceTypeFromOpenedType(
13911428 return type;
13921429}
13931430
1394- bool IsInLeftHandSideOfAssignment::operator ()(Expr *expr) const {
1395- // Walk up the parent tree.
1396- auto parent = cs.getParentExpr (expr);
1397- if (!parent)
1398- return false ;
1399-
1400- // If the parent is an assignment expression, check whether we are
1401- // the left-hand side.
1402- if (auto assignParent = dyn_cast<AssignExpr>(parent)) {
1403- return expr == assignParent->getDest ();
1404- }
1405-
1406- // Always look up through these parent kinds.
1407- if (isa<TupleExpr>(parent) || isa<IdentityExpr>(parent) ||
1408- isa<AnyTryExpr>(parent) || isa<BindOptionalExpr>(parent)) {
1409- return (*this )(parent);
1410- }
1411-
1412- // If the parent is a lookup expression, only follow from the base.
1413- if (auto lookupParent = dyn_cast<LookupExpr>(parent)) {
1414- if (lookupParent->getBase () == expr)
1415- return (*this )(parent);
1416-
1417- // The expression wasn't in the base, so this isn't part of the
1418- // left-hand side.
1419- return false ;
1420- }
1421-
1422- // If the parent is an unresolved member reference a.b, only follow
1423- // from the base.
1424- if (auto dotParent = dyn_cast<UnresolvedDotExpr>(parent)) {
1425- if (dotParent->getBase () == expr)
1426- return (*this )(parent);
1427-
1428- // The expression wasn't in the base, so this isn't part of the
1429- // left-hand side.
1430- return false ;
1431- }
1432-
1433- return false ;
1434- }
1435-
14361431DeclReferenceType ConstraintSystem::getTypeOfMemberReference (
14371432 Type baseTy, ValueDecl *value, DeclContext *useDC, bool isDynamicLookup,
14381433 FunctionRefKind functionRefKind, ConstraintLocator *locator,
@@ -1535,9 +1530,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
15351530 if (auto *subscript = dyn_cast<SubscriptDecl>(value)) {
15361531 auto elementTy = subscript->getElementInterfaceType ();
15371532
1538- if (doesStorageProduceLValue (
1539- subscript, baseTy, useDC,
1540- IsInLeftHandSideOfAssignment{*this }, locator))
1533+ if (doesStorageProduceLValue (subscript, baseTy, useDC, *this , locator))
15411534 elementTy = LValueType::get (elementTy);
15421535
15431536 auto indices = subscript->getInterfaceType ()
@@ -1791,9 +1784,7 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
17911784 auto elementTy = subscript->getElementInterfaceType ();
17921785
17931786 if (doesStorageProduceLValue (subscript, overload.getBaseType (),
1794- useDC,
1795- IsInLeftHandSideOfAssignment{*this },
1796- locator))
1787+ useDC, *this , locator))
17971788 elementTy = LValueType::get (elementTy);
17981789 else if (elementTy->hasDynamicSelfType ()) {
17991790 elementTy = withDynamicSelfResultReplaced (elementTy,
@@ -1818,8 +1809,7 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
18181809 } else if (auto var = dyn_cast<VarDecl>(decl)) {
18191810 type = var->getValueInterfaceType ();
18201811 if (doesStorageProduceLValue (
1821- var, overload.getBaseType (), useDC,
1822- IsInLeftHandSideOfAssignment{*this }, locator)) {
1812+ var, overload.getBaseType (), useDC, *this , locator)) {
18231813 type = LValueType::get (type);
18241814 } else if (type->hasDynamicSelfType ()) {
18251815 type = withDynamicSelfResultReplaced (type, /* uncurryLevel=*/ 0 );
0 commit comments