mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:30:12 +01:00
Add parsing of default value exprs in pattern lists (#7631)
Adds parsing support only for default value expressions in pattern lists, including leaving the default value unspecified with an underscore `_`. Per #7521.
This commit is contained in:
@@ -151,4 +151,14 @@ auto HandleParseNode(Context& context, Parse::PatternListCommaId /*node_id*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::DefaultValueUnspecifiedId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "pattern default values");
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::DefaultValuePatternId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "pattern default values");
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
@@ -107,14 +107,18 @@ library "[[@TEST_NAME]]";
|
||||
interface I { let X: type; }
|
||||
interface J { let Y: type; }
|
||||
|
||||
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+8]]:30: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
||||
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+12]]:30: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
||||
// CHECK:STDERR: fn F(generic T: I & J where .(I.X) = .(J.Y)) {
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+4]]:30: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+8]]:30: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(generic T: I & J where .(I.X) = .(J.Y)) {
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+4]]:39: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
||||
// CHECK:STDERR: fn F(generic T: I & J where .(I.X) = .(J.Y)) {
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
fn F(generic T: I & J where .(I.X) = .(J.Y)) {
|
||||
// Allowed since `T impls I`, `T impls J`, and has constraint providing
|
||||
// T.(I.X) = T.(J.Y)`.
|
||||
@@ -141,14 +145,18 @@ interface I(T: type) { let X: type; }
|
||||
|
||||
final impl forall [J: I(())] J as I({}) where .X = {} {}
|
||||
|
||||
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+8]]:38: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
||||
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+12]]:38: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
||||
// CHECK:STDERR: fn F(generic T: I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+4]]:38: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+8]]:38: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
||||
// CHECK:STDERR: fn F(generic T: I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+4]]:58: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
||||
// CHECK:STDERR: fn F(generic T: I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
fn F(generic T: I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
||||
|
||||
fn G(generic T: I(()) where .X = ()) {
|
||||
|
||||
@@ -378,7 +378,7 @@ class Context {
|
||||
// Pushes a new state for handling a pattern. `in_var_pattern` and
|
||||
// `in_unused_pattern` and `in_field_shorthand_pattern` indicate whether that
|
||||
// pattern is nested inside a `var`, `unused` or a struct shorthand field
|
||||
// pattern.. `binding_context` is the binding context that determines the
|
||||
// pattern. `binding_context` is the binding context that determines the
|
||||
// default phase of bindings in this pattern.
|
||||
auto PushStateForPattern(StateKind kind, bool in_var_pattern,
|
||||
bool in_unused_pattern,
|
||||
|
||||
@@ -16,6 +16,18 @@ static auto HandlePatternListElement(Context& context, StateKind pattern_state,
|
||||
state.in_unused_pattern,
|
||||
state.in_field_shorthand_pattern,
|
||||
state.binding_context, state.ambient_precedence);
|
||||
|
||||
// For patterns inside of list elements we normally check for a default value.
|
||||
// Parsing a struct designator is special case as that also is looking for a
|
||||
// required `=` sign, so we handle looking for an optional default value in
|
||||
// that state.
|
||||
if (pattern_state != StateKind::StructPatternFieldAfterDesignator) {
|
||||
context.PushStateForPattern(
|
||||
StateKind::PatternListElementCheckForDefaultValue, state.in_var_pattern,
|
||||
state.in_unused_pattern, state.in_field_shorthand_pattern,
|
||||
state.binding_context, state.ambient_precedence);
|
||||
}
|
||||
|
||||
context.PushStateForPattern(pattern_state, state.in_var_pattern,
|
||||
state.in_unused_pattern,
|
||||
state.in_field_shorthand_pattern,
|
||||
@@ -150,6 +162,46 @@ auto HandleStructPatternUnderscore(Context& context) -> void {
|
||||
}
|
||||
}
|
||||
|
||||
auto HandlePatternListElementCheckForDefaultValue(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
if (state.has_error) {
|
||||
context.ReturnErrorOnState();
|
||||
}
|
||||
|
||||
// Check for the optional `=` indicating a default value.
|
||||
auto equals_token = context.ConsumeIf(Lex::TokenKind::Equal);
|
||||
if (!equals_token) {
|
||||
return;
|
||||
}
|
||||
|
||||
state.token = *equals_token;
|
||||
state.kind = StateKind::PatternListElementFinishDefaultValue;
|
||||
context.PushState(state);
|
||||
|
||||
// Check for the underscore `_` indicating the default value is unspecified.
|
||||
auto underscore = context.ConsumeIf(Lex::TokenKind::Underscore);
|
||||
if (underscore) {
|
||||
context.AddLeafNode(NodeKind::DefaultValueUnspecified, *underscore);
|
||||
return;
|
||||
}
|
||||
|
||||
// No underscore, we parse this as a normal expression.
|
||||
context.PushStateForExpr(state.ambient_precedence);
|
||||
}
|
||||
|
||||
auto HandlePatternListElementFinishDefaultValue(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
// Propagate any expr parsing errors upwards to initiate error recovery
|
||||
// at the pattern list level.
|
||||
if (state.has_error) {
|
||||
context.ReturnErrorOnState();
|
||||
}
|
||||
|
||||
context.AddNode(NodeKind::DefaultValuePattern, state.token, state.has_error);
|
||||
}
|
||||
|
||||
// Handles PatternListElementFinishAs(Tuple|Struct|Explicit|Implicit).
|
||||
static auto HandlePatternListElementFinish(Context& context,
|
||||
Lex::TokenKind close_token,
|
||||
|
||||
@@ -242,6 +242,8 @@ CARBON_PARSE_NODE_KIND_PATTERN(FormBindingPattern)
|
||||
CARBON_PARSE_NODE_KIND_PATTERN(TemplateBindingName)
|
||||
CARBON_PARSE_NODE_KIND_PATTERN(CompileTimeBindingPatternTypeStart)
|
||||
CARBON_PARSE_NODE_KIND_PATTERN(CompileTimeBindingPattern)
|
||||
CARBON_PARSE_NODE_KIND_PATTERN(DefaultValuePattern)
|
||||
CARBON_PARSE_NODE_KIND_EXPRESSION(DefaultValueUnspecified)
|
||||
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(LetIntroducer)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(LetInitializer)
|
||||
|
||||
@@ -1003,13 +1003,15 @@ CARBON_PARSE_STATE(AliasFinish)
|
||||
// ...
|
||||
// ^
|
||||
// 1. Pattern
|
||||
// 2. PatternListElementCheckForDefaultValue
|
||||
// 2. PatternListElementFinishAs(Tuple|Struct|Explicit|Implicit)
|
||||
//
|
||||
// .foo = ... (variant is Struct)
|
||||
// ^
|
||||
// 1. PeriodAsStruct
|
||||
// 2. StructPatternFieldAfterDesignator
|
||||
// 3 PatternListElementFinishAsStruct
|
||||
// 3. PatternListElementCheckForDefaultValue
|
||||
// 4. PatternListElementFinishAsStruct
|
||||
//
|
||||
// _ ... (variant is Struct)
|
||||
// ^
|
||||
@@ -1018,6 +1020,28 @@ CARBON_PARSE_STATE(AliasFinish)
|
||||
CARBON_PARSE_STATE_VARIANTS4(PatternListElement, Tuple, Struct, Explicit,
|
||||
Implicit)
|
||||
|
||||
// Some pattern list elements support optional default value expressions,
|
||||
// this state checks for the `=` and if present parses it before moving on
|
||||
// to finish the list element.
|
||||
//
|
||||
// ... = ...
|
||||
// ^
|
||||
// 1. Expr
|
||||
// 2. PatternListElementFinishDefaultValue
|
||||
//
|
||||
// ...
|
||||
// ^
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(PatternListElementCheckForDefaultValue)
|
||||
|
||||
// After parsing the default value Expr this state attaches that Expr
|
||||
// as a default value to the pattern.
|
||||
//
|
||||
// ... = ...
|
||||
// ^
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(PatternListElementFinishDefaultValue)
|
||||
|
||||
// Finishes parsing a pattern in a comma-separated list, including the
|
||||
// optional trailing `,`. If there are more patterns, enqueues another
|
||||
// pattern parsing state.
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/function/default_values.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/function/default_values.carbon
|
||||
|
||||
fn F(x: i32, y: i32 = 0);
|
||||
fn G((x: i32, y: i32) = (1, 2));
|
||||
fn H(unused x: i32 = 25);
|
||||
var b: auto = fn (x: i32 = 0) => x;
|
||||
// Can be used in def to avoid repeating values defined in decl.
|
||||
fn I(x: i32 = _);
|
||||
|
||||
// CHECK:STDOUT: - filename: default_values.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ ├─PatternListComma ','
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'y'
|
||||
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ╭─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'G'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─TuplePatternStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─PatternListComma ','
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'y'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ ╭─TuplePattern ')'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─TupleLiteralStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntLiteral '1'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─TupleLiteralComma ','
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntLiteral '2'
|
||||
// CHECK:STDOUT: │ │ │ ├─TupleLiteral ')'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'H'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ╭─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ ╭─UnusedPattern 'unused'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntLiteral '25'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'b'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ │ ├─TerseBodyArrow '=>'
|
||||
// CHECK:STDOUT: │ │ ├─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ ├─Lambda 'fn'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'I'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ╭─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─DefaultValueUnspecified '_'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
+15
-9
@@ -186,9 +186,9 @@ let {.x = x: i32 foo, .y = y: i32} = {};
|
||||
|
||||
// --- fail_struct_pattern_extra_token_start.carbon
|
||||
|
||||
// CHECK:STDERR: fail_struct_pattern_extra_token_start.carbon:[[@LINE+4]]:26: error: expected `,` or `}` [UnexpectedTokenAfterListElement]
|
||||
// CHECK:STDERR: fail_struct_pattern_extra_token_start.carbon:[[@LINE+4]]:29: error: expected `,` or `}` [UnexpectedTokenAfterListElement]
|
||||
// CHECK:STDERR: let {.x = x: i32, foo .y = y: i32} = {};
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
let {.x = x: i32, foo .y = y: i32} = {};
|
||||
|
||||
@@ -248,9 +248,9 @@ let {.x foo x: (), .y = y: ()} = {};
|
||||
|
||||
// --- fail_struct_pattern_invalid_field.carbon
|
||||
|
||||
// CHECK:STDERR: fail_struct_pattern_invalid_field.carbon:[[@LINE+4]]:12: error: expected `,` or `}` [UnexpectedTokenAfterListElement]
|
||||
// CHECK:STDERR: fail_struct_pattern_invalid_field.carbon:[[@LINE+4]]:14: error: expected expression [ExpectedExpr]
|
||||
// CHECK:STDERR: let {"foo" = , .x = x:()} = {};
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
let {"foo" = , .x = x:()} = {};
|
||||
|
||||
@@ -566,7 +566,9 @@ let {var _: i32} = {};
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─LetIntroducer 'let'
|
||||
// CHECK:STDOUT: │ │ ╭─StructPatternStart '{'
|
||||
// CHECK:STDOUT: │ │ ├─InvalidParse '=' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─InvalidParse '=' has_error
|
||||
// CHECK:STDOUT: │ │ │ ├─IdentifierNameExpr 'y'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─StructPattern '}' has_error
|
||||
// CHECK:STDOUT: │ ├─LetInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─StructLiteralStart '{'
|
||||
@@ -829,9 +831,11 @@ let {var _: i32} = {};
|
||||
// CHECK:STDOUT: │ │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ ├─StructPatternDesignatedField '='
|
||||
// CHECK:STDOUT: │ │ ├─PatternListComma ','
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameExpr 'foo'
|
||||
// CHECK:STDOUT: │ │ │ ├─IdentifierNameNotBeforeSignature 'y'
|
||||
// CHECK:STDOUT: │ │ ├─MemberAccessExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameExpr 'foo'
|
||||
// CHECK:STDOUT: │ │ │ ├─IdentifierNameNotBeforeSignature 'y'
|
||||
// CHECK:STDOUT: │ │ │ ╭─MemberAccessExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ ├─IdentifierNameExpr 'y'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ ├─StructPattern '}' has_error
|
||||
// CHECK:STDOUT: │ ├─LetInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─StructLiteralStart '{'
|
||||
@@ -954,7 +958,9 @@ let {var _: i32} = {};
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─LetIntroducer 'let'
|
||||
// CHECK:STDOUT: │ │ ╭─StructPatternStart '{'
|
||||
// CHECK:STDOUT: │ │ ├─StringLiteral '"foo"'
|
||||
// CHECK:STDOUT: │ │ │ ╭─StringLiteral '"foo"'
|
||||
// CHECK:STDOUT: │ │ │ ├─InvalidParse ',' has_error
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ │ ├─PatternListComma ','
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ ╭─StructFieldDesignator '.'
|
||||
|
||||
+84
-66
@@ -72,13 +72,16 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'NotDesignator'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'T'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─TypeTypeLiteral 'type'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'T'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─TypeTypeLiteral 'type'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'U'
|
||||
// CHECK:STDOUT: │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
@@ -88,16 +91,18 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'DesignatorInParens'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'V'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'I'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─ParenExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'J'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─ParenExpr ')'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'V'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'I'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─ParenExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'J'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─ParenExpr ')'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ├─BoolTypeLiteral 'bool'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
@@ -107,14 +112,16 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'DotSelf'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'W'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'K'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─SelfTypeName 'Self'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'W'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'K'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─SelfTypeName 'Self'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ├─FloatTypeLiteral 'f32'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
@@ -124,14 +131,16 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'DotKeyword'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'W'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'K'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'and' has_error
|
||||
// CHECK:STDOUT: │ │ │ │ ├─DesignatorExpr '.' has_error
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'W'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'K'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'and' has_error
|
||||
// CHECK:STDOUT: │ │ │ │ ├─DesignatorExpr '.' has_error
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ├─UnsignedIntTypeLiteral 'u8'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
@@ -141,15 +150,18 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'PostfixAfterDesignator'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'X'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'L'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'M'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─PostfixOperatorStar '*'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'X'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'L'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'M'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─PostfixOperatorStar '*'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─UnsignedIntTypeLiteral 'u64'
|
||||
// CHECK:STDOUT: │ │ │ ├─PostfixOperatorStar '*'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
@@ -159,17 +171,20 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'BinaryOpAfterDesignator'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'Y'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'N'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'O'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'P'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─InfixOperatorPlus '+'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'Y'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'N'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'O'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'P'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─InfixOperatorPlus '+'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─StructLiteralStart '{'
|
||||
// CHECK:STDOUT: │ │ │ ├─StructLiteral '}'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
@@ -179,19 +194,22 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'AfterAnd'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'Z'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'Q'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'R'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─IdentifierNameExpr 'S'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─RequirementImpls 'impls'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─RequirementAnd 'and'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─TupleLiteralStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ├─TupleLiteral ')'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ ├─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'Z'
|
||||
// CHECK:STDOUT: │ │ │ ├─CompileTimeBindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'Q'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─WhereOperand 'where'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'R'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─IdentifierNameExpr 'S'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─RequirementImpls 'impls'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─RequirementAnd 'and'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─TupleLiteralStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ├─TupleLiteral ')'
|
||||
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
|
||||
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'A'
|
||||
// CHECK:STDOUT: │ │ │ ├─DesignatorExpr '.'
|
||||
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
|
||||
// CHECK:STDOUT: ├─FunctionDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
|
||||
@@ -43,7 +43,7 @@ struct LeafNode {
|
||||
//
|
||||
// Each of these types should start with a `static constexpr Kind` member
|
||||
// initialized by calling `Define` on the corresponding `NodeKind`, and passing
|
||||
// in the `NodeCategory` of that kind. This will both associate the category
|
||||
// in the `NodeCategory` of that kind. This will both associate the category
|
||||
// with the node kind and create the necessary kind object for the typed node.
|
||||
//
|
||||
// This should be followed by field declarations that describe the child nodes,
|
||||
@@ -373,6 +373,20 @@ struct UnusedPattern {
|
||||
AnyPatternId inner;
|
||||
};
|
||||
|
||||
using DefaultValueUnspecified =
|
||||
LeafNode<NodeKind::DefaultValueUnspecified, Lex::UnderscoreTokenIndex,
|
||||
NodeCategory::Expr>;
|
||||
|
||||
// A pattern with a default value specified: `pattern = expr`.
|
||||
struct DefaultValuePattern {
|
||||
static constexpr auto Kind = NodeKind::DefaultValuePattern.Define(
|
||||
{.category = NodeCategory::Pattern, .child_count = 2});
|
||||
|
||||
AnyPatternId pattern;
|
||||
Lex::EqualTokenIndex token;
|
||||
AnyExprId default_value_expr;
|
||||
};
|
||||
|
||||
// A ref binding name: `ref name`.
|
||||
struct RefBindingName {
|
||||
static constexpr auto Kind =
|
||||
@@ -1520,7 +1534,7 @@ struct StructPatternDesignatedField {
|
||||
using StructPatternFieldId =
|
||||
NodeIdOneOf<StructPatternDesignatedField, LetBindingPattern,
|
||||
VariablePattern, VarBindingPattern, UnusedPattern,
|
||||
UnderscoreName>;
|
||||
UnderscoreName, DefaultValuePattern>;
|
||||
|
||||
struct StructPattern {
|
||||
static constexpr auto Kind = NodeKind::StructPattern.Define(
|
||||
|
||||
Reference in New Issue
Block a user