[CSDiagnostics] Adapt diagnostics to handle new CoercionOperand elt

This commit is contained in:
Luciano Almeida
2023-03-11 11:08:54 -03:00
parent a93eff131c
commit 5fee07b73f
3 changed files with 79 additions and 39 deletions

View File

@@ -786,7 +786,8 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
//
// `value` has to get implicitly wrapped into 2 optionals
// before pointer types could be compared.
auto path = getLocator()->getPath();
auto locator = getLocator();
auto path = locator->getPath();
unsigned toDrop = 0;
for (const auto &elt : llvm::reverse(path)) {
if (!elt.is<LocatorPathElt::OptionalPayload>())
@@ -802,7 +803,7 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
if (path.empty()) {
if (isExpr<AssignExpr>(anchor)) {
diagnostic = getDiagnosticFor(CTP_AssignSource);
} else if (isExpr<CoerceExpr>(anchor)) {
} else if (locator->isForCoercion()) {
diagnostic = getDiagnosticFor(CTP_CoerceOperand);
} else {
return false;
@@ -887,6 +888,11 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
break;
}
case ConstraintLocator::CoercionOperand: {
diagnostic = getDiagnosticFor(CTP_CoerceOperand);
break;
}
default:
break;
}
@@ -1222,17 +1228,18 @@ ASTNode InvalidCoercionFailure::getAnchor() const {
bool InvalidCoercionFailure::diagnoseAsError() {
auto fromType = getFromType();
auto toType = getToType();
auto *CE = getAsExpr<CoerceExpr>(getRawAnchor());
emitDiagnostic(diag::cannot_coerce_to_type, fromType, toType);
if (UseConditionalCast) {
emitDiagnostic(diag::missing_optional_downcast)
.highlight(getSourceRange())
.fixItReplace(getLoc(), "as?");
.highlight(CE->getSourceRange())
.fixItReplace(CE->getAsLoc(), "as?");
} else {
emitDiagnostic(diag::missing_forced_downcast)
.highlight(getSourceRange())
.fixItReplace(getLoc(), "as!");
.highlight(CE->getSourceRange())
.fixItReplace(CE->getAsLoc(), "as!");
}
return true;
@@ -2487,7 +2494,7 @@ bool ContextualFailure::diagnoseAsError() {
diagnostic = diag::cannot_convert_condition_value;
break;
}
case ConstraintLocator::CoercionOperand:
case ConstraintLocator::InstanceType: {
if (diagnoseCoercionToUnrelatedType())
return true;
@@ -2655,7 +2662,7 @@ bool ContextualFailure::diagnoseAsError() {
}
bool ContextualFailure::diagnoseAsNote() {
auto *locator = getLocator();
auto *locator = getAmbiguityLocator();
auto overload = getCalleeOverloadChoiceIfAvailable(locator);
if (!(overload && overload->choice.isDecl()))
@@ -2809,7 +2816,7 @@ bool ContextualFailure::diagnoseConversionToNil() const {
emitDiagnostic(diag::unresolved_nil_literal);
return true;
}
} else if (isa<CoerceExpr>(parentExpr)) {
} else if (locator->isForCoercion()) {
// `nil` is passed as a left-hand side of the coercion
// operator e.g. `nil as Foo`
CTP = CTP_CoerceOperand;
@@ -2891,23 +2898,23 @@ bool ContextualFailure::diagnoseExtraneousAssociatedValues() const {
}
bool ContextualFailure::diagnoseCoercionToUnrelatedType() const {
auto anchor = getAnchor();
if (auto *coerceExpr = getAsExpr<CoerceExpr>(anchor)) {
const auto fromType = getType(coerceExpr->getSubExpr());
const auto toType = getType(coerceExpr->getCastTypeRepr());
auto diagnostic = getDiagnosticFor(CTP_CoerceOperand, toType);
auto diag = emitDiagnostic(*diagnostic, fromType, toType);
diag.highlight(getSourceRange());
(void)tryFixIts(diag);
return true;
auto anchor = getRawAnchor();
auto *coerceExpr = getAsExpr<CoerceExpr>(anchor);
if (!coerceExpr) {
return false;
}
return false;
const auto fromType = getType(coerceExpr->getSubExpr());
const auto toType = getType(coerceExpr->getCastTypeRepr());
auto diagnostic = getDiagnosticFor(CTP_CoerceOperand, toType);
auto diag = emitDiagnostic(*diagnostic, fromType, toType);
diag.highlight(getSourceRange());
(void)tryFixIts(diag);
return true;
}
bool ContextualFailure::diagnoseConversionToBool() const {
@@ -3178,9 +3185,6 @@ bool ContextualFailure::trySequenceSubsequenceFixIts(
if (getFromType()->isSubstring()) {
if (getToType()->isString()) {
auto *anchor = castToExpr(getAnchor())->getSemanticsProvidingExpr();
if (auto *CE = dyn_cast<CoerceExpr>(anchor)) {
anchor = CE->getSubExpr();
}
if (auto *call = dyn_cast<CallExpr>(anchor)) {
auto *fnExpr = call->getFn();
@@ -4927,7 +4931,7 @@ bool MissingArgumentsFailure::diagnoseAsError() {
}
bool MissingArgumentsFailure::diagnoseAsNote() {
auto *locator = getLocator();
auto *locator = getAmbiguityLocator();
if (auto overload = getCalleeOverloadChoiceIfAvailable(locator)) {
auto *fn = resolveType(overload->adjustedOpenedType)->getAs<AnyFunctionType>();
auto loc = overload->choice.getDecl()->getLoc();
@@ -5729,7 +5733,7 @@ bool ExtraneousArgumentsFailure::diagnoseAsError() {
}
bool ExtraneousArgumentsFailure::diagnoseAsNote() {
auto overload = getCalleeOverloadChoiceIfAvailable(getLocator());
auto overload = getCalleeOverloadChoiceIfAvailable(getAmbiguityLocator());
if (!(overload && overload->choice.isDecl()))
return false;
@@ -5741,7 +5745,7 @@ bool ExtraneousArgumentsFailure::diagnoseAsNote() {
(numArgs == 1));
} else {
emitDiagnosticAt(decl, diag::candidate_with_extraneous_args,
decl->getInterfaceType(), numArgs, ContextualType,
overload->adjustedOpenedType, numArgs, ContextualType,
ContextualType->getNumParams());
}
return true;
@@ -8758,12 +8762,7 @@ GlobalActorFunctionMismatchFailure::getDiagnosticMessage() const {
auto path = locator->getPath();
if (path.empty()) {
auto anchor = getAnchor();
if (isExpr<CoerceExpr>(anchor)) {
return diag::cannot_convert_global_actor_coercion;
} else {
return diag::cannot_convert_global_actor;
}
return diag::cannot_convert_global_actor;
}
auto last = path.back();
@@ -8781,6 +8780,9 @@ GlobalActorFunctionMismatchFailure::getDiagnosticMessage() const {
case ConstraintLocator::TernaryBranch: {
return diag::ternary_expr_cases_global_actor_mismatch;
}
case ConstraintLocator::CoercionOperand: {
return diag::cannot_convert_global_actor_coercion;
}
default:
break;
}