Skip to content

Commit 7b0e46b

Browse files
committed
[ConstraintSystem] Adjust impact of a missing member fix
Currently its impact is set to be less than that of a conversion fix, which is incorrect. Let's adjust that and increase it even farther for cases where base is `Any` or `AnyObject`. We couldn't do it for `Any` before because it was used to represent type holes, but it's no longer the case. Resolves: rdar://problem/68155466
1 parent 2e03264 commit 7b0e46b

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7168,18 +7168,19 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
71687168
MemberLookupResult::ErrorAlreadyDiagnosed);
71697169
auto *fix = DefineMemberBasedOnUse::create(*this, baseTy, member,
71707170
alreadyDiagnosed, locator);
7171-
// Impact is higher if the base is expected to be inferred from context,
7172-
// because a failure to find a member ultimately means that base type is
7173-
// not a match in this case.
7174-
auto impact =
7175-
locator->findLast<LocatorPathElt::UnresolvedMember>() ? 2 : 1;
71767171

7172+
auto instanceTy = baseObjTy->getMetatypeInstanceType();
7173+
7174+
auto impact = 2;
71777175
// Impact is higher if the the base type is any function type
71787176
// because function types can't have any members other than self
7179-
if (baseObjTy->is<AnyFunctionType>()) {
7180-
impact += 10;
7177+
if (instanceTy->is<AnyFunctionType>()) {
7178+
impact += 10;
71817179
}
71827180

7181+
if (instanceTy->isAny() || instanceTy->isAnyObject())
7182+
impact += 5;
7183+
71837184
if (recordFix(fix, impact))
71847185
return SolutionKind::Error;
71857186

test/Constraints/rdar68155466.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
6+
@objc class A : NSObject {
7+
func uniqueID() -> Int {
8+
42
9+
}
10+
}
11+
12+
struct Loop< // expected-note {{required by generic struct 'Loop' where 'ID' = '() -> Int'}}
13+
Data : RandomAccessCollection,
14+
ID : Hashable,
15+
Content
16+
> {
17+
public init(
18+
_ data: Data,
19+
id: KeyPath<Data.Element, ID>,
20+
content: @escaping (Data.Element) -> Content) {}
21+
}
22+
23+
func data() -> [A] {
24+
return []
25+
}
26+
27+
_ = Loop(data(), id: \.uniqueID) { $0 } // expected-error {{key path cannot refer to instance method 'uniqueID()'}}
28+
// expected-error@-1 {{type '() -> Int' cannot conform to 'Hashable'; only concrete types such as structs, enums and classes can conform to protocols}}

0 commit comments

Comments
 (0)