Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/parser.rs')
| -rw-r--r-- | crates/mbe/src/parser.rs | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 5c499c06b1..218c04640f 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs @@ -4,8 +4,8 @@ use std::sync::Arc; use arrayvec::ArrayVec; +use intern::{sym, Symbol}; use span::{Edition, Span, SyntaxContextId}; -use syntax::SmolStr; use tt::iter::TtIter; use crate::ParseError; @@ -31,15 +31,14 @@ impl MetaTemplate { edition: impl Copy + Fn(SyntaxContextId) -> Edition, pattern: &tt::Subtree<Span>, ) -> Result<Self, ParseError> { - MetaTemplate::parse(edition, pattern, Mode::Pattern, false) + MetaTemplate::parse(edition, pattern, Mode::Pattern) } pub(crate) fn parse_template( edition: impl Copy + Fn(SyntaxContextId) -> Edition, template: &tt::Subtree<Span>, - new_meta_vars: bool, ) -> Result<Self, ParseError> { - MetaTemplate::parse(edition, template, Mode::Template, new_meta_vars) + MetaTemplate::parse(edition, template, Mode::Template) } pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> { @@ -50,13 +49,12 @@ impl MetaTemplate { edition: impl Copy + Fn(SyntaxContextId) -> Edition, tt: &tt::Subtree<Span>, mode: Mode, - new_meta_vars: bool, ) -> Result<Self, ParseError> { let mut src = TtIter::new(tt); let mut res = Vec::new(); while let Some(first) = src.peek_n(0) { - let op = next_op(edition, first, &mut src, mode, new_meta_vars)?; + let op = next_op(edition, first, &mut src, mode)?; res.push(op); } @@ -67,12 +65,12 @@ impl MetaTemplate { #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum Op { Var { - name: SmolStr, + name: Symbol, kind: Option<MetaVarKind>, id: Span, }, Ignore { - name: SmolStr, + name: Symbol, id: Span, }, Index { @@ -82,7 +80,7 @@ pub(crate) enum Op { depth: usize, }, Count { - name: SmolStr, + name: Symbol, // FIXME: `usize`` once we drop support for 1.76 depth: Option<usize>, }, @@ -138,8 +136,8 @@ impl PartialEq for Separator { use Separator::*; match (self, other) { - (Ident(a), Ident(b)) => a.text == b.text, - (Literal(a), Literal(b)) => a.text == b.text, + (Ident(a), Ident(b)) => a.sym == b.sym, + (Literal(a), Literal(b)) => a.symbol == b.symbol, (Puncts(a), Puncts(b)) if a.len() == b.len() => { let a_iter = a.iter().map(|a| a.char); let b_iter = b.iter().map(|b| b.char); @@ -161,7 +159,6 @@ fn next_op( first_peeked: &tt::TokenTree<Span>, src: &mut TtIter<'_, Span>, mode: Mode, - new_meta_vars: bool, ) -> Result<Op, ParseError> { let res = match first_peeked { tt::TokenTree::Leaf(tt::Leaf::Punct(p @ tt::Punct { char: '$', .. })) => { @@ -181,14 +178,14 @@ fn next_op( tt::TokenTree::Subtree(subtree) => match subtree.delimiter.kind { tt::DelimiterKind::Parenthesis => { let (separator, kind) = parse_repeat(src)?; - let tokens = MetaTemplate::parse(edition, subtree, mode, new_meta_vars)?; + let tokens = MetaTemplate::parse(edition, subtree, mode)?; Op::Repeat { tokens, separator: separator.map(Arc::new), kind } } tt::DelimiterKind::Brace => match mode { Mode::Template => { - parse_metavar_expr(new_meta_vars, &mut TtIter::new(subtree)).map_err( - |()| ParseError::unexpected("invalid metavariable expression"), - )? + parse_metavar_expr(&mut TtIter::new(subtree)).map_err(|()| { + ParseError::unexpected("invalid metavariable expression") + })? } Mode::Pattern => { return Err(ParseError::unexpected( @@ -203,19 +200,23 @@ fn next_op( } }, tt::TokenTree::Leaf(leaf) => match leaf { - tt::Leaf::Ident(ident) if ident.text == "crate" => { + tt::Leaf::Ident(ident) if ident.sym == sym::crate_ => { // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. - Op::Ident(tt::Ident { text: "$crate".into(), span: ident.span }) + Op::Ident(tt::Ident { + sym: sym::dollar_crate.clone(), + span: ident.span, + is_raw: tt::IdentIsRaw::No, + }) } tt::Leaf::Ident(ident) => { let kind = eat_fragment_kind(edition, src, mode)?; - let name = ident.text.clone(); + let name = ident.sym.clone(); let id = ident.span; Op::Var { name, kind, id } } tt::Leaf::Literal(lit) if is_boolean_literal(lit) => { let kind = eat_fragment_kind(edition, src, mode)?; - let name = lit.text.clone(); + let name = lit.symbol.clone(); let id = lit.span; Op::Var { name, kind, id } } @@ -256,7 +257,7 @@ fn next_op( tt::TokenTree::Subtree(subtree) => { src.next().expect("first token already peeked"); - let tokens = MetaTemplate::parse(edition, subtree, mode, new_meta_vars)?; + let tokens = MetaTemplate::parse(edition, subtree, mode)?; Op::Subtree { tokens, delimiter: subtree.delimiter } } }; @@ -273,7 +274,7 @@ fn eat_fragment_kind( let ident = src .expect_ident() .map_err(|()| ParseError::unexpected("missing fragment specifier"))?; - let kind = match ident.text.as_str() { + let kind = match ident.sym.as_str() { "path" => MetaVarKind::Path, "ty" => MetaVarKind::Ty, "pat" => match edition(ident.span.ctx) { @@ -299,7 +300,7 @@ fn eat_fragment_kind( } fn is_boolean_literal(lit: &tt::Literal<Span>) -> bool { - matches!(lit.text.as_str(), "true" | "false") + matches!(lit.symbol.as_str(), "true" | "false") } fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option<Separator>, RepeatKind), ParseError> { @@ -339,7 +340,7 @@ fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option<Separator>, Repeat Err(ParseError::InvalidRepeat) } -fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result<Op, ()> { +fn parse_metavar_expr(src: &mut TtIter<'_, Span>) -> Result<Op, ()> { let func = src.expect_ident()?; let args = src.expect_subtree()?; @@ -349,23 +350,19 @@ fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result let mut args = TtIter::new(args); - let op = match &*func.text { - "ignore" => { - if new_meta_vars { - args.expect_dollar()?; - } + let op = match &func.sym { + s if sym::ignore == *s => { + args.expect_dollar()?; let ident = args.expect_ident()?; - Op::Ignore { name: ident.text.clone(), id: ident.span } + Op::Ignore { name: ident.sym.clone(), id: ident.span } } - "index" => Op::Index { depth: parse_depth(&mut args)? }, - "len" => Op::Len { depth: parse_depth(&mut args)? }, - "count" => { - if new_meta_vars { - args.expect_dollar()?; - } + s if sym::index == *s => Op::Index { depth: parse_depth(&mut args)? }, + s if sym::len == *s => Op::Len { depth: parse_depth(&mut args)? }, + s if sym::count == *s => { + args.expect_dollar()?; let ident = args.expect_ident()?; let depth = if try_eat_comma(&mut args) { Some(parse_depth(&mut args)?) } else { None }; - Op::Count { name: ident.text.clone(), depth } + Op::Count { name: ident.sym.clone(), depth } } _ => return Err(()), }; @@ -380,9 +377,11 @@ fn parse_metavar_expr(new_meta_vars: bool, src: &mut TtIter<'_, Span>) -> Result fn parse_depth(src: &mut TtIter<'_, Span>) -> Result<usize, ()> { if src.len() == 0 { Ok(0) - } else if let tt::Leaf::Literal(lit) = src.expect_literal()? { + } else if let tt::Leaf::Literal(tt::Literal { symbol: text, suffix: None, .. }) = + src.expect_literal()? + { // Suffixes are not allowed. - lit.text.parse().map_err(|_| ()) + text.as_str().parse().map_err(|_| ()) } else { Err(()) } |