@@ -2856,6 +2856,7 @@ bool Parser::canParseCustomAttribute() {
2856
2856
2857
2857
ParserResult<CustomAttr> Parser::parseCustomAttribute (
2858
2858
SourceLoc atLoc, PatternBindingInitializer *&initContext) {
2859
+ assert (Tok.is (tok::identifier));
2859
2860
SyntaxContext->setCreateSyntax (SyntaxKind::CustomAttribute);
2860
2861
2861
2862
// Parse a custom attribute.
@@ -3093,7 +3094,7 @@ bool Parser::canParseTypeAttribute() {
3093
3094
TypeAttributes attrs; // ignored
3094
3095
PatternBindingInitializer *initContext = nullptr ;
3095
3096
return !parseTypeAttribute (attrs, /* atLoc=*/ SourceLoc (), initContext,
3096
- /* justChecking*/ true );
3097
+ /* justChecking*/ true ). isError () ;
3097
3098
}
3098
3099
3099
3100
// / Parses the '@differentiable' type attribute argument (no argument list,
@@ -3252,16 +3253,28 @@ bool Parser::parseConventionAttributeInternal(
3252
3253
// / \param justChecking - if true, we're just checking whether we
3253
3254
// / canParseTypeAttribute; don't emit any diagnostics, and there's
3254
3255
// / no need to actually record the attribute
3255
- bool Parser::parseTypeAttribute (TypeAttributes &Attributes, SourceLoc AtLoc,
3256
- PatternBindingInitializer *&initContext,
3257
- bool justChecking) {
3256
+ ParserStatus Parser::parseTypeAttribute (TypeAttributes &Attributes,
3257
+ SourceLoc AtLoc,
3258
+ PatternBindingInitializer *&initContext,
3259
+ bool justChecking) {
3258
3260
// If this not an identifier, the attribute is malformed.
3259
3261
if (Tok.isNot (tok::identifier) &&
3260
3262
// These are keywords that we accept as attribute names.
3261
3263
Tok.isNot (tok::kw_in) && Tok.isNot (tok::kw_inout)) {
3264
+
3265
+ if (Tok.is (tok::code_complete)) {
3266
+ if (!justChecking) {
3267
+ if (CodeCompletion) {
3268
+ CodeCompletion->completeTypeAttrBeginning ();
3269
+ }
3270
+ }
3271
+ consumeToken (tok::code_complete);
3272
+ return makeParserCodeCompletionStatus ();
3273
+ }
3274
+
3262
3275
if (!justChecking)
3263
3276
diagnose (Tok, diag::expected_attribute_name);
3264
- return true ;
3277
+ return makeParserError () ;
3265
3278
}
3266
3279
3267
3280
// Determine which attribute it is, and diagnose it if unknown.
@@ -3289,7 +3302,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3289
3302
if (declAttrID != DAK_Count) {
3290
3303
// This is a valid decl attribute so they should have put it on the decl
3291
3304
// instead of the type.
3292
- if (justChecking) return true ;
3305
+ if (justChecking) return makeParserError () ;
3293
3306
3294
3307
// If this is the first attribute, and if we are on a simple decl, emit a
3295
3308
// fixit to move the attribute. Otherwise, we don't have the location of
@@ -3324,21 +3337,22 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3324
3337
backtrack.cancelBacktrack ();
3325
3338
}
3326
3339
3327
- return true ;
3340
+ return makeParserError () ;
3328
3341
}
3329
3342
3330
3343
// If we're just checking, try to parse now.
3331
3344
if (justChecking)
3332
- return !canParseCustomAttribute ();
3345
+ return canParseCustomAttribute () ? makeParserSuccess ()
3346
+ : makeParserError ();
3333
3347
3334
3348
// Parse as a custom attribute.
3335
3349
auto customAttrResult = parseCustomAttribute (AtLoc, initContext);
3336
3350
if (customAttrResult.isParseErrorOrHasCompletion ())
3337
- return true ;
3351
+ return customAttrResult ;
3338
3352
3339
3353
if (auto attr = customAttrResult.get ())
3340
3354
Attributes.addCustomAttr (attr);
3341
- return false ;
3355
+ return makeParserSuccess () ;
3342
3356
}
3343
3357
3344
3358
// Ok, it is a valid attribute, eat it, and then process it.
@@ -3352,19 +3366,19 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3352
3366
if (failedToParse) {
3353
3367
if (Tok.is (tok::r_paren))
3354
3368
consumeToken ();
3355
- return true ;
3369
+ return makeParserError () ;
3356
3370
}
3357
3371
}
3358
3372
3359
3373
// In just-checking mode, we only need to consume the tokens, and we don't
3360
3374
// want to do any other analysis.
3361
3375
if (justChecking)
3362
- return false ;
3376
+ return makeParserSuccess () ;
3363
3377
3364
3378
// Diagnose duplicated attributes.
3365
3379
if (Attributes.has (attr)) {
3366
3380
diagnose (AtLoc, diag::duplicate_attribute, /* isModifier=*/ false );
3367
- return false ;
3381
+ return makeParserSuccess () ;
3368
3382
}
3369
3383
3370
3384
// Handle any attribute-specific processing logic.
@@ -3386,7 +3400,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3386
3400
case TAK_objc_metatype:
3387
3401
if (!isInSILMode ()) {
3388
3402
diagnose (AtLoc, diag::only_allowed_in_sil, Text);
3389
- return false ;
3403
+ return makeParserSuccess () ;
3390
3404
}
3391
3405
break ;
3392
3406
@@ -3395,27 +3409,27 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3395
3409
case TAK_sil_unowned:
3396
3410
if (!isInSILMode ()) {
3397
3411
diagnose (AtLoc, diag::only_allowed_in_sil, Text);
3398
- return false ;
3412
+ return makeParserSuccess () ;
3399
3413
}
3400
3414
3401
3415
if (Attributes.hasOwnership ()) {
3402
3416
diagnose (AtLoc, diag::duplicate_attribute, /* isModifier*/ false );
3403
- return false ;
3417
+ return makeParserSuccess () ;
3404
3418
}
3405
3419
break ;
3406
3420
3407
3421
// 'inout' attribute.
3408
3422
case TAK_inout:
3409
3423
if (!isInSILMode ()) {
3410
3424
diagnose (AtLoc, diag::inout_not_attribute);
3411
- return false ;
3425
+ return makeParserSuccess () ;
3412
3426
}
3413
3427
break ;
3414
3428
3415
3429
case TAK_opened: {
3416
3430
if (!isInSILMode ()) {
3417
3431
diagnose (AtLoc, diag::only_allowed_in_sil, " opened" );
3418
- return false ;
3432
+ return makeParserSuccess () ;
3419
3433
}
3420
3434
3421
3435
// Parse the opened existential ID string in parens
@@ -3449,7 +3463,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3449
3463
Attributes.differentiabilityKind = DifferentiabilityKind::Normal;
3450
3464
if (parseDifferentiableTypeAttributeArgument (
3451
3465
*this , Attributes, /* emitDiagnostics=*/ !justChecking))
3452
- return true ;
3466
+ return makeParserError () ;
3453
3467
// Only 'reverse' is supported today.
3454
3468
// TODO: Change this to an error once clients have migrated to 'reverse'.
3455
3469
if (Attributes.differentiabilityKind == DifferentiabilityKind::Normal) {
@@ -3471,31 +3485,31 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3471
3485
auto beginLoc = Tok.getLoc ();
3472
3486
if (!consumeIfNotAtStartOfLine (tok::l_paren)) {
3473
3487
diagnose (Tok, diag::attr_expected_lparen, " _opaqueReturnTypeOf" , false );
3474
- return true ;
3488
+ return makeParserError () ;
3475
3489
}
3476
3490
3477
3491
if (!Tok.is (tok::string_literal)) {
3478
3492
diagnose (Tok, diag::opened_attribute_id_value);
3479
- return true ;
3493
+ return makeParserError () ;
3480
3494
}
3481
3495
auto mangling = Tok.getText ().slice (1 , Tok.getText ().size () - 1 );
3482
3496
consumeToken (tok::string_literal);
3483
3497
3484
3498
if (!Tok.is (tok::comma)) {
3485
3499
diagnose (Tok, diag::attr_expected_comma, " _opaqueReturnTypeOf" , false );
3486
- return true ;
3500
+ return makeParserError () ;
3487
3501
}
3488
3502
consumeToken (tok::comma);
3489
3503
3490
3504
if (!Tok.is (tok::integer_literal)) {
3491
3505
diagnose (Tok, diag::attr_expected_string_literal, " _opaqueReturnTypeOf" );
3492
- return true ;
3506
+ return makeParserError () ;
3493
3507
}
3494
3508
3495
3509
unsigned index;
3496
3510
if (Tok.getText ().getAsInteger (10 , index)) {
3497
3511
diagnose (Tok, diag::attr_expected_string_literal, " _opaqueReturnTypeOf" );
3498
- return true ;
3512
+ return makeParserError () ;
3499
3513
}
3500
3514
consumeToken (tok::integer_literal);
3501
3515
@@ -3510,7 +3524,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
3510
3524
}
3511
3525
3512
3526
Attributes.setAttr (attr, AtLoc);
3513
- return false ;
3527
+ return makeParserSuccess () ;
3514
3528
}
3515
3529
3516
3530
// / \verbatim
@@ -3744,9 +3758,10 @@ bool Parser::parseDeclModifierList(DeclAttributes &Attributes,
3744
3758
// / '@' attribute
3745
3759
// / '@' attribute attribute-list-clause
3746
3760
// / \endverbatim
3747
- bool Parser::parseTypeAttributeListPresent (ParamDecl::Specifier &Specifier,
3748
- SourceLoc &SpecifierLoc,
3749
- TypeAttributes &Attributes) {
3761
+ ParserStatus
3762
+ Parser::parseTypeAttributeListPresent (ParamDecl::Specifier &Specifier,
3763
+ SourceLoc &SpecifierLoc,
3764
+ TypeAttributes &Attributes) {
3750
3765
PatternBindingInitializer *initContext = nullptr ;
3751
3766
Specifier = ParamDecl::Specifier::Default;
3752
3767
while (Tok.is (tok::kw_inout) ||
@@ -3770,21 +3785,23 @@ bool Parser::parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
3770
3785
SpecifierLoc = consumeToken ();
3771
3786
}
3772
3787
3788
+ ParserStatus status;
3773
3789
SyntaxParsingContext AttrListCtx (SyntaxContext, SyntaxKind::AttributeList);
3774
3790
while (Tok.is (tok::at_sign)) {
3775
3791
// Ignore @substituted in SIL mode and leave it for the type parser.
3776
3792
if (isInSILMode () && peekToken ().getText () == " substituted" )
3777
- return false ;
3793
+ return status ;
3778
3794
3779
3795
if (Attributes.AtLoc .isInvalid ())
3780
3796
Attributes.AtLoc = Tok.getLoc ();
3781
3797
SyntaxParsingContext AttrCtx (SyntaxContext, SyntaxKind::Attribute);
3782
3798
SourceLoc AtLoc = consumeToken ();
3783
- if (parseTypeAttribute (Attributes, AtLoc, initContext))
3784
- return true ;
3799
+ status |= parseTypeAttribute (Attributes, AtLoc, initContext);
3800
+ if (status.isError ())
3801
+ return status;
3785
3802
}
3786
3803
3787
- return false ;
3804
+ return status ;
3788
3805
}
3789
3806
3790
3807
static bool isStartOfOperatorDecl (const Token &Tok, const Token &Tok2) {
0 commit comments