Parse an Underscore as either an Op or Term
This fixes a regression introduced by the latest nightlies making an
`Underscore` parseable again.
diff --git a/src/token.rs b/src/token.rs
index 8079bc6..081ae1e 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -111,13 +111,14 @@
$($keyword:tt pub struct $keyword_name:ident #[$keyword_doc:meta])*
}
) => (
- $(token_punct! { #[$punct_doc] $punct pub struct $punct_name/$len })*
+ $(token_punct_def! { #[$punct_doc] $punct pub struct $punct_name/$len })*
+ $(token_punct_parser! { $punct pub struct $punct_name })*
$(token_delimiter! { #[$delimiter_doc] $delimiter pub struct $delimiter_name })*
$(token_keyword! { #[$keyword_doc] $keyword pub struct $keyword_name })*
)
}
-macro_rules! token_punct {
+macro_rules! token_punct_def {
(#[$doc:meta] $s:tt pub struct $name:ident/$len:tt) => {
#[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
#[$doc]
@@ -164,6 +165,16 @@
{}
}
+ impl From<Span> for $name {
+ fn from(span: Span) -> Self {
+ $name([span; $len])
+ }
+ }
+ }
+}
+
+macro_rules! token_punct_parser {
+ ($s:tt pub struct $name:ident) => {
#[cfg(feature = "printing")]
impl ::quote::ToTokens for $name {
fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
@@ -181,12 +192,6 @@
Some(concat!("`", $s, "`"))
}
}
-
- impl From<Span> for $name {
- fn from(span: Span) -> Self {
- $name([span; $len])
- }
- }
}
}
@@ -319,6 +324,37 @@
}
}
+token_punct_def! {
+ /// `_`
+ "_" pub struct Underscore/1
+}
+
+#[cfg(feature = "printing")]
+impl ::quote::ToTokens for Underscore {
+ fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
+ // FIXME: This should really be the following (see #408):
+ // tokens.append(::proc_macro2::Term::new("_", self.0[0]));
+ printing::punct("_", &self.0, tokens);
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl ::Synom for Underscore {
+ fn parse(input: ::buffer::Cursor) -> ::synom::PResult<Underscore> {
+ match input.term() {
+ Some((term, rest)) if term.as_str() == "_" => {
+ Ok((Underscore([term.span()]), rest))
+ }
+ Some(_) => ::parse_error(),
+ None => parsing::punct("_", input, Underscore)
+ }
+ }
+
+ fn description() -> Option<&'static str> {
+ Some("`_`")
+ }
+}
+
tokens! {
punct: {
"+" pub struct Add/1 /// `+`
@@ -365,7 +401,6 @@
"*" pub struct Star/1 /// `*`
"-" pub struct Sub/1 /// `-`
"-=" pub struct SubEq/2 /// `-=`
- "_" pub struct Underscore/1 /// `_`
}
delimiter: {
"{" pub struct Brace /// `{...}`