parse empty statemet as statemetn

This commit is contained in:
Aleksey Kladov 2021-12-29 20:04:36 +03:00
parent 841cd30b45
commit b5369927d7
4 changed files with 15 additions and 20 deletions

View file

@ -85,17 +85,21 @@ fn stmt_boundaries() {
check( check(
r#" r#"
macro_rules! m { macro_rules! m {
($($s:stmt)*) => (stringify!($($s |)*)) ($($s:stmt)*) => (stringify!($($s |)*);)
} }
// +errors
m!(;;92;let x = 92; loop {};); m!(;;92;let x = 92; loop {};);
"#, "#,
expect![[r#" expect![[r#"
macro_rules! m { macro_rules! m {
($($s:stmt)*) => (stringify!($($s |)*)) ($($s:stmt)*) => (stringify!($($s |)*);)
} }
/* error: expected Stmt *//* parse error: expected SEMICOLON */ stringify!(;
stringify!() |;
|92|;
|let x = 92|;
|loop {}
|;
|);
"#]], "#]],
); );
} }

View file

@ -98,11 +98,6 @@ pub(crate) mod entry {
let m = p.start(); let m = p.start();
while !p.at(EOF) { while !p.at(EOF) {
if p.at(T![;]) {
p.bump(T![;]);
continue;
}
expressions::stmt(p, expressions::Semicolon::Optional); expressions::stmt(p, expressions::Semicolon::Optional);
} }

View file

@ -30,6 +30,10 @@ fn expr_no_struct(p: &mut Parser) {
} }
pub(super) fn stmt(p: &mut Parser, semicolon: Semicolon) { pub(super) fn stmt(p: &mut Parser, semicolon: Semicolon) {
if p.eat(T![;]) {
return;
}
let m = p.start(); let m = p.start();
// test attr_on_expr_stmt // test attr_on_expr_stmt
// fn foo() { // fn foo() {
@ -143,12 +147,6 @@ pub(super) fn expr_block_contents(p: &mut Parser) {
// fn f() {}; // fn f() {};
// struct S {}; // struct S {};
// } // }
if p.at(T![;]) {
p.bump(T![;]);
continue;
}
stmt(p, Semicolon::Required); stmt(p, Semicolon::Required);
} }
} }

View file

@ -76,8 +76,7 @@ impl<'a> LexedStr<'a> {
builder.eat_trivias(); builder.eat_trivias();
(builder.sink)(StrStep::Exit); (builder.sink)(StrStep::Exit);
} }
State::PendingEnter => (), State::PendingEnter | State::Normal => (),
State::Normal => unreachable!(),
} }
let is_eof = builder.pos == builder.lexed.len(); let is_eof = builder.pos == builder.lexed.len();
@ -101,9 +100,8 @@ enum State {
impl Builder<'_, '_> { impl Builder<'_, '_> {
fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
match mem::replace(&mut self.state, State::Normal) { match mem::replace(&mut self.state, State::Normal) {
State::PendingEnter => unreachable!(),
State::PendingExit => (self.sink)(StrStep::Exit), State::PendingExit => (self.sink)(StrStep::Exit),
State::Normal => (), State::PendingEnter | State::Normal => (),
} }
self.eat_trivias(); self.eat_trivias();
self.do_token(kind, n_tokens as usize); self.do_token(kind, n_tokens as usize);