Merge pull request #85591 from kathygray-pl/kathy/diagnosticProperty

[Diagnostics] Increase possibility for missed property diagnostic
This commit is contained in:
Kathy Gray
2025-12-12 16:09:12 +00:00
committed by GitHub
14 changed files with 126 additions and 44 deletions

View File

@@ -174,7 +174,8 @@ bool ConstraintSystem::worseThanBestSolution() const {
if (isDebugMode()) {
llvm::errs().indent(solverState->getCurrentIndent())
<< "(solution is worse than the best solution)\n";
<< "(solution " << CurrentScore << " is worse than the best solution "
<< solverState->BestScore <<")\n";
}
return true;

View File

@@ -9257,6 +9257,9 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
req->is<LocatorPathElt::TypeParameterRequirement>()) {
auto *memberLoc = getConstraintLocator(anchor, path.front());
if (hasFixFor(memberLoc))
return SolutionKind::Solved;
auto signature = path[path.size() - 2]
.castTo<LocatorPathElt::OpenedGeneric>()
.getSignature();
@@ -10677,7 +10680,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
candidate,
MemberLookupResult::UR_InvalidStaticMemberOnProtocolMetatype);
}
return;
} else {
if (!hasStaticMembers) {
@@ -11625,8 +11627,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
alreadyDiagnosed, locator);
auto instanceTy = baseObjTy->getMetatypeInstanceType();
auto impact = 4;
auto impact = 2;
// Impact is higher if the base type is any function type
// because function types can't have any members other than self
if (instanceTy->is<AnyFunctionType>()) {
@@ -11654,10 +11655,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
}
}
// Increasing the impact for missing member in any argument position so
// it doesn't affect situations where there are another fixes involved.
// Increasing the impact for missing member in any argument position
// which may be less likely than other potential mistakes
if (getArgumentLocator(anchorExpr))
impact += 5;
impact += 1;
}
if (recordFix(fix, impact))

View File

@@ -22,7 +22,7 @@ var a: String? = nil
// CHECK: overload set choice binding $T0 := {{.*}}
// CHECK-NEXT: (considering: ({{.*}}) -> {{.*}} applicable fn {{.*}}
// CHECK: increasing 'sync-in-asynchronous' score by 1
// CHECK: solution is worse than the best solution
// CHECK: solution {{.*}} is worse than the best solution {{.*}}
filter_async {
Obj()

View File

@@ -182,13 +182,13 @@ enum CompassPoint {
}
func isNorth(c : CompassPoint) -> Bool {
// expected-error@+1{{member 'North' expects argument of type 'Int'}}
// FIXME: After improving property lookup fix, this message is not selected. Separate debug to reinstate {{member 'North' expects argument of type 'Int'}}
return c == .North // expected-error {{binary operator '==' cannot be applied to two 'CompassPoint' operands}}
// expected-note@-1 {{binary operator '==' cannot be synthesized for enums with associated values}}
}
func isNorth2(c : CompassPoint) -> Bool {
// expected-error@+1{{member 'North' expects argument of type 'Int'}}
// FIXME: {{member 'North' expects argument of type 'Int'}}
return .North == c // expected-error {{binary operator '==' cannot be applied to two 'CompassPoint' operands}}
// expected-note@-1 {{binary operator '==' cannot be synthesized for enums with associated values}}
}

View File

@@ -177,7 +177,7 @@ test_combo(.genericFn(42)) // expected-error {{global function 'test_combo' requ
extension P { // expected-note 13 {{missing same-type requirement on 'Self'}} {{12-12= where Self == <#Type#>}}
static func generic<T>(_: T) -> T { fatalError() }
static func genericWithReqs<T: Collection, Q>(_: T) -> Q where T.Element == Q { // expected-note 3 {{required by static method 'genericWithReqs' where 'T' = '()'}}
static func genericWithReqs<T: Collection>(_: T) -> Q where T.Element == Q { // expected-note {{required by static method 'genericWithReqs' where 'T' = '()'}}
fatalError()
}
}
@@ -213,10 +213,12 @@ _ = P.generic(S()).other // expected-error {{static member 'generic' cannot be u
_ = P.generic(G<Int>()) // expected-error {{static member 'generic' cannot be used on protocol metatype '(any P).Type'}}
_ = P.genericWithReqs([S()]) // expected-error {{static member 'genericWithReqs' cannot be used on protocol metatype '(any P).Type'}}
_ = P.genericWithReqs([42])
// expected-error@-1 {{static member 'genericWithReqs' cannot be used on protocol metatype '(any P).Type'}}
_ = P.genericWithReqs(())
// expected-error@-1 {{type '()' cannot conform to 'Collection'}} expected-note@-1 {{only concrete types such as structs, enums and classes can conform to protocols}}
// expected-error@-1 {{cannot convert value of type 'Int' to expected element type 'any Q'}}
// expected-error@-2 {{static member 'genericWithReqs' cannot be used on protocol metatype '(any P).Type'}}
_ = P.genericWithReqs(())
// expected-error@-1 {{type '()' cannot conform to 'Collection'}}
// expected-error@-2 {{static member 'genericWithReqs' cannot be used on protocol metatype '(any P).Type'}}
// expected-note@-3 {{only concrete types such as structs, enums and classes can conform to protocols}}
_ = P[q: ""]
// expected-error@-1 {{static member 'subscript' cannot be used on protocol metatype '(any P).Type'}}
_ = P[q: ""].other
@@ -227,6 +229,8 @@ test(.doesntExist) // expected-error {{type 'P' has no member 'doesntExist'}}
test(.doesnt.exist()) // expected-error {{type 'P' has no member 'doesnt'}}
test(.invalidProp)
// expected-error@-1 {{contextual member reference to static property 'invalidProp' requires 'Self' constraint in the protocol extension}}
test(.property.doesntExist)
// expected-error@-1 {{value of type 'S' has no member 'doesntExist'}}
test(.invalidProp.other)
// expected-error@-1 {{contextual member reference to static property 'invalidProp' requires 'Self' constraint in the protocol extension}}
// expected-error@-2 {{value of type 'Int' has no member 'other'}}
@@ -243,30 +247,38 @@ test(.generic(42).other)
test(.generic(S())) // expected-error {{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test(.generic(G<Int>())) // expected-error {{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test(.genericWithReqs([S()])) // expected-error {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
test(.genericWithReqs([S()]).doesntExist) // expected-error {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
// expected-error@-1 {{value of type 'any Q' has no member 'doesntExist'}}
test(.genericWithReqs([42]))
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
// expected-error@-2 {{cannot convert value of type 'Int' to expected element type 'any Q'}}
test(.genericWithReqs(()))
// expected-error@-1 {{type '()' cannot conform to 'Collection'}}
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
// expected-error@-3 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
test_combo(.doesntExist) // expected-error {{reference to member 'doesntExist' cannot be resolved without a contextual type}}
test_combo(.doesnt.exist()) // expected-error {{reference to member 'doesnt' cannot be resolved without a contextual type}}
test_combo(.invalidProp)
// expected-error@-1 {{contextual member reference to static property 'invalidProp' requires 'Self' constraint in the protocol extension}}
test_combo(.invalidProp.doesntExist) //FIXME: Requires protocol conformance fix for expected two messages below
// expected-error@-1{{type 'Q' has no member 'invalidProp'}}
// {{contextual member reference to static property 'invalidProp' requires 'Self' constraint in the protocol extension}}
// {{value of type 'Int' has no member 'doesntExist'}}
test_combo(.invalidMethod())
// expected-error@-1 {{contextual member reference to static method 'invalidMethod()' requires 'Self' constraint in the protocol extension}}
// expected-error@-1{{contextual member reference to static method 'invalidMethod()' requires 'Self' constraint in the protocol extension}}
test_combo(.generic(42))
// expected-error@-1 {{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test_combo(.generic(S())) // expected-error {{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test_combo(.generic(G<Int>())) // expected-error {{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test_combo(.genericWithReqs([S()])) // expected-error {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
test_combo(.genericWithReqs([42]))
// expected-error@-1 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
// expected-error@-1{{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test_combo(.generic(S()))
// expected-error@-1{{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test_combo(.generic(G<Int>()))
//expected-error@-1 {{contextual member reference to static method 'generic' requires 'Self' constraint in the protocol extension}}
test_combo(.genericWithReqs([S()]))
// expected-error@-1{{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
test_combo(.genericWithReqs([42])) //FIXME: Requires protocol conformance fix for expected two messages below
// expected-error@-1{{failed to produce diagnostic for expression}}
// {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
// {{cannot convert value of type 'Int' to expected element type 'any Q'}}
test_combo(.genericWithReqs(()))
// expected-error@-1 {{type '()' cannot conform to 'Collection'}}
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
// expected-error@-3 {{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
// expected-error@-1{{contextual member reference to static method 'genericWithReqs' requires 'Self' constraint in the protocol extension}}
protocol TestWithAssoc {
associatedtype U
@@ -381,4 +393,4 @@ test(.instanceProp)
// expected-error@-1 {{instance member 'instanceProp' cannot be used on type 'P'}}
test(.instanceProp2)
// expected-error@-1 {{instance member 'instanceProp2' cannot be used on type 'P'}}
// expected-error@-2 {{property 'instanceProp2' requires the types 'Self' and 'S' be equivalent}}
// expected-error@-2 {{property 'instanceProp2' requires the types 'Self' and 'S' be equivalent}}

View File

@@ -26,6 +26,6 @@ foo {
// CONSTRAINTS: attempting disjunction choice {{.*}}:12:6
// CONSTRAINTS: increasing 'disfavored overload' score
// CONSTRAINTS: solution is worse than the best solution
// CONSTRAINTS: solution {{.*}} is worse than the best solution {{.*}}
// CONSTRAINTS-NOT-NOT: increasing 'hole'

View File

@@ -0,0 +1,8 @@
// RUN: %target-typecheck-verify-swift
func example(x: Int, regions: [Int]) {
let matchingRegion =
regions.first { region in x + region.bogusProperty }
// expected-error@-1 {{value of type 'Int' has no member 'bogusProperty'}}
}

View File

@@ -0,0 +1,20 @@
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5
// REQUIRES: objc_interop
// REQUIRES: OS=macosx
//
import SwiftUI
struct ContentView: View {
var foos: [F]
var body: some View {
ForEach(foos) { foo in
let name = foo.bat //expected-error{{value of type 'F' has no member 'bat'}}
}
}
}
struct F: Identifiable, Hashable {
var id: String { bar }
var bar: String // expected-note {{'bar' declared here}}
}

View File

@@ -14,8 +14,8 @@ extension EnvironmentValues {
var myHorizontalAlignment: AlignmentID? {
get { fatalError() }
set { self[\.MyHorizontalAlignmentEnvironmentKey.self] = newValue }
// expected-error@-1 {{subscript 'subscript(_:)' requires that 'any AlignmentID' be a class type}}
// expected-error@-2 {{cannot infer key path type from context; consider explicitly specifying a root type}}
// expected-error@-1 {{value of type 'EnvironmentValues' has no member 'MyHorizontalAlignmentEnvironmentKey'}}
// expected-error@-2 {{missing argument label 'keyPath:' in subscript}}
}
}

View File

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5
// RUN: %target-typecheck-verify-swift -verify-ignore-unrelated -target %target-cpu-apple-macosx10.15 -swift-version 5
// REQUIRES: objc_interop
// REQUIRES: OS=macosx
@@ -22,17 +22,20 @@ struct ContentView: View {
var body: some View {
ScrollView {
VStack {
VStack {
Picker(selection: $selection) {
ForEach(["a", "b", "c"], id: \.self) {
Text($0) // expected-error {{reasonable time}}
.foregroundStyl(.red) // Typo is here
}
} label: {
Picker(selection: $selection) {
ForEach(["a", "b", "c"], id: \.self) {
Text($0) // expected-error {{ reasonable time}}
.foregroundStyl(.red) // Typo is here
}
.pickerStyle(.segmented)
} label: {
}
.pickerStyle(.segmented)
}
.padding(.horizontal)
.padding(.vertical)
}
.padding(.horizontal)
}
.onChange(of: a) { oldValue, newValue in
}

View File

@@ -0,0 +1,38 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unrelated -target %target-cpu-apple-macosx10.15 -swift-version 5
// REQUIRES: objc_interop
// REQUIRES: OS=macosx
// https://forums.swift.org/t/roadmap-for-improving-the-type-checker/82952/9
//
// This test formerly ran out of time. Now we catch the typo error
//
import SwiftUI
struct ContentView: View {
@State var selection = ""
@State var a: Int?
@State var b: Int?
@State var c: Int?
var body: some View {
ScrollView {
Picker(selection: $selection) {
ForEach(["a", "b", "c"], id: \.self) {
Text($0) // Formerly ran out of time
.foregroundStyl(.red) // expected-error {{value of type 'Text' has no member 'foregroundStyl'; did you mean 'foregroundStyle'}}
// expected-error@-1 {{cannot infer contextual base in reference to member 'red'}}
}
} label: {
}
.pickerStyle(.segmented)
}
.onChange(of: a) { oldValue, newValue in
}
.onChange(of: b) { oldValue, newValue in
}
.onChange(of: c) { oldValue, newValue in
}
}
}

View File

@@ -1,3 +0,0 @@
// {"kind":"typecheck","signature":"swift::constraints::SubscriptMisuseFailure::diagnoseAsError()","signatureAssert":"Assertion failed: (isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"), function cast"}
// RUN: not --crash %target-swift-frontend -typecheck %s
"" [.subscript

View File

@@ -0,0 +1,2 @@
// RUN: not %target-swift-frontend -typecheck %s
"" [.subscript

View File

@@ -1,5 +1,5 @@
// {"kind":"typecheck","original":"5b785ef0","signature":"swift::ASTWalker::PreWalkResult<swift::Expr*> (anonymous namespace)::Verifier::dispatchVisitPreExpr<swift::OpenExistentialExpr*>(swift::OpenExistentialExpr*)","signatureAssert":"Assertion failed: (isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"), function cast"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
extension Dictionary {
a(b: Sequence)
{