Skip to content

Commit b517aa1

Browse files
committed
[CS] Explore additional bindings for fixes
Previously we could skip default literal or supertype bindings if we had already found a solution with fixes, which could lead us to miss bindings that produce better diagnostics. Tweak the logic such that we continue exploring if we're in diagnostic mode. Resolves SR-12399.
1 parent 2d8bca0 commit b517aa1

File tree

6 files changed

+27
-10
lines changed

6 files changed

+27
-10
lines changed

lib/Sema/CSStep.h

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

628635
bool shouldStopAfter(const TypeVariableBinding &choice) const override {
636+
// Let's always attempt additional bindings in diagnostic mode, as that
637+
// could lead to better diagnostic for e.g trying the unwrapped type.
638+
if (CS.shouldAttemptFixes())
639+
return false;
640+
629641
// If there has been at least one solution so far
630642
// at a current batch of bindings is done it's a
631643
// success because each new batch would be less

test/Constraints/closures.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,17 @@ func verify_NotAC_to_AC_failure(_ arg: () -> ()) {
273273
// SR-1069 - Error diagnostic refers to wrong argument
274274
class SR1069_W<T> {
275275
func append<Key: AnyObject>(value: T, forKey key: Key) where Key: Hashable {}
276-
// expected-note@-1 {{where 'Key' = 'Object?'}}
277276
}
278277
class SR1069_C<T> { let w: SR1069_W<(AnyObject, T) -> ()> = SR1069_W() }
279278
struct S<T> {
280279
let cs: [SR1069_C<T>] = []
281280

282281
func subscribe<Object: AnyObject>(object: Object?, method: (Object, T) -> ()) where Object: Hashable {
283282
let wrappedMethod = { (object: AnyObject, value: T) in }
284-
// expected-error @+2 {{instance method 'append(value:forKey:)' requires that 'Object?' be a class type}}
285-
// expected-note @+1 {{wrapped type 'Object' satisfies this requirement}}
286283
cs.forEach { $0.w.append(value: wrappedMethod, forKey: object) }
284+
// expected-error@-1 {{value of optional type 'Object?' must be unwrapped to a value of type 'Object'}}
285+
// expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
286+
// expected-note@-3 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
287287
}
288288
}
289289

test/Constraints/fixes.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,14 @@ var s1116 = Set(1...10).subtracting(a1116.map({ $0.s })) // expected-error {{val
182182
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}} {{49-49=(}} {{53-53= ?? <#default value#>)}}
183183
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{53-53=!}}
184184

185+
func makeArray<T>(_ x: T) -> [T] { [x] }
186+
187+
func sr12399(_ x: Int?) {
188+
_ = Set(0...10).subtracting(makeArray(x)) // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
189+
// expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}} {{42-42= ?? <#default value#>}}
190+
// expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{42-42=!}}
191+
}
192+
185193
func moreComplexUnwrapFixes() {
186194
struct S {
187195
let value: Int

test/Constraints/keyword_arguments.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -798,19 +798,15 @@ func trailingclosure4(f: () -> Int) {}
798798
trailingclosure4 { 5 }
799799

800800
func trailingClosure5<T>(_ file: String = #file, line: UInt = #line, expression: () -> T?) { }
801-
// expected-note@-1 {{in call to function 'trailingClosure5(_:line:expression:)'}}
802801
func trailingClosure6<T>(value: Int, expression: () -> T?) { }
803-
// expected-note@-1 {{in call to function 'trailingClosure6(value:expression:)'}}
804802

805803
trailingClosure5(file: "hello", line: 17) { // expected-error{{extraneous argument label 'file:' in call}}{{18-24=}}
806-
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
807804
return Optional.Some(5)
808805
// expected-error@-1 {{enum type 'Optional<Wrapped>' has no case 'Some'; did you mean 'some'?}} {{19-23=some}}
809806
// expected-error@-2 {{generic parameter 'Wrapped' could not be inferred}}
810807
// expected-note@-3 {{explicitly specify the generic arguments to fix this issue}}
811808
}
812809
trailingClosure6(5) { // expected-error{{missing argument label 'value:' in call}}{{18-18=value: }}
813-
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
814810
return Optional.Some(5)
815811
// expected-error@-1 {{enum type 'Optional<Wrapped>' has no case 'Some'; did you mean 'some'?}} {{19-23=some}}
816812
// expected-error@-2 {{generic parameter 'Wrapped' could not be inferred}}

test/Generics/deduction.swift

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

326327
infix operator +&

test/expr/delayed-ident/static_var.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ var _: HasClosure = .factoryOpt(3)
5151
// expected-note@-2 {{coalesce}}
5252
// expected-note@-3 {{force-unwrap}}
5353
// FIXME: we should accept this
54-
var _: HasClosure = .factoryOpt!(4) // expected-error {{type 'Optional<_>' has no member 'factoryOpt'}}
54+
var _: HasClosure = .factoryOpt!(4) // expected-error {{cannot infer contextual base in reference to member 'factoryOpt'}}

0 commit comments

Comments
 (0)