@@ -212,6 +212,7 @@ class FailureDiagnostic {
212212// / Provides information about the application of a function argument to a
213213// / parameter.
214214class FunctionArgApplyInfo {
215+ ConstraintSystem &CS;
215216 Expr *ArgExpr;
216217 unsigned ArgIdx;
217218 Type ArgType;
@@ -223,11 +224,12 @@ class FunctionArgApplyInfo {
223224 const ValueDecl *Callee;
224225
225226public:
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