Add match parsing (#3664)

Adds `match` parsing to toolchain
This commit is contained in:
czapiga
2024-02-13 00:27:06 +00:00
committed by GitHub
parent cc6f21e402
commit 99bc9734d9
21 changed files with 1356 additions and 17 deletions
+95
View File
@@ -0,0 +1,95 @@
// 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
#include "toolchain/check/context.h"
#include "toolchain/check/convert.h"
namespace Carbon::Check {
auto HandleMatchConditionStart(Context& context,
Parse::MatchConditionStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchConditionStart");
}
auto HandleMatchCondition(Context& context, Parse::MatchConditionId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCondition");
}
auto HandleMatchIntroducer(Context& context,
Parse::MatchIntroducerId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchIntroducer");
}
auto HandleMatchStatementStart(Context& context,
Parse::MatchStatementStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchStatementStart");
}
auto HandleMatchCaseIntroducer(Context& context,
Parse::MatchCaseIntroducerId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseIntroducer");
}
auto HandleMatchCaseGuardIntroducer(
Context& context, Parse::MatchCaseGuardIntroducerId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchCaseGuardIntroducer");
}
auto HandleMatchCaseGuardStart(Context& context,
Parse::MatchCaseGuardStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseGuardStart");
}
auto HandleMatchCaseGuard(Context& context, Parse::MatchCaseGuardId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseGuard");
}
auto HandleMatchCaseEqualGreater(Context& context,
Parse::MatchCaseEqualGreaterId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseEqualGreater");
}
auto HandleMatchCaseStart(Context& context, Parse::MatchCaseStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseStart");
}
auto HandleMatchCase(Context& context, Parse::MatchCaseId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchCase");
}
auto HandleMatchDefaultIntroducer(Context& context,
Parse::MatchDefaultIntroducerId parse_node)
-> bool {
return context.TODO(parse_node, "MatchDefaultIntroducer");
}
auto HandleMatchDefaultEqualGreater(
Context& context, Parse::MatchDefaultEqualGreaterId parse_node) -> bool {
return context.TODO(parse_node, "MatchDefaultEqualGreater");
}
auto HandleMatchDefaultStart(Context& context,
Parse::MatchDefaultStartId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchDefaultStart");
}
auto HandleMatchDefault(Context& context, Parse::MatchDefaultId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchDefault");
}
auto HandleMatchStatement(Context& context, Parse::MatchStatementId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchStatement");
}
} // namespace Carbon::Check
@@ -73,6 +73,12 @@ CARBON_DIAGNOSTIC_KIND(ExpectedVarAfterReturned)
CARBON_DIAGNOSTIC_KIND(ExpectedVariableDecl)
CARBON_DIAGNOSTIC_KIND(ExpectedChoiceDefinition)
CARBON_DIAGNOSTIC_KIND(ExpectedChoiceAlternativeName)
CARBON_DIAGNOSTIC_KIND(ExpectedMatchCases)
CARBON_DIAGNOSTIC_KIND(ExpectedMatchCasesBlock)
CARBON_DIAGNOSTIC_KIND(ExpectedMatchCaseArrow)
CARBON_DIAGNOSTIC_KIND(ExpectedMatchCaseBlock)
CARBON_DIAGNOSTIC_KIND(UnexpectedTokenInMatchCasesBlock)
CARBON_DIAGNOSTIC_KIND(UnreachableMatchCase)
CARBON_DIAGNOSTIC_KIND(OperatorRequiresParentheses)
CARBON_DIAGNOSTIC_KIND(StatementOperatorAsSubExpr)
CARBON_DIAGNOSTIC_KIND(UnaryOperatorRequiresParentheses)
+232
View File
@@ -0,0 +1,232 @@
// 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
#include "toolchain/parse/context.h"
namespace Carbon::Parse {
static auto HandleStatementsBlockStart(Context& context, State finish,
NodeKind equal_greater, NodeKind starter,
NodeKind complete) -> void {
auto state = context.PopState();
if (!context.PositionIs(Lex::TokenKind::EqualGreater)) {
if (!state.has_error) {
CARBON_DIAGNOSTIC(ExpectedMatchCaseArrow, Error,
"Expected `=>` introducing statement block.");
context.emitter().Emit(*context.position(), ExpectedMatchCaseArrow);
}
context.AddLeafNode(equal_greater, *context.position(), true);
context.AddNode(starter, *context.position(), state.subtree_start, true);
context.AddNode(complete, *context.position(), state.subtree_start, true);
context.SkipPastLikelyEnd(*context.position());
return;
}
context.AddLeafNode(equal_greater, context.Consume());
if (!context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
if (!state.has_error) {
CARBON_DIAGNOSTIC(ExpectedMatchCaseBlock, Error,
"Expected `{{` after `=>`.");
context.emitter().Emit(*context.position(), ExpectedMatchCaseBlock);
}
context.AddNode(starter, *context.position(), state.subtree_start, true);
context.AddNode(complete, *context.position(), state.subtree_start, true);
context.SkipPastLikelyEnd(*context.position());
return;
}
context.AddNode(starter, context.Consume(), state.subtree_start,
state.has_error);
context.PushState(state, finish);
context.PushState(State::StatementScopeLoop);
}
static auto EmitUnexpectedTokenAndRecover(Context& context) -> void {
CARBON_DIAGNOSTIC(UnexpectedTokenInMatchCasesBlock, Error,
"Unexpected `{0}`; expected `case`, `default` or `}`.",
Lex::TokenKind);
context.emitter().Emit(*context.position(), UnexpectedTokenInMatchCasesBlock,
context.PositionKind());
context.ReturnErrorOnState();
context.SkipPastLikelyEnd(*context.position());
}
auto HandleMatchIntroducer(Context& context) -> void {
auto state = context.PopState();
context.AddLeafNode(NodeKind::Placeholder, *context.position());
context.PushState(state, State::MatchConditionFinish);
context.PushState(State::ParenConditionAsMatch);
context.ConsumeAndDiscard();
}
auto HandleMatchConditionFinish(Context& context) -> void {
auto state = context.PopState();
context.ReplacePlaceholderNode(state.subtree_start, NodeKind::MatchIntroducer,
state.token);
if (!context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
if (!state.has_error) {
CARBON_DIAGNOSTIC(ExpectedMatchCasesBlock, Error,
"Expected `{{` starting block with cases.");
context.emitter().Emit(*context.position(), ExpectedMatchCasesBlock);
}
context.AddNode(NodeKind::MatchStatementStart, *context.position(),
state.subtree_start, true);
context.AddNode(NodeKind::MatchStatement, *context.position(),
state.subtree_start, true);
context.SkipPastLikelyEnd(*context.position());
return;
}
context.AddNode(NodeKind::MatchStatementStart, context.Consume(),
state.subtree_start, state.has_error);
state.has_error = false;
if (context.PositionIs(Lex::TokenKind::CloseCurlyBrace)) {
CARBON_DIAGNOSTIC(ExpectedMatchCases, Error, "Expected cases.");
context.emitter().Emit(*context.position(), ExpectedMatchCases);
state.has_error = true;
}
context.PushState(state, State::MatchStatementFinish);
context.PushState(State::MatchCaseLoop);
}
auto HandleMatchCaseLoop(Context& context) -> void {
context.PopAndDiscardState();
if (context.PositionIs(Lex::TokenKind::Case)) {
context.PushState(State::MatchCaseLoop);
context.PushState(State::MatchCaseIntroducer);
} else if (context.PositionIs(Lex::TokenKind::Default)) {
context.PushState(State::MatchCaseLoopAfterDefault);
context.PushState(State::MatchDefaultIntroducer);
} else if (!context.PositionIs(Lex::TokenKind::CloseCurlyBrace)) {
EmitUnexpectedTokenAndRecover(context);
context.PushState(State::MatchCaseLoop);
}
}
auto HandleMatchCaseLoopAfterDefault(Context& context) -> void {
context.PopAndDiscardState();
Lex::TokenKind kind = context.PositionKind();
if (kind == Lex::TokenKind::Case or kind == Lex::TokenKind::Default) {
CARBON_DIAGNOSTIC(UnreachableMatchCase, Error, "Unreachable case; `{0}{1}",
Lex::TokenKind, std::string);
context.emitter().Emit(*context.position(), UnreachableMatchCase, kind,
"` occurs after the `default`");
context.ReturnErrorOnState();
context.PushState(State::MatchCaseLoopAfterDefault);
context.SkipPastLikelyEnd(*context.position());
return;
} else if (kind != Lex::TokenKind::CloseCurlyBrace) {
EmitUnexpectedTokenAndRecover(context);
context.PushState(State::MatchCaseLoopAfterDefault);
}
}
auto HandleMatchCaseIntroducer(Context& context) -> void {
auto state = context.PopState();
context.AddLeafNode(NodeKind::MatchCaseIntroducer, context.Consume());
context.PushState(state, State::MatchCaseAfterPattern);
context.PushState(State::Pattern);
}
auto HandleMatchCaseAfterPattern(Context& context) -> void {
auto state = context.PopState();
if (state.has_error) {
context.AddNode(NodeKind::MatchCaseStart, *context.position(),
state.subtree_start, true);
context.AddNode(NodeKind::MatchCase, *context.position(),
state.subtree_start, true);
context.SkipPastLikelyEnd(*context.position());
return;
}
context.PushState(state, State::MatchCaseStart);
if (context.PositionIs(Lex::TokenKind::If)) {
context.PushState(State::MatchCaseGuardFinish);
context.AddLeafNode(NodeKind::MatchCaseGuardIntroducer, context.Consume());
auto open_paren = context.ConsumeIf(Lex::TokenKind::OpenParen);
if (open_paren) {
context.AddLeafNode(NodeKind::MatchCaseGuardStart, *open_paren);
context.PushState(State::Expr);
} else {
context.AddLeafNode(NodeKind::MatchCaseGuardStart, *context.position(),
true);
context.AddLeafNode(NodeKind::InvalidParse, *context.position(), true);
state = context.PopState();
context.AddNode(NodeKind::MatchCaseGuard, *context.position(),
state.subtree_start, true);
state = context.PopState();
context.AddNode(NodeKind::MatchCaseStart, *context.position(),
state.subtree_start, true);
context.AddNode(NodeKind::MatchCase, *context.position(),
state.subtree_start, true);
context.SkipPastLikelyEnd(*context.position());
return;
}
}
}
auto HandleMatchCaseGuardFinish(Context& context) -> void {
auto state = context.PopState();
auto close_paren = context.ConsumeIf(Lex::TokenKind::CloseParen);
if (close_paren) {
context.AddNode(NodeKind::MatchCaseGuard, *close_paren, state.subtree_start,
state.has_error);
} else {
context.AddNode(NodeKind::MatchCaseGuard, *context.position(),
state.subtree_start, true);
context.ReturnErrorOnState();
context.SkipPastLikelyEnd(*context.position());
return;
}
}
auto HandleMatchCaseStart(Context& context) -> void {
HandleStatementsBlockStart(context, State::MatchCaseFinish,
NodeKind::MatchCaseEqualGreater,
NodeKind::MatchCaseStart, NodeKind::MatchCase);
}
auto HandleMatchCaseFinish(Context& context) -> void {
auto state = context.PopState();
context.AddNode(NodeKind::MatchCase,
context.ConsumeChecked(Lex::TokenKind::CloseCurlyBrace),
state.subtree_start, state.has_error);
}
auto HandleMatchDefaultIntroducer(Context& context) -> void {
context.AddLeafNode(NodeKind::MatchDefaultIntroducer, context.Consume());
HandleStatementsBlockStart(
context, State::MatchDefaultFinish, NodeKind::MatchDefaultEqualGreater,
NodeKind::MatchDefaultStart, NodeKind::MatchDefault);
}
auto HandleMatchDefaultFinish(Context& context) -> void {
auto state = context.PopState();
context.AddNode(NodeKind::MatchDefault,
context.ConsumeChecked(Lex::TokenKind::CloseCurlyBrace),
state.subtree_start, state.has_error);
}
auto HandleMatchStatementFinish(Context& context) -> void {
auto state = context.PopState();
context.AddNode(NodeKind::MatchStatement,
context.ConsumeChecked(Lex::TokenKind::CloseCurlyBrace),
state.subtree_start, state.has_error);
}
} // namespace Carbon::Parse
+13 -1
View File
@@ -6,7 +6,7 @@
namespace Carbon::Parse {
// Handles ParenConditionAs(If|While).
// Handles ParenConditionAs(If|While|Match).
static auto HandleParenCondition(Context& context, NodeKind start_kind,
State finish_state) -> void {
auto state = context.PopState();
@@ -39,6 +39,11 @@ auto HandleParenConditionAsWhile(Context& context) -> void {
State::ParenConditionFinishAsWhile);
}
auto HandleParenConditionAsMatch(Context& context) -> void {
HandleParenCondition(context, NodeKind::MatchConditionStart,
State::ParenConditionFinishAsMatch);
}
auto HandleParenConditionFinishAsIf(Context& context) -> void {
auto state = context.PopState();
@@ -52,4 +57,11 @@ auto HandleParenConditionFinishAsWhile(Context& context) -> void {
NodeKind::WhileCondition);
}
auto HandleParenConditionFinishAsMatch(Context& context) -> void {
auto state = context.PopState();
context.ConsumeAndAddCloseSymbol(state.token, state,
NodeKind::MatchCondition);
}
} // namespace Carbon::Parse
+4
View File
@@ -52,6 +52,10 @@ auto HandleStatement(Context& context) -> void {
context.PushState(State::StatementWhile);
break;
}
case Lex::TokenKind::Match: {
context.PushState(State::MatchIntroducer);
break;
}
default: {
context.PushState(State::ExprStatementFinish);
context.PushStateForExpr(PrecedenceGroup::ForExprStatement());
+58
View File
@@ -737,6 +737,64 @@ CARBON_PARSE_NODE_KIND_BRACKET(ChoiceDefinition, ChoiceDefinitionStart,
// ChoiceAlternativeList
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ChoiceAlternativeListComma, 0, Comma)
// `match`:
// MatchIntroducer
// MatchConditionStart
// _external_: expression
// MatchCondition
// MatchStatementStart
// _repeated_ _external_: MatchCase
// _optional_ _external_: MatchStatementDefault
// MatchStatement
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchIntroducer, 0, Match)
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchConditionStart, 0,
CARBON_IF_VALID(OpenParen))
CARBON_PARSE_NODE_KIND_BRACKET(MatchCondition, MatchConditionStart,
CARBON_IF_VALID(CloseParen))
CARBON_PARSE_NODE_KIND_BRACKET(MatchStatementStart, MatchIntroducer,
CARBON_IF_VALID(OpenCurlyBrace))
CARBON_PARSE_NODE_KIND_BRACKET(MatchStatement, MatchStatementStart,
CARBON_IF_VALID(CloseCurlyBrace))
// `case`:
// MatchCaseIntroducer
// _external_: Pattern
// MatchCaseGuardIntroducer
// MatchCaseGuardStart
// _external_: expression
// MatchCaseGuard
// MatchCaseEqualGreater
// MatchCaseStart
// _repeated_ _external_: statement
// MatchCase
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseIntroducer, 0, Case)
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseGuardIntroducer, 0, If)
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseGuardStart, 0,
CARBON_IF_VALID(OpenParen))
CARBON_PARSE_NODE_KIND_BRACKET(MatchCaseGuard,
MatchCaseGuardIntroducer,
CARBON_IF_VALID(CloseParen))
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchCaseEqualGreater, 0,
CARBON_IF_VALID(EqualGreater))
CARBON_PARSE_NODE_KIND_BRACKET(MatchCaseStart, MatchCaseIntroducer,
CARBON_IF_VALID(OpenCurlyBrace))
CARBON_PARSE_NODE_KIND_BRACKET(MatchCase, MatchCaseStart,
CARBON_IF_VALID(CloseCurlyBrace))
// `default`:
// MatchDefaultIntroducer
// MatchDefaultEqualGreater
// MatchDefaultStart
// _repeated_ _external_: statement
// MatchDefault
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchDefaultIntroducer, 0, Default)
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MatchDefaultEqualGreater, 0,
CARBON_IF_VALID(EqualGreater))
CARBON_PARSE_NODE_KIND_BRACKET(MatchDefaultStart, MatchDefaultIntroducer,
CARBON_IF_VALID(OpenCurlyBrace))
CARBON_PARSE_NODE_KIND_BRACKET(MatchDefault, MatchDefaultStart,
CARBON_IF_VALID(CloseCurlyBrace))
#undef CARBON_PARSE_NODE_KIND
#undef CARBON_PARSE_NODE_KIND_BRACKET
#undef CARBON_PARSE_NODE_KIND_CHILD_COUNT
+147 -16
View File
@@ -730,28 +730,28 @@ CARBON_PARSE_STATE_VARIANTS2(PatternListFinish, Implicit, Tuple)
// Handles the processing of a `(condition)` up through the expression.
//
// if/while { (invalid)
// ^
// 1. ParenConditionAs(If|While)Finish
// if/while/match { (invalid)
// ^
// 1. ParenConditionAs(If|While|Match)Finish
//
// if/while ( ... )
// ^
// if/while ???
// ^
// if/while/match ( ... )
// ^
// if/while/match ???
// ^
// 1. Expr
// 2. ParenConditionAs(If|While)Finish
CARBON_PARSE_STATE_VARIANTS2(ParenCondition, If, While)
// 2. ParenConditionAs(If|While|Match)Finish
CARBON_PARSE_STATE_VARIANTS3(ParenCondition, If, While, Match)
// Finishes the processing of a `(condition)` after the expression.
//
// if/while ( expr )
// ^
// if/while {
// ^
// if/while ??? {
// ^
// if/while/match ( expr )
// ^
// if/while/match {
// ^
// if/while/match ??? {
// ^
// (state done)
CARBON_PARSE_STATE_VARIANTS2(ParenConditionFinish, If, While)
CARBON_PARSE_STATE_VARIANTS3(ParenConditionFinish, If, While, Match)
// Handles the `(` of a parenthesized single expression
//
@@ -922,6 +922,10 @@ CARBON_PARSE_STATE_VARIANTS2(BindingPatternFinish, Generic, Regular)
// ^
// 1. Expr
// 2. ExprStatementFinish
//
// match ...
// ^
// 1. MatchIntroducer
CARBON_PARSE_STATE(Statement)
// Handles `break` processing at the `;`.
@@ -1304,4 +1308,131 @@ CARBON_PARSE_STATE(ChoiceAlternativeFinish)
// (state done)
CARBON_PARSE_STATE(ChoiceDefinitionFinish)
// Handles `match` introducer.
//
// match ...
// ^~~~~
// 1. ParenConditionAsMatch
// 2. MatchConditionFinish
CARBON_PARSE_STATE(MatchIntroducer)
// Handles `match` cases block start after the condition.
//
// match (...) { ... }
// ^
// 1. MatchCaseLoop
// 2. MatchStatementFinish
//
// match (...) ???
// ^
// (state done)
CARBON_PARSE_STATE(MatchConditionFinish)
// Handles `match` cases.
//
// match (...) { case ...}
// ^
// 1. MatchCaseIntroducer
// 2. MatchCaseLoop
// match (...) { default ...}
// ^
// 1. MatchDefaultIntroducer
// 2. MatchCaseLoopAfterDefault
CARBON_PARSE_STATE(MatchCaseLoop)
// Handles `match` `case` introducer.
//
// match (...) { case ...}
// ^~~~
// 1. Pattern
// 2. MatchCaseAfterPattern
CARBON_PARSE_STATE(MatchCaseIntroducer)
// Handles `match` case after pattern.
//
// match (...) { case ... => ... }
// ^
// 1. MatchCaseStart
// match (...) { case ... if (...) }
// ^~~~
// 1. Expr
// 2. MatchCaseGuardFinish
// 3. MatchCaseStart
CARBON_PARSE_STATE(MatchCaseAfterPattern)
// Handles `match` case guard closing parenthesis.
//
// match (...) { case ... if (...) => ... }
// ^
// (state done)
CARBON_PARSE_STATE(MatchCaseGuardFinish)
// Handles `match` case `=>` and `{` opening statements block.
//
// match (...) { case ... => {...} }
// ^~~~
// 1. StatementScopeLoop
// 2. MatchCaseFinish
//
// match (...) { case ... ??? }
// ^
// (state done)
//
// match (...) { case ... => ??? }
// ^
// (state done)
CARBON_PARSE_STATE(MatchCaseStart)
// Handles `match` case statements block closing `}`.
//
// match (...) { case ... => {...} }
// ^
// (state done)
CARBON_PARSE_STATE(MatchCaseFinish)
// Handles `match` default introducer, `=>` and `{` opening statements block.
//
// match (...) { default => {...} }
// ^~~~~~~~~~~~
// 1. StatementScopeLoop
// 2. MatchDefaultFinish
//
// match (...) { default ??? }
// ^
// (state done)
//
// match (...) { default => ??? }
// ^
// (state done)
CARBON_PARSE_STATE(MatchDefaultIntroducer)
// Handles `match` default case statements block closing `}`.
//
// match (...) { default => {...} }
// ^
// (state done)
CARBON_PARSE_STATE(MatchDefaultFinish)
// Handles `match` cases after the `default` case.
//
// match (...) { default => {...} case ... }
// ^~~~
// 1. MatchCaseLoopAfterDefault
//
// match (...) { default => {...} default ... }
// ^~~~~~~
// 1. MatchCaseLoopAfterDefault
//
// match (...) { default => {...} }
// ^
// (state done)
CARBON_PARSE_STATE(MatchCaseLoopAfterDefault)
// Finishes `match` statement.
//
// match (...) {...}
// ^
// (state done)
CARBON_PARSE_STATE(MatchStatementFinish)
#undef CARBON_PARSE_STATE
@@ -0,0 +1,62 @@
// 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
fn f() -> i32 {
var x: i32 = 3;
match (x) {
default => { return 1; }
// CHECK:STDERR: fail_cases_after_default.carbon:[[@LINE+3]]:5: ERROR: Unreachable case; `case` occurs after the `default`
// CHECK:STDERR: case a: i32 => { return 2; }
// CHECK:STDERR: ^~~~
case a: i32 => { return 2; }
// CHECK:STDERR: fail_cases_after_default.carbon:[[@LINE+3]]:5: ERROR: Unreachable case; `default` occurs after the `default`
// CHECK:STDERR: default => { return 3; }
// CHECK:STDERR: ^~~~~~~
default => { return 3; }
// CHECK:STDERR: fail_cases_after_default.carbon:[[@LINE+3]]:5: ERROR: Unreachable case; `case` occurs after the `default`
// CHECK:STDERR: case (a: i32) if (a == 4) => { return 4; }
// CHECK:STDERR: ^~~~
case (a: i32) if (a == 4) => { return 4; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_cases_after_default.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 2},
// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'x'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchDefaultIntroducer', text: 'default'},
// CHECK:STDOUT: {kind: 'MatchDefaultEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchDefaultStart', text: '{', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchDefault', text: '}', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', has_error: yes, subtree_size: 13},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 31},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,62 @@
// 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
fn f() -> i32 {
match (3) {
// CHECK:STDERR: fail_missing_case_arrow.carbon:[[@LINE+3]]:17: ERROR: Expected `=>` introducing statement block.
// CHECK:STDERR: case x: i32 { return 2; }
// CHECK:STDERR: ^
case x: i32 { return 2; }
// CHECK:STDERR: fail_missing_case_arrow.carbon:[[@LINE+3]]:29: ERROR: Expected `=>` introducing statement block.
// CHECK:STDERR: case x: i32 if (x == 3) { return 3; }
// CHECK:STDERR: ^
case x: i32 if (x == 3) { return 3; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_case_arrow.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '{', has_error: yes},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', has_error: yes, subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCase', text: '{', has_error: yes, subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'x'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'InfixOperatorEqualEqual', text: '==', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: ')', subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '{', has_error: yes},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', has_error: yes, subtree_size: 12},
// CHECK:STDOUT: {kind: 'MatchCase', text: '{', has_error: yes, subtree_size: 13},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 26},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 37},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -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
fn f() -> i32 {
match (3) {
// CHECK:STDERR: fail_missing_case_pattern.carbon:[[@LINE+3]]:10: ERROR: Expected binding pattern.
// CHECK:STDERR: case => { return 2; }
// CHECK:STDERR: ^~
case => { return 2; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_case_pattern.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: '=>', has_error: yes},
// CHECK:STDOUT: {kind: 'InvalidParse', text: '=>', has_error: yes},
// CHECK:STDOUT: {kind: 'BindingPattern', text: '=>', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '=>', has_error: yes, subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCase', text: '=>', has_error: yes, subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 12},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 23},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,46 @@
// 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
fn f() -> i32 {
match (3) {
case x: i32 =>
// CHECK:STDERR: fail_missing_case_statements_block.carbon:[[@LINE+3]]:5: ERROR: Expected `{` after `=>`.
// CHECK:STDERR: default => { return 3; }
// CHECK:STDERR: ^~~~~~~
default => { return 3; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_case_statements_block.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: 'default', has_error: yes, subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCase', text: 'default', has_error: yes, subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 24},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,37 @@
// 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
fn f() -> i32 {
// CHECK:STDERR: fail_missing_cases.carbon:[[@LINE+3]]:14: ERROR: Expected cases.
// CHECK:STDERR: match (3) {}
// CHECK:STDERR: ^
match (3) {}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_cases.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', has_error: yes, subtree_size: 6},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 17},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,33 @@
// 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
fn f() -> i32 {
match (1)
// CHECK:STDERR: fail_missing_cases_block.carbon:[[@LINE+3]]:3: ERROR: Expected `{` starting block with cases.
// CHECK:STDERR: return 0;
// CHECK:STDERR: ^~~~~~
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_cases_block.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: 'return', has_error: yes, subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchStatement', text: 'return', has_error: yes, subtree_size: 6},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 14},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -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
fn f() -> i32 {
match (3) {
// CHECK:STDERR: fail_missing_default_arrow.carbon:[[@LINE+3]]:13: ERROR: Expected `=>` introducing statement block.
// CHECK:STDERR: default { return 1; }
// CHECK:STDERR: ^
default { return 1; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_default_arrow.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchDefaultIntroducer', text: 'default'},
// CHECK:STDOUT: {kind: 'MatchDefaultEqualGreater', text: '{', has_error: yes},
// CHECK:STDOUT: {kind: 'MatchDefaultStart', text: '{', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchDefault', text: '{', has_error: yes, subtree_size: 4},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 10},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 21},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -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
fn f() -> i32 {
match (3) {
default =>
// CHECK:STDERR: fail_missing_default_statements_block.carbon:[[@LINE+3]]:3: ERROR: Expected `{` after `=>`.
// CHECK:STDERR: }
// CHECK:STDERR: ^
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_default_statements_block.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchDefaultIntroducer', text: 'default'},
// CHECK:STDOUT: {kind: 'MatchDefaultEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchDefaultStart', text: '}', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchDefault', text: '}', has_error: yes, subtree_size: 4},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 10},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 21},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,49 @@
// 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
fn f() -> i32 {
match (true) {
// CHECK:STDERR: fail_missing_guard_close_paren.carbon:[[@LINE+3]]:21: ERROR: Opening symbol without a corresponding closing symbol.
// CHECK:STDERR: case x: bool if (false => { return 1; }
// CHECK:STDERR: ^
case x: bool if (false => { return 1; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_guard_close_paren.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'BoolLiteralTrue', text: 'true'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: '('},
// CHECK:STDOUT: {kind: 'BoolLiteralFalse', text: 'false'},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: '=>', has_error: yes, subtree_size: 4},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '}', has_error: yes},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '}', has_error: yes, subtree_size: 10},
// CHECK:STDOUT: {kind: 'MatchCase', text: '}', has_error: yes, subtree_size: 11},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 17},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 28},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,48 @@
// 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
fn f() -> i32 {
match (true) {
// CHECK:STDERR: fail_missing_guard_open_paren.carbon:[[@LINE+3]]:26: ERROR: Closing symbol without a corresponding opening symbol.
// CHECK:STDERR: case x: bool if false) => { return 1; }
// CHECK:STDERR: ^
case x: bool if false) => { return 1; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_guard_open_paren.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'BoolLiteralTrue', text: 'true'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: 'false', has_error: yes},
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'false', has_error: yes},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: 'false', has_error: yes, subtree_size: 4},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: 'false', has_error: yes, subtree_size: 9},
// CHECK:STDOUT: {kind: 'MatchCase', text: 'false', has_error: yes, subtree_size: 10},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 16},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 27},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,45 @@
// 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
fn f() -> i32 {
// CHECK:STDERR: fail_missing_matched_expr.carbon:[[@LINE+3]]:9: ERROR: Expected `(` after `match`.
// CHECK:STDERR: match {
// CHECK:STDERR: ^
match {
default => { return 1; }
}
return 0;
}
// CHECK:STDOUT: - filename: fail_missing_matched_expr.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: 'match', has_error: yes},
// CHECK:STDOUT: {kind: 'InvalidParse', text: '{', has_error: yes},
// CHECK:STDOUT: {kind: 'MatchCondition', text: 'match', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchDefaultIntroducer', text: 'default'},
// CHECK:STDOUT: {kind: 'MatchDefaultEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchDefaultStart', text: '{', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchDefault', text: '}', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 24},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -0,0 +1,112 @@
// 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
fn f() -> i32 {
var x: i32 = 3;
match (x) {
// CHECK:STDERR: fail_unexpected_tokens_in_cases_block.carbon:[[@LINE+3]]:5: ERROR: Unexpected `let`; expected `case`, `default` or `}`.
// CHECK:STDERR: let u: i32 =
// CHECK:STDERR: ^~~
let u: i32 =
case y: i32 if (y > 2) => { return 1; }
// CHECK:STDERR: fail_unexpected_tokens_in_cases_block.carbon:[[@LINE+3]]:5: ERROR: Unexpected `if`; expected `case`, `default` or `}`.
// CHECK:STDERR: if (true) {
// CHECK:STDERR: ^~
if (true) {
return 2;
}
// CHECK:STDERR: fail_unexpected_tokens_in_cases_block.carbon:[[@LINE+3]]:5: ERROR: Unexpected `var`; expected `case`, `default` or `}`.
// CHECK:STDERR: var w
// CHECK:STDERR: ^~~
var w
case z: i32 if (z == 3) => { return 3; }
// CHECK:STDERR: fail_unexpected_tokens_in_cases_block.carbon:[[@LINE+3]]:5: ERROR: Unexpected `{`; expected `case`, `default` or `}`.
// CHECK:STDERR: {
// CHECK:STDERR: ^
{
break;
}
default => { return 3; }
// CHECK:STDERR: fail_unexpected_tokens_in_cases_block.carbon:[[@LINE+3]]:5: ERROR: Unexpected `return`; expected `case`, `default` or `}`.
// CHECK:STDERR: return 1;
// CHECK:STDERR: ^~~~~~
return 1;
// CHECK:STDERR: fail_unexpected_tokens_in_cases_block.carbon:[[@LINE+3]]:5: ERROR: Unexpected `(`; expected `case`, `default` or `}`.
// CHECK:STDERR: ((), (), ())
// CHECK:STDERR: ^
((), (), ())
}
return 0;
}
// CHECK:STDOUT: - filename: fail_unexpected_tokens_in_cases_block.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 2},
// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'x'},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'y'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'y'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '2'},
// CHECK:STDOUT: {kind: 'InfixOperatorGreater', text: '>', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: ')', subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', subtree_size: 12},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCase', text: '}', subtree_size: 16},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'z'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'z'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'InfixOperatorEqualEqual', text: '==', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: ')', subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', subtree_size: 12},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCase', text: '}', subtree_size: 16},
// CHECK:STDOUT: {kind: 'MatchDefaultIntroducer', text: 'default'},
// CHECK:STDOUT: {kind: 'MatchDefaultEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchDefaultStart', text: '{', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchDefault', text: '}', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', has_error: yes, subtree_size: 45},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 63},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
+106
View File
@@ -0,0 +1,106 @@
// 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
fn f() -> i32 {
var x: i32 = 3;
match (f(x)) {
case (a: i32, b: i32) => { return 0; }
case (a: i32) if (a < 0) => { return 2; }
case a: i32 if (a != x) => { return 3; }
default => { return 4; }
}
return 0;
}
// CHECK:STDOUT: - filename: match.carbon
// CHECK:STDOUT: parse_tree: [
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'f'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'x'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 2},
// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchIntroducer', text: 'match'},
// CHECK:STDOUT: {kind: 'MatchConditionStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'f'},
// CHECK:STDOUT: {kind: 'CallExprStart', text: '(', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'x'},
// CHECK:STDOUT: {kind: 'CallExpr', text: ')', subtree_size: 4},
// CHECK:STDOUT: {kind: 'MatchCondition', text: ')', subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchStatementStart', text: '{', subtree_size: 8},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'a'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'b'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', subtree_size: 12},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCase', text: '}', subtree_size: 16},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'TuplePatternStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'a'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'TuplePattern', text: ')', subtree_size: 5},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'a'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'InfixOperatorLess', text: '<', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: ')', subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', subtree_size: 14},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '2'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCase', text: '}', subtree_size: 18},
// CHECK:STDOUT: {kind: 'MatchCaseIntroducer', text: 'case'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'a'},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuardIntroducer', text: 'if'},
// CHECK:STDOUT: {kind: 'MatchCaseGuardStart', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'a'},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'x'},
// CHECK:STDOUT: {kind: 'InfixOperatorExclaimEqual', text: '!=', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCaseGuard', text: ')', subtree_size: 6},
// CHECK:STDOUT: {kind: 'MatchCaseEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchCaseStart', text: '{', subtree_size: 12},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchCase', text: '}', subtree_size: 16},
// CHECK:STDOUT: {kind: 'MatchDefaultIntroducer', text: 'default'},
// CHECK:STDOUT: {kind: 'MatchDefaultEqualGreater', text: '=>'},
// CHECK:STDOUT: {kind: 'MatchDefaultStart', text: '{', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '4'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'MatchDefault', text: '}', subtree_size: 7},
// CHECK:STDOUT: {kind: 'MatchStatement', text: '}', subtree_size: 66},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
// CHECK:STDOUT: {kind: 'ReturnStatement', text: ';', subtree_size: 3},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 84},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
+73
View File
@@ -5,6 +5,8 @@
#ifndef CARBON_TOOLCHAIN_PARSE_TYPED_NODES_H_
#define CARBON_TOOLCHAIN_PARSE_TYPED_NODES_H_
#include <optional>
#include "toolchain/parse/node_ids.h"
#include "toolchain/parse/node_kind.h"
@@ -482,6 +484,77 @@ struct WhileStatement {
CodeBlockId body;
};
using MatchConditionStart = LeafNode<NodeKind::MatchConditionStart>;
struct MatchCondition {
static constexpr auto Kind = NodeKind::MatchCondition.Define();
MatchConditionStartId left_paren;
AnyExprId condition;
};
using MatchIntroducer = LeafNode<NodeKind::MatchIntroducer>;
struct MatchStatementStart {
static constexpr auto Kind = NodeKind::MatchStatementStart.Define();
MatchIntroducerId introducer;
MatchConditionId left_brace;
};
using MatchCaseIntroducer = LeafNode<NodeKind::MatchCaseIntroducer>;
using MatchCaseGuardIntroducer = LeafNode<NodeKind::MatchCaseGuardIntroducer>;
using MatchCaseGuardStart = LeafNode<NodeKind::MatchCaseGuardStart>;
struct MatchCaseGuard {
static constexpr auto Kind = NodeKind::MatchCaseGuard.Define();
MatchCaseGuardIntroducerId introducer;
MatchCaseGuardStartId left_paren;
AnyExprId condition;
};
using MatchCaseEqualGreater = LeafNode<NodeKind::MatchCaseEqualGreater>;
struct MatchCaseStart {
static constexpr auto Kind = NodeKind::MatchCaseStart.Define();
MatchCaseIntroducerId introducer;
AnyPatternId pattern;
std::optional<MatchCaseGuardId> guard;
MatchCaseEqualGreaterId equal_greater_token;
};
struct MatchCase {
static constexpr auto Kind = NodeKind::MatchCase.Define();
MatchCaseStartId head;
llvm::SmallVector<AnyStatementId> statements;
};
using MatchDefaultIntroducer = LeafNode<NodeKind::MatchDefaultIntroducer>;
using MatchDefaultEqualGreater = LeafNode<NodeKind::MatchDefaultEqualGreater>;
struct MatchDefaultStart {
static constexpr auto Kind = NodeKind::MatchDefaultStart.Define();
MatchDefaultIntroducerId introducer;
MatchDefaultEqualGreaterId equal_greater_token;
};
struct MatchDefault {
static constexpr auto Kind = NodeKind::MatchDefault.Define();
MatchDefaultStartId introducer;
llvm::SmallVector<AnyStatementId> statements;
};
// A `match` statement: `match (expr) { case (...) => {...} default => {...}}`.
struct MatchStatement {
static constexpr auto Kind =
NodeKind::MatchStatement.Define(NodeCategory::Statement);
MatchStatementStartId head;
llvm::SmallVector<MatchCaseId> cases;
std::optional<MatchDefaultId> default_case;
};
// Expression nodes
// ----------------