mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-04 18:58:41 +00:00
Merge pull request #20180 from ChayimFriedman2/parser-stuck
Some checks are pending
metrics / build_metrics (push) Waiting to run
metrics / other_metrics (diesel-1.4.8) (push) Blocked by required conditions
metrics / other_metrics (hyper-0.14.18) (push) Blocked by required conditions
metrics / other_metrics (ripgrep-13.0.0) (push) Blocked by required conditions
metrics / other_metrics (self) (push) Blocked by required conditions
metrics / other_metrics (webrender-2022) (push) Blocked by required conditions
metrics / generate_final_metrics (push) Blocked by required conditions
rustdoc / rustdoc (push) Waiting to run
Some checks are pending
metrics / build_metrics (push) Waiting to run
metrics / other_metrics (diesel-1.4.8) (push) Blocked by required conditions
metrics / other_metrics (hyper-0.14.18) (push) Blocked by required conditions
metrics / other_metrics (ripgrep-13.0.0) (push) Blocked by required conditions
metrics / other_metrics (self) (push) Blocked by required conditions
metrics / other_metrics (webrender-2022) (push) Blocked by required conditions
metrics / generate_final_metrics (push) Blocked by required conditions
rustdoc / rustdoc (push) Waiting to run
fix: Always bump in the parser in `err_and_bump()`
This commit is contained in:
commit
778e08df16
4 changed files with 50 additions and 8 deletions
|
@ -20,13 +20,14 @@ use base_db::RootQueryDb;
|
|||
use expect_test::Expect;
|
||||
use hir_expand::{
|
||||
AstId, InFile, MacroCallId, MacroCallKind, MacroKind,
|
||||
builtin::quote::quote,
|
||||
db::ExpandDatabase,
|
||||
proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind},
|
||||
span_map::SpanMapRef,
|
||||
};
|
||||
use intern::Symbol;
|
||||
use intern::{Symbol, sym};
|
||||
use itertools::Itertools;
|
||||
use span::{Edition, Span};
|
||||
use span::{Edition, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext};
|
||||
use stdx::{format_to, format_to_acc};
|
||||
use syntax::{
|
||||
AstNode, AstPtr,
|
||||
|
@ -34,7 +35,9 @@ use syntax::{
|
|||
SyntaxNode, T,
|
||||
ast::{self, edit::IndentLevel},
|
||||
};
|
||||
use syntax_bridge::token_tree_to_syntax_node;
|
||||
use test_fixture::WithFixture;
|
||||
use tt::{TextRange, TextSize};
|
||||
|
||||
use crate::{
|
||||
AdtId, Lookup, ModuleDefId,
|
||||
|
@ -386,3 +389,38 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
|
|||
other.type_id() == TypeId::of::<Self>()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_20171() {
|
||||
// This really isn't the appropriate place to put this test, but it's convenient with access to `quote!`.
|
||||
let span = Span {
|
||||
range: TextRange::empty(TextSize::new(0)),
|
||||
anchor: SpanAnchor {
|
||||
file_id: span::EditionedFileId::current_edition(span::FileId::from_raw(0)),
|
||||
ast_id: ROOT_ERASED_FILE_AST_ID,
|
||||
},
|
||||
ctx: SyntaxContext::root(Edition::CURRENT),
|
||||
};
|
||||
let close_brace = tt::Punct { char: '}', spacing: tt::Spacing::Alone, span };
|
||||
let dotdot1 = tt::Punct { char: '.', spacing: tt::Spacing::Joint, span };
|
||||
let dotdot2 = tt::Punct { char: '.', spacing: tt::Spacing::Alone, span };
|
||||
let dollar_crate = sym::dollar_crate;
|
||||
let tt = quote! {
|
||||
span => {
|
||||
if !((matches!(
|
||||
drive_parser(&mut parser, data, false),
|
||||
Err(TarParserError::CorruptField {
|
||||
field: CorruptFieldContext::PaxKvLength,
|
||||
error: GeneralParseError::ParseInt(ParseIntError { #dotdot1 #dotdot2 })
|
||||
})
|
||||
#close_brace ))) {
|
||||
#dollar_crate::panic::panic_2021!();
|
||||
}}
|
||||
};
|
||||
token_tree_to_syntax_node(
|
||||
&tt,
|
||||
syntax_bridge::TopEntryPoint::MacroStmts,
|
||||
&mut |_| Edition::CURRENT,
|
||||
Edition::CURRENT,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ macro_rules! quote {
|
|||
}
|
||||
}
|
||||
}
|
||||
pub(super) use quote;
|
||||
pub use quote;
|
||||
|
||||
pub trait ToTokenTree {
|
||||
fn to_tokens(self, span: Span, builder: &mut TopSubtreeBuilder);
|
||||
|
|
|
@ -411,11 +411,10 @@ fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedMarker> {
|
|||
dir_spec.abandon(p);
|
||||
op.abandon(p);
|
||||
op_n.abandon(p);
|
||||
p.err_and_bump("expected asm operand");
|
||||
|
||||
// improves error recovery and handles err_and_bump recovering from `{` which gets
|
||||
// the parser stuck here
|
||||
// improves error recovery
|
||||
if p.at(T!['{']) {
|
||||
p.error("expected asm operand");
|
||||
// test_err bad_asm_expr
|
||||
// fn foo() {
|
||||
// builtin#asm(
|
||||
|
@ -423,6 +422,8 @@ fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedMarker> {
|
|||
// );
|
||||
// }
|
||||
expr(p);
|
||||
} else {
|
||||
p.err_and_bump("expected asm operand");
|
||||
}
|
||||
|
||||
if p.at(T!['}']) {
|
||||
|
|
|
@ -29,7 +29,7 @@ pub(crate) struct Parser<'t> {
|
|||
edition: Edition,
|
||||
}
|
||||
|
||||
const PARSER_STEP_LIMIT: usize = 15_000_000;
|
||||
const PARSER_STEP_LIMIT: usize = if cfg!(debug_assertions) { 150_000 } else { 15_000_000 };
|
||||
|
||||
impl<'t> Parser<'t> {
|
||||
pub(super) fn new(inp: &'t Input, edition: Edition) -> Parser<'t> {
|
||||
|
@ -254,7 +254,10 @@ impl<'t> Parser<'t> {
|
|||
|
||||
/// Create an error node and consume the next token.
|
||||
pub(crate) fn err_and_bump(&mut self, message: &str) {
|
||||
self.err_recover(message, TokenSet::EMPTY);
|
||||
let m = self.start();
|
||||
self.error(message);
|
||||
self.bump_any();
|
||||
m.complete(self, ERROR);
|
||||
}
|
||||
|
||||
/// Create an error node and consume the next token unless it is in the recovery set.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue