Skip to content

Commit 2c82882

Browse files
committed
[ConstraintSystem] Move unviable keypath dynamic member check into performMemberLookup
1 parent 9eed013 commit 2c82882

File tree

4 files changed

+34
-23
lines changed

4 files changed

+34
-23
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,7 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
811811
if (sameProblem) {
812812
switch (firstProblem) {
813813
case MemberLookupResult::UR_LabelMismatch:
814+
case MemberLookupResult::UR_WritableKeyPathOnReadOnlyMember:
814815
break;
815816
case MemberLookupResult::UR_UnavailableInExistential:
816817
diagnose(loc, diag::could_not_use_member_on_existential,

lib/Sema/CSSimplify.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3826,6 +3826,28 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
38263826
}
38273827
}
38283828

3829+
// Check whether this is overload choice found via keypath
3830+
// based dynamic member lookup. Since it's unknown upfront
3831+
// what kind of declaration lookup is going to find, let's
3832+
// double check here that given keypath is appropriate for it.
3833+
if (memberLocator) {
3834+
auto path = memberLocator->getPath();
3835+
if (!path.empty() && path.back().isKeyPathDynamicMember()) {
3836+
auto *keyPath = path.back().getKeyPath();
3837+
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
3838+
// If this is an attempt to access read-only member via
3839+
// writable key path, let's fail this choice early.
3840+
if (isReadOnlyKeyPathComponent(storage) &&
3841+
keyPath == getASTContext().getWritableKeyPathDecl()) {
3842+
result.addUnviable(
3843+
candidate,
3844+
MemberLookupResult::UR_WritableKeyPathOnReadOnlyMember);
3845+
return;
3846+
}
3847+
}
3848+
}
3849+
}
3850+
38293851
// Otherwise, we're good, add the candidate to the list.
38303852
result.addViable(candidate);
38313853
};
@@ -4193,6 +4215,11 @@ fixMemberRef(ConstraintSystem &cs, Type baseTy,
41934215
case MemberLookupResult::UR_MutatingGetterOnRValue:
41944216
case MemberLookupResult::UR_LabelMismatch:
41954217
case MemberLookupResult::UR_UnavailableInExistential:
4218+
// TODO(diagnostics): Add a new fix that is suggests to
4219+
// add `subscript(dynamicMember: KeyPath<T, U>)`
4220+
// overload here, that would help if such subscript has
4221+
// not been provided.
4222+
case MemberLookupResult::UR_WritableKeyPathOnReadOnlyMember:
41964223
break;
41974224
}
41984225
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,29 +1988,6 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
19881988
}
19891989
}
19901990

1991-
// Check whether this is overload choice found via keypath
1992-
// based dynamic member lookup. Since it's unknown upfront
1993-
// what kind of declaration lookup is going to find, let's
1994-
// double check here that given keypath is appropriate for it.
1995-
auto path = locator->getPath();
1996-
if (!path.empty() && path.back().isKeyPathDynamicMember()) {
1997-
auto *keyPath = path.back().getKeyPath();
1998-
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
1999-
// If this is an attempt to access read-only member via
2000-
// writable key path, let's fail this choice early.
2001-
//
2002-
// TODO(diagnostics): Add a new fix that is suggests to
2003-
// add `subscript(dynamicMember: WritableKeyPath<T, U>)`
2004-
// overload here, instead of failing.
2005-
if (isReadOnlyKeyPathComponent(storage) &&
2006-
keyPath == getASTContext().getWritableKeyPathDecl()) {
2007-
failedConstraint = Constraint::create(*this, ConstraintKind::Bind,
2008-
boundType, refType, locator);
2009-
return;
2010-
}
2011-
}
2012-
}
2013-
20141991
// Check whether applying this overload would result in invalid
20151992
// partial function application e.g. partial application of
20161993
// mutating method or initializer.

lib/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,12 @@ struct MemberLookupResult {
872872

873873
/// The member is inaccessible (e.g. a private member in another file).
874874
UR_Inaccessible,
875+
876+
/// This is a `WritableKeyPath` being used to look up read-only member,
877+
/// used in situations involving dynamic member lookup via keypath,
878+
/// because it's not known upfront what access capability would the
879+
/// member have.
880+
UR_WritableKeyPathOnReadOnlyMember,
875881
};
876882

877883
/// This is a list of considered (but rejected) candidates, along with a

0 commit comments

Comments
 (0)