@@ -6069,7 +6069,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6069
6069
return true ;
6070
6070
}
6071
6071
6072
- auto argumentTy = candidateInfo[0 ].getArgumentType ();
6072
+ auto candidateArgTy = candidateInfo[0 ].getArgumentType ();
6073
6073
6074
6074
// Depending on how we matched, produce tailored diagnostics.
6075
6075
switch (candidateInfo.closeness ) {
@@ -6088,9 +6088,9 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6088
6088
case CC_ExactMatch: { // This is a perfect match for the arguments.
6089
6089
6090
6090
// If we have an exact match, then we must have an argument list, check it.
6091
- if (argumentTy ) {
6091
+ if (candidateArgTy ) {
6092
6092
assert (E->getArgument () && " Exact match without argument?" );
6093
- if (!typeCheckArgumentChildIndependently (E->getArgument (), argumentTy ,
6093
+ if (!typeCheckArgumentChildIndependently (E->getArgument (), candidateArgTy ,
6094
6094
candidateInfo))
6095
6095
return true ;
6096
6096
}
@@ -6124,16 +6124,16 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6124
6124
6125
6125
case CC_ArgumentLabelMismatch: { // Argument labels are not correct.
6126
6126
auto argExpr = typeCheckArgumentChildIndependently (E->getArgument (),
6127
- argumentTy ,
6127
+ candidateArgTy ,
6128
6128
candidateInfo);
6129
6129
if (!argExpr) return true ;
6130
6130
6131
6131
// Construct the actual expected argument labels that our candidate
6132
6132
// expected.
6133
- assert (argumentTy &&
6133
+ assert (candidateArgTy &&
6134
6134
" Candidate must expect an argument to have a label mismatch" );
6135
6135
SmallVector<Identifier, 2 > argLabelsScratch;
6136
- auto arguments = decomposeArgType (argumentTy ,
6136
+ auto arguments = decomposeArgType (candidateArgTy ,
6137
6137
candidateInfo[0 ].getArgumentLabels (
6138
6138
argLabelsScratch));
6139
6139
@@ -6151,26 +6151,40 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
6151
6151
case CC_ArgumentCountMismatch: // This candidate has wrong # arguments.
6152
6152
// If we have no argument, the candidates must have expected one.
6153
6153
if (!E->getArgument ()) {
6154
- if (!argumentTy )
6154
+ if (!candidateArgTy )
6155
6155
return false ; // Candidate must be incorrect for some other reason.
6156
6156
6157
6157
// Pick one of the arguments that are expected as an exemplar.
6158
- diagnose (E->getNameLoc (), diag::expected_argument_in_contextual_member,
6159
- E->getName (), argumentTy);
6158
+ if (candidateArgTy->isVoid ()) {
6159
+ // If this member is () -> T, suggest adding parentheses.
6160
+ diagnose (E->getNameLoc (), diag::expected_parens_in_contextual_member,
6161
+ E->getName ())
6162
+ .fixItInsertAfter (E->getEndLoc (), " ()" );
6163
+ } else {
6164
+ diagnose (E->getNameLoc (), diag::expected_argument_in_contextual_member,
6165
+ E->getName (), candidateArgTy);
6166
+ }
6160
6167
return true ;
6161
6168
}
6162
6169
6163
- // If an argument value was specified, but this is a simple enumerator, then
6164
- // we fail with a nice error message.
6165
- auto argTy = candidateInfo[0 ].getArgumentType ();
6166
- if (!argTy) {
6167
- diagnose (E->getNameLoc (), diag::unexpected_argument_in_contextual_member,
6168
- E->getName ());
6170
+ // If an argument value was specified, but this member expects no arguments,
6171
+ // then we fail with a nice error message.
6172
+ if (!candidateArgTy) {
6173
+ if (E->getArgument ()->getType ()->isVoid ()) {
6174
+ diagnose (E->getNameLoc (), diag::unexpected_parens_in_contextual_member,
6175
+ E->getName ())
6176
+ .fixItRemove (E->getArgument ()->getSourceRange ());
6177
+ } else {
6178
+ diagnose (E->getNameLoc (), diag::unexpected_argument_in_contextual_member,
6179
+ E->getName ())
6180
+ .highlight (E->getArgument ()->getSourceRange ());
6181
+ }
6169
6182
return true ;
6170
6183
}
6171
6184
6172
- assert (E->getArgument () && argTy && " Exact match without an argument?" );
6173
- return !typeCheckArgumentChildIndependently (E->getArgument (), argTy,
6185
+ assert (E->getArgument () && candidateArgTy &&
6186
+ " Exact match without an argument?" );
6187
+ return !typeCheckArgumentChildIndependently (E->getArgument (), candidateArgTy,
6174
6188
candidateInfo);
6175
6189
}
6176
6190
0 commit comments