Skip to content

Commit fb49888

Browse files
Merge pull request swiftlang#33068 from LucianoPAlmeida/SR-13340-args-mismatches
[SR-13240][Sema] Removing repairFailures logic that did not allow more than one argument fix
2 parents 115244f + 8e8f081 commit fb49888

File tree

7 files changed

+47
-33
lines changed

7 files changed

+47
-33
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3653,22 +3653,6 @@ bool ConstraintSystem::repairFailures(
36533653
if (rhs->isAny())
36543654
break;
36553655

3656-
// If there are any other argument mismatches already detected
3657-
// for this call, we can consider overload unrelated.
3658-
if (llvm::any_of(getFixes(), [&](const ConstraintFix *fix) {
3659-
auto *locator = fix->getLocator();
3660-
// Since arguments to @dynamicCallable form either an array
3661-
// or a dictionary and all have to match the same element type,
3662-
// let's allow multiple invalid arguments.
3663-
if (locator->findFirst<LocatorPathElt::DynamicCallable>())
3664-
return false;
3665-
3666-
return locator->findLast<LocatorPathElt::ApplyArgToParam>()
3667-
? locator->getAnchor() == anchor
3668-
: false;
3669-
}))
3670-
break;
3671-
36723656
// If there are any restrictions here we need to wait and let
36733657
// `simplifyRestrictedConstraintImpl` handle them.
36743658
if (llvm::any_of(conversionsOrFixes,
@@ -9840,8 +9824,19 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
98409824
}
98419825

98429826
case FixKind::AllowArgumentTypeMismatch: {
9843-
increaseScore(SK_Fix);
9844-
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
9827+
auto impact = 2;
9828+
// If there are any other argument mismatches already detected for this
9829+
// call, we increase the score even higher so more argument fixes means
9830+
// less viable is the overload.
9831+
if (llvm::any_of(getFixes(), [&](const ConstraintFix *fix) {
9832+
auto *fixLocator = fix->getLocator();
9833+
return fixLocator->findLast<LocatorPathElt::ApplyArgToParam>()
9834+
? fixLocator->getAnchor() == locator.getAnchor()
9835+
: false;
9836+
}))
9837+
impact += 3;
9838+
9839+
return recordFix(fix, impact) ? SolutionKind::Error : SolutionKind::Solved;
98459840
}
98469841

98479842
case FixKind::ContextualMismatch: {

test/Constraints/argument_matching.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,3 +1623,18 @@ func sr13135() {
16231623

16241624
foo(Foo().bar, [baz])
16251625
}
1626+
1627+
// SR-13240
1628+
func twoargs(_ x: String, _ y: String) {}
1629+
1630+
func test() {
1631+
let x = 1
1632+
twoargs(x, x) // expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'String'}}
1633+
}
1634+
1635+
infix operator ---
1636+
1637+
func --- (_ lhs: String, _ rhs: String) -> Bool { true }
1638+
1639+
let x = 1
1640+
x --- x // expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'String'}}

test/Constraints/diagnostics.swift

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

1104+
// expected-error@+4 {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
1105+
// expected-error@+3 {{missing argument label 'into:' in call}}
1106+
// expected-note@+2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
1107+
// expected-note@+1 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
11041108
let _ = [i, j, k].reduce(0 as Int?) {
1105-
// expected-error@-1 3 {{cannot convert value of type 'Int?' to expected element type 'Int'}}
1109+
// expected-error@-1 3 {{cannot convert value of type 'Int?' to expected element type 'Bool'}}
11061110
$0 && $1 ? $0 + $1 : ($0 ? $0 : ($1 ? $1 : nil))
11071111
// expected-error@-1 2 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
1108-
// expected-error@-2 {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
1109-
// expected-error@-3 2 {{optional type 'Int?' cannot be used as a boolean; test for '!= nil' instead}}
1110-
// expected-note@-4:16 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
1111-
// expected-note@-5:16 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
1112+
// expected-error@-2 {{cannot convert value of type 'Bool' to expected argument type 'Int'}}
1113+
// expected-error@-3 {{result values in '? :' expression have mismatching types 'Bool' and 'Int?'}}
11121114
}
11131115
}
11141116

test/Constraints/fixes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,5 +358,5 @@ func testKeyPathSubscriptArgFixes(_ fn: @escaping () -> Int) {
358358

359359
func sr12426(a: Any, _ str: String?) {
360360
a == str // expected-error {{binary operator '==' cannot be applied to operands of type 'Any' and 'String?'}}
361-
// expected-note@-1 {{overloads for '==' exist with these partially matching parameter lists: (String, String)}}
361+
// expected-note@-1 {{overloads for '==' exist with these partially matching parameter lists: (CodingUserInfoKey, CodingUserInfoKey), (String, String)}}
362362
}

test/Constraints/optional.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,8 @@ func test_force_unwrap_not_being_too_eager() {
423423

424424
// rdar://problem/57097401
425425
func invalidOptionalChaining(a: Any) {
426-
a == "="? // expected-error {{cannot use optional chaining on non-optional value of type 'String'}}
427-
// expected-error@-1 {{cannot convert value of type 'Any' to expected argument type 'Any.Type?'}}
426+
a == "="? // expected-error {{binary operator '==' cannot be applied to operands of type 'Any' and 'String?'}}
427+
// expected-note@-1 {{overloads for '==' exist with these partially matching parameter lists: (CodingUserInfoKey, CodingUserInfoKey), (FloatingPointSign, FloatingPointSign), (String, String), (Unicode.CanonicalCombiningClass, Unicode.CanonicalCombiningClass)}}
428428
}
429429

430430
// SR-12309 - Force unwrapping 'nil' compiles without warning

test/Parse/operators.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,9 @@ postfix func ^ (x: Man) -> () -> God {
8888
return { return God() }
8989
}
9090

91-
// TODO(diagnostics): This is ambiguous operator use because if solver attempted postfix version of the operator `^`
92-
// it could have found a solution, with infix one nothing matches - neither argument nor contextual type. It should
93-
// be possible to find a way to diagnose operator use here instead of type ambiguity...
94-
var _ : God = Man()^() // expected-error{{type of expression is ambiguous without more context}}
91+
var _ : God = Man()^() // expected-error{{cannot convert value of type 'Man' to expected argument type 'TheDevil'}}
92+
// expected-error@-1 {{cannot convert value of type '()' to expected argument type 'God'}}
93+
// expected-error@-2 {{cannot convert value of type 'Man' to specified type 'God'}}
9594

9695
func &(x : Man, y : Man) -> Man { return x } // forgive amp_prefix token
9796

test/stdlib/UnicodeScalarDiagnostics.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ func isString(_ s: inout String) {}
88
func test_UnicodeScalarDoesNotImplementArithmetic(_ us: UnicodeScalar, i: Int) {
99
var a1 = "a" + "b" // OK
1010
isString(&a1)
11-
let a2 = "a" - "b" // expected-error {{binary operator '-' cannot be applied to two 'String' operands}} expected-note {{}}
12-
let a3 = "a" * "b" // expected-error {{binary operator '*' cannot be applied to two 'String' operands}} expected-note {{}}
13-
let a4 = "a" / "b" // expected-error {{binary operator '/' cannot be applied to two 'String' operands}} expected-note {{}}
11+
let a2 = "a" - "b" // expected-error {{binary operator '-' cannot be applied to two 'String' operands}}
12+
// expected-note@-1 {{overloads for '-' exist with these partially matching parameter lists: (Double, Double), (Float, Float), (Float16, Float16), (Float80, Float80), (Int, Int), (Int16, Int16), (Int32, Int32), (Int64, Int64), (Int8, Int8), (UInt, UInt), (UInt16, UInt16), (UInt32, UInt32), (UInt64, UInt64), (UInt8, UInt8)}}
13+
let a3 = "a" * "b" // expected-error {{binary operator '*' cannot be applied to two 'String' operands}}
14+
// expected-note@-1 {{overloads for '*' exist with these partially matching parameter lists: (Double, Double), (Float, Float), (Float16, Float16), (Float80, Float80), (Int, Int), (Int16, Int16), (Int32, Int32), (Int64, Int64), (Int8, Int8), (UInt, UInt), (UInt16, UInt16), (UInt32, UInt32), (UInt64, UInt64), (UInt8, UInt8)}}
15+
let a4 = "a" / "b" // expected-error {{binary operator '/' cannot be applied to two 'String' operands}}
16+
// expected-note@-1 {{overloads for '/' exist with these partially matching parameter lists: (Double, Double), (Float, Float), (Float16, Float16), (Float80, Float80), (Int, Int), (Int16, Int16), (Int32, Int32), (Int64, Int64), (Int8, Int8), (UInt, UInt), (UInt16, UInt16), (UInt32, UInt32), (UInt64, UInt64), (UInt8, UInt8)}}
1417

1518
let b1 = us + us // expected-error {{binary operator '+' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}}
1619
let b2 = us - us // expected-error {{binary operator '-' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}}

0 commit comments

Comments
 (0)