From d9ce1827c8255e751c9055c0f03e2e9505e9303f Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Fri, 18 Nov 2022 08:02:07 -0800 Subject: [PATCH] Adjust how invalid declarations pass errors. (#2413) When there's no semicolon for an invalid EmptyDeclaration, rather than producing nothing, produce an EmptyDeclaration with the original location that led to the error. Note this removes a direct edit (the only one) of the parse tree's error state. Elsewhere it's an indirection from adding an error node. --- toolchain/parser/parser.cpp | 11 ++++++----- .../testdata/basics/fail_no_intro_without_semi.carbon | 1 + .../fail_skip_without_semi_to_curly.carbon | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/toolchain/parser/parser.cpp b/toolchain/parser/parser.cpp index 1f665b282179..6fa60ebbbbff 100644 --- a/toolchain/parser/parser.cpp +++ b/toolchain/parser/parser.cpp @@ -705,11 +705,12 @@ auto Parser::HandleDeclarationLoopState() -> void { CARBON_DIAGNOSTIC(UnrecognizedDeclaration, Error, "Unrecognized declaration introducer."); emitter_->Emit(*position_, UnrecognizedDeclaration); - tree_->has_errors_ = true; - if (auto semi = SkipPastLikelyEnd(*position_)) { - AddLeafNode(ParseNodeKind::EmptyDeclaration(), *semi, - /*has_error=*/true); - } + auto cursor = *position_; + auto semi = SkipPastLikelyEnd(cursor); + // Locate the EmptyDeclaration at the semi when found, but use the + // original cursor location for an error when not. + AddLeafNode(ParseNodeKind::EmptyDeclaration(), semi ? *semi : cursor, + /*has_error=*/true); break; } } diff --git a/toolchain/parser/testdata/basics/fail_no_intro_without_semi.carbon b/toolchain/parser/testdata/basics/fail_no_intro_without_semi.carbon index bd5740161712..90be2682faef 100644 --- a/toolchain/parser/testdata/basics/fail_no_intro_without_semi.carbon +++ b/toolchain/parser/testdata/basics/fail_no_intro_without_semi.carbon @@ -5,6 +5,7 @@ // AUTOUPDATE // RUN: %{not} %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'EmptyDeclaration', text: 'foo', has_error: yes}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon b/toolchain/parser/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon index d963fd9e33b8..f758f7ab9e6a 100644 --- a/toolchain/parser/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon +++ b/toolchain/parser/testdata/function/declaration/fail_skip_without_semi_to_curly.carbon @@ -5,6 +5,7 @@ // AUTOUPDATE // RUN: %{not} %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'EmptyDeclaration', text: 'struct', has_error: yes}, // CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'F'}, // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('},