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,) {}