Skip to content

Commit 3d10f33

Browse files
authored
Merge pull request swiftlang#28131 from xedin/remove-argument-matcher
[CSDiag] Remove obsolete `ArgumentMatcher` from `FailureDiagnosis`
2 parents cdaa3ba + c3acce4 commit 3d10f33

File tree

4 files changed

+24
-142
lines changed

4 files changed

+24
-142
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,134 +1915,6 @@ bool FailureDiagnosis::diagnoseImplicitSelfErrors(
19151915
return false;
19161916
}
19171917

1918-
class ArgumentMatcher : public MatchCallArgumentListener {
1919-
Expr *ArgExpr;
1920-
ArrayRef<AnyFunctionType::Param> &Parameters;
1921-
const ParameterListInfo &ParamInfo;
1922-
SmallVectorImpl<AnyFunctionType::Param> &Arguments;
1923-
1924-
CalleeCandidateInfo CandidateInfo;
1925-
1926-
// Indicates if problem has been found and diagnostic was emitted.
1927-
bool Diagnosed = false;
1928-
// Indicates if functions we are trying to call is a subscript.
1929-
bool IsSubscript;
1930-
1931-
// Stores parameter bindings determined by call to matchCallArguments.
1932-
SmallVector<ParamBinding, 4> Bindings;
1933-
1934-
public:
1935-
ArgumentMatcher(Expr *argExpr,
1936-
ArrayRef<AnyFunctionType::Param> &params,
1937-
const ParameterListInfo &paramInfo,
1938-
SmallVectorImpl<AnyFunctionType::Param> &args,
1939-
CalleeCandidateInfo &CCI, bool isSubscript)
1940-
: ArgExpr(argExpr), Parameters(params),
1941-
ParamInfo(paramInfo), Arguments(args), CandidateInfo(CCI),
1942-
IsSubscript(isSubscript) {}
1943-
1944-
bool outOfOrderArgument(unsigned argIdx, unsigned prevArgIdx) override {
1945-
auto &cs = CandidateInfo.CS;
1946-
OutOfOrderArgumentFailure failure(nullptr, cs, argIdx, prevArgIdx, Bindings,
1947-
cs.getConstraintLocator(ArgExpr));
1948-
Diagnosed = failure.diagnoseAsError();
1949-
return true;
1950-
}
1951-
1952-
bool relabelArguments(ArrayRef<Identifier> newNames) override {
1953-
assert(!newNames.empty() && "No arguments were re-labeled");
1954-
1955-
// Let's diagnose labeling problem but only related to corrected ones.
1956-
if (diagnoseArgumentLabelError(CandidateInfo.CS.getASTContext(), ArgExpr,
1957-
newNames, IsSubscript))
1958-
Diagnosed = true;
1959-
1960-
return true;
1961-
}
1962-
1963-
bool diagnose() {
1964-
// Use matchCallArguments to determine how close the argument list is (in
1965-
// shape) to the specified candidates parameters. This ignores the
1966-
// concrete types of the arguments, looking only at the argument labels.
1967-
matchCallArguments(Arguments, Parameters, ParamInfo,
1968-
CandidateInfo.hasTrailingClosure,
1969-
/*allowFixes:*/ true, *this, Bindings);
1970-
1971-
return Diagnosed;
1972-
}
1973-
};
1974-
1975-
/// Emit a class of diagnostics that we only know how to generate when
1976-
/// there is exactly one candidate we know about. Return true if an error
1977-
/// is emitted.
1978-
static bool
1979-
diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI, Expr *fnExpr,
1980-
Expr *argExpr,
1981-
ArrayRef<Identifier> argLabels) {
1982-
// We only handle the situation where there is exactly one candidate
1983-
// here.
1984-
if (CCI.size() != 1)
1985-
return false;
1986-
1987-
auto candidate = CCI[0];
1988-
1989-
if (!candidate.hasParameters())
1990-
return false;
1991-
1992-
auto params = candidate.getParameters();
1993-
auto paramInfo = candidate.getParameterListInfo(params);
1994-
auto args = decomposeArgType(CCI.CS.getType(argExpr), argLabels);
1995-
1996-
// Check the case where a raw-representable type is constructed from an
1997-
// argument with the same type:
1998-
//
1999-
// MyEnumType(MyEnumType.foo)
2000-
//
2001-
// This is missing 'rawValue:' label, but a better fix is to just remove
2002-
// the unnecessary constructor call:
2003-
//
2004-
// MyEnumType.foo
2005-
//
2006-
if (params.size() == 1 && args.size() == 1 && candidate.getDecl() &&
2007-
isa<ConstructorDecl>(candidate.getDecl()) && candidate.skipCurriedSelf) {
2008-
AnyFunctionType::Param &arg = args[0];
2009-
auto resTy =
2010-
candidate.getResultType()->lookThroughAllOptionalTypes();
2011-
auto rawTy = isRawRepresentable(CCI.CS, resTy);
2012-
if (rawTy && arg.getOldType() && resTy->isEqual(arg.getOldType())) {
2013-
auto getInnerExpr = [](Expr *E) -> Expr * {
2014-
auto *parenE = dyn_cast<ParenExpr>(E);
2015-
if (!parenE)
2016-
return nullptr;
2017-
return parenE->getSubExpr();
2018-
};
2019-
Expr *innerE = getInnerExpr(argExpr);
2020-
2021-
InFlightDiagnostic diag = CCI.CS.getASTContext().Diags.diagnose(
2022-
fnExpr->getLoc(),
2023-
diag::invalid_initialization_parameter_same_type, resTy);
2024-
diag.highlight((innerE ? innerE : argExpr)->getSourceRange());
2025-
if (innerE) {
2026-
// Remove the unnecessary constructor call.
2027-
diag.fixItRemoveChars(fnExpr->getLoc(), innerE->getStartLoc())
2028-
.fixItRemove(argExpr->getEndLoc());
2029-
}
2030-
return true;
2031-
}
2032-
}
2033-
2034-
// We only handle structural errors here.
2035-
if (CCI.closeness != CC_ArgumentLabelMismatch &&
2036-
CCI.closeness != CC_ArgumentCountMismatch)
2037-
return false;
2038-
2039-
// If we have a single candidate that failed to match the argument list,
2040-
// attempt to use matchCallArguments to diagnose the problem.
2041-
return ArgumentMatcher(argExpr, params, paramInfo, args, CCI,
2042-
isa<SubscriptExpr>(fnExpr))
2043-
.diagnose();
2044-
}
2045-
20461918
// Extract expression for failed argument number
20471919
static Expr *getFailedArgumentExpr(CalleeCandidateInfo CCI, Expr *argExpr) {
20481920
if (auto *TE = dyn_cast<TupleExpr>(argExpr))
@@ -2094,11 +1966,6 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
20941966
if (diagnoseImplicitSelfErrors(fnExpr, argExpr, CCI, argLabels))
20951967
return true;
20961968

2097-
// Do all the stuff that we only have implemented when there is a single
2098-
// candidate.
2099-
if (diagnoseSingleCandidateFailures(CCI, fnExpr, argExpr, argLabels))
2100-
return true;
2101-
21021969
// If we have a failure where the candidate set differs on exactly one
21031970
// argument, and where we have a consistent mismatch across the candidate set
21041971
// (often because there is only one candidate in the set), then diagnose this

lib/Sema/CSSimplify.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -930,23 +930,36 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
930930
}
931931

932932
auto *anchor = Locator.getBaseLocator()->getAnchor();
933-
if (!anchor || Arguments.size() != newLabels.size())
933+
if (!anchor)
934934
return true;
935935

936936
unsigned numExtraneous = 0;
937937
unsigned numRenames = 0;
938+
unsigned numOutOfOrder = 0;
939+
938940
for (unsigned i : indices(newLabels)) {
941+
// It's already known how many arguments are missing,
942+
// it would be accounted for in the impact.
943+
if (i >= Arguments.size())
944+
continue;
945+
939946
auto argLabel = Arguments[i].getLabel();
940947
auto paramLabel = newLabels[i];
941948

942949
if (argLabel == paramLabel)
943950
continue;
944951

945952
if (!argLabel.empty()) {
946-
if (paramLabel.empty())
953+
// Instead of this being a label mismatch which requires
954+
// re-labeling, this could be an out-of-order argument
955+
// instead which has a completely different impact.
956+
if (llvm::count(newLabels, argLabel) == 1) {
957+
++numOutOfOrder;
958+
} else if (paramLabel.empty()) {
947959
++numExtraneous;
948-
else
960+
} else {
949961
++numRenames;
962+
}
950963
}
951964
}
952965

@@ -955,8 +968,12 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
955968
// Re-labeling fixes with extraneous/incorrect labels should be
956969
// lower priority vs. other fixes on same/different overload(s)
957970
// where labels did line up correctly.
958-
CS.recordFix(fix, /*impact=*/1 + numExtraneous * 2 + numRenames * 3);
959-
return false;
971+
//
972+
// If there are not only labeling problems but also some of the
973+
// arguments are missing, let's account of that in the impact.
974+
auto impact = 1 + numOutOfOrder + numExtraneous * 2 + numRenames * 3 +
975+
NumSynthesizedArgs * 2;
976+
return CS.recordFix(fix, impact);
960977
}
961978

962979
bool trailingClosureMismatch(unsigned paramIdx, unsigned argIdx) override {

test/Constraints/diagnostics.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -931,12 +931,10 @@ func valueForKey<K>(_ key: K) -> CacheValue? {
931931
// SR-2242: poor diagnostic when argument label is omitted
932932

933933
func r27212391(x: Int, _ y: Int) {
934-
// expected-note@-1 {{candidate '(Int, Int) -> ()' requires 2 arguments, but 3 were provided}}
935934
let _: Int = x + y
936935
}
937936

938937
func r27212391(a: Int, x: Int, _ y: Int) {
939-
// expected-note@-1 {{incorrect labels for candidate (have: '(a:y:x:)', expected: '(a:x:_:)')}}
940938
let _: Int = a + x + y
941939
}
942940

@@ -948,7 +946,7 @@ r27212391(y: 3, 5) // expected-error {{incorrect argument label in call
948946
r27212391(x: 3, x: 5) // expected-error {{extraneous argument label 'x:' in call}}
949947
r27212391(a: 1, 3, y: 5) // expected-error {{incorrect argument labels in call (have 'a:_:y:', expected 'a:x:_:')}}
950948
r27212391(1, x: 3, y: 5) // expected-error {{incorrect argument labels in call (have '_:x:y:', expected 'a:x:_:')}}
951-
r27212391(a: 1, y: 3, x: 5) // expected-error {{no exact matches in call to global function 'r27212391'}}
949+
r27212391(a: 1, y: 3, x: 5) // expected-error {{incorrect argument labels in call (have 'a:y:x:', expected 'a:x:_:')}}
952950
r27212391(a: 1, 3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #2}} {{17-17=x: 5, }} {{18-24=}}
953951

954952
// SR-1255

test/expr/expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ var ruleVar: Rule
602602
// FIXME(diagnostics): To be able to suggest different candidates here we need to teach the solver how to figure out to which parameter
603603
// does argument belong to in this case. If the `target` was of a different type, we currently suggest to add an argument for `dependencies:`
604604
// which is incorrect.
605-
ruleVar = Rule("a") // expected-error {{cannot convert value of type 'String' to expected argument type '(target: String, dependencies: String)'}}
605+
ruleVar = Rule("a") // expected-error {{missing argument label 'target:' in call}}
606606

607607

608608
class C {

0 commit comments

Comments
 (0)