Skip to content

Commit 073f427

Browse files
committed
Revert "Don't diagnose failures to call symmetrically-typed binary operators"
This reverts commit 35ba809.
1 parent 35ba809 commit 073f427

File tree

12 files changed

+29
-84
lines changed

12 files changed

+29
-84
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ ERROR(cannot_match_expr_pattern_with_value,none,
138138
"expression pattern of type %0 cannot match values of type %1",
139139
(Type, Type))
140140

141-
ERROR(cannot_reference_compare_types,none,
142-
"cannot check reference equality of functions; operands here have types "
143-
"%1 and %2",
144-
(StringRef, Type, Type))
145-
146141
ERROR(cannot_apply_binop_to_args,none,
147142
"binary operator '%0' cannot be applied to operands of type "
148143
"%1 and %2",

lib/Sema/CSDiag.cpp

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,8 +1806,8 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
18061806

18071807
/// Diagnose common failures due to applications of an argument list to an
18081808
/// ApplyExpr or SubscriptExpr.
1809-
bool diagnoseParameterErrors(CalleeCandidateInfo &CCI,
1810-
Expr *fnExpr, Expr *argExpr);
1809+
bool diagnoseParameterErrors(CalleeCandidateInfo &CCI, Expr *fnExpr,
1810+
Expr *argExpr);
18111811

18121812
/// Attempt to diagnose a specific failure from the info we've collected from
18131813
/// the failed constraint system.
@@ -2904,12 +2904,6 @@ typeCheckChildIndependently(Expr *subExpr, Type convertType,
29042904
TCEOptions |= TypeCheckExprFlags::PreferForceUnwrapToOptional;
29052905
}
29062906

2907-
// Ensure that the expression we're about to type-check doesn't have
2908-
// anything that the type-checker doesn't expect to see. This can happen
2909-
// because of repeated type-checking; the removal below, while independently
2910-
// important, isn't itself sufficient because of AST mutation.
2911-
eraseOpenedExistentials(subExpr);
2912-
29132907
bool hadError = CS->TC.typeCheckExpression(subExpr, CS->DC,
29142908
TypeLoc::withoutLoc(convertType),
29152909
convertTypePurpose, TCEOptions,
@@ -3340,28 +3334,6 @@ void ConstraintSystem::diagnoseAssignmentFailure(Expr *dest, Type destTy,
33403334
diag::assignment_lhs_not_lvalue);
33413335
}
33423336

3343-
static bool isSymmetricBinaryOperator(const CalleeCandidateInfo &CCI) {
3344-
// If we don't have at least one known candidate, don't trigger.
3345-
if (CCI.candidates.empty()) return false;
3346-
3347-
for (auto &candidate : CCI.candidates) {
3348-
// Each candidate must be a non-assignment operator function.
3349-
auto decl = dyn_cast_or_null<FuncDecl>(candidate.getDecl());
3350-
if (!decl) return false;
3351-
auto op = dyn_cast_or_null<InfixOperatorDecl>(decl->getOperatorDecl());
3352-
if (!op || op->isAssignment()) return false;
3353-
3354-
// It must have exactly two parameters.
3355-
auto params = decl->getParameterLists().back();
3356-
if (params->size() != 2) return false;
3357-
3358-
// Require the types to be the same.
3359-
if (!params->get(0)->getType()->isEqual(params->get(1)->getType()))
3360-
return false;
3361-
}
3362-
3363-
return true;
3364-
}
33653337

33663338
/// Special magic to handle inout exprs and tuples in argument lists.
33673339
Expr *FailureDiagnosis::
@@ -3392,11 +3364,6 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
33923364
if (decl->isInstanceMember() && candidates[0].level == 0 &&
33933365
!isa<SubscriptDecl>(decl))
33943366
argType = Type();
3395-
3396-
// Similarly, we get better results when we don't push argument types down
3397-
// to symmetric operators.
3398-
if (argType && isSymmetricBinaryOperator(candidates))
3399-
argType = Type();
34003367

34013368

34023369
// FIXME: This should all just be a matter of getting the type of the
@@ -3768,17 +3735,12 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
37683735
// (often because there is only one candidate in the set), then diagnose this
37693736
// as a specific problem of passing something of the wrong type into a
37703737
// parameter.
3771-
//
3772-
// We don't generally want to use this path to diagnose calls to
3773-
// symmetrically-typed binary operators because it's likely that both
3774-
// operands contributed to the type.
37753738
if ((CCI.closeness == CC_OneArgumentMismatch ||
37763739
CCI.closeness == CC_OneArgumentNearMismatch ||
37773740
CCI.closeness == CC_OneGenericArgumentMismatch ||
37783741
CCI.closeness == CC_OneGenericArgumentNearMismatch ||
37793742
CCI.closeness == CC_GenericNonsubstitutableMismatch) &&
3780-
CCI.failedArgument.isValid() &&
3781-
!isSymmetricBinaryOperator(CCI)) {
3743+
CCI.failedArgument.isValid()) {
37823744
// Map the argument number into an argument expression.
37833745
TCCOptions options = TCC_ForceRecheck;
37843746
if (CCI.failedArgument.parameterType->is<InOutType>())
@@ -4199,18 +4161,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
41994161
.highlight(rhsExpr->getSourceRange());
42004162
return true;
42014163
}
4202-
4203-
// Diagnose attempts to compare reference equality of certain types.
4204-
if (overloadName == "===" || overloadName == "!==") {
4205-
// Functions.
4206-
if (lhsType->is<AnyFunctionType>() || rhsType->is<AnyFunctionType>()) {
4207-
diagnose(callExpr->getLoc(), diag::cannot_reference_compare_types,
4208-
overloadName, lhsType, rhsType)
4209-
.highlight(lhsExpr->getSourceRange())
4210-
.highlight(rhsExpr->getSourceRange());
4211-
return true;
4212-
}
4213-
}
42144164

42154165
// If we found an exact match, this must be a problem with a conversion from
42164166
// the result of the call to the expected type. Diagnose this as a

test/1_stdlib/UnicodeScalarDiagnostics.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ func test_UnicodeScalarDoesNotImplementArithmetic(_ us: UnicodeScalar, i: Int) {
2323

2424
let c1 = us + i // expected-error {{binary operator '+' cannot be applied to operands of type 'UnicodeScalar' and 'Int'}} expected-note{{overloads for '+' exist with these partially matching parameter lists:}}
2525
let c2 = us - i // expected-error {{binary operator '-' cannot be applied to operands of type 'UnicodeScalar' and 'Int'}} expected-note{{overloads for '-' exist with these partially matching parameter lists:}}
26-
let c3 = us * i // expected-error {{binary operator '*' cannot be applied to operands of type 'UnicodeScalar' and 'Int'}} expected-note {{expected an argument list of type '(Int, Int)'}}
27-
let c4 = us / i // expected-error {{binary operator '/' cannot be applied to operands of type 'UnicodeScalar' and 'Int'}} expected-note {{expected an argument list of type '(Int, Int)'}}
26+
let c3 = us * i // expected-error {{cannot convert value of type 'UnicodeScalar' to expected argument type 'Int'}}
27+
let c4 = us / i // expected-error {{cannot convert value of type 'UnicodeScalar' to expected argument type 'Int'}}
2828

2929
let d1 = i + us // expected-error {{binary operator '+' cannot be applied to operands of type 'Int' and 'UnicodeScalar'}} expected-note{{overloads for '+' exist with these partially matching parameter lists:}}
30-
let d2 = i - us // expected-error {{binary operator '-' cannot be applied to operands of type 'Int' and 'UnicodeScalar'}} expected-note {{expected an argument list of type '(Int, Int)'}}
31-
let d3 = i * us // expected-error {{binary operator '*' cannot be applied to operands of type 'Int' and 'UnicodeScalar'}} expected-note {{expected an argument list of type '(Int, Int)'}}
32-
let d4 = i / us // expected-error {{binary operator '/' cannot be applied to operands of type 'Int' and 'UnicodeScalar'}} expected-note {{expected an argument list of type '(Int, Int)'}}
30+
let d2 = i - us // expected-error {{cannot convert value of type 'UnicodeScalar' to expected argument type 'Int'}}
31+
let d3 = i * us // expected-error {{cannot convert value of type 'UnicodeScalar' to expected argument type 'Int'}}
32+
let d4 = i / us // expected-error {{cannot convert value of type 'UnicodeScalar' to expected argument type 'Int'}}
3333
}
3434

test/Constraints/bridging.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ let d2: Double = 3.14159
205205
inferDouble2 = d2
206206

207207
// rdar://problem/18269449
208-
var i1: Int = 1.5 * 3.5 // expected-error {{binary operator '*' cannot be applied to two 'Double' operands}} expected-note {{expected an argument list of type '(Int, Int)'}}
208+
var i1: Int = 1.5 * 3.5 // expected-error{{cannot convert value of type 'Double' to expected argument type 'Int'}}
209209

210210
// rdar://problem/18330319
211211
func rdar18330319(_ s: String, d: [String : AnyObject]) {
@@ -266,12 +266,12 @@ func rdar19831919() {
266266
// <rdar://problem/19831698> Incorrect 'as' fixits offered for invalid literal expressions
267267
func rdar19831698() {
268268
var v70 = true + 1 // expected-error{{binary operator '+' cannot be applied to operands of type 'Bool' and 'Int'}} expected-note {{overloads for '+' exist with these partially matching parameter lists: (Int, Int), (UnsafeMutablePointer<Pointee>, Int), (UnsafePointer<Pointee>, Int)}}
269-
var v71 = true + 1.0 // expected-error {{binary operator '+' cannot be applied to operands of type 'Bool' and 'Double'}} expected-note {{expected an argument list of type '(Double, Double)'}}
269+
var v71 = true + 1.0 // expected-error{{cannot convert value of type 'Bool' to expected argument type 'Double'}}
270270
var v72 = true + true // expected-error{{binary operator '+' cannot be applied to two 'Bool' operands}}
271271
// expected-note @-1 {{overloads for '+' exist with these partially matching parameter lists:}}
272272
var v73 = true + [] // expected-error{{binary operator '+' cannot be applied to operands of type 'Bool' and '[_]'}}
273273
// expected-note @-1 {{overloads for '+' exist with these partially matching parameter lists:}}
274-
var v75 = true + "str" // expected-error {{binary operator '+' cannot be applied to operands of type 'Bool' and 'String'}} expected-note {{expected an argument list of type '(String, String)'}}
274+
var v75 = true + "str" // expected-error{{cannot convert value of type 'Bool' to expected argument type 'String'}}
275275
}
276276

277277
// <rdar://problem/19836341> Incorrect fixit for NSString? to String? conversions

test/Constraints/diagnostics.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ func r21684487() {
583583
var closures = Array<MyClosure>()
584584
let testClosure = {(list: [Int]) -> Bool in return true}
585585

586-
let closureIndex = closures.index{$0 === testClosure} // expected-error {{cannot check reference equality of functions; operands here have types '_' and '([Int]) -> Bool'}}
586+
let closureIndex = closures.index{$0 === testClosure} // expected-error {{cannot convert value of type '([Int]) -> Bool' to expected argument type 'AnyObject?'}}
587587
}
588588

589589
// <rdar://problem/18397777> QoI: special case comparisons with nil
@@ -749,8 +749,8 @@ if AssocTest.one(1) == AssocTest.one(1) {} // expected-error{{binary operator '=
749749
func r24251022() {
750750
var a = 1
751751
var b: UInt32 = 2
752-
a += a + // expected-error {{binary operator '+' cannot be applied to operands of type 'Int' and 'UInt32'}} expected-note {{expected an argument list of type '(Int, Int)'}}
753-
b
752+
a += a +
753+
b // expected-error {{cannot convert value of type 'UInt32' to expected argument type 'Int'}}
754754
}
755755

756756
func overloadSetResultType(_ a : Int, b : Int) -> Int {

test/Constraints/patterns.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ default: break
140140

141141
// <rdar://problem/21995744> QoI: Binary operator '~=' cannot be applied to operands of type 'String' and 'String?'
142142
switch ("foo" as String?) {
143-
case "what": break // expected-error{{expression pattern of type 'String' cannot match values of type 'String?'}}
143+
case "what": break // expected-error{{value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?}}
144144
default: break
145145
}
146146

test/Misc/misc_diagnostics.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if let realRoomName = roomName as! NSString { // expected-error {{initializer fo
1313

1414
var pi = 3.14159265358979
1515
var d: CGFloat = 2.0
16-
var dpi:CGFloat = d*pi // expected-error{{binary operator '*' cannot be applied to operands of type 'CGFloat' and 'Double'}} // expected-note{{expected an argument list of type '(CGFloat, CGFloat)'}}
16+
var dpi:CGFloat = d*pi // expected-error{{cannot convert value of type 'Double' to expected argument type 'CGFloat'}}
1717

1818
let ff: CGFloat = floorf(20.0) // expected-error{{cannot convert value of type 'Float' to specified type 'CGFloat'}}
1919

@@ -30,7 +30,7 @@ var b: Int = [1, 2, 3] // expected-error{{contextual type 'Int' cannot be used w
3030
var f1: Float = 2.0
3131
var f2: Float = 3.0
3232

33-
var dd: Double = f1 - f2 // expected-error{{binary operator '-' cannot be applied to two 'Float' operands}} // expected-note{{expected an argument list of type '(Double, Double)'}}
33+
var dd: Double = f1 - f2 // expected-error{{cannot convert value of type 'Float' to expected argument type 'Double'}}
3434

3535
func f() -> Bool {
3636
return 1 + 1 // expected-error{{no '+' candidates produce the expected contextual result type 'Bool'}}
@@ -60,7 +60,7 @@ func retV() { return true } // expected-error {{unexpected non-void return value
6060
func retAI() -> Int {
6161
let a = [""]
6262
let b = [""]
63-
return (a + b) // expected-error{{binary operator '+' cannot be applied to two '[String]' operands}} // expected-note{{expected an argument list of type '(Int, Int)'}}
63+
return (a + b) // expected-error {{cannot convert value of type '[String]' to expected argument type 'Int'}}
6464
}
6565

6666
func bad_return1() {
@@ -81,7 +81,7 @@ class MyBadReturnClass {
8181
}
8282

8383
func ==(lhs:MyBadReturnClass, rhs:MyBadReturnClass) {
84-
return MyBadReturnClass.intProperty == MyBadReturnClass.intProperty // expected-error{{binary operator '==' cannot be applied to two 'Int' operands}} // expected-note{{expected an argument list of type '(MyBadReturnClass, MyBadReturnClass)'}}
84+
return MyBadReturnClass.intProperty == MyBadReturnClass.intProperty // expected-error {{cannot convert value of type 'Int' to expected argument type 'MyBadReturnClass'}}
8585
}
8686

8787

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-swift-frontend -parse -enable-source-import -primary-file %s %S/Inputs/multi-file-with-main/main.swift -module-name=MultiFile -sdk "" -verify
22

33
func testOperator() {
4-
let x: Int = 1 +++ "abc" // expected-error {{binary operator '+++' cannot be applied to operands of type 'Int' and 'String'}} expected-note {{expected an argument list of type '(Int, Int)'}}
4+
let x: Int = 1 +++ "abc" // expected-error {{cannot convert value of type 'String' to expected argument type 'Int'}}
55

66
_ = x
77
}

test/Parse/recovery.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ protocol B23086402 {
616616
617617
// <rdar://problem/23550816> QoI: Poor diagnostic in argument list of "print" (varargs related)
618618
func test23086402(a: A23086402) {
619-
print(a.b.c + "") // expected-error {{binary operator '+' cannot be applied to operands of type '[String]' and 'String'}} expected-note {{expected an argument list of type '(String, String)'}}
619+
print(a.b.c + "") // expected-error {{cannot convert value of type '[String]' to expected argument type 'String'}}
620620
}
621621

622622
// <rdar://problem/23719432> [practicalswift] Compiler crashes on &(Int:_)

test/expr/closure/closures.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ var closure3a : () -> () -> (Int,Int) = {{ (4, 2) }} // multi-level closing.
1414
var closure3b : (Int,Int) -> (Int) -> (Int,Int) = {{ (4, 2) }} // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{52-52=_,_ in }}
1515
var closure4 : (Int,Int) -> Int = { $0 + $1 }
1616
var closure5 : (Double) -> Int = {
17-
$0 + 1.0 // expected-error {{binary operator '+' cannot be applied to two 'Double' operands}} expected-note {{expected an argument list of type '(Int, Int)'}}
17+
$0 + 1.0 // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
1818
}
1919

2020
var closure6 = $0 // expected-error {{anonymous closure argument not contained in a closure}}
@@ -33,7 +33,7 @@ func funcdecl5(_ a: Int, _ y: Int) {
3333

3434
func6(fn: {$0 + $1}) // Closure with two named anonymous arguments
3535
func6(fn: {($0) + $1}) // Closure with sequence expr inferred type
36-
func6(fn: {($0) + $0}) // // expected-error {{binary operator '+' cannot be applied to two '(Int, Int)' operands}} expected-note {{expected an argument list of type '(Int, Int)'}}
36+
func6(fn: {($0) + $0}) // expected-error{{cannot convert value of type '(Int, Int)' to expected argument type 'Int'}}
3737

3838

3939
var testfunc : ((), Int) -> Int

0 commit comments

Comments
 (0)