Skip to content

Commit 1bfd3e2

Browse files
author
Greg Titus
committed
Increase impact of arg/param mismatch if param has type var (likely generic) but arg does not.
1 parent a079c5c commit 1bfd3e2

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15278,6 +15278,12 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1527815278
}
1527915279
}
1528015280

15281+
// Mismatches where param has type variable but arg does not means a poor
15282+
// generic argument match, overload is less viable.
15283+
if (!type1->hasTypeVariable() && type2->hasTypeVariable()) {
15284+
impact += 6;
15285+
}
15286+
1528115287
// De-prioritize `Builtin.RawPointer` and `OpaquePointer` parameters
1528215288
// because they usually clash with generic parameter mismatches e.g.
1528315289
//

test/Constraints/bridging.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ func rdar19831698() {
276276
var v71 = true + 1.0 // expected-error{{binary operator '+' cannot be applied to operands of type 'Bool' and 'Double'}}
277277
// expected-note@-1{{overloads for '+'}}
278278
var v72 = true + true // expected-error{{binary operator '+' cannot be applied to two 'Bool' operands}}
279-
var v73 = true + [] // expected-error@:13 {{cannot convert value of type 'Bool' to expected argument type 'Array<Bool>'}}
279+
var v73 = true + [] // expected-error@:13 {{cannot convert value of type 'Bool' to expected argument type 'IndexPath'}}
280280
var v75 = true + "str" // expected-error@:13 {{cannot convert value of type 'Bool' to expected argument type 'String'}}
281281
}
282282

test/Constraints/diagnostics.swift

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

1131-
let _ = [i, j, k].reduce(0 as Int?) { // expected-error {{missing argument label 'into:' in call}}
1132-
// expected-error@-1 {{cannot convert value of type 'Int?' to expected argument type '(inout @escaping (Bool, Bool) -> Bool?, Int?) throws -> ()'}}
1131+
let _ = [i, j, k].reduce(0 as Int?) { // expected-error 3 {{cannot convert value of type 'Int?' to expected element type 'Int'}}
11331132
$0 && $1 ? $0 + $1 : ($0 ? $0 : ($1 ? $1 : nil))
1134-
// expected-error@-1 {{binary operator '+' cannot be applied to two 'Bool' operands}}
1133+
// expected-error@-1 2 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
1134+
// expected-error@-2 2 {{optional type 'Int?' cannot be used as a boolean; test for '!= nil' instead}}
1135+
// expected-error@-3 {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
1136+
// expected-note@-4 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
1137+
// expected-note@-5 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
11351138
}
11361139
}
11371140

@@ -1558,17 +1561,17 @@ func testNilCoalescingOperatorRemoveFix() {
15581561
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=}}
15591562

15601563
let _ = "" // This is a comment
1561-
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1560:13-1561:10=}}
1564+
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1563:13-1564:10=}}
15621565

15631566
let _ = "" // This is a comment
15641567
/*
15651568
* The blank line below is part of the test case, do not delete it
15661569
*/
1567-
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1563:13-1567:10=}}
1570+
?? "" // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1566:13-1570:10=}}
15681571

1569-
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-1570:9=}}
1572+
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-1573:9=}}
15701573
"").isEmpty {}
15711574

15721575
if ("" // This is a comment
1573-
?? "").isEmpty {} // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1572:9-1573:12=}}
1576+
?? "").isEmpty {} // expected-warning {{left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used}} {{1575:9-1576:12=}}
15741577
}

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: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -785,16 +785,17 @@ 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}}
789-
// expected-error@-2 {{binary operator '??' cannot be applied to operands of type 'Bool' and 'Int'}}
788+
// expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'Bool'}}
789+
// expected-error@-2 {{cannot convert value of type 'Bool' to expected argument type 'Int'}}
790790
if (cond || a) ?? (42 > 0) {} // expected-error {{cannot be used as a boolean}} {{15-15=(}} {{16-16= != nil)}}
791791

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

794794

795795
// ?? should have lower precedence than range and arithmetic operators.
796796
let r1 = r ?? (0...42) // ok
797-
let r2 = (r ?? 0)...42 // not ok: expected-error {{binary operator '??' cannot be applied to operands of type 'ClosedRange<Int>?' and 'Int'}}
797+
let r2 = (r ?? 0)...42 // not ok: expected-error {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
798+
// expected-error@-1 {{cannot convert value of type 'ClosedRange<Int>' to expected argument type 'Int'}}
798799
let r3 = r ?? 0...42 // parses as the first one, not the second.
799800

800801

0 commit comments

Comments
 (0)