Skip to content

Commit 8b63ce8

Browse files
authored
Merge pull request #64143 from xedin/ambiguity-diag-improvements
[ConstraintSystem] A couple of improvements to ambiguity diagnostics
2 parents 156edca + 6c5186f commit 8b63ce8

File tree

7 files changed

+23
-15
lines changed

7 files changed

+23
-15
lines changed

include/swift/Sema/CSFix.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,10 @@ class UnwrapOptionalBase final : public ConstraintFix {
532532

533533
bool diagnose(const Solution &solution, bool asNote = false) const override;
534534

535+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
536+
return diagnose(*commonFixes.front().first);
537+
}
538+
535539
static UnwrapOptionalBase *create(ConstraintSystem &cs, DeclNameRef member,
536540
Type memberBaseType,
537541
ConstraintLocator *locator);

lib/Sema/ConstraintSystem.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4673,10 +4673,16 @@ static bool diagnoseAmbiguity(
46734673
auto noteLoc =
46744674
decl->getLoc().isInvalid() ? getLoc(commonAnchor) : decl->getLoc();
46754675

4676-
if (solution.Fixes.size() == 1) {
4677-
diagnosed &=
4678-
solution.Fixes.front()->diagnose(solution, /*asNote*/ true);
4679-
} else if (llvm::all_of(solution.Fixes, [&](ConstraintFix *fix) {
4676+
SmallVector<const ConstraintFix *, 4> fixes;
4677+
for (const auto &entry : aggregateFix) {
4678+
if (entry.first == &solution)
4679+
fixes.push_back(entry.second);
4680+
}
4681+
4682+
if (fixes.size() == 1) {
4683+
diagnosed &= fixes.front()->diagnose(solution, /*asNote*/ true);
4684+
} else if (!fixes.empty() &&
4685+
llvm::all_of(fixes, [&](const ConstraintFix *fix) {
46804686
return fix->getLocator()
46814687
->findLast<LocatorPathElt::ApplyArgument>()
46824688
.has_value();
@@ -4690,8 +4696,7 @@ static bool diagnoseAmbiguity(
46904696
type->lookThroughAllOptionalTypes()->getAs<AnyFunctionType>();
46914697
assert(fn);
46924698

4693-
auto *argList =
4694-
solution.getArgumentList(solution.Fixes.front()->getLocator());
4699+
auto *argList = solution.getArgumentList(fixes.front()->getLocator());
46954700
assert(argList);
46964701

46974702
if (fn->getNumParams() == 1 && argList->isUnary()) {

test/Constraints/optional.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,8 @@ do {
592592

593593
// Diagnose extraneous force unwrap in ambiguous context
594594
do {
595-
func test(_: Int) {} // expected-note {{found this candidate}}
596-
func test(_: String) {} // expected-note {{found this candidate}}
595+
func test(_: Int) {} // expected-note {{candidate expects value of type 'Int' for parameter #1 (got 'Double')}}
596+
func test(_: String) {} // expected-note {{candidate expects value of type 'String' for parameter #1 (got 'Double')}}
597597

598598
var x: Double = 42
599599
test(x!) // expected-error {{no exact matches in call to local function 'test'}}

test/Generics/function_defs.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ protocol Subscriptable {
123123
func getIndex() -> Index
124124
func getValue() -> Value
125125

126-
subscript (index : Index) -> Value { get set } // expected-note {{found this candidate}}
126+
subscript (index : Index) -> Value { get set } // expected-note {{candidate expects value of type 'T.Index' for parameter #1 (got 'T.Value')}}
127127
}
128128

129129
protocol IntSubscriptable {
130130
associatedtype ElementType
131131

132132
func getElement() -> ElementType
133133

134-
subscript (index : Int) -> ElementType { get } // expected-note {{found this candidate}}
134+
subscript (index : Int) -> ElementType { get } // expected-note {{candidate expects value of type 'Int' for parameter #1 (got 'T.Value')}}
135135
}
136136

137137
func subscripting<T : Subscriptable & IntSubscriptable>(_ t: T) {

test/Sema/diag_ambiguous_overloads.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ do {
148148
}
149149
}
150150
do {
151-
func f1(_ u: Int) -> String {} // expected-note {{found this candidate}} expected-note {{candidate expects value of type 'Int' for parameter #1 (got 'Double')}}
152-
func f1(_ u: String) -> Double {} // expected-note {{found this candidate}} expected-note {{candidate expects value of type 'String' for parameter #1 (got 'Double')}}
151+
func f1(_ u: Int) -> String {} // expected-note 2 {{candidate expects value of type 'Int' for parameter #1 (got 'Double')}}
152+
func f1(_ u: String) -> Double {} // expected-note 2 {{candidate expects value of type 'String' for parameter #1 (got 'Double')}}
153153
func f2(_ u: Int) {}
154154

155155
f2(f1(1 as Double)) // expected-error {{no exact matches in call to local function 'f1'}}

test/expr/expressions.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,6 @@ func invalidDictionaryLiteral() {
749749

750750
[4].joined(separator: [1])
751751
// expected-error@-1 {{no exact matches in call to instance method 'joined'}}
752-
// expected-note@-2 {{found candidate with type '(String) -> String'}}
753752
// There is one more note here - candidate requires that 'Int' conform to 'Sequence' (requirement specified as 'Self.Element' : 'Sequence') pointing to Sequence extension
754753

755754
[4].joined(separator: [[[1]]])

test/expr/unary/keypath/keypath.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,8 +1067,8 @@ func f_56996() {
10671067
// https://github.com/apple/swift/issues/55805
10681068
// Key-path missing optional crashes compiler: Inactive constraints left over?
10691069
func f_55805() {
1070-
let _: KeyPath<String?, Int?> = \.utf8.count // expected-error {{no exact matches in reference to property 'count'}}
1071-
// expected-note@-1 {{found candidate with type 'Int'}}
1070+
let _: KeyPath<String?, Int?> = \.utf8.count // expected-error {{value of optional type 'String.UTF8View?' must be unwrapped to refer to member 'count' of wrapped base type 'String.UTF8View'}}
1071+
// expected-note@-1 {{chain the optional using '?' to access member 'count' only for non-'nil' base values}}
10721072
}
10731073

10741074
// rdar://74711236 - crash due to incorrect member access in key path

0 commit comments

Comments
 (0)