use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem;
use std::ops::{Deref, DerefMut};
-use std::rc::Rc;
// To avoid costly uniqueness checks, we require that `MatchSeq` always has a nonempty body.
/// A `ParseResult` where the `Success` variant contains a mapping of `Ident`s to `NamedMatch`es.
/// This represents the mapping of metavars to the token trees they bind to.
-pub type NamedParseResult = ParseResult<FxHashMap<Ident, Rc<NamedMatch>>>;
+pub type NamedParseResult = ParseResult<FxHashMap<Ident, NamedMatch>>;
/// Count how many metavars are named in the given matcher `ms`.
pub fn count_names(ms: &[TokenTree]) -> usize {
sess: &ParseSess,
m: &TokenTree,
res: &mut I,
- ret_val: &mut FxHashMap<Ident, Rc<NamedMatch>>,
+ ret_val: &mut FxHashMap<Ident, NamedMatch>,
) -> Result<(), (syntax_pos::Span, String)> {
match *m {
TokenTree::Sequence(_, ref seq) => for next_m in &seq.tts {
TokenTree::MetaVarDecl(sp, bind_name, _) => {
match ret_val.entry(bind_name) {
Vacant(spot) => {
- // FIXME(simulacrum): Don't construct Rc here
- spot.insert(Rc::new(res.next().unwrap()));
+ spot.insert(res.next().unwrap());
}
Occupied(..) => {
return Err((sp, format!("duplicated bind name: {}", bind_name)))
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use std::mem;
-use std::rc::Rc;
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
enum Frame {
/// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`.
///
/// Along the way, we do some additional error checking.
-pub fn transcribe(
+pub(super) fn transcribe(
cx: &ExtCtxt<'_>,
- interp: &FxHashMap<Ident, Rc<NamedMatch>>,
+ interp: &FxHashMap<Ident, NamedMatch>,
src: Vec<quoted::TokenTree>,
) -> TokenStream {
// Nothing for us to transcribe...
// Find the matched nonterminal from the macro invocation, and use it to replace
// the meta-var.
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
- if let MatchedNonterminal(ref nt) = *cur_matched {
+ if let MatchedNonterminal(ref nt) = cur_matched {
// FIXME #2887: why do we apply a mark when matching a token tree meta-var
// (e.g. `$x:tt`), but not when we are matching any other type of token
// tree?
/// See the definition of `repeats` in the `transcribe` function. `repeats` is used to descend
/// into the right place in nested matchers. If we attempt to descend too far, the macro writer has
/// made a mistake, and we return `None`.
-fn lookup_cur_matched(
+fn lookup_cur_matched<'a>(
ident: Ident,
- interpolations: &FxHashMap<Ident, Rc<NamedMatch>>,
+ interpolations: &'a FxHashMap<Ident, NamedMatch>,
repeats: &[(usize, usize)],
-) -> Option<Rc<NamedMatch>> {
+) -> Option<&'a NamedMatch> {
interpolations.get(&ident).map(|matched| {
- let mut matched = matched.clone();
+ let mut matched = matched;
for &(idx, _) in repeats {
- let m = matched.clone();
- match *m {
+ match matched {
MatchedNonterminal(_) => break,
- MatchedSeq(ref ads, _) => matched = Rc::new(ads[idx].clone()),
+ MatchedSeq(ref ads, _) => matched = ads.get(idx).unwrap(),
}
}
/// multiple nested matcher sequences.
fn lockstep_iter_size(
tree: "ed::TokenTree,
- interpolations: &FxHashMap<Ident, Rc<NamedMatch>>,
+ interpolations: &FxHashMap<Ident, NamedMatch>,
repeats: &[(usize, usize)],
) -> LockstepIterSize {
use quoted::TokenTree;
}
TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => {
match lookup_cur_matched(name, interpolations, repeats) {
- Some(matched) => match *matched {
+ Some(matched) => match matched {
MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
MatchedSeq(ref ads, _) => LockstepIterSize::Constraint(ads.len(), name),
},