Skip to content

Commit

Permalink
Merge pull request swiftlang#29746 from hborla/ambiguity-with-fixes
Browse files Browse the repository at this point in the history
[Diagnostics] Refactor diagnoseAmbiguityWithFixes.
  • Loading branch information
xedin authored Feb 13, 2020
2 parents 6853289 + 172c200 commit 355148d
Show file tree
Hide file tree
Showing 24 changed files with 339 additions and 304 deletions.
30 changes: 6 additions & 24 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,13 @@ ERROR(ambiguous_member_overload_set,none,
ERROR(ambiguous_reference_to_decl,none,
"ambiguous reference to %0 %1", (DescriptiveDeclKind, DeclName))
ERROR(no_overloads_match_exactly_in_call,none,
"no exact matches in call to %0 %1",
(DescriptiveDeclKind, DeclName))
ERROR(no_overloads_match_exactly_in_call_no_labels,none,
"no exact matches in call to %0 %1",
(DescriptiveDeclKind, DeclBaseName))
ERROR(no_overloads_match_exactly_in_call_special,none,
"no exact matches in call to %0",
(DescriptiveDeclKind))
ERROR(no_overloads_match_exactly_in_assignment,none,
"no exact matches in assignment to %0",
(DeclBaseName))
"no exact matches in %select{reference|call}0 to %1 %select{%3|}2",
(bool, DescriptiveDeclKind, bool, DeclBaseName))

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

ERROR(ambiguous_subscript,none,
"ambiguous subscript with base type %0 and index type %1",
(Type, Type))
ERROR(could_not_find_value_subscript,none,
"value of type %0 has no subscripts",
(Type))
Expand Down Expand Up @@ -282,16 +270,6 @@ ERROR(no_candidates_match_result_type,none,
"no '%0' candidates produce the expected contextual result type %1",
(StringRef, Type))

ERROR(candidates_no_match_result_type,none,
"'%0' produces %1, not the expected contextual result type %2",
(StringRef, Type, Type))



ERROR(invalid_callee_result_type,none,
"cannot convert call result type %0 to expected type %1",
(Type, Type))


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

ERROR(conflicting_arguments_for_generic_parameter,none,
"conflicting arguments to generic parameter %0 (%1)",
(Type, StringRef))

// @_nonEphemeral conversion diagnostics
ERROR(cannot_pass_type_to_non_ephemeral,none,
"cannot pass %0 to parameter; argument %1 must be a pointer that "
Expand Down
11 changes: 0 additions & 11 deletions lib/Sema/CSDiag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1247,17 +1247,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
return;
}

// Diagnose ".foo" expressions that lack context specifically.
if (auto UME =
dyn_cast<UnresolvedMemberExpr>(E->getSemanticsProvidingExpr())) {
if (!CS.getContextualType(E)) {
diagnose(E->getLoc(), diag::unresolved_member_no_inference,UME->getName())
.highlight(SourceRange(UME->getDotLoc(),
UME->getNameLoc().getSourceRange().End));
return;
}
}

// Attempt to re-type-check the entire expression, allowing ambiguity, but
// ignoring a contextual type.
if (expr == E) {
Expand Down
34 changes: 0 additions & 34 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5585,40 +5585,6 @@ bool ArgumentMismatchFailure::diagnoseArchetypeMismatch() const {
if (!(paramDecl && argDecl))
return false;

auto describeGenericType = [&](ValueDecl *genericParam,
bool includeName = false) -> std::string {
if (!genericParam)
return "";

Decl *parent = nullptr;
if (auto *AT = dyn_cast<AssociatedTypeDecl>(genericParam)) {
parent = AT->getProtocol();
} else {
auto *dc = genericParam->getDeclContext();
parent = dc->getInnermostDeclarationDeclContext();
}

if (!parent)
return "";

llvm::SmallString<64> result;
llvm::raw_svector_ostream OS(result);

OS << Decl::getDescriptiveKindName(genericParam->getDescriptiveKind());

if (includeName && genericParam->hasName())
OS << " '" << genericParam->getBaseName() << "'";

OS << " of ";
OS << Decl::getDescriptiveKindName(parent->getDescriptiveKind());
if (auto *decl = dyn_cast<ValueDecl>(parent)) {
if (decl->hasName())
OS << " '" << decl->getFullName() << "'";
}

return OS.str();
};

emitDiagnostic(
getAnchor()->getLoc(), diag::cannot_convert_argument_value_generic, argTy,
describeGenericType(argDecl), paramTy, describeGenericType(paramDecl));
Expand Down
24 changes: 24 additions & 0 deletions lib/Sema/CSFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,24 @@ bool DefineMemberBasedOnUse::diagnose(bool asNote) const {
return AlreadyDiagnosed || failure.diagnose(asNote);
}

bool
DefineMemberBasedOnUse::diagnoseForAmbiguity(ArrayRef<Solution> solutions) const {
Type concreteBaseType;
for (const auto &solution: solutions) {
auto baseType = solution.simplifyType(BaseType);
if (!concreteBaseType)
concreteBaseType = baseType;

if (concreteBaseType->getCanonicalType() != baseType->getCanonicalType()) {
getConstraintSystem().getASTContext().Diags.diagnose(getAnchor()->getLoc(),
diag::unresolved_member_no_inference, Name);
return true;
}
}

return diagnose();
}

DefineMemberBasedOnUse *
DefineMemberBasedOnUse::create(ConstraintSystem &cs, Type baseType,
DeclNameRef member, bool alreadyDiagnosed,
Expand Down Expand Up @@ -1088,6 +1106,12 @@ UseValueTypeOfRawRepresentative::attempt(ConstraintSystem &cs, Type argType,
return nullptr;
}

unsigned AllowArgumentMismatch::getParamIdx() const {
const auto *locator = getLocator();
auto elt = locator->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
return elt.getParamIdx();
}

bool AllowArgumentMismatch::diagnose(bool asNote) const {
auto &cs = getConstraintSystem();
ArgumentMismatchFailure failure(cs, getFromType(), getToType(),
Expand Down
26 changes: 26 additions & 0 deletions lib/Sema/CSFix.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ class ConstraintFix {
/// Diagnose a failure associated with this fix.
virtual bool diagnose(bool asNote = false) const = 0;

virtual bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const { return false; }

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

SWIFT_DEBUG_DUMP;
Expand Down Expand Up @@ -843,6 +845,8 @@ class DefineMemberBasedOnUse final : public ConstraintFix {

bool diagnose(bool asNote = false) const override;

bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override;

static DefineMemberBasedOnUse *create(ConstraintSystem &cs, Type baseType,
DeclNameRef member, bool alreadyDiagnosed,
ConstraintLocator *locator);
Expand Down Expand Up @@ -1109,6 +1113,10 @@ class AddMissingArguments final

bool diagnose(bool asNote = false) const override;

bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
return diagnose();
}

static AddMissingArguments *create(ConstraintSystem &cs,
llvm::ArrayRef<Param> synthesizedArgs,
ConstraintLocator *locator);
Expand Down Expand Up @@ -1149,6 +1157,10 @@ class RemoveExtraneousArguments final

bool diagnose(bool asNote = false) const override;

bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
return diagnose();
}

/// FIXME(diagnostics): Once `resolveDeclRefExpr` is gone this
/// logic would be obsolete.
///
Expand Down Expand Up @@ -1349,6 +1361,10 @@ class DefaultGenericArgument final : public ConstraintFix {

bool diagnose(bool asNote = false) const override;

bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
return diagnose();
}

static DefaultGenericArgument *create(ConstraintSystem &cs,
GenericTypeParamType *param,
ConstraintLocator *locator);
Expand Down Expand Up @@ -1420,6 +1436,10 @@ class IgnoreContextualType : public ContextualMismatch {

bool diagnose(bool asNote = false) const override;

bool diagnoseForAmbiguity(ArrayRef<Solution> solutions) const override {
return diagnose();
}

static IgnoreContextualType *create(ConstraintSystem &cs, Type resultTy,
Type specifiedTy,
ConstraintLocator *locator);
Expand Down Expand Up @@ -1479,11 +1499,17 @@ class AllowArgumentMismatch : public ContextualMismatch {
return "allow argument to parameter type conversion mismatch";
}

unsigned getParamIdx() const;

bool diagnose(bool asNote = false) const override;

static AllowArgumentMismatch *create(ConstraintSystem &cs, Type argType,
Type paramType,
ConstraintLocator *locator);

static bool classof(const ConstraintFix *fix) {
return fix->getKind() == FixKind::AllowArgumentTypeMismatch;
}
};

class ExpandArrayIntoVarargs final : public AllowArgumentMismatch {
Expand Down
Loading

0 comments on commit 355148d

Please sign in to comment.