Skip to content

Commit 9a2b29b

Browse files
authored
Merge pull request #29056 from hborla/general-ambiguity-failures
[Diagnostics] Diagnose general ambiguity failures in diagnoseAmbiguityWithFixes
2 parents 8e3dc7e + 43712bb commit 9a2b29b

File tree

7 files changed

+41
-20
lines changed

7 files changed

+41
-20
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2872,9 +2872,28 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
28722872

28732873
return true;
28742874
}
2875-
case AmbiguityKind::General:
2876-
// TODO: Handle general ambiguity here.
2877-
return false;
2875+
case AmbiguityKind::General: {
2876+
emitGeneralAmbiguityFailure();
2877+
2878+
// Notes for operators are diagnosed through emitGeneralAmbiguityFailure
2879+
if (name.isOperator())
2880+
return true;
2881+
2882+
llvm::SmallSet<CanType, 4> candidateTypes;
2883+
for (const auto &viable: viableSolutions) {
2884+
auto overload = viable->getOverloadChoice(commonCalleeLocator);
2885+
auto *decl = overload.choice.getDecl();
2886+
auto type = viable->simplifyType(overload.openedType);
2887+
if (decl->getLoc().isInvalid()) {
2888+
if (candidateTypes.insert(type->getCanonicalType()).second)
2889+
DE.diagnose(commonAnchor->getLoc(), diag::found_candidate_type, type);
2890+
} else {
2891+
DE.diagnose(decl->getLoc(), diag::found_candidate);
2892+
}
2893+
}
2894+
2895+
return true;
2896+
}
28782897
}
28792898

28802899
auto *fix = viableSolutions.front()->Fixes.front();

test/Constraints/members.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,11 @@ func rdar50679161() {
616616

617617
func rdar_50467583_and_50909555() {
618618
// rdar://problem/50467583
619-
let _: Set = [Int][]
620-
// expected-error@-1 {{instance member 'subscript' cannot be used on type '[Int]'}}
619+
let _: Set = [Int][] // expected-error {{no exact matches in call to subscript}}
620+
// expected-note@-1 {{found candidate with type '(Int) -> Int'}}
621+
// expected-note@-2 {{found candidate with type '(Range<Int>) -> ArraySlice<Int>'}}
622+
// expected-note@-3 {{found candidate with type '((UnboundedRange_) -> ()) -> ArraySlice<Int>'}}
623+
// expected-note@-4 {{found candidate with type '(Range<Array<Int>.Index>) -> Slice<[Int]>' (aka '(Range<Int>) -> Slice<Array<Int>>')}}
621624

622625
// rdar://problem/50909555
623626
struct S {

test/Constraints/operator.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,6 @@ func rdar46459603() {
218218

219219
_ = arr.values == [e]
220220
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type 'Dictionary<String, E>.Values' and '[E]'}}
221-
// expected-note@-2 {{expected an argument list of type '(Self, Self)'}}
222221
_ = [arr.values] == [[e]]
223222
// expected-error@-1 {{value of protocol type 'Any' cannot conform to 'Equatable'; only struct/enum/class types can conform to protocols}}
224223
// expected-note@-2 {{requirement from conditional conformance of '[Any]' to 'Equatable'}}

test/Constraints/overload.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,11 @@ func test20886179(_ handlers: [(Int) -> Void], buttonIndex: Int) {
127127

128128
// The problem here is that the call has a contextual result type incompatible
129129
// with *all* overload set candidates. This is not an ambiguity.
130-
func overloaded_identity(_ a : Int) -> Int {}
131-
func overloaded_identity(_ b : Float) -> Float {}
130+
func overloaded_identity(_ a : Int) -> Int {} // expected-note {{found this candidate}}
131+
func overloaded_identity(_ b : Float) -> Float {} // expected-note {{found this candidate}}
132132

133133
func test_contextual_result_1() {
134-
return overloaded_identity() // expected-error {{cannot invoke 'overloaded_identity' with no arguments}}
135-
// expected-note @-1 {{overloads for 'overloaded_identity' exist with these partially matching parameter lists: (Float), (Int)}}
134+
return overloaded_identity() // expected-error {{no exact matches in call to global function 'overloaded_identity'}}
136135
}
137136

138137
func test_contextual_result_2() {

test/Parse/super.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ class B {
44
var foo: Int
55
func bar() {}
66

7-
init() {}
8-
init(x: Int) {}
7+
init() {} // expected-note {{found this candidate}}
8+
init(x: Int) {} // expected-note {{found this candidate}}
99

1010
subscript(x: Int) -> Int {
1111
get {}
@@ -38,7 +38,8 @@ class D : B {
3838
super.foo.bar // expected-error {{value of type 'Int' has no member 'bar'}}
3939
super.bar // expected-error {{expression resolves to an unused function}}
4040
super.bar()
41-
super.init // expected-error{{'super.init' cannot be called outside of an initializer}}
41+
// FIXME: should also say "'super.init' cannot be referenced outside of an initializer"
42+
super.init // expected-error{{no exact matches in call to initializer}}
4243
super.init() // expected-error{{'super.init' cannot be called outside of an initializer}}
4344
super.init(0) // expected-error{{'super.init' cannot be called outside of an initializer}} // expected-error {{missing argument label 'x:' in call}}
4445
super[0] // expected-error {{expression resolves to an unused subscript}}

test/Parse/type_expr.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ protocol P2 {}
265265
protocol P3 {}
266266
func compositionType() {
267267
_ = P1 & P2 // expected-error {{expected member name or constructor call after type name}} expected-note{{use '.self'}} {{7-7=(}} {{14-14=).self}}
268-
_ = P1 & P2.self // expected-error {{binary operator '&' cannot be applied to operands of type 'P1.Protocol' and 'P2.Protocol'}} expected-note {{overloads}}
268+
_ = P1 & P2.self // expected-error {{binary operator '&' cannot be applied to operands of type 'P1.Protocol' and 'P2.Protocol'}}
269269
_ = (P1 & P2).self // Ok.
270270
_ = (P1 & (P2)).self // FIXME: OK? while `typealias P = P1 & (P2)` is rejected.
271271
_ = (P1 & (P2, P3)).self // expected-error {{non-protocol, non-class type '(P2, P3)' cannot be used within a protocol-constrained type}}

test/decl/subscript/subscripting.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,14 @@ func testUnresolvedMemberSubscriptFixit(_ s0: GenSubscriptFixitTest) {
349349

350350
struct SubscriptTest1 {
351351
subscript(keyword:String) -> Bool { return true }
352-
// expected-note@-1 3 {{found this candidate}} expected-note@-1 {{found candidate with type 'Bool'}}
352+
// expected-note@-1 5 {{found this candidate}} expected-note@-1 {{found candidate with type 'Bool'}}
353353
subscript(keyword:String) -> String? {return nil }
354-
// expected-note@-1 3 {{found this candidate}} expected-note@-1 {{found candidate with type 'String?'}}
354+
// expected-note@-1 5 {{found this candidate}} expected-note@-1 {{found candidate with type 'String?'}}
355355

356356
subscript(arg: SubClass) -> Bool { return true } // expected-note {{declared here}}
357+
// expected-note@-1 2 {{found this candidate}}
357358
subscript(arg: Protocol) -> Bool { return true } // expected-note 2 {{declared here}}
359+
// expected-note@-1 2 {{found this candidate}}
358360

359361
subscript(arg: (foo: Bool, bar: (Int, baz: SubClass)), arg2: String) -> Bool { return true }
360362
// expected-note@-1 3 {{declared here}}
@@ -379,11 +381,9 @@ func testSubscript1(_ s1 : SubscriptTest1) {
379381
_ = s1.subscript(ClassConformingToRefinedProtocol())
380382
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{54-55=]}}
381383
_ = s1.subscript(true)
382-
// expected-error@-1 {{cannot invoke 'subscript' with an argument list of type '(Bool)'}}
383-
// expected-note@-2 {{overloads for 'subscript' exist with these partially matching parameter lists: (Protocol), (String), (SubClass)}}
384+
// expected-error@-1 {{no exact matches in call to subscript}}
384385
_ = s1.subscript(SuperClass())
385-
// expected-error@-1 {{cannot invoke 'subscript' with an argument list of type '(SuperClass)'}}
386-
// expected-note@-2 {{overloads for 'subscript' exist with these partially matching parameter lists: (Protocol), (String), (SubClass)}}
386+
// expected-error@-1 {{no exact matches in call to subscript}}
387387
_ = s1.subscript("hello")
388388
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
389389
_ = s1.subscript("hello"

0 commit comments

Comments
 (0)