@@ -186,27 +186,31 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
186
186
status |= makeParserCodeCompletionStatus ();
187
187
}
188
188
}
189
+
189
190
// ('inout' | 'let' | 'var')?
190
- if (Tok.is (tok::kw_inout)) {
191
- param.LetVarInOutLoc = consumeToken ();
192
- param.SpecifierKind = ParsedParameter::InOut;
193
- } else if (Tok.is (tok::kw_let)) {
194
- param.LetVarInOutLoc = consumeToken ();
195
- param.SpecifierKind = ParsedParameter::Let;
196
- } else if (Tok.is (tok::kw_var)) {
197
- diagnose (Tok.getLoc (), diag::var_parameter_not_allowed)
198
- .fixItRemove (Tok.getLoc ());
199
- param.LetVarInOutLoc = consumeToken ();
200
- param.SpecifierKind = ParsedParameter::Var;
201
- }
202
-
203
- // Redundant specifiers are fairly common, recognize, reject, and recover
204
- // from this gracefully.
205
- if (Tok.isAny (tok::kw_inout, tok::kw_let, tok::kw_var)) {
206
- diagnose (Tok, diag::parameter_inout_var_let)
191
+ bool hasSpecifier = false ;
192
+ while (Tok.isAny (tok::kw_inout, tok::kw_let, tok::kw_var)) {
193
+ if (!hasSpecifier) {
194
+ if (Tok.is (tok::kw_let)) {
195
+ diagnose (Tok, diag::parameter_let_as_attr)
196
+ .fixItRemove (Tok.getLoc ());
197
+ param.isInvalid = true ;
198
+ } else {
199
+ // We handle the var error in sema for a better fixit and inout is
200
+ // handled later in this function for better fixits.
201
+ param.SpecifierKind = Tok.is (tok::kw_inout) ? ParsedParameter::InOut :
202
+ ParsedParameter::Var;
203
+ }
204
+ param.LetVarInOutLoc = consumeToken ();
205
+ hasSpecifier = true ;
206
+ } else {
207
+ // Redundant specifiers are fairly common, recognize, reject, and recover
208
+ // from this gracefully.
209
+ diagnose (Tok, diag::parameter_inout_var_let_repeated)
207
210
.fixItRemove (Tok.getLoc ());
208
- consumeToken ();
209
- param.isInvalid = true ;
211
+ consumeToken ();
212
+ param.isInvalid = true ;
213
+ }
210
214
}
211
215
212
216
if (startsParameterName (*this , isClosure)) {
@@ -248,20 +252,28 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
248
252
249
253
bool hasDeprecatedInOut =
250
254
param.SpecifierKind == ParsedParameter::InOut;
251
-
252
- if (Tok.is (tok::kw_inout)) {
253
- param.LetVarInOutLoc = consumeToken ();
254
- param.SpecifierKind = ParsedParameter::InOut;
255
- if (hasDeprecatedInOut) {
256
- diagnose (param.LetVarInOutLoc , diag::inout_as_attr_deprecated)
257
- .fixItRemove (param.LetVarInOutLoc );
255
+ bool hasValidInOut = false ;
256
+
257
+ while (Tok.is (tok::kw_inout)) {
258
+ hasValidInOut = true ;
259
+ if (hasSpecifier) {
260
+ diagnose (Tok.getLoc (), diag::parameter_inout_var_let_repeated)
261
+ .fixItRemove (param.LetVarInOutLoc );
262
+ consumeToken (tok::kw_inout);
263
+ param.isInvalid = true ;
264
+ } else {
265
+ hasSpecifier = true ;
266
+ param.LetVarInOutLoc = consumeToken (tok::kw_inout);
267
+ param.SpecifierKind = ParsedParameter::InOut;
258
268
}
259
- } else if (hasDeprecatedInOut) {
260
- diagnose (param.LetVarInOutLoc , diag::inout_as_attr_deprecated)
261
- .fixItRemove (param.LetVarInOutLoc )
262
- .fixItInsert (postColonLoc, " inout " );
263
269
}
264
-
270
+ if (!hasValidInOut && hasDeprecatedInOut) {
271
+ diagnose (Tok.getLoc (), diag::inout_as_attr_disallowed)
272
+ .fixItRemove (param.LetVarInOutLoc )
273
+ .fixItInsert (postColonLoc, " inout " );
274
+ param.isInvalid = true ;
275
+ }
276
+
265
277
auto type = parseType (diag::expected_parameter_type);
266
278
status |= type;
267
279
param.Type = type.getPtrOrNull ();
0 commit comments