Skip to content

Commit 2e5a45d

Browse files
authored
---
yaml --- r: 341418 b: refs/heads/rxwei-patch-1 c: f5f6d89 h: refs/heads/master
1 parent e576d53 commit 2e5a45d

File tree

6 files changed

+48
-19
lines changed

6 files changed

+48
-19
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-08-18-a: b10b1fce14385faa6d44f6b933e95
10151015
refs/heads/rdar-43033749-fix-batch-mode-no-diags-swift-5.0-branch: a14e64eaad30de89f0f5f0b2a782eed7ecdcb255
10161016
refs/heads/revert-19006-error-bridging-integer-type: 8a9065a3696535305ea53fe9b71f91cbe6702019
10171017
refs/heads/revert-19050-revert-19006-error-bridging-integer-type: ecf752d54b05dd0a20f510f0bfa54a3fec3bcaca
1018-
refs/heads/rxwei-patch-1: 7a3c6d58f541b05f235988cd0efaf8b043555b67
1018+
refs/heads/rxwei-patch-1: f5f6d896fde7702e80df8bec741498dcfac8c6ec
10191019
refs/heads/shahmishal-patch-1: e58ec0f7488258d42bef51bc3e6d7b3dc74d7b2a
10201020
refs/heads/typelist-existential: 4046359efd541fb5c72d69a92eefc0a784df8f5e
10211021
refs/tags/swift-4.2-DEVELOPMENT-SNAPSHOT-2018-08-20-a: 4319ba09e4fb8650ee86061075c74a016b6baab9

branches/rxwei-patch-1/include/swift/AST/Identifier.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ class DeclBaseName {
264264

265265
bool isSpecial() const { return getKind() != Kind::Normal; }
266266

267+
bool isSubscript() const { return getKind() == Kind::Subscript; }
268+
267269
/// Return the identifier backing the name. Assumes that the name is not
268270
/// special.
269271
Identifier getIdentifier() const {

branches/rxwei-patch-1/lib/Sema/CSSimplify.cpp

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,6 +3973,19 @@ bool swift::hasDynamicMemberLookupAttribute(Type type) {
39733973
return ::hasDynamicMemberLookupAttribute(type, DynamicMemberLookupCache);
39743974
}
39753975

3976+
static bool isForKeyPathSubscript(ConstraintSystem &cs,
3977+
ConstraintLocator *locator) {
3978+
if (!locator || !locator->getAnchor())
3979+
return false;
3980+
3981+
if (auto *SE = dyn_cast<SubscriptExpr>(locator->getAnchor())) {
3982+
auto *indexExpr = dyn_cast<TupleExpr>(SE->getIndex());
3983+
return indexExpr && indexExpr->getNumElements() == 1 &&
3984+
indexExpr->getElementName(0) == cs.getASTContext().Id_keyPath;
3985+
}
3986+
return false;
3987+
}
3988+
39763989
/// Given a ValueMember, UnresolvedValueMember, or TypeMember constraint,
39773990
/// perform a lookup into the specified base type to find a candidate list.
39783991
/// The list returned includes the viable candidates as well as the unviable
@@ -4004,14 +4017,7 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
40044017
MemberLookupResult result;
40054018
result.OverallResult = MemberLookupResult::HasResults;
40064019

4007-
// If we're looking for a subscript, consider key path operations.
4008-
//
4009-
// TODO: This logic needs to be refactored to make sure that implicit
4010-
// keypath result is only introduced when it makes sense e.g. if there
4011-
// is a single argument with `keypath:` label or `\.` syntax is used.
4012-
if (memberName.isSimpleName() &&
4013-
memberName.getBaseName().getKind() == DeclBaseName::Kind::Subscript &&
4014-
!(memberLocator && memberLocator->isForKeyPathDynamicMemberLookup())) {
4020+
if (isForKeyPathSubscript(*this, memberLocator)) {
40154021
if (baseTy->isAnyObject()) {
40164022
result.addUnviable(
40174023
OverloadChoice(baseTy, OverloadChoiceKind::KeyPathApplication),
@@ -4756,17 +4762,21 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
47564762
performMemberLookup(kind, member, baseTy, functionRefKind, locator,
47574763
/*includeInaccessibleMembers*/ shouldAttemptFixes());
47584764

4759-
switch (result.OverallResult) {
4760-
case MemberLookupResult::Unsolved:
4765+
auto formUnsolved = [&] {
47614766
// If requested, generate a constraint.
47624767
if (flags.contains(TMF_GenerateConstraints)) {
4763-
addUnsolvedConstraint(
4764-
Constraint::createMemberOrOuterDisjunction(*this, kind, baseTy, memberTy, member, useDC,
4765-
functionRefKind, outerAlternatives, locator));
4768+
addUnsolvedConstraint(Constraint::createMemberOrOuterDisjunction(
4769+
*this, kind, baseTy, memberTy, member, useDC, functionRefKind,
4770+
outerAlternatives, locator));
47664771
return SolutionKind::Solved;
47674772
}
47684773

47694774
return SolutionKind::Unsolved;
4775+
};
4776+
4777+
switch (result.OverallResult) {
4778+
case MemberLookupResult::Unsolved:
4779+
return formUnsolved();
47704780

47714781
case MemberLookupResult::ErrorAlreadyDiagnosed:
47724782
return SolutionKind::Error;
@@ -4779,6 +4789,18 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
47794789
SmallVector<Constraint *, 4> candidates;
47804790
// If we found viable candidates, then we're done!
47814791
if (!result.ViableCandidates.empty()) {
4792+
// If only possible choice to refer to member is via keypath
4793+
// dynamic member dispatch, let's delay solving this constraint
4794+
// until constraint generation phase is complete, because
4795+
// subscript dispatch relies on presence of function application.
4796+
if (result.ViableCandidates.size() == 1) {
4797+
auto &choice = result.ViableCandidates.front();
4798+
if (!solverState && choice.isKeyPathDynamicMemberLookup() &&
4799+
member.getBaseName().isSubscript()) {
4800+
return formUnsolved();
4801+
}
4802+
}
4803+
47824804
generateConstraints(
47834805
candidates, memberTy, result.ViableCandidates, useDC, locator,
47844806
result.getFavoredIndex(), /*requiresFix=*/false,
@@ -5855,7 +5877,11 @@ Type ConstraintSystem::simplifyAppliedOverloads(
58555877
}
58565878

58575879
// FIXME: Could also rewrite fnType to include this result type.
5858-
addConstraint(ConstraintKind::Bind, argFnType->getResult(),
5880+
// Introduction of `Bind` constraint here could result in the disconnect
5881+
// in the constraint system with unintended consequences because e.g.
5882+
// in case of key path application it could disconnect one of the
5883+
// components like subscript from the rest of the context.
5884+
addConstraint(ConstraintKind::Equal, argFnType->getResult(),
58595885
commonResultType, locator);
58605886
}
58615887

branches/rxwei-patch-1/lib/Sema/OverloadChoice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ class OverloadChoice {
256256
/// unwrapped.
257257
bool isImplicitlyUnwrappedValueOrReturnValue() const;
258258

259+
bool isKeyPathDynamicMemberLookup() const {
260+
return getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup;
261+
}
262+
259263
/// Get the name of the overload choice.
260264
DeclName getName() const;
261265

branches/rxwei-patch-1/test/Constraints/overload_filtering.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ struct X {
2626
}
2727

2828
func testSubscript(x: X, i: Int) {
29-
// CHECK: disabled disjunction term {{.*}} bound to key path application
30-
// CHECK-NEXT: disabled disjunction term {{.*}}X.subscript(_:)
29+
// CHECK: disabled disjunction term {{.*}}X.subscript(_:)
3130
// CHECK-NEXT: disabled disjunction term {{.*}}X.subscript(_:_:_:)
3231
// CHECK-NEXT: introducing single enabled disjunction term {{.*}} bound to decl overload_filtering.(file).X.subscript(_:_:)
3332
_ = x[i, i]

branches/rxwei-patch-1/test/expr/unary/keypath/keypath.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,6 @@ func testKeyPath(sub: Sub, optSub: OptSub,
128128
let _: ReferenceWritableKeyPath<A, Prop> = \.property
129129
//expected-error@-1 {{cannot convert value of type 'WritableKeyPath<A, Prop>' to specified type 'ReferenceWritableKeyPath<A, Prop>'}}
130130

131-
// FIXME: shouldn't be ambiguous
132-
// expected-error@+1{{ambiguous}}
133131
let _: PartialKeyPath<A> = \.[sub]
134132
let _: KeyPath<A, A> = \.[sub]
135133
let _: WritableKeyPath<A, A> = \.[sub]

0 commit comments

Comments
 (0)