From 81a7adc0e5115b3399fb4803572c7617ada07ee2 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 10 Apr 2023 15:54:43 -0700 Subject: [PATCH] Fix handling of invalid struct entries (#2755) This was incorrectly setting the finish state back to unknown, which resulted in a check. Instead, the finish state should be maintained. --- toolchain/parser/parser.cpp | 3 +- .../struct/fail_mix_with_unknown.carbon | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon diff --git a/toolchain/parser/parser.cpp b/toolchain/parser/parser.cpp index 2076fe26d919..7d52caa99bdb 100644 --- a/toolchain/parser/parser.cpp +++ b/toolchain/parser/parser.cpp @@ -600,8 +600,7 @@ auto Parser::HandleBraceExpressionParameterAfterDesignator( } else if (PositionIs(TokenKind::Equal)) { is_type = false; } else { - HandleBraceExpressionParameterError( - state, ParserState::BraceExpressionParameterFinishAsUnknown); + HandleBraceExpressionParameterError(state, param_finish_state); return; } diff --git a/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon b/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon new file mode 100644 index 000000000000..125d664f87a5 --- /dev/null +++ b/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon @@ -0,0 +1,57 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{not} %{carbon-run-parser} +// CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'a'}, +// CHECK:STDOUT: {kind: 'StructFieldDesignator', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'Literal', text: '1'}, +// CHECK:STDOUT: {kind: 'StructFieldValue', text: '=', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'StructComma', text: ','}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'b'}, +// CHECK:STDOUT: {kind: 'StructFieldDesignator', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StructFieldUnknown', text: '.', has_error: yes}, +// CHECK:STDOUT: {kind: 'StructComma', text: ','}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'c'}, +// CHECK:STDOUT: {kind: 'StructFieldDesignator', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StructFieldUnknown', text: '.', has_error: yes}, +// CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 20}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'a'}, +// CHECK:STDOUT: {kind: 'StructFieldDesignator', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, +// CHECK:STDOUT: {kind: 'StructFieldType', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'StructComma', text: ','}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'b'}, +// CHECK:STDOUT: {kind: 'StructFieldDesignator', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StructFieldUnknown', text: '.', has_error: yes}, +// CHECK:STDOUT: {kind: 'StructComma', text: ','}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'c'}, +// CHECK:STDOUT: {kind: 'StructFieldDesignator', text: '.', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StructFieldUnknown', text: '.', has_error: yes}, +// CHECK:STDOUT: {kind: 'StructTypeLiteral', text: '}', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 20}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] + +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon:[[@LINE+2]]:25: Expected `.field = value`. +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon:[[@LINE+1]]:29: Expected `.field = value`. +var x: i32 = {.a = 1, .b, .c: i32}; + +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon:[[@LINE+2]]:26: Expected `.field: field_type`. +// CHECK:STDERR: {{.*}}/toolchain/parser/testdata/struct/fail_mix_with_unknown.carbon:[[@LINE+1]]:31: Expected `.field: field_type`. +var x: i32 = {.a: i32, .b, .c = 1};