@@ -6049,7 +6049,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6049
6049
return true ;
6050
6050
}
6051
6051
6052
- auto argumentTy = candidateInfo[0 ].getArgumentType ();
6052
+ auto candidateArgTy = candidateInfo[0 ].getArgumentType ();
6053
6053
6054
6054
// Depending on how we matched, produce tailored diagnostics.
6055
6055
switch (candidateInfo.closeness ) {
@@ -6068,9 +6068,9 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6068
6068
case CC_ExactMatch: { // This is a perfect match for the arguments.
6069
6069
6070
6070
// If we have an exact match, then we must have an argument list, check it.
6071
- if (argumentTy ) {
6071
+ if (candidateArgTy ) {
6072
6072
assert (E->getArgument () && " Exact match without argument?" );
6073
- if (!typeCheckArgumentChildIndependently (E->getArgument (), argumentTy ,
6073
+ if (!typeCheckArgumentChildIndependently (E->getArgument (), candidateArgTy ,
6074
6074
candidateInfo))
6075
6075
return true ;
6076
6076
}
@@ -6104,16 +6104,16 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6104
6104
6105
6105
case CC_ArgumentLabelMismatch: { // Argument labels are not correct.
6106
6106
auto argExpr = typeCheckArgumentChildIndependently (E->getArgument (),
6107
- argumentTy ,
6107
+ candidateArgTy ,
6108
6108
candidateInfo);
6109
6109
if (!argExpr) return true ;
6110
6110
6111
6111
// Construct the actual expected argument labels that our candidate
6112
6112
// expected.
6113
- assert (argumentTy &&
6113
+ assert (candidateArgTy &&
6114
6114
" Candidate must expect an argument to have a label mismatch" );
6115
6115
SmallVector<Identifier, 2 > argLabelsScratch;
6116
- auto arguments = decomposeArgType (argumentTy ,
6116
+ auto arguments = decomposeArgType (candidateArgTy ,
6117
6117
candidateInfo[0 ].getArgumentLabels (
6118
6118
argLabelsScratch));
6119
6119
@@ -6131,26 +6131,40 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6131
6131
case CC_ArgumentCountMismatch: // This candidate has wrong # arguments.
6132
6132
// If we have no argument, the candidates must have expected one.
6133
6133
if (!E->getArgument ()) {
6134
- if (!argumentTy )
6134
+ if (!candidateArgTy )
6135
6135
return false ; // Candidate must be incorrect for some other reason.
6136
6136
6137
6137
// Pick one of the arguments that are expected as an exemplar.
6138
- diagnose (E->getNameLoc (), diag::expected_argument_in_contextual_member,
6139
- E->getName (), argumentTy);
6138
+ if (candidateArgTy->isVoid ()) {
6139
+ // If this member is () -> T, suggest adding parentheses.
6140
+ diagnose (E->getNameLoc (), diag::expected_parens_in_contextual_member,
6141
+ E->getName ())
6142
+ .fixItInsertAfter (E->getEndLoc (), " ()" );
6143
+ } else {
6144
+ diagnose (E->getNameLoc (), diag::expected_argument_in_contextual_member,
6145
+ E->getName (), candidateArgTy);
6146
+ }
6140
6147
return true ;
6141
6148
}
6142
6149
6143
- // If an argument value was specified, but this is a simple enumerator, then
6144
- // we fail with a nice error message.
6145
- auto argTy = candidateInfo[0 ].getArgumentType ();
6146
- if (!argTy) {
6147
- diagnose (E->getNameLoc (), diag::unexpected_argument_in_contextual_member,
6148
- E->getName ());
6150
+ // If an argument value was specified, but this member expects no arguments,
6151
+ // then we fail with a nice error message.
6152
+ if (!candidateArgTy) {
6153
+ if (E->getArgument ()->getType ()->isVoid ()) {
6154
+ diagnose (E->getNameLoc (), diag::unexpected_parens_in_contextual_member,
6155
+ E->getName ())
6156
+ .fixItRemove (E->getArgument ()->getSourceRange ());
6157
+ } else {
6158
+ diagnose (E->getNameLoc (), diag::unexpected_argument_in_contextual_member,
6159
+ E->getName ())
6160
+ .highlight (E->getArgument ()->getSourceRange ());
6161
+ }
6149
6162
return true ;
6150
6163
}
6151
6164
6152
- assert (E->getArgument () && argTy && " Exact match without an argument?" );
6153
- return !typeCheckArgumentChildIndependently (E->getArgument (), argTy,
6165
+ assert (E->getArgument () && candidateArgTy &&
6166
+ " Exact match without an argument?" );
6167
+ return !typeCheckArgumentChildIndependently (E->getArgument (), candidateArgTy,
6154
6168
candidateInfo);
6155
6169
}
6156
6170
0 commit comments