From 8d62576a9b47922ce58ac757e6e4944d45b223a6 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 10 Jan 2021 20:52:46 +0800 Subject: Fixed expr meta var after path colons in mbe --- crates/mbe/src/tests.rs | 23 ++++++++++++++++++++++- crates/parser/src/parser.rs | 16 +++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs index d854985c5..17ddd0a9c 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs @@ -1,7 +1,11 @@ use std::fmt::Write; use ::parser::FragmentKind; -use syntax::{ast, AstNode, NodeOrToken, SyntaxKind::IDENT, SyntaxNode, WalkEvent, T}; +use syntax::{ + ast, AstNode, NodeOrToken, + SyntaxKind::{ERROR, IDENT}, + SyntaxNode, WalkEvent, T, +}; use test_utils::assert_eq_text; use super::*; @@ -1194,6 +1198,23 @@ macro_rules! foo { ); } +#[test] +fn test_expr_after_path_colons() { + assert!(parse_macro( + r#" +macro_rules! m { + ($k:expr) => { + f(K::$k); + } +} +"#, + ) + .expand_statements(r#"m!(C("0"))"#) + .descendants() + .find(|token| token.kind() == ERROR) + .is_some()); +} + // The following tests are based on real world situations #[test] fn 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; use crate::{ event::Event, ParseError, - SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, + SyntaxKind::{self, EOF, ERROR, L_DOLLAR, R_DOLLAR, TOMBSTONE}, TokenSet, TokenSource, T, }; @@ -215,13 +215,23 @@ 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); + match self.current() { + L_DOLLAR | R_DOLLAR => { + let m = self.start(); + self.error(message); + self.bump_any(); + m.complete(self, ERROR); + } + _ => { + self.err_recover(message, TokenSet::EMPTY); + } + } } /// Create an error node and consume the next token. pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { match self.current() { - T!['{'] | T!['}'] => { + T!['{'] | T!['}'] | L_DOLLAR | R_DOLLAR => { self.error(message); return; } -- cgit v1.2.3