@@ -212,6 +212,7 @@ class FailureDiagnostic {
212
212
// / Provides information about the application of a function argument to a
213
213
// / parameter.
214
214
class FunctionArgApplyInfo {
215
+ ConstraintSystem &CS;
215
216
Expr *ArgExpr;
216
217
unsigned ArgIdx;
217
218
Type ArgType;
@@ -223,11 +224,12 @@ class FunctionArgApplyInfo {
223
224
const ValueDecl *Callee;
224
225
225
226
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,
228
229
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) {}
231
233
232
234
// / \returns The argument being applied.
233
235
Expr *getArgExpr () const { return ArgExpr; }
@@ -247,6 +249,45 @@ class FunctionArgApplyInfo {
247
249
return withSpecifier ? ArgType : ArgType->getWithoutSpecifierType ();
248
250
}
249
251
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
+
250
291
// / \returns The interface type for the function being applied. Note that this
251
292
// / may not a function type, for example it could be a generic parameter.
252
293
Type getFnInterfaceType () const { return FnInterfaceType; }
@@ -1847,6 +1888,13 @@ class ArgumentMismatchFailure : public ContextualFailure {
1847
1888
return Info->getArgType (withSpecifier);
1848
1889
}
1849
1890
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
+
1850
1898
// / \returns The interface type for the function being applied.
1851
1899
Type getFnInterfaceType () const { return Info->getFnInterfaceType (); }
1852
1900
0 commit comments