From 482b25b321d06ee2b9e438e458ed41b691553736 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 8 Apr 2022 13:10:52 +1000 Subject: [PATCH 1/3] Change internal naming of macros. When a `macro_rules! foo { ... }` invocation is compiled the name used is `foo`, not `macro_rules!`. This is different to all other macro invocations, and confused me when I was inserted debugging println statements for macro evaluation. This commit changes it to `macro_rules` (or just `macro`), which is what I expected. There are no externally visible changes. --- compiler/rustc_expand/src/mbe/macro_rules.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 31dae6a2fb437..f5c7186bc4b18 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -439,7 +439,8 @@ pub fn compile_declarative_macro( let argument_gram = mbe::macro_parser::compute_locs(&sess.parse_sess, &argument_gram); let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS); - let mut tt_parser = TtParser::new(def.ident); + let mut tt_parser = + TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro })); let argument_map = match tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &argument_gram) { Success(m) => m, Failure(token, msg) => { From 4ba609601f1a99ddf3cf0cf70f57c4a045f0f23f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 8 Apr 2022 14:16:44 +1000 Subject: [PATCH 2/3] Tweak `NamedMatch` representation. The `Lrc` isn't necessary, neither is the `SmallVec`. Performance is changed negligibly, but the new code is simpler. --- compiler/rustc_expand/src/mbe/macro_parser.rs | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index ce243b4a67272..d26f80e82fcfe 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -81,22 +81,12 @@ use rustc_session::parse::ParseSess; use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::Span; -use smallvec::{smallvec, SmallVec}; - use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use rustc_span::symbol::Ident; use std::borrow::Cow; use std::collections::hash_map::Entry::{Occupied, Vacant}; -// One element is enough to cover 95-99% of vectors for most benchmarks. Also, vectors longer than -// one frequently have many elements, not just two or three. -type NamedMatchVec = SmallVec<[NamedMatch; 1]>; - -// This type is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(NamedMatchVec, 48); - /// A unit within a matcher that a `MatcherPos` can refer to. Similar to (and derived from) /// `mbe::TokenTree`, but designed specifically for fast and easy traversal during matching. /// Notable differences to `mbe::TokenTree`: @@ -221,7 +211,7 @@ struct MatcherPos { /// with one element per metavar decl in the matcher. Each element records token trees matched /// against the relevant metavar by the black box parser. An element will be a `MatchedSeq` if /// the corresponding metavar decl is within a sequence. - matches: Lrc, + matches: Lrc>, } // This type is used a lot. Make sure it doesn't unintentionally get bigger. @@ -246,18 +236,12 @@ impl MatcherPos { let mut curr = &mut matches[metavar_idx]; for _ in 0..seq_depth - 1 { match curr { - MatchedSeq(seq) => { - let seq = Lrc::make_mut(seq); - curr = seq.last_mut().unwrap(); - } + MatchedSeq(seq) => curr = seq.last_mut().unwrap(), _ => unreachable!(), } } match curr { - MatchedSeq(seq) => { - let seq = Lrc::make_mut(seq); - seq.push(m); - } + MatchedSeq(seq) => seq.push(m), _ => unreachable!(), } } @@ -350,7 +334,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize { /// ``` #[derive(Debug, Clone)] crate enum NamedMatch { - MatchedSeq(Lrc), + MatchedSeq(Vec), // A metavar match of type `tt`. MatchedTokenTree(rustc_ast::tokenstream::TokenTree), @@ -388,7 +372,7 @@ pub struct TtParser { /// Pre-allocate an empty match array, so it can be cloned cheaply for macros with many rules /// that have no metavars. - empty_matches: Lrc, + empty_matches: Lrc>, } impl TtParser { @@ -398,7 +382,7 @@ impl TtParser { cur_mps: vec![], next_mps: vec![], bb_mps: vec![], - empty_matches: Lrc::new(smallvec![]), + empty_matches: Lrc::new(vec![]), } } @@ -452,11 +436,7 @@ impl TtParser { } => { // Install an empty vec for each metavar within the sequence. for metavar_idx in next_metavar..next_metavar + num_metavar_decls { - mp.push_match( - metavar_idx, - seq_depth, - MatchedSeq(self.empty_matches.clone()), - ); + mp.push_match(metavar_idx, seq_depth, MatchedSeq(vec![])); } if op == KleeneOp::ZeroOrMore || op == KleeneOp::ZeroOrOne { From edd7f2cdab424ff8ed64a84f784a5c1273bcb138 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 8 Apr 2022 14:25:37 +1000 Subject: [PATCH 3/3] Add a useful comment. --- compiler/rustc_expand/src/mbe/macro_parser.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index d26f80e82fcfe..b5f56d7d6dc84 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -211,6 +211,10 @@ struct MatcherPos { /// with one element per metavar decl in the matcher. Each element records token trees matched /// against the relevant metavar by the black box parser. An element will be a `MatchedSeq` if /// the corresponding metavar decl is within a sequence. + /// + /// It is critical to performance that this is an `Lrc`, because it gets cloned frequently when + /// processing sequences. Mostly for sequence-ending possibilities that must be tried but end + /// up failing. matches: Lrc>, }