Просмотр исходного кода

Switch VariableInitializer order to accommodate GlobalInit (#3708)

This undoes parts of #3515 in order to allow PushGlobalInit to be called
when the initializer is called, instead of at the end of the binding
pattern. The current approach is fragile because supported patterns will
become more complex. We also will likely want similar support in `let`,
which puts the initializer first, so this offers a consistent approach
for both.

[Looking
back](https://discord.com/channels/655572317891461132/655578254970716160/1184237511766179840),
this is more or less the second option in that message, but using the
PeekNextIs to avoid vagueness about what's being popped first.

Note I'm putting in PeekNextIs for what I'm hoping will be a pretty
narrow use-case. I could've added depth arguments to the Peek functions,
but that would've rippled through a number of APIs and it's not clear to
me that this has generic utility. I mean, right now it could just be
PeekNextIsVariableInitializer, since it's only optional in that case.
Jon Ross-Perkins 2 лет назад
Родитель
Сommit
03347793cc
75 измененных файлов с 404 добавлено и 407 удалено
  1. 0 3
      toolchain/check/handle_binding_pattern.cpp
  2. 17 8
      toolchain/check/handle_variable.cpp
  3. 12 1
      toolchain/check/node_stack.h
  4. 2 8
      toolchain/parse/handle_var.cpp
  5. 4 2
      toolchain/parse/node_kind.def
  6. 0 7
      toolchain/parse/state.def
  7. 2 2
      toolchain/parse/testdata/auto/var.carbon
  8. 6 6
      toolchain/parse/testdata/basics/builtin_types.carbon
  9. 4 4
      toolchain/parse/testdata/basics/fail_paren_match_regression.carbon
  10. 30 30
      toolchain/parse/testdata/basics/numeric_literals.carbon
  11. 5 5
      toolchain/parse/testdata/if_expr/fail_condition_missing.carbon
  12. 7 7
      toolchain/parse/testdata/if_expr/fail_else_expr_missing.carbon
  13. 7 7
      toolchain/parse/testdata/if_expr/fail_else_missing.carbon
  14. 6 6
      toolchain/parse/testdata/if_expr/fail_then_expr_missing.carbon
  15. 6 6
      toolchain/parse/testdata/if_expr/fail_then_missing.carbon
  16. 5 5
      toolchain/parse/testdata/index/assign_to_var.carbon
  17. 5 5
      toolchain/parse/testdata/index/fail_empty_expr.carbon
  18. 5 5
      toolchain/parse/testdata/index/fail_malformed_expr.carbon
  19. 2 2
      toolchain/parse/testdata/match/fail_cases_after_default.carbon
  20. 2 2
      toolchain/parse/testdata/match/fail_unexpected_tokens_in_cases_block.carbon
  21. 2 2
      toolchain/parse/testdata/match/match.carbon
  22. 4 4
      toolchain/parse/testdata/operators/assign.carbon
  23. 3 3
      toolchain/parse/testdata/operators/fail_infix_uneven_space_after.carbon
  24. 12 12
      toolchain/parse/testdata/operators/fail_invalid_infix.carbon
  25. 2 2
      toolchain/parse/testdata/operators/fail_postincrement.carbon
  26. 4 4
      toolchain/parse/testdata/operators/fail_precedence_star_minus.carbon
  27. 5 5
      toolchain/parse/testdata/operators/fail_precedence_star_star.carbon
  28. 4 4
      toolchain/parse/testdata/operators/fail_star_star_no_space.carbon
  29. 5 5
      toolchain/parse/testdata/operators/fixity_in_var.carbon
  30. 4 4
      toolchain/parse/testdata/operators/infix.carbon
  31. 4 4
      toolchain/parse/testdata/operators/infix_no_space.carbon
  32. 6 6
      toolchain/parse/testdata/operators/infix_with_paren_after.carbon
  33. 6 6
      toolchain/parse/testdata/operators/infix_with_paren_before.carbon
  34. 3 3
      toolchain/parse/testdata/operators/postfix.carbon
  35. 3 3
      toolchain/parse/testdata/operators/postfix_space_after_op.carbon
  36. 6 6
      toolchain/parse/testdata/operators/prefix.carbon
  37. 3 3
      toolchain/parse/testdata/operators/prefix_no_space.carbon
  38. 4 4
      toolchain/parse/testdata/operators/recover_infix_uneven_space_before.carbon
  39. 3 3
      toolchain/parse/testdata/operators/recover_postfix_space.carbon
  40. 8 8
      toolchain/parse/testdata/operators/recover_postfix_space_before_comma.carbon
  41. 6 6
      toolchain/parse/testdata/operators/recover_postfix_space_in_call.carbon
  42. 3 3
      toolchain/parse/testdata/operators/recover_postfix_space_surrounding.carbon
  43. 3 3
      toolchain/parse/testdata/operators/recover_prefix_space.carbon
  44. 3 3
      toolchain/parse/testdata/operators/recover_prefix_uneven_space_with_assign.carbon
  45. 4 4
      toolchain/parse/testdata/package_expr/basic.carbon
  46. 8 8
      toolchain/parse/testdata/pointer/pointer_type.carbon
  47. 8 8
      toolchain/parse/testdata/pointer/pointer_value.carbon
  48. 2 2
      toolchain/parse/testdata/return/returned_var.carbon
  49. 3 3
      toolchain/parse/testdata/struct/fail_comma_only.carbon
  50. 3 3
      toolchain/parse/testdata/struct/fail_comma_repeat_in_type.carbon
  51. 3 3
      toolchain/parse/testdata/struct/fail_comma_repeat_in_value.carbon
  52. 3 3
      toolchain/parse/testdata/struct/fail_dot_only.carbon
  53. 3 3
      toolchain/parse/testdata/struct/fail_dot_string_colon.carbon
  54. 3 3
      toolchain/parse/testdata/struct/fail_dot_string_equals.carbon
  55. 7 7
      toolchain/parse/testdata/struct/fail_extra_token_in_type.carbon
  56. 7 7
      toolchain/parse/testdata/struct/fail_extra_token_in_value.carbon
  57. 3 3
      toolchain/parse/testdata/struct/fail_identifier_colon.carbon
  58. 3 3
      toolchain/parse/testdata/struct/fail_identifier_equals.carbon
  59. 3 3
      toolchain/parse/testdata/struct/fail_identifier_only.carbon
  60. 3 3
      toolchain/parse/testdata/struct/fail_missing_type.carbon
  61. 3 3
      toolchain/parse/testdata/struct/fail_missing_value.carbon
  62. 3 3
      toolchain/parse/testdata/struct/fail_mix_type_and_value.carbon
  63. 3 3
      toolchain/parse/testdata/struct/fail_mix_value_and_type.carbon
  64. 28 28
      toolchain/parse/testdata/struct/fail_mix_with_unknown.carbon
  65. 3 3
      toolchain/parse/testdata/struct/fail_no_colon_or_equals.carbon
  66. 3 3
      toolchain/parse/testdata/struct/fail_type_no_designator.carbon
  67. 3 3
      toolchain/parse/testdata/struct/no_entries.carbon
  68. 7 7
      toolchain/parse/testdata/struct/one_entry_no_comma.carbon
  69. 8 8
      toolchain/parse/testdata/struct/one_entry_with_comma.carbon
  70. 12 12
      toolchain/parse/testdata/struct/two_entries.carbon
  71. 6 6
      toolchain/parse/testdata/tuple/two_entries.carbon
  72. 4 4
      toolchain/parse/testdata/var/var.carbon
  73. 6 6
      toolchain/parse/testdata/var/var_tuple.carbon
  74. 6 8
      toolchain/parse/typed_nodes.h
  75. 10 17
      toolchain/parse/typed_nodes_test.cpp

+ 0 - 3
toolchain/check/handle_binding_pattern.cpp

@@ -116,9 +116,6 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
       if (context_parse_node_kind == Parse::NodeKind::ReturnedModifier) {
         RegisterReturnedVar(context, bind_id);
       }
-      if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
-        context.inst_block_stack().PushGlobalInit();
-      }
       break;
     }
 

+ 17 - 8
toolchain/check/handle_variable.cpp

@@ -26,18 +26,27 @@ auto HandleReturnedModifier(Context& context,
 auto HandleVariableInitializer(Context& context,
                                Parse::VariableInitializerId parse_node)
     -> bool {
-  SemIR::InstId init_id = context.node_stack().PopExpr();
-  context.node_stack().Push(parse_node, init_id);
+  if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
+    context.inst_block_stack().PushGlobalInit();
+  }
+  context.node_stack().Push(parse_node);
   return true;
 }
 
 auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
     -> bool {
   // Handle the optional initializer.
-  std::optional<SemIR::InstId> init_id =
-      context.node_stack().PopIf<Parse::NodeKind::VariableInitializer>();
+  std::optional<SemIR::InstId> init_id;
+  if (context.node_stack().PeekNextIs<Parse::NodeKind::VariableInitializer>()) {
+    init_id = context.node_stack().PopExpr();
+    context.node_stack()
+        .PopAndDiscardSoloParseNode<Parse::NodeKind::VariableInitializer>();
+  }
 
   if (context.node_stack().PeekIs<Parse::NodeKind::TuplePattern>()) {
+    if (init_id && context.scope_stack().PeekIndex() == ScopeIndex::Package) {
+      context.inst_block_stack().PopGlobalInit();
+    }
     return context.TODO(parse_node, "tuple pattern in var");
   }
 
@@ -65,7 +74,7 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
       .PopAndDiscardSoloParseNodeIf<Parse::NodeKind::ReturnedModifier>();
 
   // If there was an initializer, assign it to the storage.
-  if (init_id.has_value()) {
+  if (init_id) {
     if (context.GetCurrentScopeAs<SemIR::ClassDecl>()) {
       // TODO: In a class scope, we should instead save the initializer
       // somewhere so that we can use it as a default.
@@ -76,6 +85,9 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
       // initialization.
       context.AddInst({parse_node, SemIR::Assign{value_id, *init_id}});
     }
+    if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
+      context.inst_block_stack().PopGlobalInit();
+    }
   }
 
   context.node_stack()
@@ -95,9 +107,6 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
   }
 
   context.decl_state_stack().Pop(DeclState::Var);
-  if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
-    context.inst_block_stack().PopGlobalInit();
-  }
 
   return true;
 }

+ 12 - 1
toolchain/check/node_stack.h

@@ -157,6 +157,17 @@ class NodeStack {
                                   Id::KindFor<SemIR::NameId>();
   }
 
+  // Returns whether the *next* node on the stack is a given kind. This doesn't
+  // have the breadth of support versus other Peek functions because it's
+  // expected to be used in narrow circumstances when determining how to treat
+  // the *current* top of the stack.
+  template <const Parse::NodeKind& RequiredParseKind>
+  auto PeekNextIs() const -> bool {
+    CARBON_CHECK(stack_.size() >= 2);
+    return parse_tree_->node_kind(stack_[stack_.size() - 2].parse_node) ==
+           RequiredParseKind;
+  }
+
   // Pops the top of the stack without any verification.
   auto PopAndIgnore() -> void {
     Entry back = stack_.pop_back_val();
@@ -432,7 +443,6 @@ class NodeStack {
         case Parse::NodeKind::ShortCircuitOperandOr:
         case Parse::NodeKind::StructFieldValue:
         case Parse::NodeKind::StructFieldType:
-        case Parse::NodeKind::VariableInitializer:
           return Id::KindFor<SemIR::InstId>();
         case Parse::NodeKind::IfCondition:
         case Parse::NodeKind::IfExprIf:
@@ -468,6 +478,7 @@ class NodeStack {
         case Parse::NodeKind::ReturnVarModifier:
         case Parse::NodeKind::StructLiteralOrStructTypeLiteralStart:
         case Parse::NodeKind::TuplePatternStart:
+        case Parse::NodeKind::VariableInitializer:
         case Parse::NodeKind::VariableIntroducer:
           return Id::Kind::None;
         default:

+ 2 - 8
toolchain/parse/handle_var.cpp

@@ -66,18 +66,12 @@ auto HandleVarAfterPattern(Context& context) -> void {
   }
 
   if (context.PositionIs(Lex::TokenKind::Equal)) {
-    context.PushState(State::VarInitializer);
-    context.ConsumeChecked(Lex::TokenKind::Equal);
+    context.AddLeafNode(NodeKind::VariableInitializer,
+                        context.ConsumeChecked(Lex::TokenKind::Equal));
     context.PushState(State::Expr);
   }
 }
 
-auto HandleVarInitializer(Context& context) -> void {
-  auto state = context.PopState();
-  context.AddNode(NodeKind::VariableInitializer, state.token,
-                  state.subtree_start, state.has_error);
-}
-
 auto HandleVarFinishAsDecl(Context& context) -> void {
   auto state = context.PopState();
 

+ 4 - 2
toolchain/parse/node_kind.def

@@ -334,17 +334,19 @@ CARBON_PARSE_NODE_KIND_BRACKET(LetDecl, LetIntroducer, CARBON_IF_VALID(Semi))
 //   _repeated_ _external_: modifier
 //   _optional_ ReturnedModifier
 //   _external_: BindingPattern or TuplePattern
+//     VariableInitializer
 //     _external_: expression
-//   _optional_ VariableInitializer
+//   _optional_
 // VariableDecl
 //
 // Access and declaration modifier keywords only appear for `var` declarations,
 // whereas the returned modifier only appears on `var` statements.
+//
 // The VariableInitializer and following expression are paired: either both will
 // be present, or neither will.
 CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableIntroducer, 0, CARBON_IF_VALID(Var))
 CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnedModifier, 0, Returned)
-CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 1, Equal)
+CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 0, Equal)
 CARBON_PARSE_NODE_KIND_BRACKET(VariableDecl, VariableIntroducer,
                                CARBON_IF_VALID(Semi))
 

+ 0 - 7
toolchain/parse/state.def

@@ -1227,19 +1227,12 @@ CARBON_PARSE_STATE_VARIANTS3(Var, Decl, Returned, For)
 // var ... ??? = ...
 //         ^~~~~
 //   1. Expr
-//   2. VarInitializer
 //
 // var ... ...
 //        ^
 //   (state done)
 CARBON_PARSE_STATE(VarAfterPattern)
 
-// var ... = ... ;
-//              ^
-//
-//   (state done)
-CARBON_PARSE_STATE(VarInitializer)
-
 // Handles `var` parsing at the end.
 //
 // var ... ;        (variant is Semicolon)

+ 2 - 2
toolchain/parse/testdata/auto/var.carbon

@@ -13,8 +13,8 @@ var y: auto = false;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'y'},
 // CHECK:STDOUT:         {kind: 'AutoTypeLiteral', text: 'auto'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:         {kind: 'BoolLiteralFalse', text: 'false'},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:       {kind: 'BoolLiteralFalse', text: 'false'},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 6 - 6
toolchain/parse/testdata/basics/builtin_types.carbon

@@ -15,22 +15,22 @@ var test_str: String = "Test";
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'test_i32'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:       {kind: 'IntLiteral', text: '0'},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:       {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'test_f64'},
 // CHECK:STDOUT:         {kind: 'FloatTypeLiteral', text: 'f64'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:         {kind: 'RealLiteral', text: '0.1'},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:       {kind: 'RealLiteral', text: '0.1'},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:       {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'test_str'},
 // CHECK:STDOUT:         {kind: 'StringTypeLiteral', text: 'String'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:         {kind: 'StringLiteral', text: '"Test"'},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:       {kind: 'StringLiteral', text: '"Test"'},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 4 - 4
toolchain/parse/testdata/basics/fail_paren_match_regression.carbon

@@ -22,10 +22,10 @@ var = (foo {})
 // 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: 'ExprOpenParen', text: '('},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'foo'},
-// CHECK:STDOUT:         {kind: 'ParenExpr', text: ')', has_error: yes, subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', 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: ')', has_error: yes, subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 30 - 30
toolchain/parse/testdata/basics/numeric_literals.carbon

@@ -41,19 +41,19 @@ fn F() {
 // CHECK:STDOUT:             {kind: 'IntLiteral', text: '5'},
 // CHECK:STDOUT:           {kind: 'ArrayExpr', text: ']', subtree_size: 5},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 7},
-// CHECK:STDOUT:             {kind: 'ExprOpenParen', text: '('},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '8'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '9'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '0x8'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '0b1000'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '39999999999999999993'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:           {kind: 'TupleLiteral', text: ')', subtree_size: 12},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 13},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'ExprOpenParen', text: '('},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '8'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '9'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0x8'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0b1000'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '39999999999999999993'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:         {kind: 'TupleLiteral', text: ')', subtree_size: 12},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 22},
 // CHECK:STDOUT:         {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'floats'},
@@ -63,23 +63,23 @@ fn F() {
 // CHECK:STDOUT:             {kind: 'IntLiteral', text: '7'},
 // CHECK:STDOUT:           {kind: 'ArrayExpr', text: ']', subtree_size: 5},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 7},
-// CHECK:STDOUT:             {kind: 'ExprOpenParen', text: '('},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '0.9'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '8.0'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '80.0'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '1.0e7'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '1.0e8'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '1.0e-8'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'RealLiteral', text: '39999999999999999993.0e39999999999999999993'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:           {kind: 'TupleLiteral', text: ')', subtree_size: 16},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 17},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', 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'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'RealLiteral', text: '80.0'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'RealLiteral', text: '1.0e7'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'RealLiteral', text: '1.0e8'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'RealLiteral', text: '1.0e-8'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'RealLiteral', text: '39999999999999999993.0e39999999999999999993'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:         {kind: 'TupleLiteral', text: ')', subtree_size: 16},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 26},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 54},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 5 - 5
toolchain/parse/testdata/if_expr/fail_condition_missing.carbon

@@ -23,12 +23,12 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:               {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:             {kind: 'IfExprIf', text: 'if', has_error: yes, subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
 // CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:           {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 5},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:           {kind: 'IfExprIf', text: 'if', has_error: yes, subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:         {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 5},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 7 - 7
toolchain/parse/testdata/if_expr/fail_else_expr_missing.carbon

@@ -23,13 +23,13 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:               {kind: 'BoolLiteralTrue', text: 'true'},
-// CHECK:STDOUT:             {kind: 'IfExprIf', text: 'if', subtree_size: 2},
-// CHECK:STDOUT:               {kind: 'IntLiteral', text: '1'},
-// CHECK:STDOUT:             {kind: 'IfExprThen', text: 'then', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:           {kind: 'IfExprElse', text: 'else', has_error: yes, subtree_size: 6},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 7},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:             {kind: 'BoolLiteralTrue', text: 'true'},
+// CHECK:STDOUT:           {kind: 'IfExprIf', text: 'if', subtree_size: 2},
+// CHECK:STDOUT:             {kind: 'IntLiteral', text: '1'},
+// CHECK:STDOUT:           {kind: 'IfExprThen', text: 'then', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:         {kind: 'IfExprElse', text: 'else', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 12},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 18},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 7 - 7
toolchain/parse/testdata/if_expr/fail_else_missing.carbon

@@ -23,13 +23,13 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:               {kind: 'BoolLiteralTrue', text: 'true'},
-// CHECK:STDOUT:             {kind: 'IfExprIf', text: 'if', subtree_size: 2},
-// CHECK:STDOUT:               {kind: 'IntLiteral', text: '1'},
-// CHECK:STDOUT:             {kind: 'IfExprThen', text: 'then', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:           {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 6},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 7},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:             {kind: 'BoolLiteralTrue', text: 'true'},
+// CHECK:STDOUT:           {kind: 'IfExprIf', text: 'if', subtree_size: 2},
+// CHECK:STDOUT:             {kind: 'IntLiteral', text: '1'},
+// CHECK:STDOUT:           {kind: 'IfExprThen', text: 'then', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:         {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 12},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 18},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 6 - 6
toolchain/parse/testdata/if_expr/fail_then_expr_missing.carbon

@@ -23,13 +23,13 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:               {kind: 'BoolLiteralTrue', text: 'true'},
-// CHECK:STDOUT:             {kind: 'IfExprIf', text: 'if', subtree_size: 2},
-// CHECK:STDOUT:               {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:             {kind: 'IfExprThen', text: 'then', has_error: yes, subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:             {kind: 'BoolLiteralTrue', text: 'true'},
+// CHECK:STDOUT:           {kind: 'IfExprIf', text: 'if', subtree_size: 2},
 // CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:           {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 6},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 7},
+// CHECK:STDOUT:           {kind: 'IfExprThen', text: 'then', has_error: yes, subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:         {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 12},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 18},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 6 - 6
toolchain/parse/testdata/if_expr/fail_then_missing.carbon

@@ -23,12 +23,12 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:               {kind: 'BoolLiteralTrue', text: 'true'},
-// CHECK:STDOUT:             {kind: 'IfExprIf', text: 'if', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:             {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:           {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 5},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:             {kind: 'BoolLiteralTrue', text: 'true'},
+// CHECK:STDOUT:           {kind: 'IfExprIf', text: 'if', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:         {kind: 'IfExprElse', text: 'if', has_error: yes, subtree_size: 5},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 5 - 5
toolchain/parse/testdata/index/assign_to_var.carbon

@@ -13,11 +13,11 @@ var v: i32 = t[0];
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 't'},
-// CHECK:STDOUT:           {kind: 'IndexExprStart', text: '[', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:         {kind: 'IndexExpr', text: ']', subtree_size: 4},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 5},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 't'},
+// CHECK:STDOUT:         {kind: 'IndexExprStart', text: '[', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
+// CHECK:STDOUT:       {kind: 'IndexExpr', text: ']', subtree_size: 4},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 5 - 5
toolchain/parse/testdata/index/fail_empty_expr.carbon

@@ -16,11 +16,11 @@ var v: i32 = t[];
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 't'},
-// CHECK:STDOUT:           {kind: 'IndexExprStart', text: '[', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: ']', has_error: yes},
-// CHECK:STDOUT:         {kind: 'IndexExpr', text: ']', has_error: yes, subtree_size: 4},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 5},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 't'},
+// CHECK:STDOUT:         {kind: 'IndexExprStart', text: '[', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: ']', has_error: yes},
+// CHECK:STDOUT:       {kind: 'IndexExpr', text: ']', has_error: yes, subtree_size: 4},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 5 - 5
toolchain/parse/testdata/index/fail_malformed_expr.carbon

@@ -16,11 +16,11 @@ var v: i32 = t[0,];
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 't'},
-// CHECK:STDOUT:           {kind: 'IndexExprStart', text: '[', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:         {kind: 'IndexExpr', text: ']', has_error: yes, subtree_size: 4},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 5},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 't'},
+// CHECK:STDOUT:         {kind: 'IndexExprStart', text: '[', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
+// CHECK:STDOUT:       {kind: 'IndexExpr', text: ']', has_error: yes, subtree_size: 4},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 2 - 2
toolchain/parse/testdata/match/fail_cases_after_default.carbon

@@ -38,8 +38,8 @@ fn f() -> i32 {
 // 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: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '3'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:           {kind: 'MatchIntroducer', text: 'match'},
 // CHECK:STDOUT:             {kind: 'MatchConditionStart', text: '('},

+ 2 - 2
toolchain/parse/testdata/match/fail_unexpected_tokens_in_cases_block.carbon

@@ -56,8 +56,8 @@ fn f() -> i32 {
 // 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: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '3'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:           {kind: 'MatchIntroducer', text: 'match'},
 // CHECK:STDOUT:             {kind: 'MatchConditionStart', text: '('},

+ 2 - 2
toolchain/parse/testdata/match/match.carbon

@@ -29,8 +29,8 @@ fn f() -> i32 {
 // 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: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '3'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:           {kind: 'MatchIntroducer', text: 'match'},
 // CHECK:STDOUT:             {kind: 'MatchConditionStart', text: '('},

+ 4 - 4
toolchain/parse/testdata/operators/assign.carbon

@@ -34,15 +34,15 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'a'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:         {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'b'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '1'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '1'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'a'},
 // CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'b'},

+ 3 - 3
toolchain/parse/testdata/operators/fail_infix_uneven_space_after.carbon

@@ -18,9 +18,9 @@ var n: i8 = n* n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', has_error: yes, subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 12 - 12
toolchain/parse/testdata/operators/fail_invalid_infix.carbon

@@ -27,28 +27,28 @@ var c: i32 = == ;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'a'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:         {kind: 'InfixOperatorEqualEqual', text: '==', has_error: yes, subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:       {kind: 'InfixOperatorEqualEqual', text: '==', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:       {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'b'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: '==', has_error: yes},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorEqualEqual', text: '==', has_error: yes, subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: '==', has_error: yes},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorEqualEqual', text: '==', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:       {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'c'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: '==', has_error: yes},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: ';', has_error: yes},
-// CHECK:STDOUT:         {kind: 'InfixOperatorEqualEqual', text: '==', has_error: yes, subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: '==', has_error: yes},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: ';', has_error: yes},
+// CHECK:STDOUT:       {kind: 'InfixOperatorEqualEqual', text: '==', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 2 - 2
toolchain/parse/testdata/operators/fail_postincrement.carbon

@@ -29,8 +29,8 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
 // CHECK:STDOUT:       {kind: 'ExprStatement', text: ';', has_error: yes, subtree_size: 2},

+ 4 - 4
toolchain/parse/testdata/operators/fail_precedence_star_minus.carbon

@@ -16,11 +16,11 @@ var n: i8 = n* -n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
 // CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorMinus', text: '-', has_error: yes, subtree_size: 4},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 5},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorMinus', text: '-', has_error: yes, subtree_size: 4},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 5 - 5
toolchain/parse/testdata/operators/fail_precedence_star_star.carbon

@@ -16,11 +16,11 @@ var n: i8 = n* *p;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'p'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorStar', text: '*', has_error: yes, subtree_size: 4},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 5},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'p'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorStar', text: '*', has_error: yes, subtree_size: 4},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 4 - 4
toolchain/parse/testdata/operators/fail_star_star_no_space.carbon

@@ -20,10 +20,10 @@ var n: i8 = n**p;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'PostfixOperatorStar', text: '*', subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', has_error: yes, subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 5 - 5
toolchain/parse/testdata/operators/fixity_in_var.carbon

@@ -22,16 +22,16 @@ fn F() {
 // CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 4},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'p'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'p'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:         {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 't'},
 // CHECK:STDOUT:           {kind: 'TypeTypeLiteral', text: 'type'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i32'},
-// CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 22},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 4 - 4
toolchain/parse/testdata/operators/infix.carbon

@@ -13,10 +13,10 @@ var n: i8 = n * n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorStar', text: '*', subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorStar', text: '*', subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 4 - 4
toolchain/parse/testdata/operators/infix_no_space.carbon

@@ -13,10 +13,10 @@ var n: i8 = n*n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorStar', text: '*', subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorStar', text: '*', subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 6 - 6
toolchain/parse/testdata/operators/infix_with_paren_after.carbon

@@ -13,12 +13,12 @@ var n: i8 = 3*(n);
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '3'},
-// CHECK:STDOUT:             {kind: 'ExprOpenParen', text: '('},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'ParenExpr', text: ')', subtree_size: 3},
-// CHECK:STDOUT:         {kind: 'InfixOperatorStar', text: '*', subtree_size: 5},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '3'},
+// CHECK:STDOUT:           {kind: 'ExprOpenParen', text: '('},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'ParenExpr', text: ')', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'InfixOperatorStar', text: '*', subtree_size: 5},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 6 - 6
toolchain/parse/testdata/operators/infix_with_paren_before.carbon

@@ -13,12 +13,12 @@ var n: i8 = (n)*3;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// 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'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorStar', text: '*', subtree_size: 5},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', 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'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorStar', text: '*', subtree_size: 5},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/postfix.carbon

@@ -13,9 +13,9 @@ var v: type = i8*;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'TypeTypeLiteral', text: 'type'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i8'},
-// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
+// CHECK:STDOUT:       {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/postfix_space_after_op.carbon

@@ -13,9 +13,9 @@ var v: type = i8* ;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'TypeTypeLiteral', text: 'type'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i8'},
-// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
+// CHECK:STDOUT:       {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 6 - 6
toolchain/parse/testdata/operators/prefix.carbon

@@ -14,17 +14,17 @@ var b: bool = not true;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:       {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'b'},
 // CHECK:STDOUT:         {kind: 'BoolTypeLiteral', text: 'bool'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'BoolLiteralTrue', text: 'true'},
-// CHECK:STDOUT:         {kind: 'PrefixOperatorNot', text: 'not', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'BoolLiteralTrue', text: 'true'},
+// CHECK:STDOUT:       {kind: 'PrefixOperatorNot', text: 'not', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/prefix_no_space.carbon

@@ -14,9 +14,9 @@ var n: i8 =-n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 4 - 4
toolchain/parse/testdata/operators/recover_infix_uneven_space_before.carbon

@@ -16,10 +16,10 @@ var n: i8 = n *n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'InfixOperatorStar', text: '*', subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'InfixOperatorStar', text: '*', subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/recover_postfix_space.carbon

@@ -16,9 +16,9 @@ var v: type = i8 *;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'TypeTypeLiteral', text: 'type'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i8'},
-// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
+// CHECK:STDOUT:       {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 8 - 8
toolchain/parse/testdata/operators/recover_postfix_space_before_comma.carbon

@@ -16,14 +16,14 @@ var n: i8 = F(i8 *, 0);
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'F'},
-// CHECK:STDOUT:           {kind: 'CallExprStart', text: '(', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i8'},
-// CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'CallExprComma', text: ','},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:         {kind: 'CallExpr', text: ')', subtree_size: 7},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 8},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'F'},
+// CHECK:STDOUT:         {kind: 'CallExprStart', text: '(', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i8'},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'CallExprComma', text: ','},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
+// CHECK:STDOUT:       {kind: 'CallExpr', text: ')', subtree_size: 7},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 13},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 6 - 6
toolchain/parse/testdata/operators/recover_postfix_space_in_call.carbon

@@ -16,12 +16,12 @@ var n: i8 = F(i8 *);
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'F'},
-// CHECK:STDOUT:           {kind: 'CallExprStart', text: '(', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i8'},
-// CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:         {kind: 'CallExpr', text: ')', subtree_size: 5},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'F'},
+// CHECK:STDOUT:         {kind: 'CallExprStart', text: '(', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i8'},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'CallExpr', text: ')', subtree_size: 5},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/recover_postfix_space_surrounding.carbon

@@ -16,9 +16,9 @@ var v: type = i8 * ;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'TypeTypeLiteral', text: 'type'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i8'},
-// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
+// CHECK:STDOUT:       {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/recover_prefix_space.carbon

@@ -16,9 +16,9 @@ var n: i8 = - n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/operators/recover_prefix_uneven_space_with_assign.carbon

@@ -16,9 +16,9 @@ var n: i8 =- n;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i8'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:         {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:       {kind: 'PrefixOperatorMinus', text: '-', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 4 - 4
toolchain/parse/testdata/package_expr/basic.carbon

@@ -15,10 +15,10 @@ var x: package.Foo = package.Bar;
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'Foo'},
 // CHECK:STDOUT:         {kind: 'MemberAccessExpr', text: '.', subtree_size: 3},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 5},
-// CHECK:STDOUT:           {kind: 'PackageExpr', text: 'package'},
-// CHECK:STDOUT:           {kind: 'IdentifierName', text: 'Bar'},
-// CHECK:STDOUT:         {kind: 'MemberAccessExpr', text: '.', subtree_size: 3},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'PackageExpr', text: 'package'},
+// CHECK:STDOUT:         {kind: 'IdentifierName', text: 'Bar'},
+// CHECK:STDOUT:       {kind: 'MemberAccessExpr', text: '.', subtree_size: 3},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 8 - 8
toolchain/parse/testdata/pointer/pointer_type.carbon

@@ -33,15 +33,15 @@ var T: type = if true then i32* else f64*;
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'T'},
 // CHECK:STDOUT:         {kind: 'TypeTypeLiteral', text: 'type'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'BoolLiteralTrue', text: 'true'},
-// CHECK:STDOUT:           {kind: 'IfExprIf', text: 'if', subtree_size: 2},
-// CHECK:STDOUT:               {kind: 'IntTypeLiteral', text: 'i32'},
-// CHECK:STDOUT:             {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'IfExprThen', text: 'then', subtree_size: 3},
-// CHECK:STDOUT:             {kind: 'FloatTypeLiteral', text: 'f64'},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'BoolLiteralTrue', text: 'true'},
+// CHECK:STDOUT:         {kind: 'IfExprIf', text: 'if', subtree_size: 2},
+// CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
-// CHECK:STDOUT:         {kind: 'IfExprElse', text: 'else', subtree_size: 8},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 9},
+// CHECK:STDOUT:         {kind: 'IfExprThen', text: 'then', subtree_size: 3},
+// CHECK:STDOUT:           {kind: 'FloatTypeLiteral', text: 'f64'},
+// CHECK:STDOUT:         {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'IfExprElse', text: 'else', subtree_size: 8},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 14},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 8 - 8
toolchain/parse/testdata/pointer/pointer_value.carbon

@@ -25,17 +25,17 @@ fn F() -> i32 {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'n'},
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:         {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'p'},
 // CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 4},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'n'},
-// CHECK:STDOUT:           {kind: 'PrefixOperatorAmp', text: '&', subtree_size: 2},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'n'},
+// CHECK:STDOUT:         {kind: 'PrefixOperatorAmp', text: '&', subtree_size: 2},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:         {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 'q'},
@@ -43,9 +43,9 @@ fn F() -> i32 {
 // CHECK:STDOUT:             {kind: 'PostfixOperatorStar', text: '*', subtree_size: 2},
 // CHECK:STDOUT:           {kind: 'PostfixOperatorStar', text: '*', subtree_size: 3},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 5},
-// CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'p'},
-// CHECK:STDOUT:           {kind: 'PrefixOperatorAmp', text: '&', subtree_size: 2},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'IdentifierNameExpr', text: 'p'},
+// CHECK:STDOUT:         {kind: 'PrefixOperatorAmp', text: '&', subtree_size: 2},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:         {kind: 'ReturnStatementStart', text: 'return'},
 // CHECK:STDOUT:             {kind: 'IdentifierNameExpr', text: 'q'},

+ 2 - 2
toolchain/parse/testdata/return/returned_var.carbon

@@ -24,8 +24,8 @@ fn F() -> String {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 's'},
 // CHECK:STDOUT:           {kind: 'StringTypeLiteral', text: 'String'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'StringLiteral', text: '"hello"'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StringLiteral', text: '"hello"'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 8},
 // CHECK:STDOUT:         {kind: 'ReturnStatementStart', text: 'return'},
 // CHECK:STDOUT:         {kind: 'ReturnVarModifier', text: 'var'},

+ 3 - 3
toolchain/parse/testdata/struct/fail_comma_only.carbon

@@ -19,9 +19,9 @@ var x: {,} = {};
 // CHECK:STDOUT:           {kind: 'StructComma', text: ','},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 4},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 6},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_comma_repeat_in_type.carbon

@@ -24,9 +24,9 @@ var x: {.a: i32,,} = {};
 // CHECK:STDOUT:           {kind: 'StructComma', text: ','},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 9},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 11},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 16},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_comma_repeat_in_value.carbon

@@ -24,9 +24,9 @@ var x: {.a = 0,,} = {};
 // CHECK:STDOUT:           {kind: 'StructComma', text: ','},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 9},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 11},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 16},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_dot_only.carbon

@@ -20,9 +20,9 @@ var x: {.} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 5},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 7},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 12},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_dot_string_colon.carbon

@@ -26,9 +26,9 @@ var x: {."hello": i32, .y: i32} = {};
 // CHECK:STDOUT:           {kind: 'StructFieldType', text: ':', subtree_size: 4},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 11},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 13},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 18},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_dot_string_equals.carbon

@@ -26,9 +26,9 @@ var x: {."hello" = 0, .y = 4} = {};
 // CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 11},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 13},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 18},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 7 - 7
toolchain/parse/testdata/struct/fail_extra_token_in_type.carbon

@@ -21,13 +21,13 @@ var x: {.a: i32 banana} = {.a = 0};
 // CHECK:STDOUT:           {kind: 'StructFieldType', text: ':', subtree_size: 4},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 8},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'a'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 6},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 7},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'a'},
+// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 6},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 7 - 7
toolchain/parse/testdata/struct/fail_extra_token_in_value.carbon

@@ -21,13 +21,13 @@ var x: {.a: i32} = {.a = 0 banana};
 // CHECK:STDOUT:           {kind: 'StructFieldType', text: ':', subtree_size: 4},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 8},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'a'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 6},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 7},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'a'},
+// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_identifier_colon.carbon

@@ -18,9 +18,9 @@ var x: {a:} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: 'a', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 5},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_identifier_equals.carbon

@@ -18,9 +18,9 @@ var x: {a=} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: 'a', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 5},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_identifier_only.carbon

@@ -18,9 +18,9 @@ var x: {a} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: 'a', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 5},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_missing_type.carbon

@@ -21,9 +21,9 @@ var x: {.a:} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: ':', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 8},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 13},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_missing_value.carbon

@@ -21,9 +21,9 @@ var x: {.a=} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: '=', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 8},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 13},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_mix_type_and_value.carbon

@@ -25,9 +25,9 @@ var x: {.a: i32, .b = 0} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 10},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 12},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_mix_value_and_type.carbon

@@ -23,9 +23,9 @@ var x: {.a = 0, b: i32} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: 'b', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 8},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 10},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 15},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 28 - 28
toolchain/parse/testdata/struct/fail_mix_with_unknown.carbon

@@ -27,41 +27,41 @@ var x: i32 = {.a: i32, .b, .c = 1};
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'x'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'a'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '1'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:           {kind: 'StructComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'b'},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'a'},
 // CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
-// CHECK:STDOUT:           {kind: 'StructComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'c'},
-// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 14},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 15},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '1'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:         {kind: 'StructComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IdentifierName', text: 'b'},
+// CHECK:STDOUT:         {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: '.', has_error: yes},
+// CHECK:STDOUT:         {kind: 'StructComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IdentifierName', text: 'c'},
+// CHECK:STDOUT:         {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: '.', has_error: yes},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 14},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 20},
 // 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: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'a'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntTypeLiteral', text: 'i32'},
-// CHECK:STDOUT:           {kind: 'StructFieldType', text: ':', subtree_size: 4},
-// CHECK:STDOUT:           {kind: 'StructComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'b'},
-// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
-// CHECK:STDOUT:           {kind: 'StructComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'c'},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'a'},
 // CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
-// CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 14},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 15},
+// CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
+// CHECK:STDOUT:         {kind: 'StructFieldType', text: ':', subtree_size: 4},
+// CHECK:STDOUT:         {kind: 'StructComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IdentifierName', text: 'b'},
+// CHECK:STDOUT:         {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: '.', has_error: yes},
+// CHECK:STDOUT:         {kind: 'StructComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IdentifierName', text: 'c'},
+// CHECK:STDOUT:         {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'InvalidParse', text: '.', has_error: yes},
+// CHECK:STDOUT:       {kind: 'StructTypeLiteral', text: '}', has_error: yes, subtree_size: 14},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 20},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_no_colon_or_equals.carbon

@@ -20,9 +20,9 @@ var x: {.a} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: '.', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 5},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 7},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 12},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/fail_type_no_designator.carbon

@@ -18,9 +18,9 @@ var x: {i32} = {};
 // CHECK:STDOUT:           {kind: 'InvalidParse', text: 'i32', has_error: yes},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', has_error: yes, subtree_size: 3},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 5},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 10},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 3 - 3
toolchain/parse/testdata/struct/no_entries.carbon

@@ -14,9 +14,9 @@ var y: {} = {};
 // CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
 // CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 4},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 2},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 3},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 2},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 9},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 7 - 7
toolchain/parse/testdata/struct/one_entry_no_comma.carbon

@@ -18,13 +18,13 @@ var z: {.n: i32} = {.n = 4};
 // CHECK:STDOUT:           {kind: 'StructFieldType', text: ':', subtree_size: 4},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', subtree_size: 6},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 8},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'n'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '4'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 6},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 7},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'n'},
+// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '4'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 6},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 8 - 8
toolchain/parse/testdata/struct/one_entry_with_comma.carbon

@@ -19,14 +19,14 @@ var z: {.n: i32,} = {.n = 4,};
 // CHECK:STDOUT:           {kind: 'StructComma', text: ','},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', subtree_size: 7},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 9},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'n'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '4'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:           {kind: 'StructComma', text: ','},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 7},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 8},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'n'},
+// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '4'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:         {kind: 'StructComma', text: ','},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 7},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 19},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 12 - 12
toolchain/parse/testdata/struct/two_entries.carbon

@@ -23,18 +23,18 @@ var x: {.a: i32, .b: i32} = {.a = 1, .b = 2};
 // CHECK:STDOUT:           {kind: 'StructFieldType', text: ':', subtree_size: 4},
 // CHECK:STDOUT:         {kind: 'StructTypeLiteral', text: '}', subtree_size: 11},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 13},
-// CHECK:STDOUT:           {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'a'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '1'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:           {kind: 'StructComma', text: ','},
-// CHECK:STDOUT:               {kind: 'IdentifierName', text: 'b'},
-// CHECK:STDOUT:             {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '2'},
-// CHECK:STDOUT:           {kind: 'StructFieldValue', text: '=', subtree_size: 4},
-// CHECK:STDOUT:         {kind: 'StructLiteral', text: '}', subtree_size: 11},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 12},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'a'},
+// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '1'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:         {kind: 'StructComma', text: ','},
+// CHECK:STDOUT:             {kind: 'IdentifierName', text: 'b'},
+// CHECK:STDOUT:           {kind: 'StructFieldDesignator', text: '.', subtree_size: 2},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '2'},
+// CHECK:STDOUT:         {kind: 'StructFieldValue', text: '=', subtree_size: 4},
+// CHECK:STDOUT:       {kind: 'StructLiteral', text: '}', subtree_size: 11},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 27},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 6 - 6
toolchain/parse/testdata/tuple/two_entries.carbon

@@ -17,12 +17,12 @@ var x: (i32, i32) = (1, 2);
 // CHECK:STDOUT:           {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:         {kind: 'TupleLiteral', text: ')', subtree_size: 5},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 7},
-// CHECK:STDOUT:           {kind: 'ExprOpenParen', text: '('},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '1'},
-// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:           {kind: 'IntLiteral', text: '2'},
-// CHECK:STDOUT:         {kind: 'TupleLiteral', text: ')', subtree_size: 5},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'ExprOpenParen', text: '('},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '1'},
+// CHECK:STDOUT:         {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:         {kind: 'IntLiteral', text: '2'},
+// CHECK:STDOUT:       {kind: 'TupleLiteral', text: ')', subtree_size: 5},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 15},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},
 // CHECK:STDOUT:   ]

+ 4 - 4
toolchain/parse/testdata/var/var.carbon

@@ -17,8 +17,8 @@ fn F() {
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'v'},
 // CHECK:STDOUT:         {kind: 'IntTypeLiteral', text: 'i32'},
 // CHECK:STDOUT:       {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:         {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:       {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:       {kind: 'IntLiteral', text: '0'},
 // CHECK:STDOUT:     {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:       {kind: 'VariableIntroducer', text: 'var'},
 // CHECK:STDOUT:         {kind: 'IdentifierName', text: 'w'},
@@ -34,8 +34,8 @@ fn F() {
 // CHECK:STDOUT:           {kind: 'IdentifierName', text: 's'},
 // CHECK:STDOUT:           {kind: 'StringTypeLiteral', text: 'String'},
 // CHECK:STDOUT:         {kind: 'BindingPattern', text: ':', subtree_size: 3},
-// CHECK:STDOUT:           {kind: 'StringLiteral', text: '"hello"'},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 2},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:         {kind: 'StringLiteral', text: '"hello"'},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 7},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 13},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 6 - 6
toolchain/parse/testdata/var/var_tuple.carbon

@@ -26,12 +26,12 @@ fn F() {
 // CHECK:STDOUT:             {kind: 'IntLiteral', text: '32'},
 // CHECK:STDOUT:           {kind: 'BindingPattern', text: ':', subtree_size: 3},
 // CHECK:STDOUT:         {kind: 'TuplePattern', text: ')', subtree_size: 9},
-// CHECK:STDOUT:             {kind: 'ExprOpenParen', text: '('},
-// CHECK:STDOUT:             {kind: 'StringLiteral', text: '"hello"'},
-// CHECK:STDOUT:             {kind: 'TupleLiteralComma', text: ','},
-// CHECK:STDOUT:             {kind: 'IntLiteral', text: '0'},
-// CHECK:STDOUT:           {kind: 'TupleLiteral', text: ')', subtree_size: 5},
-// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '=', subtree_size: 6},
+// CHECK:STDOUT:         {kind: 'VariableInitializer', text: '='},
+// CHECK:STDOUT:           {kind: 'ExprOpenParen', text: '('},
+// CHECK:STDOUT:           {kind: 'StringLiteral', text: '"hello"'},
+// CHECK:STDOUT:           {kind: 'TupleLiteralComma', text: ','},
+// CHECK:STDOUT:           {kind: 'IntLiteral', text: '0'},
+// CHECK:STDOUT:         {kind: 'TupleLiteral', text: ')', subtree_size: 5},
 // CHECK:STDOUT:       {kind: 'VariableDecl', text: ';', subtree_size: 17},
 // CHECK:STDOUT:     {kind: 'FunctionDefinition', text: '}', subtree_size: 23},
 // CHECK:STDOUT:     {kind: 'FileEnd', text: ''},

+ 6 - 8
toolchain/parse/typed_nodes.h

@@ -354,13 +354,7 @@ struct LetDecl {
 
 using VariableIntroducer = LeafNode<NodeKind::VariableIntroducer>;
 using ReturnedModifier = LeafNode<NodeKind::ReturnedModifier>;
-
-// The initializer part of a `var` declaration.
-struct VariableInitializer {
-  static constexpr auto Kind = NodeKind::VariableInitializer.Define();
-
-  AnyExprId value;
-};
+using VariableInitializer = LeafNode<NodeKind::VariableInitializer>;
 
 // A `var` declaration: `var a: i32;` or `var a: i32 = 5;`.
 struct VariableDecl {
@@ -372,7 +366,11 @@ struct VariableDecl {
   std::optional<ReturnedModifierId> returned;
   AnyPatternId pattern;
 
-  std::optional<VariableInitializerId> initializer;
+  struct Initializer {
+    VariableInitializerId equals;
+    AnyExprId value;
+  };
+  std::optional<Initializer> initializer;
 };
 
 // Statement nodes

+ 10 - 17
toolchain/parse/typed_nodes_test.cpp

@@ -172,7 +172,9 @@ TEST_F(TypedNodeTest, VerifyExtractTraceVarNoInit) {
   EXPECT_THAT(err.message(), testing::MatchesRegex(
                                  R"Trace(Aggregate [^:]*: begin
 Optional [^:]*: begin
-NodeIdForKind error: wrong kind BindingPattern, expected VariableInitializer
+Aggregate [^:]*: begin
+NodeIdInCategory Expr error: kind BindingPattern doesn't match
+Aggregate [^:]*: error
 Optional [^:]*: missing
 NodeIdInCategory Pattern: kind BindingPattern consumed
 Optional [^:]*: begin
@@ -200,8 +202,11 @@ TEST_F(TypedNodeTest, VerifyExtractTraceExpression) {
   // Use Regex matching to avoid hard-coding the result of `typeinfo(T).name()`.
   EXPECT_THAT(err1.message(), testing::MatchesRegex(
                                   R"Trace(Aggregate [^:]*: begin
-Optional [^:]*: begin
+Optional [^:]*leDecl11InitializerE: begin
+Aggregate [^:]*: begin
+NodeIdInCategory Expr: kind MemberAccessExpr consumed
 NodeIdForKind: VariableInitializer consumed
+Aggregate [^:]*: success
 Optional [^:]*: found
 NodeIdInCategory Pattern: kind BindingPattern consumed
 Optional [^:]*: begin
@@ -216,24 +221,12 @@ Aggregate [^:]*: success
 
   ASSERT_TRUE(var->initializer.has_value());
   ErrorBuilder trace2;
-  auto initializer =
-      tree->VerifyExtractAs<VariableInitializer>(*var->initializer, &trace2);
-  ASSERT_TRUE(initializer.has_value());
-  Error err2 = trace2;
-  // Use Regex matching to avoid hard-coding the result of `typeinfo(T).name()`.
-  EXPECT_THAT(err2.message(), testing::MatchesRegex(
-                                  R"Trace(Aggregate [^:]*: begin
-NodeIdInCategory Expr: kind MemberAccessExpr consumed
-Aggregate [^:]*: success
-)Trace"));
-
-  ErrorBuilder trace3;
   auto value =
-      tree->VerifyExtractAs<MemberAccessExpr>(initializer->value, &trace3);
+      tree->VerifyExtractAs<MemberAccessExpr>(var->initializer->value, &trace2);
   ASSERT_TRUE(value.has_value());
-  Error err3 = trace3;
+  Error err2 = trace2;
   // Use Regex matching to avoid hard-coding the result of `typeinfo(T).name()`.
-  EXPECT_THAT(err3.message(), testing::MatchesRegex(
+  EXPECT_THAT(err2.message(), testing::MatchesRegex(
                                   R"Trace(Aggregate [^:]*: begin
 NodeIdInCategory MemberName: kind IdentifierName consumed
 NodeIdInCategory Expr: kind PointerMemberAccessExpr consumed