Skip to content

Commit b2e6048

Browse files
authored
Merge pull request #30844 from hborla/diagnose-for-ambiguity
[Diagnostics] In DefineMemberBasedOnUse::diagnoseForAmbiguity, use the base type from each solution
2 parents eefe9a0 + ece84b1 commit b2e6048

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

lib/Sema/CSFix.cpp

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

491491
bool
492-
DefineMemberBasedOnUse::diagnoseForAmbiguity(ArrayRef<Solution> solutions) const {
492+
DefineMemberBasedOnUse::diagnoseForAmbiguity(CommonFixesArray commonFixes) const {
493493
Type concreteBaseType;
494-
for (const auto &solution: solutions) {
495-
auto baseType = solution.simplifyType(BaseType);
494+
for (const auto &solutionAndFix : commonFixes) {
495+
const auto *solution = solutionAndFix.first;
496+
const auto *fix = solutionAndFix.second->getAs<DefineMemberBasedOnUse>();
497+
498+
auto baseType = solution->simplifyType(fix->BaseType);
496499
if (!concreteBaseType)
497500
concreteBaseType = baseType;
498501

@@ -503,7 +506,7 @@ DefineMemberBasedOnUse::diagnoseForAmbiguity(ArrayRef<Solution> solutions) const
503506
}
504507
}
505508

506-
return diagnose(solutions.front());
509+
return diagnose(*commonFixes.front().first);
507510
}
508511

509512
DefineMemberBasedOnUse *

lib/Sema/CSFix.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,12 @@ 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+
using CommonFixesArray =
295+
ArrayRef<std::pair<const Solution *, const ConstraintFix *>>;
296+
297+
virtual bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const {
298+
return false;
299+
}
295300

296301
void print(llvm::raw_ostream &Out) const;
297302

@@ -847,11 +852,15 @@ class DefineMemberBasedOnUse final : public ConstraintFix {
847852

848853
bool diagnose(const Solution &solution, bool asNote = false) const override;
849854

850-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override;
855+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override;
851856

852857
static DefineMemberBasedOnUse *create(ConstraintSystem &cs, Type baseType,
853858
DeclNameRef member, bool alreadyDiagnosed,
854859
ConstraintLocator *locator);
860+
861+
static bool classof(const ConstraintFix *fix) {
862+
return fix->getKind() == FixKind::DefineMemberBasedOnUse;
863+
}
855864
};
856865

857866
class AllowInvalidMemberRef : public ConstraintFix {
@@ -1117,8 +1126,8 @@ class AddMissingArguments final
11171126

11181127
bool diagnose(const Solution &solution, bool asNote = false) const override;
11191128

1120-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1121-
return diagnose(solutions.front());
1129+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
1130+
return diagnose(*commonFixes.front().first);
11221131
}
11231132

11241133
static AddMissingArguments *create(ConstraintSystem &cs,
@@ -1161,8 +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 {
1165-
return diagnose(solutions.front());
1173+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
1174+
return diagnose(*commonFixes.front().first);
11661175
}
11671176

11681177
/// FIXME(diagnostics): Once `resolveDeclRefExpr` is gone this
@@ -1371,8 +1380,8 @@ class DefaultGenericArgument final : public ConstraintFix {
13711380

13721381
bool diagnose(const Solution &solution, bool asNote = false) const override;
13731382

1374-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1375-
return diagnose(solutions.front());
1383+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
1384+
return diagnose(*commonFixes.front().first);
13761385
}
13771386

13781387
static DefaultGenericArgument *create(ConstraintSystem &cs,
@@ -1446,8 +1455,8 @@ class IgnoreContextualType : public ContextualMismatch {
14461455

14471456
bool diagnose(const Solution &solution, bool asNote = false) const override;
14481457

1449-
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1450-
return diagnose(solutions.front());
1458+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
1459+
return diagnose(*commonFixes.front().first);
14511460
}
14521461

14531462
static IgnoreContextualType *create(ConstraintSystem &cs, Type resultTy,

lib/Sema/ConstraintSystem.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,12 +2947,15 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
29472947
return true;
29482948

29492949
// Collect aggregated fixes from all solutions
2950-
llvm::SmallMapVector<std::pair<ConstraintLocator *, FixKind>,
2951-
llvm::TinyPtrVector<ConstraintFix *>, 4>
2950+
using LocatorAndKind = std::pair<ConstraintLocator *, FixKind>;
2951+
using SolutionAndFix = std::pair<const Solution *, const ConstraintFix *>;
2952+
llvm::SmallMapVector<LocatorAndKind, llvm::SmallVector<SolutionAndFix, 4>, 4>
29522953
aggregatedFixes;
29532954
for (const auto &solution : solutions) {
2954-
for (auto *fix : solution.Fixes)
2955-
aggregatedFixes[{fix->getLocator(), fix->getKind()}].push_back(fix);
2955+
for (const auto *fix : solution.Fixes) {
2956+
LocatorAndKind key(fix->getLocator(), fix->getKind());
2957+
aggregatedFixes[key].emplace_back(&solution, fix);
2958+
}
29562959
}
29572960

29582961
// If there is an overload difference, let's see if there's a common callee
@@ -2983,8 +2986,11 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
29832986
bool diagnosed = false;
29842987
for (auto fixes: aggregatedFixes) {
29852988
// A common fix must appear in all solutions
2986-
if (fixes.second.size() < solutions.size()) continue;
2987-
diagnosed |= fixes.second.front()->diagnoseForAmbiguity(solutions);
2989+
auto &commonFixes = fixes.second;
2990+
if (commonFixes.size() != solutions.size()) continue;
2991+
2992+
auto *firstFix = commonFixes.front().second;
2993+
diagnosed |= firstFix->diagnoseForAmbiguity(commonFixes);
29882994
}
29892995
return diagnosed;
29902996
}

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)