mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Diagnostics : Increase possibility for missed property diagnostic
Impact for an unknown property access was frequently higher than other options on ambiguous selections, by 3 to 5 points, causing fix selections that were farther away and frequently noted to be in accurate. This commit lowers the impact to be in a similar range to other fixes and this causes property accesses to be selected more proprotionaly. In the existing test suite, this changed the diagnostic only in the case of protocol composition, which was also discovered to be a flawed binding lookup. Tests added for the property lookup, tests updated for protocol composition (Including correcting a likely error in a test specification)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -9253,6 +9253,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();
|
||||
@@ -10673,7 +10676,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
|
||||
candidate,
|
||||
MemberLookupResult::UR_InvalidStaticMemberOnProtocolMetatype);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
if (!hasStaticMembers) {
|
||||
@@ -11621,8 +11623,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>()) {
|
||||
@@ -11650,10 +11651,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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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}}
|
||||
}
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -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'
|
||||
|
||||
8
test/Sema/property_access_lookup.swift
Normal file
8
test/Sema/property_access_lookup.swift
Normal 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'}}
|
||||
}
|
||||
|
||||
@@ -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}}
|
||||
}
|
||||
@@ -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}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
38
validation-test/Sema/SwiftUI/was_too_complex.swift
Normal file
38
validation-test/Sema/SwiftUI/was_too_complex.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,2 @@
|
||||
// RUN: not %target-swift-frontend -typecheck %s
|
||||
"" [.subscript
|
||||
@@ -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)
|
||||
{
|
||||
Reference in New Issue
Block a user