Skip to content

Commit 912a7ac

Browse files
committed
Add FunctionArgApplyInfo::getArgDescription
This commit adds a member which produces a string describing the argument being applied. This will either be its argument label or position in the argument list.
1 parent 398cb58 commit 912a7ac

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
286286
auto argIdx = applyArgElt->getArgIdx();
287287
auto paramIdx = applyArgElt->getParamIdx();
288288

289-
return FunctionArgApplyInfo(argExpr, argIdx, getType(argExpr), paramIdx,
290-
fnInterfaceType, fnType, callee);
289+
return FunctionArgApplyInfo(cs, argExpr, argIdx, getType(argExpr),
290+
paramIdx, fnInterfaceType, fnType, callee);
291291
}
292292

293293
Type FailureDiagnostic::restoreGenericParameters(

lib/Sema/CSDiagnostics.h

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ class FailureDiagnostic {
212212
/// Provides information about the application of a function argument to a
213213
/// parameter.
214214
class FunctionArgApplyInfo {
215+
ConstraintSystem &CS;
215216
Expr *ArgExpr;
216217
unsigned ArgIdx;
217218
Type ArgType;
@@ -223,11 +224,12 @@ class FunctionArgApplyInfo {
223224
const ValueDecl *Callee;
224225

225226
public:
226-
FunctionArgApplyInfo(Expr *argExpr, unsigned argIdx, Type argType,
227-
unsigned paramIdx, Type fnInterfaceType,
227+
FunctionArgApplyInfo(ConstraintSystem &cs, Expr *argExpr, unsigned argIdx,
228+
Type argType, unsigned paramIdx, Type fnInterfaceType,
228229
FunctionType *fnType, const ValueDecl *callee)
229-
: ArgExpr(argExpr), ArgIdx(argIdx), ArgType(argType), ParamIdx(paramIdx),
230-
FnInterfaceType(fnInterfaceType), FnType(fnType), Callee(callee) {}
230+
: CS(cs), ArgExpr(argExpr), ArgIdx(argIdx), ArgType(argType),
231+
ParamIdx(paramIdx), FnInterfaceType(fnInterfaceType), FnType(fnType),
232+
Callee(callee) {}
231233

232234
/// \returns The argument being applied.
233235
Expr *getArgExpr() const { return ArgExpr; }
@@ -247,6 +249,45 @@ class FunctionArgApplyInfo {
247249
return withSpecifier ? ArgType : ArgType->getWithoutSpecifierType();
248250
}
249251

252+
/// \returns The label for the argument being applied.
253+
Identifier getArgLabel() const {
254+
auto *parent = CS.getParentExpr(ArgExpr);
255+
if (auto *te = dyn_cast<TupleExpr>(parent))
256+
return te->getElementName(ArgIdx);
257+
258+
assert(isa<ParenExpr>(parent));
259+
return Identifier();
260+
}
261+
262+
/// \returns A textual description of the argument suitable for diagnostics.
263+
/// For an argument with an unambiguous label, this will the label. Otherwise
264+
/// it will be its position in the argument list.
265+
StringRef getArgDescription(SmallVectorImpl<char> &scratch) const {
266+
llvm::raw_svector_ostream stream(scratch);
267+
268+
// Use the argument label only if it's unique within the argument list.
269+
auto argLabel = getArgLabel();
270+
auto useArgLabel = [&]() -> bool {
271+
if (argLabel.empty())
272+
return false;
273+
274+
if (auto *te = dyn_cast<TupleExpr>(CS.getParentExpr(ArgExpr)))
275+
return llvm::count(te->getElementNames(), argLabel) == 1;
276+
277+
return false;
278+
};
279+
280+
if (useArgLabel()) {
281+
stream << "'";
282+
stream << argLabel;
283+
stream << "'";
284+
} else {
285+
stream << "#";
286+
stream << getArgPosition();
287+
}
288+
return StringRef(scratch.data(), scratch.size());
289+
}
290+
250291
/// \returns The interface type for the function being applied. Note that this
251292
/// may not a function type, for example it could be a generic parameter.
252293
Type getFnInterfaceType() const { return FnInterfaceType; }
@@ -1847,6 +1888,13 @@ class ArgumentMismatchFailure : public ContextualFailure {
18471888
return Info->getArgType(withSpecifier);
18481889
}
18491890

1891+
/// \returns A textual description of the argument suitable for diagnostics.
1892+
/// For an argument with an unambiguous label, this will the label. Otherwise
1893+
/// it will be its position in the argument list.
1894+
StringRef getArgDescription(SmallVectorImpl<char> &scratch) const {
1895+
return Info->getArgDescription(scratch);
1896+
}
1897+
18501898
/// \returns The interface type for the function being applied.
18511899
Type getFnInterfaceType() const { return Info->getFnInterfaceType(); }
18521900

0 commit comments

Comments
 (0)