Skip to content

Commit 1e8ae99

Browse files
committed
[CSFix] Add a fix for invalid reference to mutating member on immutable base
1 parent 133e85b commit 1e8ae99

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

lib/Sema/CSFix.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,3 +643,15 @@ bool SkipUnhandledConstructInFunctionBuilder::diagnose(Expr *root,
643643
root, getConstraintSystem(), unhandled, builder, getLocator());
644644
return failure.diagnose(asNote);
645645
}
646+
647+
bool AllowMutatingMemberOrRValueBase::diagnose(Expr *root, bool asNote) const {
648+
return false;
649+
}
650+
651+
AllowMutatingMemberOrRValueBase *
652+
AllowMutatingMemberOrRValueBase::create(ConstraintSystem &cs, Type baseType,
653+
ValueDecl *member, DeclName name,
654+
ConstraintLocator *locator) {
655+
return new (cs.getAllocator())
656+
AllowMutatingMemberOrRValueBase(cs, baseType, member, name, locator);
657+
}

lib/Sema/CSFix.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ enum class FixKind : uint8_t {
179179
/// matches up with a
180180
/// parameter that has a function builder.
181181
SkipUnhandledConstructInFunctionBuilder,
182+
183+
/// Allow invalid reference to a member declared as `mutating`
184+
/// when base is an r-value type.
185+
AllowMutatingMemberOrRValueBase,
182186
};
183187

184188
class ConstraintFix {
@@ -858,6 +862,25 @@ class AllowInvalidInitRef final : public ConstraintFix {
858862
ConstraintLocator *locator);
859863
};
860864

865+
class AllowMutatingMemberOrRValueBase final : public AllowInvalidMemberRef {
866+
AllowMutatingMemberOrRValueBase(ConstraintSystem &cs, Type baseType,
867+
ValueDecl *member, DeclName name,
868+
ConstraintLocator *locator)
869+
: AllowInvalidMemberRef(cs, FixKind::AllowMutatingMemberOrRValueBase,
870+
baseType, member, name, locator) {}
871+
872+
public:
873+
std::string getName() const override {
874+
return "allow `mutating` method on r-value base";
875+
}
876+
877+
bool diagnose(Expr *root, bool asNote = false) const override;
878+
879+
static AllowMutatingMemberOrRValueBase *
880+
create(ConstraintSystem &cs, Type baseType, ValueDecl *member, DeclName name,
881+
ConstraintLocator *locator);
882+
};
883+
861884
class AllowClosureParamDestructuring final : public ConstraintFix {
862885
FunctionType *ContextualType;
863886

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4761,7 +4761,13 @@ fixMemberRef(ConstraintSystem &cs, Type baseTy,
47614761
}
47624762

47634763
case MemberLookupResult::UR_MutatingMemberOnRValue:
4764-
case MemberLookupResult::UR_MutatingGetterOnRValue:
4764+
case MemberLookupResult::UR_MutatingGetterOnRValue: {
4765+
return choice.isDecl()
4766+
? AllowMutatingMemberOrRValueBase::create(
4767+
cs, baseTy, choice.getDecl(), memberName, locator)
4768+
: nullptr;
4769+
}
4770+
47654771
case MemberLookupResult::UR_LabelMismatch:
47664772
// TODO(diagnostics): Add a new fix that is suggests to
47674773
// add `subscript(dynamicMember: {Writable}KeyPath<T, U>)`
@@ -6929,6 +6935,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
69296935
case FixKind::AllowInvalidRefInKeyPath:
69306936
case FixKind::ExplicitlySpecifyGenericArguments:
69316937
case FixKind::GenericArgumentsMismatch:
6938+
case FixKind::AllowMutatingMemberOrRValueBase:
69326939
llvm_unreachable("handled elsewhere");
69336940
}
69346941

0 commit comments

Comments
 (0)