From 7d553107dd579d02567caa72f365832a3ed03728 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 16 Mar 2023 09:06:45 -0700 Subject: [PATCH] Extend deduced and regular parameter handling to types. (#2684) This makes it possible to specify both deduced and regular parameters on types. It reorganizes the handling of parameter lists in order to allow more reuse of code in this approach. Both functions and types use the new DeclarationNameAndParams handling. Overall the goal here is to take advantage of commonality in structure. Regarding destructors, the likely approach would be to use ParameterListAsDeduced directly because `destructor` is a keyword with no declaration name and no regular parameters. --- .codespell_ignore | 3 +- toolchain/diagnostics/diagnostic_kind.def | 3 +- toolchain/parser/parser.cpp | 319 ++++++++++-------- toolchain/parser/parser.h | 33 +- toolchain/parser/parser_state.def | 143 ++++---- ...educed_one.carbon => deduced_empty.carbon} | 9 +- .../deduced_one_suffix_comma.carbon | 22 -- ...duced_two.carbon => deduced_params.carbon} | 0 .../function/declaration/deduced_six.carbon | 41 --- .../deduced_two_suffix_comma.carbon | 26 -- .../fail_identifier_instead_of_sig.carbon | 2 +- .../fail_missing_deduced_close.carbon | 2 +- .../declaration/fail_no_sig_or_semi.carbon | 2 +- .../{params_two.carbon => params.carbon} | 0 .../function/declaration/params_one.carbon | 19 -- .../params_one_suffix_comma.carbon | 20 -- .../function/declaration/params_six.carbon | 39 --- .../params_two_suffix_comma.carbon | 24 -- .../generics/deduced_params/empty.carbon | 28 ++ .../deduced_params/fail_no_parens.carbon | 47 +++ .../generics/deduced_params/one.carbon | 34 ++ .../deduced_params/one_suffix_comma.carbon | 36 ++ .../generics/deduced_params/six.carbon | 74 ++++ .../generics/deduced_params/two.carbon | 42 +++ .../deduced_params/two_suffix_comma.carbon | 44 +++ .../testdata/generics/params/empty.carbon | 24 ++ .../testdata/generics/params/one.carbon | 30 ++ .../generics/params/one_suffix_comma.carbon | 32 ++ .../testdata/generics/params/six.carbon | 70 ++++ .../testdata/generics/params/two.carbon | 38 +++ .../generics/params/two_suffix_comma.carbon | 40 +++ 31 files changed, 831 insertions(+), 415 deletions(-) rename toolchain/parser/testdata/function/declaration/{deduced_one.carbon => deduced_empty.carbon} (76%) delete mode 100644 toolchain/parser/testdata/function/declaration/deduced_one_suffix_comma.carbon rename toolchain/parser/testdata/function/declaration/{deduced_two.carbon => deduced_params.carbon} (100%) delete mode 100644 toolchain/parser/testdata/function/declaration/deduced_six.carbon delete mode 100644 toolchain/parser/testdata/function/declaration/deduced_two_suffix_comma.carbon rename toolchain/parser/testdata/function/declaration/{params_two.carbon => params.carbon} (100%) delete mode 100644 toolchain/parser/testdata/function/declaration/params_one.carbon delete mode 100644 toolchain/parser/testdata/function/declaration/params_one_suffix_comma.carbon delete mode 100644 toolchain/parser/testdata/function/declaration/params_six.carbon delete mode 100644 toolchain/parser/testdata/function/declaration/params_two_suffix_comma.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/empty.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/one.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/one_suffix_comma.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/six.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/two.carbon create mode 100644 toolchain/parser/testdata/generics/deduced_params/two_suffix_comma.carbon create mode 100644 toolchain/parser/testdata/generics/params/empty.carbon create mode 100644 toolchain/parser/testdata/generics/params/one.carbon create mode 100644 toolchain/parser/testdata/generics/params/one_suffix_comma.carbon create mode 100644 toolchain/parser/testdata/generics/params/six.carbon create mode 100644 toolchain/parser/testdata/generics/params/two.carbon create mode 100644 toolchain/parser/testdata/generics/params/two_suffix_comma.carbon diff --git a/.codespell_ignore b/.codespell_ignore index 0bd55bee31ec..3815d77f9a07 100644 --- a/.codespell_ignore +++ b/.codespell_ignore @@ -4,11 +4,12 @@ atleast circularly +compiletime copyable crate crossreference falsy inout +parameteras pullrequest statics -compiletime diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index ff4bfefa223f..97889bd1fe80 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -53,7 +53,6 @@ CARBON_DIAGNOSTIC_KIND(BinaryOperatorRequiresWhitespace) CARBON_DIAGNOSTIC_KIND(ExpectedCloseParen) CARBON_DIAGNOSTIC_KIND(ExpectedCodeBlock) CARBON_DIAGNOSTIC_KIND(ExpectedExpression) -CARBON_DIAGNOSTIC_KIND(ExpectedFunctionParams) CARBON_DIAGNOSTIC_KIND(ExpectedIdentifierAfterDot) CARBON_DIAGNOSTIC_KIND(ExpectedParameterName) CARBON_DIAGNOSTIC_KIND(ExpectedParenAfter) @@ -83,6 +82,8 @@ CARBON_DIAGNOSTIC_KIND(ExpectedInNotColon) CARBON_DIAGNOSTIC_KIND(ExpectedDeclarationName) CARBON_DIAGNOSTIC_KIND(ExpectedDeclarationSemiOrDefinition) CARBON_DIAGNOSTIC_KIND(MethodImplNotAllowed) +CARBON_DIAGNOSTIC_KIND(ParametersRequiredByIntroducer) +CARBON_DIAGNOSTIC_KIND(ParametersRequiredByDeduced) // ============================================================================ // Semantics diagnostics diff --git a/toolchain/parser/parser.cpp b/toolchain/parser/parser.cpp index 5d9f17af50b4..5e58fe50fb9a 100644 --- a/toolchain/parser/parser.cpp +++ b/toolchain/parser/parser.cpp @@ -22,9 +22,6 @@ CARBON_DIAGNOSTIC( OperatorRequiresParentheses, Error, "Parentheses are required to disambiguate operator precedence."); -CARBON_DIAGNOSTIC(ExpectedParenAfter, Error, "Expected `(` after `{0}`.", - TokenKind); - CARBON_DIAGNOSTIC(ExpectedSemiAfterExpression, Error, "Expected `;` after expression."); @@ -127,6 +124,8 @@ auto Parser::ConsumeAndAddOpenParen(TokenizedBuffer::Token default_token, if (auto open_paren = ConsumeIf(TokenKind::OpenParen)) { AddLeafNode(start_kind, *open_paren, /*has_error=*/false); } else { + CARBON_DIAGNOSTIC(ExpectedParenAfter, Error, "Expected `(` after `{0}`.", + TokenKind); emitter_->Emit(*position_, ExpectedParenAfter, tokens_->GetKind(default_token)); AddLeafNode(start_kind, default_token, /*has_error=*/true); @@ -766,6 +765,53 @@ auto Parser::HandleCodeBlockFinishState() -> void { } } +auto Parser::HandleDeclarationNameAndParams(bool params_required) -> void { + auto state = PopState(); + + if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier, + ParseNodeKind::DeclaredName)) { + emitter_->Emit(*position_, ExpectedDeclarationName, + tokens_->GetKind(state.token)); + ReturnErrorOnState(); + return; + } + + if (PositionIs(TokenKind::OpenSquareBracket)) { + PushState(ParserState::DeclarationNameAndParamsAfterDeduced); + PushState(ParserState::ParameterListAsDeduced); + } else if (PositionIs(TokenKind::OpenParen)) { + PushState(ParserState::ParameterListAsRegular); + } else if (params_required) { + CARBON_DIAGNOSTIC(ParametersRequiredByIntroducer, Error, + "`{0}` requires a `(` for parameters.", TokenKind); + emitter_->Emit(*position_, ParametersRequiredByIntroducer, + tokens_->GetKind(state.token)); + ReturnErrorOnState(); + } +} + +auto Parser::HandleDeclarationNameAndParamsAsOptionalState() -> void { + HandleDeclarationNameAndParams(/*params_required=*/false); +} + +auto Parser::HandleDeclarationNameAndParamsAsRequiredState() -> void { + HandleDeclarationNameAndParams(/*params_required=*/true); +} + +auto Parser::HandleDeclarationNameAndParamsAfterDeducedState() -> void { + PopAndDiscardState(); + + if (PositionIs(TokenKind::OpenParen)) { + PushState(ParserState::ParameterListAsRegular); + } else { + CARBON_DIAGNOSTIC( + ParametersRequiredByDeduced, Error, + "A `(` for parameters is required after deduced parameters."); + emitter_->Emit(*position_, ParametersRequiredByDeduced); + ReturnErrorOnState(); + } +} + auto Parser::HandleDeclarationScopeLoopState() -> void { // This maintains the current state unless we're at the end of the scope. @@ -807,35 +853,6 @@ auto Parser::HandleDeclarationScopeLoopState() -> void { } } -auto Parser::HandleDeducedParameterState() -> void { - PopAndDiscardState(); - - PushState(ParserState::DeducedParameterFinish); - PushState(ParserState::PatternAsDeducedParameter); -} - -auto Parser::HandleDeducedParameterFinishState() -> void { - auto state = PopState(); - - if (state.has_error) { - ReturnErrorOnState(); - } - - if (ConsumeListToken(ParseNodeKind::ParameterListComma, - TokenKind::CloseSquareBracket, - state.has_error) == ListTokenKind::Comma) { - PushState(ParserState::DeducedParameter); - } -} - -auto Parser::HandleDeducedParameterListFinishState() -> void { - auto state = PopState(); - - AddNode(ParseNodeKind::DeducedParameterList, - ConsumeChecked(TokenKind::CloseSquareBracket), state.subtree_start, - state.has_error); -} - auto Parser::HandleDesignator(bool as_struct) -> void { auto state = PopState(); @@ -1084,87 +1101,13 @@ auto Parser::HandleFunctionIntroducerState() -> void { AddLeafNode(ParseNodeKind::FunctionIntroducer, Consume()); - if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier, - ParseNodeKind::DeclaredName)) { - emitter_->Emit(*position_, ExpectedDeclarationName, TokenKind::Fn); - // TODO: We could change the lexer to allow us to synthesize certain - // kinds of tokens and try to "recover" here, but unclear that this is - // really useful. - HandleDeclarationError(state, ParseNodeKind::FunctionDeclaration, - /*skip_past_likely_end=*/true); - return; - } - - // Proceed to the same state regardless of whether there's a deduced - // parameter list. - state.state = ParserState::FunctionAfterDeducedParameterList; + state.state = ParserState::FunctionAfterParameters; PushState(state); - - if (!PositionIs(TokenKind::OpenSquareBracket)) { - return; - } - - // Parse the deduced parameter list as its own subtree. - PushState(ParserState::DeducedParameterListFinish); - AddLeafNode(ParseNodeKind::DeducedParameterListStart, Consume()); - - if (!PositionIs(TokenKind::CloseSquareBracket)) { - PushState(ParserState::DeducedParameter); - } -} - -auto Parser::HandleFunctionAfterDeducedParameterListState() -> void { - auto state = PopState(); - - if (!PositionIs(TokenKind::OpenParen)) { - CARBON_DIAGNOSTIC(ExpectedFunctionParams, Error, - "Expected `(` after function name."); - emitter_->Emit(*position_, ExpectedFunctionParams); - HandleDeclarationError(state, ParseNodeKind::FunctionDeclaration, - /*skip_past_likely_end=*/true); - return; - } - - // Parse the parameter list as its own subtree; once that pops, resume - // function parsing. - state.state = ParserState::FunctionAfterParameterList; + state.state = ParserState::DeclarationNameAndParamsAsRequired; PushState(state); - PushState(ParserState::FunctionParameterListFinish); - AddLeafNode(ParseNodeKind::ParameterListStart, Consume()); - - if (!PositionIs(TokenKind::CloseParen)) { - PushState(ParserState::FunctionParameter); - } } -auto Parser::HandleFunctionParameterState() -> void { - PopAndDiscardState(); - - PushState(ParserState::FunctionParameterFinish); - PushState(ParserState::PatternAsFunctionParameter); -} - -auto Parser::HandleFunctionParameterFinishState() -> void { - auto state = PopState(); - - if (state.has_error) { - ReturnErrorOnState(); - } - - if (ConsumeListToken(ParseNodeKind::ParameterListComma, TokenKind::CloseParen, - state.has_error) == ListTokenKind::Comma) { - PushState(ParserState::FunctionParameter); - } -} - -auto Parser::HandleFunctionParameterListFinishState() -> void { - auto state = PopState(); - - AddNode(ParseNodeKind::ParameterList, ConsumeChecked(TokenKind::CloseParen), - state.subtree_start, state.has_error); -} - -auto Parser::HandleFunctionAfterParameterListState() -> void { +auto Parser::HandleFunctionAfterParametersState() -> void { auto state = PopState(); // Regardless of whether there's a return type, we'll finish the signature. @@ -1219,8 +1162,10 @@ auto Parser::HandleFunctionSignatureFinishState() -> void { break; } default: { - emitter_->Emit(*position_, ExpectedDeclarationSemiOrDefinition, - TokenKind::Fn); + if (!state.has_error) { + emitter_->Emit(*position_, ExpectedDeclarationSemiOrDefinition, + TokenKind::Fn); + } // Only need to skip if we've not already found a new line. bool skip_past_likely_end = tokens_->GetLine(*position_) == tokens_->GetLine(state.token); @@ -1316,6 +1261,93 @@ auto Parser::HandlePackageState() -> void { /*has_error=*/false); } +auto Parser::HandleParameter(ParserState pattern_state, + ParserState finish_state) -> void { + PopAndDiscardState(); + + PushState(finish_state); + PushState(pattern_state); +} + +auto Parser::HandleParameterAsDeducedState() -> void { + HandleParameter(ParserState::PatternAsDeducedParameter, + ParserState::ParameterFinishAsDeduced); +} + +auto Parser::HandleParameterAsRegularState() -> void { + HandleParameter(ParserState::PatternAsParameter, + ParserState::ParameterFinishAsRegular); +} + +auto Parser::HandleParameterFinish(TokenKind close_token, + ParserState param_state) -> void { + auto state = PopState(); + + if (state.has_error) { + ReturnErrorOnState(); + } + + if (ConsumeListToken(ParseNodeKind::ParameterListComma, close_token, + state.has_error) == ListTokenKind::Comma) { + PushState(param_state); + } +} + +auto Parser::HandleParameterFinishAsDeducedState() -> void { + HandleParameterFinish(TokenKind::CloseSquareBracket, + ParserState::ParameterAsDeduced); +} + +auto Parser::HandleParameterFinishAsRegularState() -> void { + HandleParameterFinish(TokenKind::CloseParen, ParserState::ParameterAsRegular); +} + +auto Parser::HandleParameterList(ParseNodeKind parse_node_kind, + TokenKind open_token_kind, + TokenKind close_token_kind, + ParserState param_state, + ParserState finish_state) -> void { + PopAndDiscardState(); + + PushState(finish_state); + AddLeafNode(parse_node_kind, ConsumeChecked(open_token_kind)); + + if (!PositionIs(close_token_kind)) { + PushState(param_state); + } +} + +auto Parser::HandleParameterListAsDeducedState() -> void { + HandleParameterList( + ParseNodeKind::DeducedParameterListStart, TokenKind::OpenSquareBracket, + TokenKind::CloseSquareBracket, ParserState::ParameterAsDeduced, + ParserState::ParameterListFinishAsDeduced); +} + +auto Parser::HandleParameterListAsRegularState() -> void { + HandleParameterList(ParseNodeKind::ParameterListStart, TokenKind::OpenParen, + TokenKind::CloseParen, ParserState::ParameterAsRegular, + ParserState::ParameterListFinishAsRegular); +} + +auto Parser::HandleParameterListFinish(ParseNodeKind parse_node_kind, + TokenKind token_kind) -> void { + auto state = PopState(); + + AddNode(parse_node_kind, ConsumeChecked(token_kind), state.subtree_start, + state.has_error); +} + +auto Parser::HandleParameterListFinishAsDeducedState() -> void { + HandleParameterListFinish(ParseNodeKind::DeducedParameterList, + TokenKind::CloseSquareBracket); +} + +auto Parser::HandleParameterListFinishAsRegularState() -> void { + HandleParameterListFinish(ParseNodeKind::ParameterList, + TokenKind::CloseParen); +} + auto Parser::HandleParenCondition(ParseNodeKind start_kind, ParserState finish_state) -> void { auto state = PopState(); @@ -1489,7 +1521,7 @@ auto Parser::HandlePatternAsDeducedParameterState() -> void { HandlePattern(PatternKind::DeducedParameter); } -auto Parser::HandlePatternAsFunctionParameterState() -> void { +auto Parser::HandlePatternAsParameterState() -> void { HandlePattern(PatternKind::Parameter); } @@ -1733,17 +1765,39 @@ auto Parser::HandleStatementWhileBlockFinishState() -> void { } auto Parser::HandleTypeIntroducer(ParseNodeKind introducer_kind, - ParseNodeKind declaration_kind, - ParseNodeKind definition_start_kind, - ParserState definition_finish_state) -> void { + ParserState after_params_state) -> void { auto state = PopState(); AddLeafNode(introducer_kind, Consume()); - if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier, - ParseNodeKind::DeclaredName)) { - emitter_->Emit(*position_, ExpectedDeclarationName, - tokens_->GetKind(state.token)); + state.state = after_params_state; + PushState(state); + state.state = ParserState::DeclarationNameAndParamsAsOptional; + PushState(state); +} + +auto Parser::HandleTypeIntroducerAsClassState() -> void { + HandleTypeIntroducer(ParseNodeKind::ClassIntroducer, + ParserState::TypeAfterParamsAsClass); +} + +auto Parser::HandleTypeIntroducerAsInterfaceState() -> void { + HandleTypeIntroducer(ParseNodeKind::InterfaceIntroducer, + ParserState::TypeAfterParamsAsInterface); +} + +auto Parser::HandleTypeIntroducerAsNamedConstraintState() -> void { + HandleTypeIntroducer(ParseNodeKind::NamedConstraintIntroducer, + ParserState::TypeAfterParamsAsNamedConstraint); +} + +auto Parser::HandleTypeAfterParams(ParseNodeKind declaration_kind, + ParseNodeKind definition_start_kind, + ParserState definition_finish_state) + -> void { + auto state = PopState(); + + if (state.has_error) { HandleDeclarationError(state, declaration_kind, /*skip_past_likely_end=*/true); return; @@ -1769,25 +1823,22 @@ auto Parser::HandleTypeIntroducer(ParseNodeKind introducer_kind, state.has_error); } -auto Parser::HandleTypeIntroducerAsClassState() -> void { - HandleTypeIntroducer(ParseNodeKind::ClassIntroducer, - ParseNodeKind::ClassDeclaration, - ParseNodeKind::ClassDefinitionStart, - ParserState::TypeDefinitionFinishAsClass); +auto Parser::HandleTypeAfterParamsAsClassState() -> void { + HandleTypeAfterParams(ParseNodeKind::ClassDeclaration, + ParseNodeKind::ClassDefinitionStart, + ParserState::TypeDefinitionFinishAsClass); } -auto Parser::HandleTypeIntroducerAsInterfaceState() -> void { - HandleTypeIntroducer(ParseNodeKind::InterfaceIntroducer, - ParseNodeKind::InterfaceDeclaration, - ParseNodeKind::InterfaceDefinitionStart, - ParserState::TypeDefinitionFinishAsInterface); +auto Parser::HandleTypeAfterParamsAsInterfaceState() -> void { + HandleTypeAfterParams(ParseNodeKind::InterfaceDeclaration, + ParseNodeKind::InterfaceDefinitionStart, + ParserState::TypeDefinitionFinishAsInterface); } -auto Parser::HandleTypeIntroducerAsNamedConstraintState() -> void { - HandleTypeIntroducer(ParseNodeKind::NamedConstraintIntroducer, - ParseNodeKind::NamedConstraintDeclaration, - ParseNodeKind::NamedConstraintDefinitionStart, - ParserState::TypeDefinitionFinishAsNamedConstraint); +auto Parser::HandleTypeAfterParamsAsNamedConstraintState() -> void { + HandleTypeAfterParams(ParseNodeKind::NamedConstraintDeclaration, + ParseNodeKind::NamedConstraintDefinitionStart, + ParserState::TypeDefinitionFinishAsNamedConstraint); } auto Parser::HandleTypeDefinitionFinish(ParseNodeKind definition_kind) -> void { diff --git a/toolchain/parser/parser.h b/toolchain/parser/parser.h index ef8b064fd6b0..ab15f17d39f0 100644 --- a/toolchain/parser/parser.h +++ b/toolchain/parser/parser.h @@ -305,9 +305,30 @@ class Parser { // Handles BraceExpressionFinishAs(Type|Value|Unknown). auto HandleBraceExpressionFinish(BraceExpressionKind kind) -> void; + // Handles DeclarationNameAndParamsAs(Optional|Required). + auto HandleDeclarationNameAndParams(bool params_required) -> void; + // Handles DesignatorAs. auto HandleDesignator(bool as_struct) -> void; + // Handles ParameterAs(Deduced|Regular). + auto HandleParameter(ParserState pattern_state, ParserState finish_state) + -> void; + + // Handles ParameterFinishAs(Deduced|Regular). + auto HandleParameterFinish(TokenKind close_token, ParserState param_state) + -> void; + + // Handles ParameterListAs(Deduced|Regular). + auto HandleParameterList(ParseNodeKind parse_node_kind, + TokenKind open_token_kind, + TokenKind close_token_kind, ParserState param_state, + ParserState finish_state) -> void; + + // Handles ParameterListFinishAs(Deduced|Regular). + auto HandleParameterListFinish(ParseNodeKind parse_node_kind, + TokenKind token_kind) -> void; + // Handles ParenConditionAs(If|While) auto HandleParenCondition(ParseNodeKind start_kind, ParserState finish_state) -> void; @@ -321,11 +342,15 @@ class Parser { // Handles the `;` after a keyword statement. auto HandleStatementKeywordFinish(ParseNodeKind node_kind) -> void; - // Handles processing of a type's ` {`. + // Handles processing of a type's introducer. auto HandleTypeIntroducer(ParseNodeKind introducer_kind, - ParseNodeKind declaration_kind, - ParseNodeKind definition_start_kind, - ParserState definition_finish_state) -> void; + ParserState after_params_state) -> void; + + // Handles processing after params, deciding whether it's a declaration or + // definition. + auto HandleTypeAfterParams(ParseNodeKind declaration_kind, + ParseNodeKind definition_start_kind, + ParserState definition_finish_state) -> void; // Handles parsing after the declaration scope of a type. auto HandleTypeDefinitionFinish(ParseNodeKind definition_kind) -> void; diff --git a/toolchain/parser/parser_state.def b/toolchain/parser/parser_state.def index 81ddd726344d..fa1200c4d2c2 100644 --- a/toolchain/parser/parser_state.def +++ b/toolchain/parser/parser_state.def @@ -127,6 +127,26 @@ CARBON_PARSER_STATE(CodeBlock) // (state done) CARBON_PARSER_STATE(CodeBlockFinish) +// Handles a general declaration name and parameters, such as `Foo[...](...)`. +// +// If `OpenSquareBracket`: +// 1. ParameterListAsDeduced +// 2. DeclarationNameAndParamsAfterDeduced +// If `OpenParen`: +// 1. ParameterListAsRegular +// Else: +// (state done) +CARBON_PARSER_STATE_VARIANTS2(DeclarationNameAndParams, Optional, Required) + +// Handles regular parameters such as `(...)` for the general declaration case. +// Only used after deduced parameters. +// +// If `OpenParen`: +// 1. ParameterListAsRegular +// Else: +// (state done) +CARBON_PARSER_STATE(DeclarationNameAndParamsAfterDeduced) + // Handles processing of a declaration scope. Things like fn, class, interface, // and so on. // @@ -153,28 +173,6 @@ CARBON_PARSER_STATE(CodeBlockFinish) // 1. DeclarationScopeLoop CARBON_PARSER_STATE(DeclarationScopeLoop) -// Starts deduced parameter processing. -// -// Always: -// 1. PatternAsDeducedParameter -// 2. DeducedParameterFinish -CARBON_PARSER_STATE(DeducedParameter) - -// Finishes deduced parameter processing, including `,`. If there are more -// parameters, enqueues another parameter processing state. -// -// If `Comma` without `CloseSquareBracket`: -// 1. DeducedParameter -// Else: -// (state done) -CARBON_PARSER_STATE(DeducedParameterFinish) - -// Handles processing of a deduced parameter list `]`. -// -// Always: -// (state done) -CARBON_PARSER_STATE(DeducedParameterListFinish) - // Handles a designator expression, such as `.z` in `x.(y.z)`. // // Always: @@ -251,55 +249,15 @@ CARBON_PARSER_STATE(ExpressionLoopForPrefix) // (state done) CARBON_PARSER_STATE(ExpressionStatementFinish) -// Handles processing of a function's `fn (`, and enqueues parameter list -// handling. +// Handles a function's introducer. // // If invalid: // (state done) -// If deduced parameters: -// 1. DeducedParameter -// 2. DeducedParameterListFinish -// 3. FunctionAfterDeducedParameterList // Else: -// 1. FunctionAfterDeducedParameterList +// 1. DeclarationNameAndParamsAsRequired +// 2. FunctionAfterParameters CARBON_PARSER_STATE(FunctionIntroducer) -// Handles processing of a functions' syntax after the deduced parameter lists's -// `]`. This applies only to interfaces and classes. -// -// If invalid: -// (state done) -// If parenthesized parameters: -// 1. FunctionParameter -// 2. FunctionParameterListFinish -// 3. FunctionAfterParameterList -// Else: -// 1. FunctionParameterListFinish -// 2. FunctionAfterParameterList -CARBON_PARSER_STATE(FunctionAfterDeducedParameterList) - -// Starts function parameter processing. -// -// Always: -// 1. PatternAsFunctionParameter -// 2. FunctionParameterFinish -CARBON_PARSER_STATE(FunctionParameter) - -// Finishes function parameter processing, including `,`. If there are more -// parameters, enqueues another parameter processing state. -// -// If `Comma` without `CloseParen`: -// 1. FunctionParameter -// Else: -// (state done) -CARBON_PARSER_STATE(FunctionParameterFinish) - -// Handles processing of a function's parameter list `)`. -// -// Always: -// (state done) -CARBON_PARSER_STATE(FunctionParameterListFinish) - // Handles processing of a function's syntax after `)`, primarily the // possibility a `->` return type is there. Always enqueues signature finish // handling. @@ -310,7 +268,7 @@ CARBON_PARSER_STATE(FunctionParameterListFinish) // 3. FunctionSignatureFinish // Else: // 1. FunctionSignatureFinish -CARBON_PARSER_STATE(FunctionAfterParameterList) +CARBON_PARSER_STATE(FunctionAfterParameters) // Finishes a function return type. // @@ -342,6 +300,37 @@ CARBON_PARSER_STATE(FunctionDefinitionFinish) // (state done) CARBON_PARSER_STATE(Package) +// Starts deduced parameter processing. +// +// Always: +// 1. PatternAs(DeducedParameter|Parameter) +// 2. ParameterFinishAs(Deduced|Regular) +CARBON_PARSER_STATE_VARIANTS2(Parameter, Deduced, Regular) + +// Finishes deduced parameter processing, including `,`. If there are more +// parameters, enqueues another parameter processing state. +// +// If `Comma` without the list close token: +// 1. ParameterAs(Deduced|Regular) +// Else: +// (state done) +CARBON_PARSER_STATE_VARIANTS2(ParameterFinish, Deduced, Regular) + +// Handles processing of a parameter list `[` or `(`. +// +// If the list close token: +// 1. ParameterListFinishAs(Deduced|Regular) +// Else: +// 1. ParameterAs(Deduced|Regular) +// 2. ParameterListFinishAs(Deduced|Regular) +CARBON_PARSER_STATE_VARIANTS2(ParameterList, Deduced, Regular) + +// Handles processing of a parameter list `]` or `)`. +// +// Always: +// (state done) +CARBON_PARSER_STATE_VARIANTS2(ParameterListFinish, Deduced, Regular) + // Handles the processing of a `(condition)` up through the expression. // // Always: @@ -394,8 +383,7 @@ CARBON_PARSER_STATE_VARIANTS2(ParenExpressionFinish, Normal, Tuple) // 2. PatternFinish // Else: // 1. PatternFinish -CARBON_PARSER_STATE_VARIANTS3(Pattern, DeducedParameter, FunctionParameter, - Variable) +CARBON_PARSER_STATE_VARIANTS3(Pattern, DeducedParameter, Parameter, Variable) // Handles `addr` in a pattern. // @@ -563,11 +551,17 @@ CARBON_PARSER_STATE(StatementWhileBlockFinish) // // Always: // (state done) -CARBON_PARSER_STATE(TypeDefinitionFinishAsClass) -CARBON_PARSER_STATE(TypeDefinitionFinishAsInterface) -CARBON_PARSER_STATE(TypeDefinitionFinishAsNamedConstraint) +CARBON_PARSER_STATE_VARIANTS3(TypeDefinitionFinish, Class, Interface, + NamedConstraint) -// Handles processing of a type's ` [;{]`. +// Handles processing of a type's introducer. +// +// Always: +// 1. DeclarationNameAndParamsAsOptional +// 2. TypeAfterParamsAs(Class|Interface|NamedConstraint) +CARBON_PARSER_STATE_VARIANTS3(TypeIntroducer, Class, Interface, NamedConstraint) + +// Handles processing of a type after its optional parameters. // // If `Semi`: // (state done) @@ -576,9 +570,8 @@ CARBON_PARSER_STATE(TypeDefinitionFinishAsNamedConstraint) // 2. TypeDefinitionFinishAs(Class|Interface|NamedConstraint) // Else: // (state done) -CARBON_PARSER_STATE(TypeIntroducerAsClass) -CARBON_PARSER_STATE(TypeIntroducerAsInterface) -CARBON_PARSER_STATE(TypeIntroducerAsNamedConstraint) +CARBON_PARSER_STATE_VARIANTS3(TypeAfterParams, Class, Interface, + NamedConstraint) // Handles the start of a `var`. // diff --git a/toolchain/parser/testdata/function/declaration/deduced_one.carbon b/toolchain/parser/testdata/function/declaration/deduced_empty.carbon similarity index 76% rename from toolchain/parser/testdata/function/declaration/deduced_one.carbon rename to toolchain/parser/testdata/function/declaration/deduced_empty.carbon index b7534ee18659..91b161775a6d 100644 --- a/toolchain/parser/testdata/function/declaration/deduced_one.carbon +++ b/toolchain/parser/testdata/function/declaration/deduced_empty.carbon @@ -8,14 +8,11 @@ // CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, // CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 2}, // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 7}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] -fn foo[a: i32](); +fn foo[](); diff --git a/toolchain/parser/testdata/function/declaration/deduced_one_suffix_comma.carbon b/toolchain/parser/testdata/function/declaration/deduced_one_suffix_comma.carbon deleted file mode 100644 index 01e130ca7929..000000000000 --- a/toolchain/parser/testdata/function/declaration/deduced_one_suffix_comma.carbon +++ /dev/null @@ -1,22 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 11}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo[a: i32,](); diff --git a/toolchain/parser/testdata/function/declaration/deduced_two.carbon b/toolchain/parser/testdata/function/declaration/deduced_params.carbon similarity index 100% rename from toolchain/parser/testdata/function/declaration/deduced_two.carbon rename to toolchain/parser/testdata/function/declaration/deduced_params.carbon diff --git a/toolchain/parser/testdata/function/declaration/deduced_six.carbon b/toolchain/parser/testdata/function/declaration/deduced_six.carbon deleted file mode 100644 index 306c5271ca2c..000000000000 --- a/toolchain/parser/testdata/function/declaration/deduced_six.carbon +++ /dev/null @@ -1,41 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'c'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'd'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'e'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'f'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 25}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 30}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo[a: i32, b: i32, c: i32, d: i32, e: i32, f: i32](); diff --git a/toolchain/parser/testdata/function/declaration/deduced_two_suffix_comma.carbon b/toolchain/parser/testdata/function/declaration/deduced_two_suffix_comma.carbon deleted file mode 100644 index 30bebd69cb8a..000000000000 --- a/toolchain/parser/testdata/function/declaration/deduced_two_suffix_comma.carbon +++ /dev/null @@ -1,26 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 10}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 15}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo[a: i32, b: i32,](); diff --git a/toolchain/parser/testdata/function/declaration/fail_identifier_instead_of_sig.carbon b/toolchain/parser/testdata/function/declaration/fail_identifier_instead_of_sig.carbon index c54e50d4b4ac..9d8a737e384f 100644 --- a/toolchain/parser/testdata/function/declaration/fail_identifier_instead_of_sig.carbon +++ b/toolchain/parser/testdata/function/declaration/fail_identifier_instead_of_sig.carbon @@ -11,5 +11,5 @@ // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] -// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_identifier_instead_of_sig.carbon:[[@LINE+1]]:8: Expected `(` after function name. +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_identifier_instead_of_sig.carbon:[[@LINE+1]]:8: `fn` requires a `(` for parameters. fn foo bar; diff --git a/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon b/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon index 0f79c7e73646..5eaf8e1c93e7 100644 --- a/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon +++ b/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon @@ -17,4 +17,4 @@ // CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon:[[@LINE+2]]:7: Closing symbol does not match most recent opening symbol. // CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon:[[@LINE+1]]:8: Expected parameter declaration. fn Div[(); -// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon:[[@LINE+0]]:156: Expected `(` after function name. +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_missing_deduced_close.carbon:[[@LINE+0]]:181: A `(` for parameters is required after deduced parameters. diff --git a/toolchain/parser/testdata/function/declaration/fail_no_sig_or_semi.carbon b/toolchain/parser/testdata/function/declaration/fail_no_sig_or_semi.carbon index eba6e4312bb7..42ef84ce45a6 100644 --- a/toolchain/parser/testdata/function/declaration/fail_no_sig_or_semi.carbon +++ b/toolchain/parser/testdata/function/declaration/fail_no_sig_or_semi.carbon @@ -11,5 +11,5 @@ // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] -// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_no_sig_or_semi.carbon:[[@LINE+1]]:7: Expected `(` after function name. +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/function/declaration/fail_no_sig_or_semi.carbon:[[@LINE+1]]:7: `fn` requires a `(` for parameters. fn foo diff --git a/toolchain/parser/testdata/function/declaration/params_two.carbon b/toolchain/parser/testdata/function/declaration/params.carbon similarity index 100% rename from toolchain/parser/testdata/function/declaration/params_two.carbon rename to toolchain/parser/testdata/function/declaration/params.carbon diff --git a/toolchain/parser/testdata/function/declaration/params_one.carbon b/toolchain/parser/testdata/function/declaration/params_one.carbon deleted file mode 100644 index 21dd3b90d47b..000000000000 --- a/toolchain/parser/testdata/function/declaration/params_one.carbon +++ /dev/null @@ -1,19 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo(a: i32); diff --git a/toolchain/parser/testdata/function/declaration/params_one_suffix_comma.carbon b/toolchain/parser/testdata/function/declaration/params_one_suffix_comma.carbon deleted file mode 100644 index 9f61a2e41323..000000000000 --- a/toolchain/parser/testdata/function/declaration/params_one_suffix_comma.carbon +++ /dev/null @@ -1,20 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 9}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo(a: i32,); diff --git a/toolchain/parser/testdata/function/declaration/params_six.carbon b/toolchain/parser/testdata/function/declaration/params_six.carbon deleted file mode 100644 index 672bfa408417..000000000000 --- a/toolchain/parser/testdata/function/declaration/params_six.carbon +++ /dev/null @@ -1,39 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'c'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'd'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'e'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'f'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 25}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 28}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32); diff --git a/toolchain/parser/testdata/function/declaration/params_two_suffix_comma.carbon b/toolchain/parser/testdata/function/declaration/params_two_suffix_comma.carbon deleted file mode 100644 index 900f90cc4857..000000000000 --- a/toolchain/parser/testdata/function/declaration/params_two_suffix_comma.carbon +++ /dev/null @@ -1,24 +0,0 @@ -// Part of the Carbon Language project, under the Apache License v2.0 with LLVM -// Exceptions. See /LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// AUTOUPDATE -// RUN: %{carbon-run-parser} -// CHECK:STDOUT: [ -// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, -// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, -// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 10}, -// CHECK:STDOUT: {kind: 'FunctionDeclaration', text: ';', subtree_size: 13}, -// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, -// CHECK:STDOUT: ] - -fn foo(a: i32, b: i32,); diff --git a/toolchain/parser/testdata/generics/deduced_params/empty.carbon b/toolchain/parser/testdata/generics/deduced_params/empty.carbon new file mode 100644 index 000000000000..177b8827d650 --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/empty.carbon @@ -0,0 +1,28 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo[](); + +interface Bar[]() {} diff --git a/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon b/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon new file mode 100644 index 000000000000..7534ec55039a --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon @@ -0,0 +1,47 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{not} %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', has_error: yes, subtree_size: 8}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDeclaration', text: 'interface', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceDeclaration', text: 'interface', has_error: yes, subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon:[[@LINE+1]]:12: A `(` for parameters is required after deduced parameters. +class Foo[]; + +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon:[[@LINE+1]]:18: A `(` for parameters is required after deduced parameters. +class Foo[a: i32]; + +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon:[[@LINE+1]]:17: A `(` for parameters is required after deduced parameters. +interface Bar[] {} + +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/generics/deduced_params/fail_no_parens.carbon:[[@LINE+1]]:23: A `(` for parameters is required after deduced parameters. +interface Bar[a: i32] {} diff --git a/toolchain/parser/testdata/generics/deduced_params/one.carbon b/toolchain/parser/testdata/generics/deduced_params/one.carbon new file mode 100644 index 000000000000..653efc807618 --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/one.carbon @@ -0,0 +1,34 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo[a: i32](); + +interface Bar[a: i32]() {} diff --git a/toolchain/parser/testdata/generics/deduced_params/one_suffix_comma.carbon b/toolchain/parser/testdata/generics/deduced_params/one_suffix_comma.carbon new file mode 100644 index 000000000000..5f4951cca627 --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/one_suffix_comma.carbon @@ -0,0 +1,36 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo[a: i32,](); + +interface Bar[a: i32,]() {} diff --git a/toolchain/parser/testdata/generics/deduced_params/six.carbon b/toolchain/parser/testdata/generics/deduced_params/six.carbon new file mode 100644 index 000000000000..0c555efc8000 --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/six.carbon @@ -0,0 +1,74 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'c'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'd'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'e'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'f'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 25}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 30}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'c'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'd'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'e'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'f'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 25}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 30}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 31}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo[a: i32, b: i32, c: i32, d: i32, e: i32, f: i32](); + +interface Bar[a: i32, b: i32, c: i32, d: i32, e: i32, f: i32]() {} diff --git a/toolchain/parser/testdata/generics/deduced_params/two.carbon b/toolchain/parser/testdata/generics/deduced_params/two.carbon new file mode 100644 index 000000000000..beaf9b21343f --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/two.carbon @@ -0,0 +1,42 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo[a: i32, b: i32](); + +interface Bar[a: i32, b: i32]() {} diff --git a/toolchain/parser/testdata/generics/deduced_params/two_suffix_comma.carbon b/toolchain/parser/testdata/generics/deduced_params/two_suffix_comma.carbon new file mode 100644 index 000000000000..f70c0daf9648 --- /dev/null +++ b/toolchain/parser/testdata/generics/deduced_params/two_suffix_comma.carbon @@ -0,0 +1,44 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'DeducedParameterListStart', text: '['}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeducedParameterList', text: ']', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 16}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo[a: i32, b: i32,](); + +interface Bar[a: i32, b: i32,]() {} diff --git a/toolchain/parser/testdata/generics/params/empty.carbon b/toolchain/parser/testdata/generics/params/empty.carbon new file mode 100644 index 000000000000..28fac6a361a2 --- /dev/null +++ b/toolchain/parser/testdata/generics/params/empty.carbon @@ -0,0 +1,24 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo(); + +interface Bar() {} diff --git a/toolchain/parser/testdata/generics/params/one.carbon b/toolchain/parser/testdata/generics/params/one.carbon new file mode 100644 index 000000000000..df707855567f --- /dev/null +++ b/toolchain/parser/testdata/generics/params/one.carbon @@ -0,0 +1,30 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo(a: i32); + +interface Bar(a: i32) {} diff --git a/toolchain/parser/testdata/generics/params/one_suffix_comma.carbon b/toolchain/parser/testdata/generics/params/one_suffix_comma.carbon new file mode 100644 index 000000000000..4673ea28bfde --- /dev/null +++ b/toolchain/parser/testdata/generics/params/one_suffix_comma.carbon @@ -0,0 +1,32 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo(a: i32,); + +interface Bar(a: i32,) {} diff --git a/toolchain/parser/testdata/generics/params/six.carbon b/toolchain/parser/testdata/generics/params/six.carbon new file mode 100644 index 000000000000..e2741420cafc --- /dev/null +++ b/toolchain/parser/testdata/generics/params/six.carbon @@ -0,0 +1,70 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'c'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'd'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'e'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'f'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 25}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 28}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'c'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'd'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'e'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'f'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 25}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 28}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 29}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32); + +interface Bar(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32) {} diff --git a/toolchain/parser/testdata/generics/params/two.carbon b/toolchain/parser/testdata/generics/params/two.carbon new file mode 100644 index 000000000000..35f020bf5f5c --- /dev/null +++ b/toolchain/parser/testdata/generics/params/two.carbon @@ -0,0 +1,38 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 12}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 13}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo(a: i32, b: i32); + +interface Bar(a: i32, b: i32) {} diff --git a/toolchain/parser/testdata/generics/params/two_suffix_comma.carbon b/toolchain/parser/testdata/generics/params/two_suffix_comma.carbon new file mode 100644 index 000000000000..db229bd65030 --- /dev/null +++ b/toolchain/parser/testdata/generics/params/two_suffix_comma.carbon @@ -0,0 +1,40 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'ClassIntroducer', text: 'class'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Foo'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ClassDeclaration', text: ';', subtree_size: 13}, +// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'Bar'}, +// CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'a'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'b'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParameterListComma', text: ','}, +// CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 13}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +class Foo(a: i32, b: i32,); + +interface Bar(a: i32, b: i32,) {}