Reduce the size of Token
and make it cheaper to clone by refactoring
`Token::Interpolated(Nonterminal)` -> `Token::Interpolated(Rc<Nonterminal>)`.
This commit is contained in:
parent
5f280a5c60
commit
eb3ac29a10
10 changed files with 163 additions and 230 deletions
|
@ -107,125 +107,41 @@ pub enum SemiColonMode {
|
|||
/// be. The important thing is to make sure that lookahead doesn't balk at
|
||||
/// `token::Interpolated` tokens.
|
||||
macro_rules! maybe_whole_expr {
|
||||
($p:expr) => (
|
||||
{
|
||||
let found = match $p.token {
|
||||
token::Interpolated(token::NtExpr(ref e)) => {
|
||||
Some((*e).clone())
|
||||
}
|
||||
token::Interpolated(token::NtPath(_)) => {
|
||||
// FIXME: The following avoids an issue with lexical borrowck scopes,
|
||||
// but the clone is unfortunate.
|
||||
let pt = match $p.token {
|
||||
token::Interpolated(token::NtPath(ref pt)) => (**pt).clone(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
let span = $p.span;
|
||||
Some($p.mk_expr(span.lo, span.hi, ExprKind::Path(None, pt), ThinVec::new()))
|
||||
}
|
||||
token::Interpolated(token::NtBlock(_)) => {
|
||||
// FIXME: The following avoids an issue with lexical borrowck scopes,
|
||||
// but the clone is unfortunate.
|
||||
let b = match $p.token {
|
||||
token::Interpolated(token::NtBlock(ref b)) => (*b).clone(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
let span = $p.span;
|
||||
Some($p.mk_expr(span.lo, span.hi, ExprKind::Block(b), ThinVec::new()))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
match found {
|
||||
Some(e) => {
|
||||
($p:expr) => {
|
||||
if let token::Interpolated(nt) = $p.token.clone() {
|
||||
match *nt {
|
||||
token::NtExpr(ref e) => {
|
||||
$p.bump();
|
||||
return Ok(e);
|
||||
return Ok((*e).clone());
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
token::NtPath(ref path) => {
|
||||
$p.bump();
|
||||
let span = $p.span;
|
||||
let kind = ExprKind::Path(None, (*path).clone());
|
||||
return Ok($p.mk_expr(span.lo, span.hi, kind, ThinVec::new()));
|
||||
}
|
||||
token::NtBlock(ref block) => {
|
||||
$p.bump();
|
||||
let span = $p.span;
|
||||
let kind = ExprKind::Block((*block).clone());
|
||||
return Ok($p.mk_expr(span.lo, span.hi, kind, ThinVec::new()));
|
||||
}
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// As maybe_whole_expr, but for things other than expressions
|
||||
macro_rules! maybe_whole {
|
||||
($p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return Ok(x.clone());
|
||||
($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
|
||||
if let token::Interpolated(nt) = $p.token.clone() {
|
||||
if let token::$constructor($x) = (*nt).clone() {
|
||||
$p.bump();
|
||||
return Ok($e);
|
||||
}
|
||||
}
|
||||
);
|
||||
(no_clone $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return Ok(x);
|
||||
}
|
||||
}
|
||||
);
|
||||
(no_clone_from_p $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return Ok(x.unwrap());
|
||||
}
|
||||
}
|
||||
);
|
||||
(deref $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return Ok((*x).clone());
|
||||
}
|
||||
}
|
||||
);
|
||||
(Some deref $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return Ok(Some((*x).clone()));
|
||||
}
|
||||
}
|
||||
);
|
||||
(pair_empty $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return Ok((Vec::new(), x));
|
||||
}
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
|
||||
|
@ -516,9 +432,6 @@ impl<'a> Parser<'a> {
|
|||
self.bump();
|
||||
Ok(i)
|
||||
}
|
||||
token::Interpolated(token::NtIdent(..)) => {
|
||||
self.bug("ident interpolation not converted to real token");
|
||||
}
|
||||
_ => {
|
||||
Err(if self.prev_token_kind == PrevTokenKind::DocComment {
|
||||
self.span_fatal_help(self.prev_span,
|
||||
|
@ -1162,7 +1075,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse the items in a trait declaration
|
||||
pub fn parse_trait_item(&mut self) -> PResult<'a, TraitItem> {
|
||||
maybe_whole!(no_clone_from_p self, NtTraitItem);
|
||||
maybe_whole!(self, NtTraitItem, |x| x);
|
||||
let mut attrs = self.parse_outer_attributes()?;
|
||||
let lo = self.span.lo;
|
||||
|
||||
|
@ -1331,7 +1244,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse a type.
|
||||
pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
|
||||
maybe_whole!(no_clone self, NtTy);
|
||||
maybe_whole!(self, NtTy, |x| x);
|
||||
|
||||
let lo = self.span.lo;
|
||||
|
||||
|
@ -1476,7 +1389,7 @@ impl<'a> Parser<'a> {
|
|||
/// This version of parse arg doesn't necessarily require
|
||||
/// identifier names.
|
||||
pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
|
||||
maybe_whole!(no_clone self, NtArg);
|
||||
maybe_whole!(self, NtArg, |x| x);
|
||||
|
||||
let pat = if require_name || self.is_named_argument() {
|
||||
debug!("parse_arg_general parse_pat (require_name:{})",
|
||||
|
@ -1542,12 +1455,13 @@ impl<'a> Parser<'a> {
|
|||
/// Matches token_lit = LIT_INTEGER | ...
|
||||
pub fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
|
||||
let out = match self.token {
|
||||
token::Interpolated(token::NtExpr(ref v)) => {
|
||||
match v.node {
|
||||
token::Interpolated(ref nt) => match **nt {
|
||||
token::NtExpr(ref v) => match v.node {
|
||||
ExprKind::Lit(ref lit) => { lit.node.clone() }
|
||||
_ => { return self.unexpected_last(&self.token); }
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => { return self.unexpected_last(&self.token); }
|
||||
},
|
||||
token::Literal(lit, suf) => {
|
||||
let (suffix_illegal, out) = match lit {
|
||||
token::Byte(i) => (true, LitKind::Byte(parse::byte_lit(&i.as_str()).0)),
|
||||
|
@ -1703,14 +1617,7 @@ impl<'a> Parser<'a> {
|
|||
/// bounds are permitted and whether `::` must precede type parameter
|
||||
/// groups.
|
||||
pub fn parse_path(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> {
|
||||
// Check for a whole path...
|
||||
let found = match self.token {
|
||||
token::Interpolated(token::NtPath(_)) => Some(self.bump_and_get()),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(token::Interpolated(token::NtPath(path))) = found {
|
||||
return Ok(*path);
|
||||
}
|
||||
maybe_whole!(self, NtPath, |x| x);
|
||||
|
||||
let lo = self.span.lo;
|
||||
let is_global = self.eat(&token::ModSep);
|
||||
|
@ -2746,7 +2653,7 @@ impl<'a> Parser<'a> {
|
|||
// and token::SubstNt's; it's too early to know yet
|
||||
// whether something will be a nonterminal or a seq
|
||||
// yet.
|
||||
maybe_whole!(deref self, NtTT);
|
||||
maybe_whole!(self, NtTT, |x| x);
|
||||
|
||||
match self.token {
|
||||
token::Eof => {
|
||||
|
@ -3327,7 +3234,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
pub fn parse_arm(&mut self) -> PResult<'a, Arm> {
|
||||
maybe_whole!(no_clone self, NtArm);
|
||||
maybe_whole!(self, NtArm, |x| x);
|
||||
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let pats = self.parse_pats()?;
|
||||
|
@ -3583,7 +3490,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse a pattern.
|
||||
pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||
maybe_whole!(self, NtPat);
|
||||
maybe_whole!(self, NtPat, |x| x);
|
||||
|
||||
let lo = self.span.lo;
|
||||
let pat;
|
||||
|
@ -3888,7 +3795,7 @@ impl<'a> Parser<'a> {
|
|||
fn parse_stmt_without_recovery(&mut self,
|
||||
macro_legacy_warnings: bool)
|
||||
-> PResult<'a, Option<Stmt>> {
|
||||
maybe_whole!(Some deref self, NtStmt);
|
||||
maybe_whole!(self, NtStmt, |x| Some(x));
|
||||
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let lo = self.span.lo;
|
||||
|
@ -4077,7 +3984,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse a block. No inner attrs are allowed.
|
||||
pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
|
||||
maybe_whole!(no_clone self, NtBlock);
|
||||
maybe_whole!(self, NtBlock, |x| x);
|
||||
|
||||
let lo = self.span.lo;
|
||||
|
||||
|
@ -4115,7 +4022,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse a block. Inner attrs are allowed.
|
||||
fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
|
||||
maybe_whole!(pair_empty self, NtBlock);
|
||||
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
|
||||
|
||||
let lo = self.span.lo;
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
|
@ -4290,7 +4197,7 @@ impl<'a> Parser<'a> {
|
|||
/// | ( < lifetimes , typaramseq ( , )? > )
|
||||
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
|
||||
pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
|
||||
maybe_whole!(self, NtGenerics);
|
||||
maybe_whole!(self, NtGenerics, |x| x);
|
||||
let span_lo = self.span.lo;
|
||||
|
||||
if self.eat(&token::Lt) {
|
||||
|
@ -4431,7 +4338,7 @@ impl<'a> Parser<'a> {
|
|||
/// where T : Trait<U, V> + 'b, 'a : 'b
|
||||
/// ```
|
||||
pub fn parse_where_clause(&mut self) -> PResult<'a, ast::WhereClause> {
|
||||
maybe_whole!(self, NtWhereClause);
|
||||
maybe_whole!(self, NtWhereClause, |x| x);
|
||||
|
||||
let mut where_clause = WhereClause {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
|
@ -4839,7 +4746,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parse an impl item.
|
||||
pub fn parse_impl_item(&mut self) -> PResult<'a, ImplItem> {
|
||||
maybe_whole!(no_clone_from_p self, NtImplItem);
|
||||
maybe_whole!(self, NtImplItem, |x| x);
|
||||
|
||||
let mut attrs = self.parse_outer_attributes()?;
|
||||
let lo = self.span.lo;
|
||||
|
@ -5707,19 +5614,13 @@ impl<'a> Parser<'a> {
|
|||
/// extern crate.
|
||||
fn parse_item_(&mut self, attrs: Vec<Attribute>,
|
||||
macros_allowed: bool, attributes_allowed: bool) -> PResult<'a, Option<P<Item>>> {
|
||||
let nt_item = match self.token {
|
||||
token::Interpolated(token::NtItem(ref item)) => {
|
||||
Some((**item).clone())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(mut item) = nt_item {
|
||||
self.bump();
|
||||
maybe_whole!(self, NtItem, |item| {
|
||||
let mut item = item.unwrap();
|
||||
let mut attrs = attrs;
|
||||
mem::swap(&mut item.attrs, &mut attrs);
|
||||
item.attrs.extend(attrs);
|
||||
return Ok(Some(P(item)));
|
||||
}
|
||||
Some(P(item))
|
||||
});
|
||||
|
||||
let lo = self.span.lo;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue