Skip to content

Commit 186c4fd

Browse files
author
Greg Titus
committed
Increase impact of arg/param mismatch if param has generic param but arg does not.
1 parent 0350023 commit 186c4fd

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15276,6 +15276,20 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1527615276
}
1527715277
}
1527815278

15279+
// Mismatches where param involves a generic parameter means a poor
15280+
// generic parameter match, overload is much less viable.
15281+
if (!type1->hasTypeVariable() && type2->hasTypeVariable()) {
15282+
SmallPtrSet<TypeVariableType *, 4> typeVariables;
15283+
type2->getTypeVariables(typeVariables);
15284+
if (llvm::any_of(typeVariables, [&](const TypeVariableType *tv) {
15285+
auto tvLocator = tv->getImpl().getLocator();
15286+
return tvLocator
15287+
->isLastElement<LocatorPathElt::GenericParameter>() &&
15288+
tvLocator->getAnchor() == locator.getAnchor();
15289+
}))
15290+
impact += 6;
15291+
}
15292+
1527915293
// De-prioritize `Builtin.RawPointer` and `OpaquePointer` parameters
1528015294
// because they usually clash with generic parameter mismatches e.g.
1528115295
//

test/Constraints/diagnostics.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ func rdar17170728() {
11241124
// expected-error@-1 4 {{optional type 'Int?' cannot be used as a boolean; test for '!= nil' instead}}
11251125
}
11261126

1127-
let _ = [i, j, k].reduce(0 as Int?) { // expected-error {{missing argument label 'into:' in call}}
1127+
let _ = [i, j, k].reduce(0 as Int?) { // expected-error {{missing argument label 'into:' in call}}}
11281128
// expected-error@-1 {{cannot convert value of type 'Int?' to expected argument type '(inout @escaping (Bool, Bool) -> Bool?, Int?) throws -> ()'}}
11291129
$0 && $1 ? $0 + $1 : ($0 ? $0 : ($1 ? $1 : nil))
11301130
// expected-error@-1 {{binary operator '+' cannot be applied to two 'Bool' operands}}
@@ -1552,19 +1552,19 @@ func testNilCoalescingOperatorRemoveFix() {
15521552
let _ = "" /* This is a comment */ ?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{13-43=}}
15531553

15541554
let _ = "" // This is a comment
1555-
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1554:13-1555:10=}}
1555+
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{-1:13-+0:10=}}
15561556

15571557
let _ = "" // This is a comment
15581558
/*
15591559
* The blank line below is part of the test case, do not delete it
15601560
*/
1561-
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1557:13-1561:10=}}
1561+
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{-4:13-+0:10=}}
15621562

1563-
if ("" ?? // This is a comment // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{9-1564:9=}}
1563+
if ("" ?? // This is a comment // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{9-+1:9=}}
15641564
"").isEmpty {}
15651565

15661566
if ("" // This is a comment
1567-
?? "").isEmpty {} // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1566:9-1567:12=}}
1567+
?? "").isEmpty {} // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{-1:9-+0:12=}}
15681568
}
15691569

15701570
// https://github.com/apple/swift/issues/74617

test/Constraints/issue-74700.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol Idable<ID> {
4+
associatedtype ID
5+
var id: ID { get }
6+
}
7+
func test74700() {
8+
@dynamicMemberLookup struct Binding<C> {
9+
subscript(dynamicMember member: String) -> String { "" }
10+
}
11+
struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID: Hashable {
12+
init(_ data: Data, content: (Data.Element) -> Content) where ID == Data.Element.ID, Data.Element : Idable {}
13+
// expected-note@-1 {{where 'Data.Element' = 'User'}}
14+
init<C>(_ data: Binding<C>, content: (Binding<C.Element>) -> Content) where Data == Array<C>, ID == C.Element.ID, C : MutableCollection, C : RandomAccessCollection, C.Element : Idable, C.Index : Hashable {}
15+
}
16+
17+
struct User {
18+
let name: String // expected-note {{'name' declared here}}
19+
}
20+
21+
struct ContentView {
22+
let users: [User] = []
23+
func body() -> Void {
24+
ForEach(users) { user in // expected-error {{initializer 'init(_:content:)' requires that 'User' conform to 'Idable'}}
25+
return user.nam // expected-error {{value of type 'User' has no member 'nam'; did you mean 'name'?}}
26+
}
27+
}
28+
}
29+
}

test/expr/expressions.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,9 @@ func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange<Int>?) {
785785
// ?? should have higher precedence than logical operators like || and comparisons.
786786
if cond || (a ?? 42 > 0) {} // Ok.
787787
if (cond || a) ?? 42 > 0 {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
788-
// expected-error@-1 {{binary operator '>' cannot be applied to operands of type 'Bool' and 'Int'}} expected-note@-1 {{overloads for '>' exist with these partially matching parameter list}}
788+
// expected-error@-1 {{binary operator '>' cannot be applied to operands of type 'Bool' and 'Int'}}
789789
// expected-error@-2 {{binary operator '??' cannot be applied to operands of type 'Bool' and 'Int'}}
790+
// expected-note@-3 {{overloads for '>' exist with these partially matching parameter lists: (Int, Int)}}
790791
if (cond || a) ?? (42 > 0) {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
791792

792793
if cond || a ?? 42 > 0 {} // Parses as the first one, not the others.

0 commit comments

Comments
 (0)