Skip to content

Commit 96297b7

Browse files
committed
[CSStep] Always attempt literal bindings in diagnostic mode
In case of contextual failures such bindings could produce better solutions with fewer fixes.
1 parent 3e01160 commit 96297b7

File tree

9 files changed

+24
-19
lines changed

9 files changed

+24
-19
lines changed

lib/Sema/CSStep.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,15 @@ class TypeVariableStep final : public BindingStep<TypeVarBindingProducer> {
620620
/// Check whether attempting type variable binding choices should
621621
/// be stopped, because optimal solution has already been found.
622622
bool shouldStopAt(const TypeVariableBinding &choice) const override {
623+
if (CS.shouldAttemptFixes()) {
624+
// Let's always attempt default types inferred from literals
625+
// in diagnostic mode because that could lead to better
626+
// diagnostics if the problem is contextual like argument/parameter
627+
// conversion or collection element mismatch.
628+
if (choice.hasDefaultedProtocol())
629+
return false;
630+
}
631+
623632
// If we were able to solve this without considering
624633
// default literals, don't bother looking at default literals.
625634
return AnySolved && choice.hasDefaultedProtocol() &&

test/Constraints/array_literal.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ useDoubleList([1.0,2,3])
5050
useDoubleList([1.0,2.0,3.0])
5151

5252
useIntDict(["Niners" => 31, "Ravens" => 34])
53-
useIntDict(["Niners" => 31, "Ravens" => 34.0]) // expected-error{{cannot convert value of type 'Double' to expected argument type 'Int'}}
53+
useIntDict(["Niners" => 31, "Ravens" => 34.0]) // expected-error{{cannot convert value of type 'Double' to expected element type 'Int'}}
5454
// <rdar://problem/22333090> QoI: Propagate contextual information in a call to operands
5555
useDoubleDict(["Niners" => 31, "Ravens" => 34.0])
5656
useDoubleDict(["Niners" => 31.0, "Ravens" => 34])

test/Constraints/closures.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,7 @@ extension Collection {
456456
}
457457
}
458458
func fn_r28909024(n: Int) {
459-
// FIXME(diagnostics): Unfortunately there is no easy way to fix this diagnostic issue at the moment
460-
// because the problem is related to ordering of the bindings - we'd attempt to bind result of the expression
461-
// to contextual type of `Void` which prevents solver from discovering correct types for range - 0..<10
462-
// (since both arguments are literal they are ranked lower than contextual type).
463-
//
464-
// Good diagnostic for this is - `unexpected non-void return value in void function`
465-
return (0..<10).r28909024 { // expected-error {{type of expression is ambiguous without more context}}
459+
return (0..<10).r28909024 { // expected-error {{unexpected non-void return value in void function}} expected-note {{did you mean to add a return type?}}
466460
_ in true
467461
}
468462
}

test/Generics/deduction.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,9 @@ func foo() {
318318
let j = min(Int(3), Float(2.5)) // expected-error{{conflicting arguments to generic parameter 'T' ('Int' vs. 'Float')}}
319319
let k = min(A(), A()) // expected-error{{global function 'min' requires that 'A' conform to 'Comparable'}}
320320
let oi : Int? = 5
321-
let l = min(3, oi) // expected-error{{global function 'min' requires that 'Int?' conform to 'Comparable'}}
322-
// expected-note@-1{{wrapped type 'Int' satisfies this requirement}}
321+
let l = min(3, oi) // expected-error{{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
322+
// expected-note@-1 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
323+
// expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
323324
}
324325

325326
infix operator +&

test/Parse/omit_return.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ var fvs_stubMyOwnFatalError: () {
10051005
var fvs_forceTryExplicit: String {
10061006
get { "ok" }
10071007
set {
1008-
return try! failableIdentity("shucks") // expected-error {{cannot convert value of type 'String' to expected argument type '()'}}
1008+
return try! failableIdentity("shucks") // expected-error {{unexpected non-void return value in void function}}
10091009
}
10101010
}
10111011

test/decl/typealias/generic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ _ = A<String, Int>(a: "foo", // expected-error {{cannot convert value of type 'S
103103
b: 42) // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
104104
_ = B(a: 12, b: 42)
105105
_ = B(a: 12, b: 42 as Float)
106-
_ = B(a: "foo", b: 42) // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
106+
_ = B(a: "foo", b: 42) // expected-error {{conflicting arguments to generic parameter 'T1' ('String' vs. 'Int')}}
107107
_ = C(a: "foo", b: 42)
108108
_ = C(a: 42, // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
109109
b: 42)

test/expr/expressions.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,9 @@ func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange<Int>?) {
791791

792792
// ?? should have lower precedence than range and arithmetic operators.
793793
let r1 = r ?? (0...42) // ok
794-
let r2 = (r ?? 0)...42 // not ok: expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
795-
// expected-error@-1 {{referencing operator function '...' on 'Comparable' requires that 'ClosedRange<Int>' conform to 'Comparable'}}
794+
let r2 = (r ?? 0)...42 // not ok
795+
// expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
796+
// expected-error@-2 {{cannot convert value of type 'ClosedRange<Int>' to expected argument type 'Int'}}
796797
let r3 = r ?? 0...42 // parses as the first one, not the second.
797798

798799

test/type/protocol_composition.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ takesP1AndP2([Swift.AnyObject & P1 & P2]())
173173
takesP1AndP2([AnyObject & protocol_composition.P1 & P2]())
174174
takesP1AndP2([AnyObject & P1 & protocol_composition.P2]())
175175
takesP1AndP2([DoesNotExist & P1 & P2]()) // expected-error {{use of unresolved identifier 'DoesNotExist'}}
176-
takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{module 'Swift' has no member named 'DoesNotExist'}}
176+
takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{module 'Swift' has no member named 'DoesNotExist'}} expected-error {{cannot call value of non-function type 'Array<_>'}}
177177

178178
typealias T08 = P1 & inout P2 // expected-error {{'inout' may only be used on parameters}}
179179
typealias T09 = P1 & __shared P2 // expected-error {{'__shared' may only be used on parameters}}

validation-test/stdlib/FixedPointDiagnostics.swift.gyb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
// RUN: %line-directive %t/main.swift -- %target-swift-frontend -typecheck -verify -swift-version 4.2 %t/main.swift
44

55
func testUnaryMinusInUnsigned() {
6-
var a: UInt8 = -(1) // expected-error {{no '-' candidates produce the expected contextual result type 'UInt8'}} expected-note * {{}} expected-warning * {{}}
6+
var a: UInt8 = -(1) // expected-error {{cannot convert value of type 'Int' to specified type 'UInt8'}} expected-note * {{}} expected-warning * {{}}
77

8-
var b: UInt16 = -(1) // expected-error {{no '-' candidates produce the expected contextual result type 'UInt16'}} expected-note * {{}} expected-warning * {{}}
8+
var b: UInt16 = -(1) // expected-error {{cannot convert value of type 'Int' to specified type 'UInt16'}} expected-note * {{}} expected-warning * {{}}
99

10-
var c: UInt32 = -(1) // expected-error {{no '-' candidates produce the expected contextual result type 'UInt32'}} expected-note * {{}} expected-warning * {{}}
10+
var c: UInt32 = -(1) // expected-error {{cannot convert value of type 'Int' to specified type 'UInt32'}} expected-note * {{}} expected-warning * {{}}
1111

12-
var d: UInt64 = -(1) // expected-error {{no '-' candidates produce the expected contextual result type 'UInt64'}} expected-note * {{}} expected-warning * {{}}
12+
var d: UInt64 = -(1) // expected-error {{cannot convert value of type 'Int' to specified type 'UInt64'}} expected-note * {{}} expected-warning * {{}}
1313
}
1414

1515
// Int and UInt are not identical to any fixed-size integer type

0 commit comments

Comments
 (0)