@@ -2817,6 +2817,7 @@ bool Parser::canParseCustomAttribute() {
28172817
28182818ParserResult<CustomAttr> Parser::parseCustomAttribute (
28192819 SourceLoc atLoc, PatternBindingInitializer *&initContext) {
2820+ assert (Tok.is (tok::identifier));
28202821 SyntaxContext->setCreateSyntax (SyntaxKind::CustomAttribute);
28212822
28222823 // Parse a custom attribute.
@@ -3054,7 +3055,7 @@ bool Parser::canParseTypeAttribute() {
30543055 TypeAttributes attrs; // ignored
30553056 PatternBindingInitializer *initContext = nullptr ;
30563057 return !parseTypeAttribute (attrs, /* atLoc=*/ SourceLoc (), initContext,
3057- /* justChecking*/ true );
3058+ /* justChecking*/ true ). isError () ;
30583059}
30593060
30603061// / Parses the '@differentiable' type attribute argument (no argument list,
@@ -3213,16 +3214,28 @@ bool Parser::parseConventionAttributeInternal(
32133214// / \param justChecking - if true, we're just checking whether we
32143215// / canParseTypeAttribute; don't emit any diagnostics, and there's
32153216// / no need to actually record the attribute
3216- bool Parser::parseTypeAttribute (TypeAttributes &Attributes, SourceLoc AtLoc,
3217- PatternBindingInitializer *&initContext,
3218- bool justChecking) {
3217+ ParserStatus Parser::parseTypeAttribute (TypeAttributes &Attributes,
3218+ SourceLoc AtLoc,
3219+ PatternBindingInitializer *&initContext,
3220+ bool justChecking) {
32193221 // If this not an identifier, the attribute is malformed.
32203222 if (Tok.isNot (tok::identifier) &&
32213223 // These are keywords that we accept as attribute names.
32223224 Tok.isNot (tok::kw_in) && Tok.isNot (tok::kw_inout)) {
3225+
3226+ if (Tok.is (tok::code_complete)) {
3227+ if (!justChecking) {
3228+ if (CodeCompletion) {
3229+ CodeCompletion->completeTypeAttrBeginning ();
3230+ }
3231+ }
3232+ consumeToken (tok::code_complete);
3233+ return makeParserCodeCompletionStatus ();
3234+ }
3235+
32233236 if (!justChecking)
32243237 diagnose (Tok, diag::expected_attribute_name);
3225- return true ;
3238+ return makeParserError () ;
32263239 }
32273240
32283241 // Determine which attribute it is, and diagnose it if unknown.
@@ -3250,7 +3263,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
32503263 if (declAttrID != DAK_Count) {
32513264 // This is a valid decl attribute so they should have put it on the decl
32523265 // instead of the type.
3253- if (justChecking) return true ;
3266+ if (justChecking) return makeParserError () ;
32543267
32553268 // If this is the first attribute, and if we are on a simple decl, emit a
32563269 // fixit to move the attribute. Otherwise, we don't have the location of
@@ -3285,21 +3298,22 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
32853298 backtrack.cancelBacktrack ();
32863299 }
32873300
3288- return true ;
3301+ return makeParserError () ;
32893302 }
32903303
32913304 // If we're just checking, try to parse now.
32923305 if (justChecking)
3293- return !canParseCustomAttribute ();
3306+ return canParseCustomAttribute () ? makeParserSuccess ()
3307+ : makeParserError ();
32943308
32953309 // Parse as a custom attribute.
32963310 auto customAttrResult = parseCustomAttribute (AtLoc, initContext);
32973311 if (customAttrResult.isParseErrorOrHasCompletion ())
3298- return true ;
3312+ return customAttrResult ;
32993313
33003314 if (auto attr = customAttrResult.get ())
33013315 Attributes.addCustomAttr (attr);
3302- return false ;
3316+ return makeParserSuccess () ;
33033317 }
33043318
33053319 // Ok, it is a valid attribute, eat it, and then process it.
@@ -3313,19 +3327,19 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
33133327 if (failedToParse) {
33143328 if (Tok.is (tok::r_paren))
33153329 consumeToken ();
3316- return true ;
3330+ return makeParserError () ;
33173331 }
33183332 }
33193333
33203334 // In just-checking mode, we only need to consume the tokens, and we don't
33213335 // want to do any other analysis.
33223336 if (justChecking)
3323- return false ;
3337+ return makeParserSuccess () ;
33243338
33253339 // Diagnose duplicated attributes.
33263340 if (Attributes.has (attr)) {
33273341 diagnose (AtLoc, diag::duplicate_attribute, /* isModifier=*/ false );
3328- return false ;
3342+ return makeParserSuccess () ;
33293343 }
33303344
33313345 // Handle any attribute-specific processing logic.
@@ -3347,7 +3361,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
33473361 case TAK_objc_metatype:
33483362 if (!isInSILMode ()) {
33493363 diagnose (AtLoc, diag::only_allowed_in_sil, Text);
3350- return false ;
3364+ return makeParserSuccess () ;
33513365 }
33523366 break ;
33533367
@@ -3356,27 +3370,27 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
33563370 case TAK_sil_unowned:
33573371 if (!isInSILMode ()) {
33583372 diagnose (AtLoc, diag::only_allowed_in_sil, Text);
3359- return false ;
3373+ return makeParserSuccess () ;
33603374 }
33613375
33623376 if (Attributes.hasOwnership ()) {
33633377 diagnose (AtLoc, diag::duplicate_attribute, /* isModifier*/ false );
3364- return false ;
3378+ return makeParserSuccess () ;
33653379 }
33663380 break ;
33673381
33683382 // 'inout' attribute.
33693383 case TAK_inout:
33703384 if (!isInSILMode ()) {
33713385 diagnose (AtLoc, diag::inout_not_attribute);
3372- return false ;
3386+ return makeParserSuccess () ;
33733387 }
33743388 break ;
33753389
33763390 case TAK_opened: {
33773391 if (!isInSILMode ()) {
33783392 diagnose (AtLoc, diag::only_allowed_in_sil, " opened" );
3379- return false ;
3393+ return makeParserSuccess () ;
33803394 }
33813395
33823396 // Parse the opened existential ID string in parens
@@ -3410,7 +3424,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
34103424 Attributes.differentiabilityKind = DifferentiabilityKind::Normal;
34113425 if (parseDifferentiableTypeAttributeArgument (
34123426 *this , Attributes, /* emitDiagnostics=*/ !justChecking))
3413- return true ;
3427+ return makeParserError () ;
34143428 // Only 'reverse' is supported today.
34153429 // TODO: Change this to an error once clients have migrated to 'reverse'.
34163430 if (Attributes.differentiabilityKind == DifferentiabilityKind::Normal) {
@@ -3432,31 +3446,31 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
34323446 auto beginLoc = Tok.getLoc ();
34333447 if (!consumeIfNotAtStartOfLine (tok::l_paren)) {
34343448 diagnose (Tok, diag::attr_expected_lparen, " _opaqueReturnTypeOf" , false );
3435- return true ;
3449+ return makeParserError () ;
34363450 }
34373451
34383452 if (!Tok.is (tok::string_literal)) {
34393453 diagnose (Tok, diag::opened_attribute_id_value);
3440- return true ;
3454+ return makeParserError () ;
34413455 }
34423456 auto mangling = Tok.getText ().slice (1 , Tok.getText ().size () - 1 );
34433457 consumeToken (tok::string_literal);
34443458
34453459 if (!Tok.is (tok::comma)) {
34463460 diagnose (Tok, diag::attr_expected_comma, " _opaqueReturnTypeOf" , false );
3447- return true ;
3461+ return makeParserError () ;
34483462 }
34493463 consumeToken (tok::comma);
34503464
34513465 if (!Tok.is (tok::integer_literal)) {
34523466 diagnose (Tok, diag::attr_expected_string_literal, " _opaqueReturnTypeOf" );
3453- return true ;
3467+ return makeParserError () ;
34543468 }
34553469
34563470 unsigned index;
34573471 if (Tok.getText ().getAsInteger (10 , index)) {
34583472 diagnose (Tok, diag::attr_expected_string_literal, " _opaqueReturnTypeOf" );
3459- return true ;
3473+ return makeParserError () ;
34603474 }
34613475 consumeToken (tok::integer_literal);
34623476
@@ -3471,7 +3485,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
34713485 }
34723486
34733487 Attributes.setAttr (attr, AtLoc);
3474- return false ;
3488+ return makeParserSuccess () ;
34753489}
34763490
34773491// / \verbatim
@@ -3705,9 +3719,10 @@ bool Parser::parseDeclModifierList(DeclAttributes &Attributes,
37053719// / '@' attribute
37063720// / '@' attribute attribute-list-clause
37073721// / \endverbatim
3708- bool Parser::parseTypeAttributeListPresent (ParamDecl::Specifier &Specifier,
3709- SourceLoc &SpecifierLoc,
3710- TypeAttributes &Attributes) {
3722+ ParserStatus
3723+ Parser::parseTypeAttributeListPresent (ParamDecl::Specifier &Specifier,
3724+ SourceLoc &SpecifierLoc,
3725+ TypeAttributes &Attributes) {
37113726 PatternBindingInitializer *initContext = nullptr ;
37123727 Specifier = ParamDecl::Specifier::Default;
37133728 while (Tok.is (tok::kw_inout) ||
@@ -3731,21 +3746,23 @@ bool Parser::parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
37313746 SpecifierLoc = consumeToken ();
37323747 }
37333748
3749+ ParserStatus status;
37343750 SyntaxParsingContext AttrListCtx (SyntaxContext, SyntaxKind::AttributeList);
37353751 while (Tok.is (tok::at_sign)) {
37363752 // Ignore @substituted in SIL mode and leave it for the type parser.
37373753 if (isInSILMode () && peekToken ().getText () == " substituted" )
3738- return false ;
3754+ return status ;
37393755
37403756 if (Attributes.AtLoc .isInvalid ())
37413757 Attributes.AtLoc = Tok.getLoc ();
37423758 SyntaxParsingContext AttrCtx (SyntaxContext, SyntaxKind::Attribute);
37433759 SourceLoc AtLoc = consumeToken ();
3744- if (parseTypeAttribute (Attributes, AtLoc, initContext))
3745- return true ;
3760+ status |= parseTypeAttribute (Attributes, AtLoc, initContext);
3761+ if (status.isError ())
3762+ return status;
37463763 }
37473764
3748- return false ;
3765+ return status ;
37493766}
37503767
37513768static bool isStartOfOperatorDecl (const Token &Tok, const Token &Tok2) {
0 commit comments