Skip to content

Commit 6375481

Browse files
committed
[Diagnostics] In DefineMemberBasedOnUse::diagnoseForAmbiguity, use
the base type from each solution instead of only the base type from the first solution.
1 parent 829f258 commit 6375481

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

lib/Sema/CSFix.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,15 @@ bool DefineMemberBasedOnUse::diagnose(const Solution &solution,
489489
}
490490

491491
bool
492-
DefineMemberBasedOnUse::diagnoseForAmbiguity(ArrayRef<Solution> solutions) const {
492+
DefineMemberBasedOnUse::diagnoseForAmbiguity(ArrayRef<Solution> solutions,
493+
ArrayRef<ConstraintFix *> fixes) const {
493494
Type concreteBaseType;
494-
for (const auto &solution: solutions) {
495-
auto baseType = solution.simplifyType(BaseType);
495+
for (unsigned i = 0; i < solutions.size(); ++i) {
496+
const auto *fix = fixes[i]->getAs<DefineMemberBasedOnUse>();
497+
const auto &solution = solutions[i];
498+
assert(llvm::find(solution.Fixes, fix) != solution.Fixes.end());
499+
500+
auto baseType = solution.simplifyType(fix->BaseType);
496501
if (!concreteBaseType)
497502
concreteBaseType = baseType;
498503

lib/Sema/CSFix.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,10 @@ class ConstraintFix {
291291
virtual bool diagnose(const Solution &solution,
292292
bool asNote = false) const = 0;
293293

294-
virtual bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const { return false; }
294+
virtual bool diagnoseForAmbiguity(ArrayRef<Solution> solutions,
295+
ArrayRef<ConstraintFix *> fixes) const {
296+
return false;
297+
}
295298

296299
void print(llvm::raw_ostream &Out) const;
297300

@@ -847,11 +850,16 @@ class DefineMemberBasedOnUse final : public ConstraintFix {
847850

848851
bool diagnose(const Solution &solution, bool asNote = false) const override;
849852

850-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override;
853+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions,
854+
ArrayRef<ConstraintFix *> fixes) const override;
851855

852856
static DefineMemberBasedOnUse *create(ConstraintSystem &cs, Type baseType,
853857
DeclNameRef member, bool alreadyDiagnosed,
854858
ConstraintLocator *locator);
859+
860+
static bool classof(const ConstraintFix *fix) {
861+
return fix->getKind() == FixKind::DefineMemberBasedOnUse;
862+
}
855863
};
856864

857865
class AllowInvalidMemberRef : public ConstraintFix {
@@ -1117,7 +1125,8 @@ class AddMissingArguments final
11171125

11181126
bool diagnose(const Solution &solution, bool asNote = false) const override;
11191127

1120-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1128+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions,
1129+
ArrayRef<ConstraintFix *> fixes) const override {
11211130
return diagnose(solutions.front());
11221131
}
11231132

@@ -1161,7 +1170,8 @@ class RemoveExtraneousArguments final
11611170

11621171
bool diagnose(const Solution &solution, bool asNote = false) const override;
11631172

1164-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1173+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions,
1174+
ArrayRef<ConstraintFix *> fixes) const override {
11651175
return diagnose(solutions.front());
11661176
}
11671177

@@ -1371,7 +1381,8 @@ class DefaultGenericArgument final : public ConstraintFix {
13711381

13721382
bool diagnose(const Solution &solution, bool asNote = false) const override;
13731383

1374-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1384+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions,
1385+
ArrayRef<ConstraintFix *> fixes) const override {
13751386
return diagnose(solutions.front());
13761387
}
13771388

@@ -1446,7 +1457,8 @@ class IgnoreContextualType : public ContextualMismatch {
14461457

14471458
bool diagnose(const Solution &solution, bool asNote = false) const override;
14481459

1449-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1460+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions,
1461+
ArrayRef<ConstraintFix *> fixes) const override {
14501462
return diagnose(solutions.front());
14511463
}
14521464

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,8 +2983,9 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
29832983
bool diagnosed = false;
29842984
for (auto fixes: aggregatedFixes) {
29852985
// A common fix must appear in all solutions
2986-
if (fixes.second.size() < solutions.size()) continue;
2987-
diagnosed |= fixes.second.front()->diagnoseForAmbiguity(solutions);
2986+
if (fixes.second.size() != solutions.size()) continue;
2987+
diagnosed |= fixes.second.front()->diagnoseForAmbiguity(solutions,
2988+
fixes.second);
29882989
}
29892990
return diagnosed;
29902991
}

test/Sema/diag_ambiguous_overloads.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ struct S {
4040
}
4141
}
4242

43+
struct School {
44+
var name: String
45+
}
46+
func testDiagnoseForAmbiguityCrash(schools: [School]) {
47+
schools.map({ $0.name }).sorted(by: { $0.nothing < $1.notAThing })
48+
// expected-error@-1 {{value of type 'String' has no member 'nothing'}}
49+
// expected-error@-2 {{value of type 'String' has no member 'notAThing'}}
50+
}
4351

4452
class DefaultValue {
4553
static func foo(_ a: Int) {}

0 commit comments

Comments
 (0)