Skip to content

Commit b3590c5

Browse files
authored
Merge pull request #29734 from LucianoPAlmeida/remove-diag-parameters-errors
[Diagnostics] Remove `FailureDiagnosis::diagnoseParameterErrors` from CSDiag
2 parents 988e9d6 + 46092af commit b3590c5

File tree

4 files changed

+68
-88
lines changed

4 files changed

+68
-88
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,6 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
182182
return type;
183183
}
184184

185-
/// Diagnose common failures due to applications of an argument list to an
186-
/// ApplyExpr or SubscriptExpr.
187-
bool diagnoseParameterErrors(CalleeCandidateInfo &CCI,
188-
Expr *fnExpr, Expr *argExpr,
189-
ArrayRef<Identifier> argLabels);
190-
191185
/// Attempt to diagnose a specific failure from the info we've collected from
192186
/// the failed constraint system.
193187
bool diagnoseExprFailure();
@@ -918,48 +912,6 @@ static Expr *getFailedArgumentExpr(CalleeCandidateInfo CCI, Expr *argExpr) {
918912
}
919913
}
920914

921-
/// If the candidate set has been narrowed down to a specific structural
922-
/// problem, e.g. that there are too few parameters specified or that argument
923-
/// labels don't match up, diagnose that error and return true.
924-
bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
925-
Expr *fnExpr, Expr *argExpr,
926-
ArrayRef<Identifier> argLabels) {
927-
// If we have a failure where the candidate set differs on exactly one
928-
// argument, and where we have a consistent mismatch across the candidate set
929-
// (often because there is only one candidate in the set), then diagnose this
930-
// as a specific problem of passing something of the wrong type into a
931-
// parameter.
932-
//
933-
// We don't generally want to use this path to diagnose calls to
934-
// symmetrically-typed binary operators because it's likely that both
935-
// operands contributed to the type.
936-
if ((CCI.closeness == CC_OneArgumentMismatch ||
937-
CCI.closeness == CC_OneArgumentNearMismatch ||
938-
CCI.closeness == CC_OneGenericArgumentMismatch ||
939-
CCI.closeness == CC_OneGenericArgumentNearMismatch ||
940-
CCI.closeness == CC_GenericNonsubstitutableMismatch) &&
941-
CCI.failedArgument.isValid() &&
942-
!isSymmetricBinaryOperator(CCI)) {
943-
// Map the argument number into an argument expression.
944-
TCCOptions options = TCC_ForceRecheck;
945-
if (CCI.failedArgument.parameterType->is<InOutType>())
946-
options |= TCC_AllowLValue;
947-
948-
// It could be that the argument doesn't conform to an archetype.
949-
Expr *badArgExpr = getFailedArgumentExpr(CCI, argExpr);
950-
951-
// Re-type-check the argument with the expected type of the candidate set.
952-
// This should produce a specific and tailored diagnostic saying that the
953-
// type mismatches with expectations.
954-
Type paramType = CCI.failedArgument.parameterType;
955-
if (!typeCheckChildIndependently(badArgExpr, paramType,
956-
CTP_CallArgument, options))
957-
return true;
958-
}
959-
960-
return false;
961-
}
962-
963915
bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
964916
auto *fnExpr = callExpr->getFn();
965917
auto fnType = CS.getType(fnExpr)->getRValueType();
@@ -997,9 +949,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
997949
SmallVector<Identifier, 2> argLabelsScratch;
998950
ArrayRef<Identifier> argLabels =
999951
callExpr->getArgumentLabels(argLabelsScratch);
1000-
if (diagnoseParameterErrors(calleeInfo, callExpr->getFn(),
1001-
callExpr->getArg(), argLabels))
1002-
return true;
1003952

1004953
Type argType; // argument list, if known.
1005954
if (auto FTy = fnType->getAs<AnyFunctionType>()) {
@@ -1025,10 +974,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
1025974

1026975
calleeInfo.filterListArgs(decomposeArgType(CS.getType(argExpr), argLabels));
1027976

1028-
if (diagnoseParameterErrors(calleeInfo, callExpr->getFn(), argExpr,
1029-
argLabels))
1030-
return true;
1031-
1032977
// Force recheck of the arg expression because we allowed unresolved types
1033978
// before, and that turned out not to help, and now we want any diagnoses
1034979
// from disallowing them.

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3072,23 +3072,16 @@ bool ConstraintSystem::repairFailures(
30723072
auto elt = path.back();
30733073
switch (elt.getKind()) {
30743074
case ConstraintLocator::LValueConversion: {
3075-
auto CTP = getContextualTypePurpose(anchor);
3076-
// Special case for `CTP_CallArgument` set by CSDiag
3077-
// while type-checking each argument because we yet
3078-
// to cover argument-to-parameter conversions in the
3079-
// new framework.
3080-
if (CTP != CTP_CallArgument) {
3081-
// Ignore l-value conversion element since it has already
3082-
// played its role.
3083-
path.pop_back();
3084-
// If this is a contextual mismatch between l-value types e.g.
3085-
// `@lvalue String vs. @lvalue Int`, let's pretend that it's okay.
3086-
if (!path.empty() && path.back().is<LocatorPathElt::ContextualType>()) {
3087-
auto *locator = getConstraintLocator(anchor, path.back());
3088-
conversionsOrFixes.push_back(
3089-
IgnoreContextualType::create(*this, lhs, rhs, locator));
3090-
break;
3091-
}
3075+
// Ignore l-value conversion element since it has already
3076+
// played its role.
3077+
path.pop_back();
3078+
// If this is a contextual mismatch between l-value types e.g.
3079+
// `@lvalue String vs. @lvalue Int`, let's pretend that it's okay.
3080+
if (!path.empty() && path.back().is<LocatorPathElt::ContextualType>()) {
3081+
auto *locator = getConstraintLocator(anchor, path.back());
3082+
conversionsOrFixes.push_back(
3083+
IgnoreContextualType::create(*this, lhs, rhs, locator));
3084+
break;
30923085
}
30933086

30943087
LLVM_FALLTHROUGH;
@@ -3521,13 +3514,6 @@ bool ConstraintSystem::repairFailures(
35213514
if (rhs->isExistentialType())
35223515
break;
35233516

3524-
// TODO(diagnostics): This is a problem related to `inout` mismatch,
3525-
// in argument position, and we got here from CSDiag. Once
3526-
// argument-to-pararameter conversion failures are implemented,
3527-
// this check could be removed.
3528-
if (lhs->is<InOutType>() || rhs->is<InOutType>())
3529-
break;
3530-
35313517
if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes,
35323518
locator))
35333519
break;

lib/Sema/ConstraintSystem.cpp

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,6 +2765,9 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
27652765
ParameterList,
27662766
/// General ambiguity failure.
27672767
General,
2768+
/// Argument mismatch ambiguity where each solution has the same
2769+
/// argument mismatch fixes for the same call.
2770+
ArgumentMismatch
27682771
};
27692772
auto ambiguityKind = AmbiguityKind::CloseMatch;
27702773

@@ -2775,16 +2778,52 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
27752778
return false;
27762779

27772780
if (fixes.size() > 1) {
2778-
ambiguityKind = (ambiguityKind == AmbiguityKind::CloseMatch ||
2779-
ambiguityKind == AmbiguityKind::ParameterList) &&
2781+
// Attempt to disambiguite in cases where the argument matches
2782+
// involves tuple mismatches. e.g.
2783+
// func t<T, U>(_: (T, U), _: (U, T)) {}
2784+
// func useTuples(_ x: Int, y: Float) {
2785+
// t((x, y), (x, y))
2786+
// }
2787+
// So fixes are ambiguous in all solutions.
2788+
if ((ambiguityKind == AmbiguityKind::CloseMatch ||
2789+
ambiguityKind == AmbiguityKind::ArgumentMismatch) &&
27802790
llvm::all_of(fixes, [](const ConstraintFix *fix) -> bool {
2781-
auto *locator = fix->getLocator();
2782-
return locator->findLast<LocatorPathElt::ApplyArgument>().hasValue();
2783-
}) ? AmbiguityKind::ParameterList
2784-
: AmbiguityKind::General;
2791+
return fix->getKind() == FixKind::AllowTupleTypeMismatch;
2792+
})) {
2793+
ambiguityKind = AmbiguityKind::ArgumentMismatch;
2794+
} else {
2795+
ambiguityKind =
2796+
(ambiguityKind == AmbiguityKind::CloseMatch ||
2797+
ambiguityKind == AmbiguityKind::ArgumentMismatch ||
2798+
ambiguityKind == AmbiguityKind::ParameterList) &&
2799+
llvm::all_of(
2800+
fixes,
2801+
[](const ConstraintFix *fix) -> bool {
2802+
auto *locator = fix->getLocator();
2803+
return locator
2804+
->findLast<LocatorPathElt::ApplyArgument>()
2805+
.hasValue();
2806+
})
2807+
? AmbiguityKind::ParameterList
2808+
: AmbiguityKind::General;
2809+
}
2810+
}
2811+
2812+
if (fixes.size() == 1) {
2813+
// Attempt to disambiguite in cases where all the solutions
2814+
// produces the same fixes for different generic arguments e.g.
2815+
// func f<T>(_: T, _: T) {}
2816+
// f(Int(1), Float(1))
2817+
//
2818+
ambiguityKind =
2819+
((ambiguityKind == AmbiguityKind::CloseMatch ||
2820+
ambiguityKind == AmbiguityKind::ArgumentMismatch) &&
2821+
fixes.front()->getKind() == FixKind::AllowArgumentTypeMismatch)
2822+
? AmbiguityKind::ArgumentMismatch
2823+
: AmbiguityKind::CloseMatch;
27852824
}
27862825

2787-
for (const auto *fix: fixes) {
2826+
for (const auto *fix : fixes) {
27882827
auto *locator = fix->getLocator();
27892828
// Assignment failures are all about the source expression,
27902829
// because they treat destination as a contextual type.
@@ -2816,6 +2855,15 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
28162855
return true;
28172856
});
28182857

2858+
if (ambiguityKind == AmbiguityKind::ArgumentMismatch &&
2859+
viableSolutions.size() == 1) {
2860+
// Let's apply the solution so the contextual generic types
2861+
// are available in the system for diagnostics.
2862+
applySolution(*viableSolutions[0]);
2863+
solutions.front().Fixes.front()->diagnose(/*asNote*/ false);
2864+
return true;
2865+
}
2866+
28192867
if (!diagnosable || viableSolutions.size() < 2)
28202868
return false;
28212869

@@ -2860,6 +2908,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
28602908
};
28612909

28622910
switch (ambiguityKind) {
2911+
case AmbiguityKind::ArgumentMismatch:
28632912
case AmbiguityKind::CloseMatch:
28642913
// Handled below
28652914
break;

test/type/opaque.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,10 @@ func associatedTypeIdentity() {
270270

271271
sameType(cr, c.r_out())
272272
sameType(dr, d.r_out())
273-
sameType(cr, dr) // expected-error{{}} expected-note {{}}
273+
sameType(cr, dr) // expected-error {{cannot convert value of type '(some opaque.R).S' (associated type of protocol 'R') to expected argument type '(some opaque.R).S' (associated type of protocol 'R')}}
274274
sameType(gary(candace()).r_out(), gary(candace()).r_out())
275275
sameType(gary(doug()).r_out(), gary(doug()).r_out())
276-
sameType(gary(doug()).r_out(), gary(candace()).r_out()) // expected-error{{}} expected-note {{}}
276+
sameType(gary(doug()).r_out(), gary(candace()).r_out()) // expected-error {{cannot convert value of type 'some R' (result of 'candace()') to expected argument type 'some R' (result of 'doug()')}}
277277
}
278278

279279
func redeclaration() -> some P { return 0 } // expected-note 2{{previously declared}}

0 commit comments

Comments
 (0)