@@ -254,6 +254,7 @@ ParserResult<TypeRepr> Parser::parseSILBoxType(GenericParamList *generics,
254
254
// /
255
255
// / type-function:
256
256
// / type-composition '->' type
257
+ // / type-composition 'throws' '->' type
257
258
// /
258
259
ParserResult<TypeRepr> Parser::parseType (Diag<> MessageID,
259
260
bool HandleCodeCompletion,
@@ -284,62 +285,45 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
284
285
parseTypeSimpleOrComposition (MessageID, HandleCodeCompletion);
285
286
if (ty.hasCodeCompletion ())
286
287
return makeParserCodeCompletionResult<TypeRepr>();
287
-
288
288
if (ty.isNull ())
289
289
return nullptr ;
290
+ auto tyR = ty.get ();
290
291
291
- // Parse a throws specifier. 'throw' is probably a typo for 'throws',
292
- // but in local contexts we could just be at the end of a statement,
293
- // so we need to check for the arrow.
294
- ParserPosition beforeThrowsPos;
292
+ // Parse a throws specifier.
293
+ // Don't consume 'throws', if the next token is not '->', so we can emit a
294
+ // more useful diagnostic when parsing a function decl.
295
295
SourceLoc throwsLoc;
296
- bool rethrows = false ;
297
- if (Tok.isAny (tok::kw_throws, tok::kw_rethrows) ||
298
- (Tok.is (tok::kw_throw) && peekToken ().is (tok::arrow))) {
299
- if (Tok.is (tok::kw_throw)) {
300
- diagnose (Tok.getLoc (), diag::throw_in_function_type)
296
+ if (Tok.isAny (tok::kw_throws, tok::kw_rethrows, tok::kw_throw) &&
297
+ peekToken ().is (tok::arrow)) {
298
+ if (Tok.isNot (tok::kw_throws)) {
299
+ // 'rethrows' is only allowed on function declarations for now.
300
+ // 'throw' is probably a typo for 'throws'.
301
+ Diag<> DiagID = Tok.is (tok::kw_rethrows) ?
302
+ diag::rethrowing_function_type : diag::throw_in_function_type;
303
+ diagnose (Tok.getLoc (), DiagID)
301
304
.fixItReplace (Tok.getLoc (), " throws" );
302
305
}
303
-
304
- beforeThrowsPos = getParserPosition ();
305
- rethrows = Tok.is (tok::kw_rethrows);
306
306
throwsLoc = consumeToken ();
307
307
}
308
308
309
- // Handle type-function if we have an arrow.
310
- SourceLoc arrowLoc;
311
- if ( consumeIf (tok::arrow, arrowLoc)) {
309
+ if (Tok. is (tok::arrow)) {
310
+ // Handle type-function if we have an arrow.
311
+ SourceLoc arrowLoc = consumeToken ();
312
312
ParserResult<TypeRepr> SecondHalf =
313
313
parseType (diag::expected_type_function_result);
314
314
if (SecondHalf.hasCodeCompletion ())
315
315
return makeParserCodeCompletionResult<TypeRepr>();
316
316
if (SecondHalf.isNull ())
317
317
return nullptr ;
318
- if (rethrows) {
319
- // 'rethrows' is only allowed on function declarations for now.
320
- diagnose (throwsLoc, diag::rethrowing_function_type);
321
- }
322
- auto fnTy = new (Context) FunctionTypeRepr (generics, ty.get (),
323
- throwsLoc,
324
- arrowLoc,
325
- SecondHalf.get ());
326
- return makeParserResult (applyAttributeToType (fnTy, inoutLoc, attrs));
327
- } else if (throwsLoc.isValid ()) {
328
- // Don't consume 'throws', so we can emit a more useful diagnostic when
329
- // parsing a function decl.
330
- restoreParserPosition (beforeThrowsPos);
331
- }
332
-
333
- // Only function types may be generic.
334
- if (generics) {
318
+ tyR = new (Context) FunctionTypeRepr (generics, tyR, throwsLoc, arrowLoc,
319
+ SecondHalf.get ());
320
+ } else if (generics) {
321
+ // Only function types may be generic.
335
322
auto brackets = generics->getSourceRange ();
336
323
diagnose (brackets.Start , diag::generic_non_function);
337
324
}
338
325
339
- if (ty.isNonNull () && !ty.hasCodeCompletion ()) {
340
- ty = makeParserResult (applyAttributeToType (ty.get (), inoutLoc, attrs));
341
- }
342
- return ty;
326
+ return makeParserResult (applyAttributeToType (tyR, inoutLoc, attrs));
343
327
}
344
328
345
329
ParserResult<TypeRepr> Parser::parseTypeForInheritance (
0 commit comments