mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ConstraintSystem] Don't introduce implicit keypath choice for keypath dynamic member lookup
This commit is contained in:
@@ -3537,6 +3537,10 @@ static bool hasDynamicMemberLookupAttribute(Type type,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isKeyPathDynamicMemberLookup(ConstraintLocator *locator) {
|
||||||
|
auto path = locator ? locator->getPath() : None;
|
||||||
|
return !path.empty() && path.back().isKeyPathDynamicMember();
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a ValueMember, UnresolvedValueMember, or TypeMember constraint,
|
/// Given a ValueMember, UnresolvedValueMember, or TypeMember constraint,
|
||||||
/// perform a lookup into the specified base type to find a candidate list.
|
/// perform a lookup into the specified base type to find a candidate list.
|
||||||
@@ -3570,8 +3574,13 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
|
|||||||
result.OverallResult = MemberLookupResult::HasResults;
|
result.OverallResult = MemberLookupResult::HasResults;
|
||||||
|
|
||||||
// If we're looking for a subscript, consider key path operations.
|
// If we're looking for a subscript, consider key path operations.
|
||||||
|
//
|
||||||
|
// TODO: This logic needs to be refactored to make sure that implicit
|
||||||
|
// keypath result is only introduced when it makes sense e.g. if there
|
||||||
|
// is a single argument with `keypath:` label or `\.` syntax is used.
|
||||||
if (memberName.isSimpleName() &&
|
if (memberName.isSimpleName() &&
|
||||||
memberName.getBaseName().getKind() == DeclBaseName::Kind::Subscript) {
|
memberName.getBaseName().getKind() == DeclBaseName::Kind::Subscript &&
|
||||||
|
!isKeyPathDynamicMemberLookup(memberLocator)) {
|
||||||
result.ViableCandidates.push_back(
|
result.ViableCandidates.push_back(
|
||||||
OverloadChoice(baseTy, OverloadChoiceKind::KeyPathApplication));
|
OverloadChoice(baseTy, OverloadChoiceKind::KeyPathApplication));
|
||||||
}
|
}
|
||||||
@@ -3831,9 +3840,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
|
|||||||
// based dynamic member lookup. Since it's unknown upfront
|
// based dynamic member lookup. Since it's unknown upfront
|
||||||
// what kind of declaration lookup is going to find, let's
|
// what kind of declaration lookup is going to find, let's
|
||||||
// double check here that given keypath is appropriate for it.
|
// double check here that given keypath is appropriate for it.
|
||||||
if (memberLocator) {
|
if (isKeyPathDynamicMemberLookup(memberLocator)) {
|
||||||
auto path = memberLocator->getPath();
|
auto path = memberLocator->getPath();
|
||||||
if (!path.empty() && path.back().isKeyPathDynamicMember()) {
|
|
||||||
auto *keyPath = path.back().getKeyPath();
|
auto *keyPath = path.back().getKeyPath();
|
||||||
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
|
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
|
||||||
// If this is an attempt to access read-only member via
|
// If this is an attempt to access read-only member via
|
||||||
@@ -3847,7 +3855,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, we're good, add the candidate to the list.
|
// Otherwise, we're good, add the candidate to the list.
|
||||||
result.addViable(candidate);
|
result.addViable(candidate);
|
||||||
|
|||||||
@@ -601,6 +601,9 @@ struct WithTrailingClosure {
|
|||||||
|
|
||||||
func keypath_with_trailing_closure_subscript(_ ty: inout SubscriptLens<WithTrailingClosure>) {
|
func keypath_with_trailing_closure_subscript(_ ty: inout SubscriptLens<WithTrailingClosure>) {
|
||||||
_ = ty[0] { 42 } // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
_ = ty[0] { 42 } // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
||||||
|
_ = ty[0] { 42 } = 0 // FIXME(diagnostics): Once keypath related diagnostics are using fixes, "ambiguous" error would disappear
|
||||||
|
// expected-error@-1 {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
||||||
|
// expected-error@-2 {{type of expression is ambiguous without more context}}
|
||||||
_ = ty[] { 42 } // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
_ = ty[] { 42 } // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
||||||
_ = ty[] { 42 } = 0 // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
_ = ty[] { 42 } = 0 // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user