Skip to content

Commit 8dc3b46

Browse files
committed
fix: avoid panic when parsing extern block
closes #10083
1 parent a833fba commit 8dc3b46

File tree

5 files changed

+43
-13
lines changed

5 files changed

+43
-13
lines changed

crates/parser/src/grammar/items.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
9393
};
9494

9595
let mut has_mods = false;
96+
let mut has_extern = false;
9697

9798
// modifiers
9899
if p.at(T![const]) && p.nth(1) != T!['{'] {
@@ -102,7 +103,7 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
102103

103104
// test_err async_without_semicolon
104105
// fn foo() { let _ = async {} }
105-
if p.at(T![async]) && p.nth(1) != T!['{'] && p.nth(1) != T![move] && p.nth(1) != T![|] {
106+
if p.at(T![async]) && !matches!(p.nth(1), T!['{'] | T![move] | T![|]) {
106107
p.eat(T![async]);
107108
has_mods = true;
108109
}
@@ -114,7 +115,8 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
114115
has_mods = true;
115116
}
116117

117-
if p.at(T![extern]) && p.nth(1) != T!['{'] && (p.nth(1) != STRING || p.nth(2) != T!['{']) {
118+
if p.at(T![extern]) {
119+
has_extern = true;
118120
has_mods = true;
119121
abi(p);
120122
}
@@ -211,25 +213,23 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
211213
type_alias(p, m);
212214
}
213215

216+
// test unsafe_extern_block
214217
// unsafe extern "C" {}
215-
T![extern] => {
216-
abi(p);
218+
T!['{'] if has_extern => {
217219
extern_item_list(p);
218220
m.complete(p, EXTERN_BLOCK);
219221
}
220222

221-
_ => {
222-
if !has_visibility && !has_mods {
223-
return Err(m);
223+
_ if has_visibility || has_mods => {
224+
if has_mods {
225+
p.error("expected existential, fn, trait or impl");
224226
} else {
225-
if has_mods {
226-
p.error("expected existential, fn, trait or impl");
227-
} else {
228-
p.error("expected an item");
229-
}
230-
m.complete(p, ERROR);
227+
p.error("expected an item");
231228
}
229+
m.complete(p, ERROR);
232230
}
231+
232+
_ => return Err(m),
233233
}
234234
Ok(())
235235
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+
12+
13+
14+
error 10..10: expected existential, fn, trait or impl
15+
error 21..21: expected existential, fn, trait or impl
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extern "C" extern "C"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+
12+
13+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
unsafe extern "C" {}

0 commit comments

Comments
 (0)