Skip to content

Commit dc4b089

Browse files
committed
[CS] Don't fix an _OptionalNilComparison argument
We should only be attempting such overloads for nil literal args. Resolves SR-12426.
1 parent b517aa1 commit dc4b089

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3301,6 +3301,17 @@ bool ConstraintSystem::repairFailures(
33013301
if (hasFixFor(loc, FixKind::AllowInvalidUseOfTrailingClosure))
33023302
return true;
33033303

3304+
// Don't attempt to fix an argument being passed to a
3305+
// _OptionalNilComparisonType parameter. Such an overload should only take
3306+
// effect when a nil literal is used in valid code, and doesn't offer any
3307+
// useful fixes for invalid code.
3308+
if (auto *nominal = rhs->getAnyNominal()) {
3309+
if (nominal->isStdlibDecl() &&
3310+
nominal->getName() == getASTContext().Id_OptionalNilComparisonType) {
3311+
return false;
3312+
}
3313+
}
3314+
33043315
if (repairByInsertingExplicitCall(lhs, rhs))
33053316
break;
33063317

test/Constraints/fixes.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,10 @@ func testKeyPathSubscriptArgFixes(_ fn: @escaping () -> Int) {
356356
_ = \S.[nil] // expected-error {{'nil' is not compatible with expected argument type 'Int'}}
357357
_ = \S.[fn] // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{13-13=()}}
358358
}
359+
360+
func sr12426(a: Any, _ str: String?) {
361+
a == str // expected-error {{cannot convert value of type 'Any' to expected argument type 'String'}}
362+
// expected-error@-1 {{value of optional type 'String?' must be unwrapped to a value of type 'String'}}
363+
// expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
364+
// expected-note@-3 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
365+
}

test/Constraints/operator.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,11 @@ func rdar46459603() {
217217
var arr = ["key": e]
218218

219219
_ = arr.values == [e]
220-
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type 'Dictionary<String, E>.Values' and '[E]'}}
220+
// expected-error@-1 {{referencing operator function '==' on 'Equatable' requires that 'Dictionary<String, E>.Values' conform to 'Equatable'}}
221+
// expected-error@-2 {{cannot convert value of type '[E]' to expected argument type 'Dictionary<String, E>.Values'}}
221222
_ = [arr.values] == [[e]]
222-
// expected-error@-1 {{value of protocol type 'Any' cannot conform to 'Equatable'; only struct/enum/class types can conform to protocols}}
223-
// expected-note@-2 {{requirement from conditional conformance of '[Any]' to 'Equatable'}}
223+
// expected-error@-1 {{operator function '==' requires that 'Dictionary<String, E>.Values' conform to 'Equatable'}}
224+
// expected-error@-2 {{cannot convert value of type '[E]' to expected element type 'Dictionary<String, E>.Values'}}
224225
}
225226

226227
// SR-10843

test/Misc/misc_diagnostics.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ func test17875634() {
140140

141141
// <rdar://problem/20770032> Pattern matching ranges against tuples crashes the compiler
142142
func test20770032() {
143-
if case let 1...10 = (1, 1) { // expected-warning{{'let' pattern has no effect; sub-pattern didn't bind any variables}} {{11-15=}} expected-error{{expression pattern of type 'ClosedRange<Int>' cannot match values of type '(Int, Int)'}}
143+
if case let 1...10 = (1, 1) { // expected-warning{{'let' pattern has no effect; sub-pattern didn't bind any variables}} {{11-15=}}
144+
// expected-error@-1 {{expression pattern of type 'ClosedRange<Int>' cannot match values of type '(Int, Int)'}}
145+
// expected-error@-2 {{'(Int, Int)' cannot conform to 'Equatable'; only struct/enum/class types can conform to protocols}}
146+
// expected-note@-3 {{required by operator function '~=' where 'T' = '(Int, Int)'}}
144147
}
145148
}
146149

0 commit comments

Comments
 (0)