aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-01-14 10:52:12 +0000
committerGitHub <[email protected]>2021-01-14 10:52:12 +0000
commitd76143da19fcfcd210acc930e68acd6c43db9088 (patch)
tree0a1aab6dbe05e7a16caad5f58a787fd39abda6b8
parentd635806ea5090426cd4a5a57601a7f823277e84c (diff)
parent8d62576a9b47922ce58ac757e6e4944d45b223a6 (diff)
Merge #7211
7211: Fixed expr meta var after path colons in mbe r=matklad a=edwin0cheng Fixes #7207 Added `L_DOLLAR` in `ITEM_RECOVERY_SET` , but I don't know whether it is a good idea. r? @matklad Co-authored-by: Edwin Cheng <[email protected]>
-rw-r--r--crates/mbe/src/tests.rs23
-rw-r--r--crates/parser/src/parser.rs16
2 files changed, 35 insertions, 4 deletions
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs
index ecea15c11..9ff901e97 100644
--- a/crates/mbe/src/tests.rs
+++ b/crates/mbe/src/tests.rs
@@ -1,7 +1,11 @@
1use std::fmt::Write; 1use std::fmt::Write;
2 2
3use ::parser::FragmentKind; 3use ::parser::FragmentKind;
4use syntax::{ast, AstNode, NodeOrToken, SyntaxKind::IDENT, SyntaxNode, WalkEvent, T}; 4use syntax::{
5 ast, AstNode, NodeOrToken,
6 SyntaxKind::{ERROR, IDENT},
7 SyntaxNode, WalkEvent, T,
8};
5use test_utils::assert_eq_text; 9use test_utils::assert_eq_text;
6 10
7use super::*; 11use super::*;
@@ -1194,6 +1198,23 @@ macro_rules! foo {
1194 ); 1198 );
1195} 1199}
1196 1200
1201#[test]
1202fn test_expr_after_path_colons() {
1203 assert!(parse_macro(
1204 r#"
1205macro_rules! m {
1206 ($k:expr) => {
1207 f(K::$k);
1208 }
1209}
1210"#,
1211 )
1212 .expand_statements(r#"m!(C("0"))"#)
1213 .descendants()
1214 .find(|token| token.kind() == ERROR)
1215 .is_some());
1216}
1217
1197// The following tests are based on real world situations 1218// The following tests are based on real world situations
1198#[test] 1219#[test]
1199fn test_vec() { 1220fn test_vec() {
diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs
index d2487acc3..81e26e009 100644
--- a/crates/parser/src/parser.rs
+++ b/crates/parser/src/parser.rs
@@ -7,7 +7,7 @@ use drop_bomb::DropBomb;
7use crate::{ 7use crate::{
8 event::Event, 8 event::Event,
9 ParseError, 9 ParseError,
10 SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, 10 SyntaxKind::{self, EOF, ERROR, L_DOLLAR, R_DOLLAR, TOMBSTONE},
11 TokenSet, TokenSource, T, 11 TokenSet, TokenSource, T,
12}; 12};
13 13
@@ -215,13 +215,23 @@ impl<'t> Parser<'t> {
215 215
216 /// Create an error node and consume the next token. 216 /// Create an error node and consume the next token.
217 pub(crate) fn err_and_bump(&mut self, message: &str) { 217 pub(crate) fn err_and_bump(&mut self, message: &str) {
218 self.err_recover(message, TokenSet::EMPTY); 218 match self.current() {
219 L_DOLLAR | R_DOLLAR => {
220 let m = self.start();
221 self.error(message);
222 self.bump_any();
223 m.complete(self, ERROR);
224 }
225 _ => {
226 self.err_recover(message, TokenSet::EMPTY);
227 }
228 }
219 } 229 }
220 230
221 /// Create an error node and consume the next token. 231 /// Create an error node and consume the next token.
222 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { 232 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
223 match self.current() { 233 match self.current() {
224 T!['{'] | T!['}'] => { 234 T!['{'] | T!['}'] | L_DOLLAR | R_DOLLAR => {
225 self.error(message); 235 self.error(message);
226 return; 236 return;
227 } 237 }