Skip to content

Commit

Permalink
Clarify naming around paren expressions (carbon-language#3444)
Browse files Browse the repository at this point in the history
(Split out of carbon-language#3410)

Consistently use `ParenExpr` solely for parenthesized single
expressions, and use more syntax-oriented terminology for states and
nodes that might represent either a `ParenExpr` or a tuple literal.
  • Loading branch information
geoffromer committed Dec 8, 2023
1 parent 18c51ea commit 5897e57
Show file tree
Hide file tree
Showing 18 changed files with 98 additions and 83 deletions.
14 changes: 5 additions & 9 deletions toolchain/check/handle_paren.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ auto HandleParenExpr(Context& context, Parse::NodeId parse_node) -> bool {
auto value_id = context.node_stack().PopExpr();
// ParamOrArgStart was called for tuple handling; clean up the ParamOrArg
// support for non-tuple cases.
context.ParamOrArgEnd(Parse::NodeKind::ParenExprOrTupleLiteralStart);
context.ParamOrArgEnd(Parse::NodeKind::ExprOpenParen);
context.node_stack()
.PopAndDiscardSoloParseNode<
Parse::NodeKind::ParenExprOrTupleLiteralStart>();
.PopAndDiscardSoloParseNode<Parse::NodeKind::ExprOpenParen>();
context.node_stack().Push(parse_node, value_id);
return true;
}

auto HandleParenExprOrTupleLiteralStart(Context& context,
Parse::NodeId parse_node) -> bool {
auto HandleExprOpenParen(Context& context, Parse::NodeId parse_node) -> bool {
context.node_stack().Push(parse_node);
context.ParamOrArgStart();
return true;
Expand All @@ -32,12 +30,10 @@ auto HandleTupleLiteralComma(Context& context, Parse::NodeId /*parse_node*/)
}

auto HandleTupleLiteral(Context& context, Parse::NodeId parse_node) -> bool {
auto refs_id =
context.ParamOrArgEnd(Parse::NodeKind::ParenExprOrTupleLiteralStart);
auto refs_id = context.ParamOrArgEnd(Parse::NodeKind::ExprOpenParen);

context.node_stack()
.PopAndDiscardSoloParseNode<
Parse::NodeKind::ParenExprOrTupleLiteralStart>();
.PopAndDiscardSoloParseNode<Parse::NodeKind::ExprOpenParen>();
const auto& inst_block = context.inst_blocks().Get(refs_id);
llvm::SmallVector<SemIR::TypeId> type_ids;
type_ids.reserve(inst_block.size());
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/node_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,13 @@ class NodeStack {
case Parse::NodeKind::ArrayExprSemi:
case Parse::NodeKind::ClassIntroducer:
case Parse::NodeKind::CodeBlockStart:
case Parse::NodeKind::ExprOpenParen:
case Parse::NodeKind::FunctionIntroducer:
case Parse::NodeKind::IfStatementElse:
case Parse::NodeKind::ImplicitParamListStart:
case Parse::NodeKind::InterfaceIntroducer:
case Parse::NodeKind::LetIntroducer:
case Parse::NodeKind::ParamListStart:
case Parse::NodeKind::ParenExprOrTupleLiteralStart:
case Parse::NodeKind::QualifiedDecl:
case Parse::NodeKind::ReturnedModifier:
case Parse::NodeKind::ReturnStatementStart:
Expand Down
55 changes: 26 additions & 29 deletions toolchain/parse/handle_paren_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@ auto HandleParenExpr(Context& context) -> void {
auto state = context.PopState();

// Advance past the open paren.
context.AddLeafNode(NodeKind::ParenExprOrTupleLiteralStart,
context.AddLeafNode(NodeKind::ExprOpenParen,
context.ConsumeChecked(Lex::TokenKind::OpenParen));

if (context.PositionIs(Lex::TokenKind::CloseParen)) {
state.state = State::ParenExprFinishAsTuple;
state.state = State::TupleLiteralFinish;
context.PushState(state);
} else {
state.state = State::ParenExprFinishAsNormal;
state.state = State::ParenExprFinish;
context.PushState(state);
context.PushState(State::ParenExprParamFinishAsUnknown);
context.PushState(State::ExprAfterOpenParenFinish);
context.PushState(State::Expr);
}
}

// Handles ParenExprParamFinishAs(Unknown|Tuple).
static auto HandleParenExprParamFinish(Context& context, bool as_tuple)
-> void {
auto HandleExprAfterOpenParenFinish(Context& context) -> void {
auto state = context.PopState();

auto list_token_kind = context.ConsumeListToken(
Expand All @@ -35,42 +33,41 @@ static auto HandleParenExprParamFinish(Context& context, bool as_tuple)
return;
}

// If this is the first item and a comma was found, switch to tuple handling.
// Note this could be `(expr,)` so we may not reuse the current state, but
// it's still necessary to switch the parent.
if (!as_tuple) {
state.state = State::ParenExprParamFinishAsTuple;

auto finish_state = context.PopState();
CARBON_CHECK(finish_state.state == State::ParenExprFinishAsNormal)
<< "Unexpected parent state, found: " << finish_state.state;
finish_state.state = State::ParenExprFinishAsTuple;
context.PushState(finish_state);
}

// On a comma, push another expression handler.
if (list_token_kind == Context::ListTokenKind::Comma) {
// We found a comma, so switch parent state to tuple handling.
auto finish_state = context.PopState();
CARBON_CHECK(finish_state.state == State::ParenExprFinish)
<< "Unexpected parent state, found: " << finish_state.state;
finish_state.state = State::TupleLiteralFinish;
context.PushState(finish_state);

// If the comma is not immediately followed by a close paren, push handlers
// for the next tuple element.
if (list_token_kind != Context::ListTokenKind::CommaClose) {
state.state = State::TupleLiteralElementFinish;
context.PushState(state);
context.PushState(State::Expr);
}
}

auto HandleParenExprParamFinishAsUnknown(Context& context) -> void {
HandleParenExprParamFinish(context, /*as_tuple=*/false);
}
auto HandleTupleLiteralElementFinish(Context& context) -> void {
auto state = context.PopState();

auto HandleParenExprParamFinishAsTuple(Context& context) -> void {
HandleParenExprParamFinish(context, /*as_tuple=*/true);
if (context.ConsumeListToken(NodeKind::TupleLiteralComma,
Lex::TokenKind::CloseParen, state.has_error) ==
Context::ListTokenKind::Comma) {
context.PushState(state);
context.PushState(State::Expr);
}
}

auto HandleParenExprFinishAsNormal(Context& context) -> void {
auto HandleParenExprFinish(Context& context) -> void {
auto state = context.PopState();

context.AddNode(NodeKind::ParenExpr, context.Consume(), state.subtree_start,
state.has_error);
}

auto HandleParenExprFinishAsTuple(Context& context) -> void {
auto HandleTupleLiteralFinish(Context& context) -> void {
auto state = context.PopState();

context.AddNode(NodeKind::TupleLiteral, context.Consume(),
Expand Down
12 changes: 6 additions & 6 deletions toolchain/parse/node_kind.def
Original file line number Diff line number Diff line change
Expand Up @@ -419,26 +419,26 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(IndexExprStart, 1,
CARBON_PARSE_NODE_KIND_BRACKET(IndexExpr, IndexExprStart,
CARBON_TOKEN(CloseSquareBracket))

// Parenthesized expressions, such as `(2)`:
// ParenExprOrTupleLiteralStart
// Parenthesized single expressions, such as `(2)`:
// ExprOpenParen
// _external_: expression
// ParenExpr
//
// Tuples, such as `(1, 2)`:
// ParenExprOrTupleLiteralStart
// ExprOpenParen
// _external_: expression
// TupleLiteralComma
// _repeated_
// TupleLiteral
//
// Expressions and TupleLiteralComma may repeat with TupleLiteralComma as a
// separator.
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParenExprOrTupleLiteralStart, 0,
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExprOpenParen, 0,
CARBON_TOKEN(OpenParen))
CARBON_PARSE_NODE_KIND_BRACKET(ParenExpr, ParenExprOrTupleLiteralStart,
CARBON_PARSE_NODE_KIND_BRACKET(ParenExpr, ExprOpenParen,
CARBON_TOKEN(CloseParen))
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteralComma, 0, CARBON_TOKEN(Comma))
CARBON_PARSE_NODE_KIND_BRACKET(TupleLiteral, ParenExprOrTupleLiteralStart,
CARBON_PARSE_NODE_KIND_BRACKET(TupleLiteral, ExprOpenParen,
CARBON_TOKEN(CloseParen))

// Call expressions, such as `a()`:
Expand Down
52 changes: 37 additions & 15 deletions toolchain/parse/state.def
Original file line number Diff line number Diff line change
Expand Up @@ -725,45 +725,67 @@ CARBON_PARSE_STATE_VARIANTS2(ParenCondition, If, While)
// (state done)
CARBON_PARSE_STATE_VARIANTS2(ParenConditionFinish, If, While)

// Handles the `(` of a parenthesized expression.
// Handles the `(` of a parenthesized single expression
//
// ( )
// ^
// 1. ParenExprFinishAsTuple
// 1. TupleLiteralFinish
//
// ( ... )
// ^
// 1. Expr
// 2. ParenExprParamFinishAsUnknown
// 3. ParenExprFinishAsNormal (SPECIAL: may be replaced)
// 2. ExprAfterOpenParenFinish
// 3. ParenExprFinish (SPECIAL: may be replaced)
CARBON_PARSE_STATE(ParenExpr)

// Handles the end of a parenthesized expression's parameter. This will start as
// AsUnknown on the first parameter; if there are more, it switches to AsTuple
// processing.
// Handles the `)` of a tuple literal.
//
// ( ... )
// ^
// (state done)
CARBON_PARSE_STATE(TupleLiteralFinish)

// Handles the end of an expression following an open parenthesis.
//
// ( ... , )
// ^
// (state done)
// SPECIAL (variant is Unknown): parent becomes ParenExprFinishAsTuple
// SPECIAL: parent becomes TupleLiteralFinish
//
// ( ... , ... )
// ^
// 1. Expression
// 2. ParenExpressionParamFinishAsTuple
// SPECIAL (variant is Unknown): parent becomes ParenExprFinishAsTuple
// 2. TupleLiteralElementFinish
// SPECIAL: parent becomes TupleLiteralFinish
//
// ...
// ^
// ( ... )
// ^
// (state done)
CARBON_PARSE_STATE(ExprAfterOpenParenFinish)

// Handles the end of an expression that is known to be an element of a tuple
// literal expression.
//
// ( ... , )
// ^
// (state done)
//
// ( ... , ... )
// ^
// 1. Expression
// 2. TupleLiteralElementFinish
//
// ( ... )
// ^
// (state done)
CARBON_PARSE_STATE_VARIANTS2(ParenExprParamFinish, Unknown, Tuple)
CARBON_PARSE_STATE(TupleLiteralElementFinish)

// Handles the `)` of a parenthesized expression.
// Handles the `)` of a parenthesized single expression.
//
// ( ... )
// ^
// (state done)
CARBON_PARSE_STATE_VARIANTS2(ParenExprFinish, Normal, Tuple)
CARBON_PARSE_STATE(ParenExprFinish)

// Handles processing of a pattern.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var = (foo {})
// CHECK:STDOUT: {kind: 'InvalidParse', text: '=', has_error: yes},
// CHECK:STDOUT: {kind: 'BindingPattern', text: '=', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'foo'},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'VariableDecl', text: 'var', has_error: yes, subtree_size: 9},
Expand Down
2 changes: 1 addition & 1 deletion toolchain/parse/testdata/basics/function_call.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn F() {
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'd'},
// CHECK:STDOUT: {kind: 'MemberAccessExpr', text: '.', subtree_size: 3},
// CHECK:STDOUT: {kind: 'CallExprComma', text: ','},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'e'},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'CallExpr', text: ')', subtree_size: 14},
Expand Down
4 changes: 2 additions & 2 deletions toolchain/parse/testdata/basics/numeric_literals.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn F() {
// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 5},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '8'},
// CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '9'},
Expand All @@ -64,7 +64,7 @@ fn F() {
// CHECK:STDOUT: {kind: 'ArrayExpr', text: ']', subtree_size: 5},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 7},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'RealLiteral', text: '0.9'},
// CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','},
// CHECK:STDOUT: {kind: 'RealLiteral', text: '8.0'},
Expand Down
8 changes: 4 additions & 4 deletions toolchain/parse/testdata/basics/parens.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ fn F(n: i32) -> i32 {
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 10},
// CHECK:STDOUT: {kind: 'ReturnStatementStart', text: 'return'},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'n'},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 5},
Expand Down
2 changes: 1 addition & 1 deletion toolchain/parse/testdata/let/let_tuple.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn F() {
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'LetInitializer', text: '='},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'StringLiteral', text: '"hello"'},
// CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ fn F() {
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 5},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'a'},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', has_error: yes, subtree_size: 3},
// CHECK:STDOUT: {kind: 'InfixOperator', text: '+', subtree_size: 5},
// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 6},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'BoolLiteralTrue', text: 'true'},
// CHECK:STDOUT: {kind: 'IfExprIf', text: 'if', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'a'},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var n: i8 = 3*(n);
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'n'},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'InfixOperator', text: '*', subtree_size: 5},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var n: i8 = (n)*3;
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i8'},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'n'},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 3},
// CHECK:STDOUT: {kind: 'IntLiteral', text: '3'},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fn F(c: bool) {
// CHECK:STDOUT: {kind: 'IfExprElse', text: 'else', subtree_size: 6},
// CHECK:STDOUT: {kind: 'InfixOperator', text: '=', subtree_size: 9},
// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 10},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'c'},
// CHECK:STDOUT: {kind: 'IfExprIf', text: 'if', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'a'},
Expand Down
4 changes: 2 additions & 2 deletions toolchain/parse/testdata/pointer/const_pointer.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn C() -> const (i32*) { return C(); }
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'B'},
// CHECK:STDOUT: {kind: 'ParamListStart', text: '('},
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'PrefixOperator', text: 'const', subtree_size: 2},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 4},
Expand All @@ -47,7 +47,7 @@ fn C() -> const (i32*) { return C(); }
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'C'},
// CHECK:STDOUT: {kind: 'ParamListStart', text: '('},
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
// CHECK:STDOUT: {kind: 'PostfixOperator', text: '*', subtree_size: 2},
// CHECK:STDOUT: {kind: 'ParenExpr', text: ')', subtree_size: 4},
Expand Down
8 changes: 4 additions & 4 deletions toolchain/parse/testdata/tuple/nested.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ var y: ((), (), ());
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'},
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'y'},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','},
// CHECK:STDOUT: {kind: 'ParenExprOrTupleLiteralStart', text: '('},
// CHECK:STDOUT: {kind: 'ExprOpenParen', text: '('},
// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2},
// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 10},
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 12},
Expand Down
Loading

0 comments on commit 5897e57

Please sign in to comment.