@@ -776,7 +776,7 @@ bool MissingOptionalUnwrapFailure::diagnoseAsError() {
776776bool RValueTreatedAsLValueFailure::diagnoseAsError () {
777777 Diag<StringRef> subElementDiagID;
778778 Diag<Type> rvalueDiagID = diag::assignment_lhs_not_lvalue;
779- Expr *diagExpr = getLocator ()-> getAnchor ();
779+ Expr *diagExpr = getRawAnchor ();
780780 SourceLoc loc = diagExpr->getLoc ();
781781
782782 if (auto assignExpr = dyn_cast<AssignExpr>(diagExpr)) {
@@ -854,12 +854,18 @@ bool RValueTreatedAsLValueFailure::diagnoseAsError() {
854854 }
855855 }
856856
857- if (auto resolvedOverload = getResolvedOverload (getLocator ()))
857+ if (auto resolvedOverload = getResolvedOverload (getLocator ())) {
858858 if (resolvedOverload->Choice .getKind () ==
859- OverloadChoiceKind::DynamicMemberLookup ||
860- resolvedOverload->Choice .getKind () ==
861- OverloadChoiceKind::KeyPathDynamicMemberLookup)
859+ OverloadChoiceKind::DynamicMemberLookup)
862860 subElementDiagID = diag::assignment_dynamic_property_has_immutable_base;
861+
862+ if (resolvedOverload->Choice .getKind () ==
863+ OverloadChoiceKind::KeyPathDynamicMemberLookup) {
864+ if (!getType (member->getBase ())->hasLValueType ())
865+ subElementDiagID =
866+ diag::assignment_dynamic_property_has_immutable_base;
867+ }
868+ }
863869 } else if (auto sub = dyn_cast<SubscriptExpr>(diagExpr)) {
864870 subElementDiagID = diag::assignment_subscript_has_immutable_base;
865871 } else {
@@ -1204,7 +1210,7 @@ AssignmentFailure::resolveImmutableBase(Expr *expr) const {
12041210 if (!member) {
12051211 auto loc =
12061212 cs.getConstraintLocator (SE, ConstraintLocator::SubscriptMember);
1207- member = dyn_cast_or_null<SubscriptDecl>(cs. findResolvedMemberRef (loc));
1213+ member = dyn_cast_or_null<SubscriptDecl>(getMemberRef (loc));
12081214 }
12091215
12101216 // If it isn't settable, return it.
@@ -1233,9 +1239,10 @@ AssignmentFailure::resolveImmutableBase(Expr *expr) const {
12331239 // If we found a decl for the UDE, check it.
12341240 auto loc = cs.getConstraintLocator (UDE, ConstraintLocator::Member);
12351241
1242+ auto *member = getMemberRef (loc);
12361243 // If we can resolve a member, we can determine whether it is settable in
12371244 // this context.
1238- if (auto * member = cs. findResolvedMemberRef (loc) ) {
1245+ if (member) {
12391246 auto *memberVD = dyn_cast<VarDecl>(member);
12401247
12411248 // If the member isn't a vardecl (e.g. its a funcdecl), or it isn't
@@ -1283,6 +1290,43 @@ AssignmentFailure::resolveImmutableBase(Expr *expr) const {
12831290 return {expr, nullptr };
12841291}
12851292
1293+ ValueDecl *AssignmentFailure::getMemberRef (ConstraintLocator *locator) const {
1294+ auto member = getOverloadChoiceIfAvailable (locator);
1295+ if (!member || !member->choice .isDecl ())
1296+ return nullptr ;
1297+
1298+ auto *DC = getDC ();
1299+ auto &TC = getTypeChecker ();
1300+
1301+ auto *decl = member->choice .getDecl ();
1302+ if (isa<SubscriptDecl>(decl) &&
1303+ isValidDynamicMemberLookupSubscript (cast<SubscriptDecl>(decl), DC, TC)) {
1304+ auto *subscript = cast<SubscriptDecl>(decl);
1305+ // If this is a keypath dynamic member lookup, we have to
1306+ // adjust the locator to find member referred by it.
1307+ if (isValidKeyPathDynamicMemberLookup (subscript, TC)) {
1308+ auto &cs = getConstraintSystem ();
1309+ // Type has a following format:
1310+ // `(Self) -> (dynamicMember: {Writable}KeyPath<T, U>) -> U`
1311+ auto *fullType = member->openedFullType ->castTo <FunctionType>();
1312+ auto *fnType = fullType->getResult ()->castTo <FunctionType>();
1313+
1314+ auto paramTy = fnType->getParams ()[0 ].getPlainType ();
1315+ auto keyPath = paramTy->getAnyNominal ();
1316+ auto memberLoc = cs.getConstraintLocator (
1317+ locator, LocatorPathElt::getKeyPathDynamicMember (keyPath));
1318+
1319+ auto memberRef = getOverloadChoiceIfAvailable (memberLoc);
1320+ return memberRef ? memberRef->choice .getDecl () : nullptr ;
1321+ }
1322+
1323+ // If this is a string based dynamic lookup, there is no member declaration.
1324+ return nullptr ;
1325+ }
1326+
1327+ return decl;
1328+ }
1329+
12861330Diag<StringRef> AssignmentFailure::findDeclDiagonstic (ASTContext &ctx,
12871331 Expr *destExpr) {
12881332 if (isa<ApplyExpr>(destExpr) || isa<SelfApplyExpr>(destExpr))
0 commit comments