Skip to content

Commit 355148d

Browse files
authored
Merge pull request #29746 from hborla/ambiguity-with-fixes
[Diagnostics] Refactor diagnoseAmbiguityWithFixes.
2 parents 6853289 + 172c200 commit 355148d

24 files changed

+339
-304
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,13 @@ ERROR(ambiguous_member_overload_set,none,
6161
ERROR(ambiguous_reference_to_decl,none,
6262
"ambiguous reference to %0 %1", (DescriptiveDeclKind, DeclName))
6363
ERROR(no_overloads_match_exactly_in_call,none,
64-
"no exact matches in call to %0 %1",
65-
(DescriptiveDeclKind, DeclName))
66-
ERROR(no_overloads_match_exactly_in_call_no_labels,none,
67-
"no exact matches in call to %0 %1",
68-
(DescriptiveDeclKind, DeclBaseName))
69-
ERROR(no_overloads_match_exactly_in_call_special,none,
70-
"no exact matches in call to %0",
71-
(DescriptiveDeclKind))
72-
ERROR(no_overloads_match_exactly_in_assignment,none,
73-
"no exact matches in assignment to %0",
74-
(DeclBaseName))
64+
"no exact matches in %select{reference|call}0 to %1 %select{%3|}2",
65+
(bool, DescriptiveDeclKind, bool, DeclBaseName))
7566

7667
NOTE(candidate_partial_match,none,
7768
"candidate has partially matching parameter list %0",
7869
(StringRef))
7970

80-
ERROR(ambiguous_subscript,none,
81-
"ambiguous subscript with base type %0 and index type %1",
82-
(Type, Type))
8371
ERROR(could_not_find_value_subscript,none,
8472
"value of type %0 has no subscripts",
8573
(Type))
@@ -282,16 +270,6 @@ ERROR(no_candidates_match_result_type,none,
282270
"no '%0' candidates produce the expected contextual result type %1",
283271
(StringRef, Type))
284272

285-
ERROR(candidates_no_match_result_type,none,
286-
"'%0' produces %1, not the expected contextual result type %2",
287-
(StringRef, Type, Type))
288-
289-
290-
291-
ERROR(invalid_callee_result_type,none,
292-
"cannot convert call result type %0 to expected type %1",
293-
(Type, Type))
294-
295273

296274
ERROR(cannot_invoke_closure,none,
297275
"cannot invoke closure expression with an argument list of type '%0'",
@@ -407,6 +385,10 @@ ERROR(cannot_convert_argument_value_generic,none,
407385
"cannot convert value of type %0 (%1) to expected argument type %2 (%3)",
408386
(Type, StringRef, Type, StringRef))
409387

388+
ERROR(conflicting_arguments_for_generic_parameter,none,
389+
"conflicting arguments to generic parameter %0 (%1)",
390+
(Type, StringRef))
391+
410392
// @_nonEphemeral conversion diagnostics
411393
ERROR(cannot_pass_type_to_non_ephemeral,none,
412394
"cannot pass %0 to parameter; argument %1 must be a pointer that "

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,17 +1247,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
12471247
return;
12481248
}
12491249

1250-
// Diagnose ".foo" expressions that lack context specifically.
1251-
if (auto UME =
1252-
dyn_cast<UnresolvedMemberExpr>(E->getSemanticsProvidingExpr())) {
1253-
if (!CS.getContextualType(E)) {
1254-
diagnose(E->getLoc(), diag::unresolved_member_no_inference,UME->getName())
1255-
.highlight(SourceRange(UME->getDotLoc(),
1256-
UME->getNameLoc().getSourceRange().End));
1257-
return;
1258-
}
1259-
}
1260-
12611250
// Attempt to re-type-check the entire expression, allowing ambiguity, but
12621251
// ignoring a contextual type.
12631252
if (expr == E) {

lib/Sema/CSDiagnostics.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5585,40 +5585,6 @@ bool ArgumentMismatchFailure::diagnoseArchetypeMismatch() const {
55855585
if (!(paramDecl && argDecl))
55865586
return false;
55875587

5588-
auto describeGenericType = [&](ValueDecl *genericParam,
5589-
bool includeName = false) -> std::string {
5590-
if (!genericParam)
5591-
return "";
5592-
5593-
Decl *parent = nullptr;
5594-
if (auto *AT = dyn_cast<AssociatedTypeDecl>(genericParam)) {
5595-
parent = AT->getProtocol();
5596-
} else {
5597-
auto *dc = genericParam->getDeclContext();
5598-
parent = dc->getInnermostDeclarationDeclContext();
5599-
}
5600-
5601-
if (!parent)
5602-
return "";
5603-
5604-
llvm::SmallString<64> result;
5605-
llvm::raw_svector_ostream OS(result);
5606-
5607-
OS << Decl::getDescriptiveKindName(genericParam->getDescriptiveKind());
5608-
5609-
if (includeName && genericParam->hasName())
5610-
OS << " '" << genericParam->getBaseName() << "'";
5611-
5612-
OS << " of ";
5613-
OS << Decl::getDescriptiveKindName(parent->getDescriptiveKind());
5614-
if (auto *decl = dyn_cast<ValueDecl>(parent)) {
5615-
if (decl->hasName())
5616-
OS << " '" << decl->getFullName() << "'";
5617-
}
5618-
5619-
return OS.str();
5620-
};
5621-
56225588
emitDiagnostic(
56235589
getAnchor()->getLoc(), diag::cannot_convert_argument_value_generic, argTy,
56245590
describeGenericType(argDecl), paramTy, describeGenericType(paramDecl));

lib/Sema/CSFix.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,24 @@ bool DefineMemberBasedOnUse::diagnose(bool asNote) const {
479479
return AlreadyDiagnosed || failure.diagnose(asNote);
480480
}
481481

482+
bool
483+
DefineMemberBasedOnUse::diagnoseForAmbiguity(ArrayRef<Solution> solutions) const {
484+
Type concreteBaseType;
485+
for (const auto &solution: solutions) {
486+
auto baseType = solution.simplifyType(BaseType);
487+
if (!concreteBaseType)
488+
concreteBaseType = baseType;
489+
490+
if (concreteBaseType->getCanonicalType() != baseType->getCanonicalType()) {
491+
getConstraintSystem().getASTContext().Diags.diagnose(getAnchor()->getLoc(),
492+
diag::unresolved_member_no_inference, Name);
493+
return true;
494+
}
495+
}
496+
497+
return diagnose();
498+
}
499+
482500
DefineMemberBasedOnUse *
483501
DefineMemberBasedOnUse::create(ConstraintSystem &cs, Type baseType,
484502
DeclNameRef member, bool alreadyDiagnosed,
@@ -1088,6 +1106,12 @@ UseValueTypeOfRawRepresentative::attempt(ConstraintSystem &cs, Type argType,
10881106
return nullptr;
10891107
}
10901108

1109+
unsigned AllowArgumentMismatch::getParamIdx() const {
1110+
const auto *locator = getLocator();
1111+
auto elt = locator->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
1112+
return elt.getParamIdx();
1113+
}
1114+
10911115
bool AllowArgumentMismatch::diagnose(bool asNote) const {
10921116
auto &cs = getConstraintSystem();
10931117
ArgumentMismatchFailure failure(cs, getFromType(), getToType(),

lib/Sema/CSFix.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ class ConstraintFix {
289289
/// Diagnose a failure associated with this fix.
290290
virtual bool diagnose(bool asNote = false) const = 0;
291291

292+
virtual bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const { return false; }
293+
292294
void print(llvm::raw_ostream &Out) const;
293295

294296
SWIFT_DEBUG_DUMP;
@@ -843,6 +845,8 @@ class DefineMemberBasedOnUse final : public ConstraintFix {
843845

844846
bool diagnose(bool asNote = false) const override;
845847

848+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override;
849+
846850
static DefineMemberBasedOnUse *create(ConstraintSystem &cs, Type baseType,
847851
DeclNameRef member, bool alreadyDiagnosed,
848852
ConstraintLocator *locator);
@@ -1109,6 +1113,10 @@ class AddMissingArguments final
11091113

11101114
bool diagnose(bool asNote = false) const override;
11111115

1116+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1117+
return diagnose();
1118+
}
1119+
11121120
static AddMissingArguments *create(ConstraintSystem &cs,
11131121
llvm::ArrayRef<Param> synthesizedArgs,
11141122
ConstraintLocator *locator);
@@ -1149,6 +1157,10 @@ class RemoveExtraneousArguments final
11491157

11501158
bool diagnose(bool asNote = false) const override;
11511159

1160+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1161+
return diagnose();
1162+
}
1163+
11521164
/// FIXME(diagnostics): Once `resolveDeclRefExpr` is gone this
11531165
/// logic would be obsolete.
11541166
///
@@ -1349,6 +1361,10 @@ class DefaultGenericArgument final : public ConstraintFix {
13491361

13501362
bool diagnose(bool asNote = false) const override;
13511363

1364+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1365+
return diagnose();
1366+
}
1367+
13521368
static DefaultGenericArgument *create(ConstraintSystem &cs,
13531369
GenericTypeParamType *param,
13541370
ConstraintLocator *locator);
@@ -1420,6 +1436,10 @@ class IgnoreContextualType : public ContextualMismatch {
14201436

14211437
bool diagnose(bool asNote = false) const override;
14221438

1439+
bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
1440+
return diagnose();
1441+
}
1442+
14231443
static IgnoreContextualType *create(ConstraintSystem &cs, Type resultTy,
14241444
Type specifiedTy,
14251445
ConstraintLocator *locator);
@@ -1479,11 +1499,17 @@ class AllowArgumentMismatch : public ContextualMismatch {
14791499
return "allow argument to parameter type conversion mismatch";
14801500
}
14811501

1502+
unsigned getParamIdx() const;
1503+
14821504
bool diagnose(bool asNote = false) const override;
14831505

14841506
static AllowArgumentMismatch *create(ConstraintSystem &cs, Type argType,
14851507
Type paramType,
14861508
ConstraintLocator *locator);
1509+
1510+
static bool classof(const ConstraintFix *fix) {
1511+
return fix->getKind() == FixKind::AllowArgumentTypeMismatch;
1512+
}
14871513
};
14881514

14891515
class ExpandArrayIntoVarargs final : public AllowArgumentMismatch {

0 commit comments

Comments
 (0)