Merge branch master into next
diff --git a/codegen/src/main.rs b/codegen/src/main.rs
index 4a7ec38..9f884b9 100644
--- a/codegen/src/main.rs
+++ b/codegen/src/main.rs
@@ -54,13 +54,9 @@
const TERMINAL_TYPES: &[&str] = &["Span", "Ident"];
fn path_eq(a: &syn::Path, b: &str) -> bool {
- if a.global() {
- return false;
- }
- if a.segments.len() != 1 {
- return false;
- }
- a.segments[0].ident == b
+ a.leading_colon.is_none()
+ && a.segments.len() == 1
+ && a.segments[0].ident == b
}
fn get_features(attrs: &[Attribute], mut features: TokenStream) -> TokenStream {
@@ -149,15 +145,15 @@
// Try to parse the AstItem declaration out of the item.
let tts = &item.mac.tts;
let found = if path_eq(&item.mac.path, "ast_struct") {
- syn::parse_str::<parsing::AstStruct>("e!(#tts).to_string())
+ syn::parse2::<parsing::AstStruct>(quote!(#tts))
.map_err(|_| err_msg("failed to parse ast_struct"))?
.0
} else if path_eq(&item.mac.path, "ast_enum") {
- syn::parse_str::<parsing::AstEnum>("e!(#tts).to_string())
+ syn::parse2::<parsing::AstEnum>(quote!(#tts))
.map_err(|_| err_msg("failed to parse ast_enum"))?
.0
} else if path_eq(&item.mac.path, "ast_enum_of_structs") {
- syn::parse_str::<parsing::AstEnumOfStructs>("e!(#tts).to_string())
+ syn::parse2::<parsing::AstEnumOfStructs>(quote!(#tts))
.map_err(|_| err_msg("failed to parse ast_enum_of_structs"))?
.0
} else {
@@ -204,85 +200,95 @@
use proc_macro2::TokenStream;
use syn;
- use syn::synom::*;
+ use syn::parse::{Parse, ParseStream, Result};
use syn::*;
+ fn peek_tag(input: ParseStream, tag: &str) -> bool {
+ let ahead = input.fork();
+ ahead.parse::<Token![#]>().is_ok() && ahead
+ .parse::<Ident>()
+ .map(|ident| ident == tag)
+ .unwrap_or(false)
+ }
+
// Parses #full - returns #[cfg(feature = "full")] if it is present, and
// nothing otherwise.
- named!(full -> (TokenStream, bool), map!(option!(do_parse!(
- punct!(#) >>
- id: syn!(Ident) >>
- cond_reduce!(id == "full") >>
- ()
- )), |s| if s.is_some() {
- (quote!(#[cfg(feature = "full")]), true)
- } else {
- (quote!(), false)
- }));
+ fn full(input: ParseStream) -> (TokenStream, bool) {
+ if peek_tag(input, "full") {
+ input.parse::<Token![#]>().unwrap();
+ input.parse::<Ident>().unwrap();
+ (quote!(#[cfg(feature = "full")]), true)
+ } else {
+ (quote!(), false)
+ }
+ }
- named!(manual_extra_traits -> (), do_parse!(
- punct!(#) >>
- id: syn!(Ident) >>
- cond_reduce!(id == "manual_extra_traits") >>
- ()
- ));
+ fn skip_manual_extra_traits(input: ParseStream) {
+ if peek_tag(input, "manual_extra_traits") {
+ input.parse::<Token![#]>().unwrap();
+ input.parse::<Ident>().unwrap();
+ }
+ }
// Parses a simple AstStruct without the `pub struct` prefix.
- named!(ast_struct_inner -> AstItem, do_parse!(
- id: syn!(Ident) >>
- features: full >>
- option!(manual_extra_traits) >>
- rest: syn!(TokenStream) >>
- (AstItem {
- ast: syn::parse_str("e! {
- pub struct #id #rest
- }.to_string())?,
- features: features.0,
- eos_full: features.1,
+ fn ast_struct_inner(input: ParseStream) -> Result<AstItem> {
+ let ident: Ident = input.parse()?;
+ let (features, eos_full) = full(input);
+ skip_manual_extra_traits(input);
+ let rest: TokenStream = input.parse()?;
+ Ok(AstItem {
+ ast: syn::parse2(quote! {
+ pub struct #ident #rest
+ })?,
+ features: features,
+ eos_full: eos_full,
})
- ));
+ }
// ast_struct! parsing
pub struct AstStruct(pub Vec<AstItem>);
- impl Synom for AstStruct {
- named!(parse -> Self, do_parse!(
- many0!(Attribute::parse_outer) >>
- keyword!(pub) >>
- keyword!(struct) >>
- res: call!(ast_struct_inner) >>
- (AstStruct(vec![res]))
- ));
+ impl Parse for AstStruct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.call(Attribute::parse_outer)?;
+ input.parse::<Token![pub]>()?;
+ input.parse::<Token![struct]>()?;
+ let res = input.call(ast_struct_inner)?;
+ Ok(AstStruct(vec![res]))
+ }
}
- named!(no_visit -> (), do_parse!(
- punct!(#) >>
- id: syn!(Ident) >>
- cond_reduce!(id == "no_visit") >>
- ()
- ));
+ fn no_visit(input: ParseStream) -> bool {
+ if peek_tag(input, "no_visit") {
+ input.parse::<Token![#]>().unwrap();
+ input.parse::<Ident>().unwrap();
+ true
+ } else {
+ false
+ }
+ }
// ast_enum! parsing
pub struct AstEnum(pub Vec<AstItem>);
- impl Synom for AstEnum {
- named!(parse -> Self, do_parse!(
- many0!(Attribute::parse_outer) >>
- keyword!(pub) >>
- keyword!(enum) >>
- id: syn!(Ident) >>
- no_visit: option!(no_visit) >>
- rest: syn!(TokenStream) >>
- (AstEnum(if no_visit.is_some() {
+ impl Parse for AstEnum {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.call(Attribute::parse_outer)?;
+ input.parse::<Token![pub]>()?;
+ input.parse::<Token![enum]>()?;
+ let ident: Ident = input.parse()?;
+ let no_visit = no_visit(input);
+ let rest: TokenStream = input.parse()?;
+ Ok(AstEnum(if no_visit {
vec![]
} else {
vec![AstItem {
- ast: syn::parse_str("e! {
- pub enum #id #rest
- }.to_string())?,
+ ast: syn::parse2(quote! {
+ pub enum #ident #rest
+ })?,
features: quote!(),
eos_full: false,
}]
}))
- ));
+ }
}
// A single variant of an ast_enum_of_structs!
@@ -291,57 +297,73 @@
member: Option<Path>,
inner: Option<AstItem>,
}
- named!(eos_variant -> EosVariant, do_parse!(
- many0!(Attribute::parse_outer) >>
- keyword!(pub) >>
- variant: syn!(Ident) >>
- member: option!(map!(parens!(alt!(
- call!(ast_struct_inner) => { |x: AstItem| (Path::from(x.ast.ident.clone()), Some(x)) }
- |
- syn!(Path) => { |x| (x, None) }
- )), |x| x.1)) >>
- punct!(,) >>
- (EosVariant {
+ fn eos_variant(input: ParseStream) -> Result<EosVariant> {
+ input.call(Attribute::parse_outer)?;
+ input.parse::<Token![pub]>()?;
+ let variant: Ident = input.parse()?;
+ let (member, inner) = if input.peek(token::Paren) {
+ let content;
+ parenthesized!(content in input);
+ if content.fork().call(ast_struct_inner).is_ok() {
+ let item = content.call(ast_struct_inner)?;
+ (Some(Path::from(item.ast.ident.clone())), Some(item))
+ } else {
+ let path: Path = content.parse()?;
+ (Some(path), None)
+ }
+ } else {
+ (None, None)
+ };
+ input.parse::<Token![,]>()?;
+ Ok(EosVariant {
name: variant,
- member: member.clone().map(|x| x.0),
- inner: member.map(|x| x.1).unwrap_or_default(),
+ member: member,
+ inner: inner,
})
- ));
+ }
// ast_enum_of_structs! parsing
pub struct AstEnumOfStructs(pub Vec<AstItem>);
- impl Synom for AstEnumOfStructs {
- named!(parse -> Self, do_parse!(
- many0!(Attribute::parse_outer) >>
- keyword!(pub) >>
- keyword!(enum) >>
- id: syn!(Ident) >>
- variants: braces!(many0!(eos_variant)) >>
- option!(syn!(Ident)) >> // do_not_generate_to_tokens
- ({
- let enum_item = {
- let variants = variants.1.iter().map(|v| {
- let name = v.name.clone();
- match v.member {
- Some(ref member) => quote!(#name(#member)),
- None => quote!(#name),
- }
- });
- parse_quote! {
- pub enum #id {
- #(#variants),*
- }
+ impl Parse for AstEnumOfStructs {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.call(Attribute::parse_outer)?;
+ input.parse::<Token![pub]>()?;
+ input.parse::<Token![enum]>()?;
+ let ident: Ident = input.parse()?;
+
+ let content;
+ braced!(content in input);
+ let mut variants = Vec::new();
+ while !content.is_empty() {
+ variants.push(content.call(eos_variant)?);
+ }
+
+ if let Some(ident) = input.parse::<Option<Ident>>()? {
+ assert_eq!(ident, "do_not_generate_to_tokens");
+ }
+
+ let enum_item = {
+ let variants = variants.iter().map(|v| {
+ let name = v.name.clone();
+ match v.member {
+ Some(ref member) => quote!(#name(#member)),
+ None => quote!(#name),
}
- };
- let mut items = vec![AstItem {
- ast: enum_item,
- features: quote!(),
- eos_full: false,
- }];
- items.extend(variants.1.into_iter().filter_map(|v| v.inner));
- AstEnumOfStructs(items)
- })
- ));
+ });
+ parse_quote! {
+ pub enum #ident {
+ #(#variants),*
+ }
+ }
+ };
+ let mut items = vec![AstItem {
+ ast: enum_item,
+ features: quote!(),
+ eos_full: false,
+ }];
+ items.extend(variants.into_iter().filter_map(|v| v.inner));
+ Ok(AstEnumOfStructs(items))
+ }
}
}
@@ -350,6 +372,8 @@
use inflections::Inflect;
use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, TokenStreamExt};
+ use syn::ext::IdentExt;
+ use syn::parse::Parser;
use syn::punctuated::Punctuated;
use syn::*;
@@ -374,7 +398,9 @@
Option(&'a Type),
Tuple(&'a Punctuated<Type, Token![,]>),
Simple(&'a AstItem),
- Token(TokenStream),
+ TokenPunct(TokenStream),
+ TokenKeyword(TokenStream),
+ TokenGroup(Ident),
Pass,
}
@@ -391,7 +417,7 @@
"Punctuated" => RelevantType::Punctuated(first_arg(&last.arguments)),
"Option" => RelevantType::Option(first_arg(&last.arguments)),
"Brace" | "Bracket" | "Paren" | "Group" => {
- RelevantType::Token(last.ident.clone().into_token_stream())
+ RelevantType::TokenGroup(last.ident.clone())
}
_ => {
if let Some(item) = lookup.get(&last.ident) {
@@ -406,7 +432,13 @@
Type::Macro(TypeMacro { ref mac })
if mac.path.segments.last().unwrap().into_value().ident == "Token" =>
{
- RelevantType::Token(mac.into_token_stream())
+ let is_ident = Ident::parse_any.parse2(mac.tts.clone()).is_ok();
+ let is_underscore = parse2::<Token![_]>(mac.tts.clone()).is_ok();
+ if is_ident && !is_underscore {
+ RelevantType::TokenKeyword(mac.into_token_stream())
+ } else {
+ RelevantType::TokenPunct(mac.into_token_stream())
+ }
}
_ => RelevantType::Pass,
}
@@ -642,17 +674,47 @@
})
}
- fn token_visit(ty: TokenStream, kind: Kind, name: &Operand) -> TokenStream {
+ fn token_punct_visit(ty: TokenStream, kind: Kind, name: &Operand) -> TokenStream {
let name = name.tokens();
match kind {
Fold => quote! {
- #ty(tokens_helper(_visitor, &(#name).0))
+ #ty(tokens_helper(_visitor, &#name.spans))
},
Visit => quote! {
- tokens_helper(_visitor, &(#name).0)
+ tokens_helper(_visitor, &#name.spans)
},
VisitMut => quote! {
- tokens_helper(_visitor, &mut (#name).0)
+ tokens_helper(_visitor, &mut #name.spans)
+ },
+ }
+ }
+
+ fn token_keyword_visit(ty: TokenStream, kind: Kind, name: &Operand) -> TokenStream {
+ let name = name.tokens();
+ match kind {
+ Fold => quote! {
+ #ty(tokens_helper(_visitor, &#name.span))
+ },
+ Visit => quote! {
+ tokens_helper(_visitor, &#name.span)
+ },
+ VisitMut => quote! {
+ tokens_helper(_visitor, &mut #name.span)
+ },
+ }
+ }
+
+ fn token_group_visit(ty: Ident, kind: Kind, name: &Operand) -> TokenStream {
+ let name = name.tokens();
+ match kind {
+ Fold => quote! {
+ #ty(tokens_helper(_visitor, &#name.span))
+ },
+ Visit => quote! {
+ tokens_helper(_visitor, &#name.span)
+ },
+ VisitMut => quote! {
+ tokens_helper(_visitor, &mut #name.span)
},
}
}
@@ -686,7 +748,9 @@
res
})
}
- RelevantType::Token(ty) => Some(token_visit(ty, kind, name)),
+ RelevantType::TokenPunct(ty) => Some(token_punct_visit(ty, kind, name)),
+ RelevantType::TokenKeyword(ty) => Some(token_keyword_visit(ty, kind, name)),
+ RelevantType::TokenGroup(ty) => Some(token_group_visit(ty, kind, name)),
RelevantType::Pass => None,
}
}
diff --git a/examples/heapsize/example/src/main.rs b/examples/heapsize/example/src/main.rs
index 9c9d88a..f29d237 100644
--- a/examples/heapsize/example/src/main.rs
+++ b/examples/heapsize/example/src/main.rs
@@ -21,10 +21,12 @@
};
// 10 + 0 + 0 + 6 = 16
- println!("heap size = {} + {} + {} + {} = {}",
+ println!(
+ "heap size = {} + {} + {} + {} = {}",
demo.a.heap_size_of_children(),
demo.b.heap_size_of_children(),
demo.c.heap_size_of_children(),
demo.d.heap_size_of_children(),
- demo.heap_size_of_children());
+ demo.heap_size_of_children()
+ );
}
diff --git a/examples/heapsize/heapsize_derive/src/lib.rs b/examples/heapsize/heapsize_derive/src/lib.rs
index 68055e5..e4435b4 100644
--- a/examples/heapsize/heapsize_derive/src/lib.rs
+++ b/examples/heapsize/heapsize_derive/src/lib.rs
@@ -8,7 +8,7 @@
extern crate quote;
use proc_macro2::TokenStream;
-use syn::{DeriveInput, Data, Fields, Generics, GenericParam};
+use syn::{Data, DeriveInput, Fields, GenericParam, Generics};
#[proc_macro_derive(HeapSize)]
pub fn derive_heap_size(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
diff --git a/examples/heapsize2/example/src/main.rs b/examples/heapsize2/example/src/main.rs
index 1c66692..e424c11 100644
--- a/examples/heapsize2/example/src/main.rs
+++ b/examples/heapsize2/example/src/main.rs
@@ -25,5 +25,8 @@
e: "String".to_owned(),
},
};
- println!("heap size = {}", heapsize::HeapSize::heap_size_of_children(&demo));
+ println!(
+ "heap size = {}",
+ heapsize::HeapSize::heap_size_of_children(&demo)
+ );
}
diff --git a/examples/heapsize2/heapsize_derive/src/lib.rs b/examples/heapsize2/heapsize_derive/src/lib.rs
index 87bb60e..4b46c1f 100644
--- a/examples/heapsize2/heapsize_derive/src/lib.rs
+++ b/examples/heapsize2/heapsize_derive/src/lib.rs
@@ -8,8 +8,8 @@
extern crate quote;
use proc_macro2::{Span, TokenStream};
-use syn::{DeriveInput, Data, Fields, Generics, GenericParam, Index};
use syn::spanned::Spanned;
+use syn::{Data, DeriveInput, Fields, GenericParam, Generics, Index};
#[proc_macro_derive(HeapSize)]
pub fn derive_heap_size(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
@@ -84,7 +84,10 @@
//
// 0 + HeapSize::heap_size(&self.0) + HeapSize::heap_size(&self.1)
let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
- let index = Index { index: i as u32, span: call_site };
+ let index = Index {
+ index: i as u32,
+ span: call_site,
+ };
let access = quote_spanned!(call_site=> #var.#index);
quote_spanned! {f.span()=>
::heapsize::HeapSize::heap_size_of_children(&#access)
diff --git a/examples/lazy-static/example/src/main.rs b/examples/lazy-static/example/src/main.rs
index 16cfb36..4c3a160 100644
--- a/examples/lazy-static/example/src/main.rs
+++ b/examples/lazy-static/example/src/main.rs
@@ -1,5 +1,3 @@
-#![feature(proc_macro)]
-
extern crate lazy_static;
extern crate regex;
diff --git a/examples/lazy-static/lazy-static/src/lib.rs b/examples/lazy-static/lazy-static/src/lib.rs
index 4d4131f..e324905 100644
--- a/examples/lazy-static/lazy-static/src/lib.rs
+++ b/examples/lazy-static/lazy-static/src/lib.rs
@@ -1,5 +1,5 @@
#![recursion_limit = "128"]
-#![feature(proc_macro)]
+#![feature(proc_macro_diagnostic)]
#[macro_use]
extern crate syn;
@@ -7,10 +7,10 @@
extern crate quote;
extern crate proc_macro;
-use syn::{Visibility, Ident, Type, Expr};
-use syn::synom::Synom;
-use syn::spanned::Spanned;
use proc_macro::TokenStream;
+use syn::parse::{Parse, ParseStream, Result};
+use syn::spanned::Spanned;
+use syn::{Expr, Ident, Type, Visibility};
/// Parses the following syntax, which aligns with the input of the real
/// `lazy_static` crate.
@@ -31,24 +31,34 @@
init: Expr,
}
-impl Synom for LazyStatic {
- named!(parse -> Self, do_parse!(
- visibility: syn!(Visibility) >>
- keyword!(static) >>
- keyword!(ref) >>
- name: syn!(Ident) >>
- punct!(:) >>
- ty: syn!(Type) >>
- punct!(=) >>
- init: syn!(Expr) >>
- punct!(;) >>
- (LazyStatic { visibility, name, ty, init })
- ));
+impl Parse for LazyStatic {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let visibility: Visibility = input.parse()?;
+ input.parse::<Token![static]>()?;
+ input.parse::<Token![ref]>()?;
+ let name: Ident = input.parse()?;
+ input.parse::<Token![:]>()?;
+ let ty: Type = input.parse()?;
+ input.parse::<Token![=]>()?;
+ let init: Expr = input.parse()?;
+ input.parse::<Token![;]>()?;
+ Ok(LazyStatic {
+ visibility,
+ name,
+ ty,
+ init,
+ })
+ }
}
#[proc_macro]
pub fn lazy_static(input: TokenStream) -> TokenStream {
- let LazyStatic { visibility, name, ty, init } = syn::parse(input).unwrap();
+ let LazyStatic {
+ visibility,
+ name,
+ ty,
+ init,
+ } = syn::parse(input).unwrap();
// The warning looks like this.
//
@@ -58,7 +68,8 @@
// 10 | static ref FOO: String = "lazy_static".to_owned();
// | ^^^
if name == "FOO" {
- name.span().unstable()
+ name.span()
+ .unstable()
.warning("come on, pick a more creative name")
.emit();
}
@@ -72,7 +83,8 @@
// | ^^
if let Expr::Tuple(ref init) = init {
if init.elems.is_empty() {
- init.span().unstable()
+ init.span()
+ .unstable()
.error("I can't think of a legitimate use for lazily initializing the value `()`")
.emit();
return TokenStream::new();
diff --git a/examples/trace-var/example/src/main.rs b/examples/trace-var/example/src/main.rs
index c9371f3..3e069ae 100644
--- a/examples/trace-var/example/src/main.rs
+++ b/examples/trace-var/example/src/main.rs
@@ -1,5 +1,3 @@
-#![feature(proc_macro)]
-
extern crate trace_var;
use trace_var::trace_var;
diff --git a/examples/trace-var/trace-var/src/lib.rs b/examples/trace-var/trace-var/src/lib.rs
index 5fb6ccf..6cf0a3c 100644
--- a/examples/trace-var/trace-var/src/lib.rs
+++ b/examples/trace-var/trace-var/src/lib.rs
@@ -1,5 +1,3 @@
-#![feature(proc_macro)]
-
extern crate proc_macro;
#[macro_use]
@@ -12,30 +10,30 @@
use quote::ToTokens;
use std::collections::HashSet as Set;
use syn::fold::{self, Fold};
+use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
-use syn::synom::Synom;
use syn::{Expr, Ident, ItemFn, Local, Pat, Stmt};
-/// Parses a parenthesized nonempty list of variable names separated by commas.
+/// Parses a list of variable names separated by commas.
///
-/// (a, b, c)
+/// a, b, c
///
/// This is how the compiler passes in arguments to our attribute -- it is
-/// everything that comes after the attribute name.
+/// everything inside the delimiters after the attribute name.
///
/// #[trace_var(a, b, c)]
-/// ^^^^^^^^^
+/// ^^^^^^^
struct Args {
vars: Set<Ident>,
}
-impl Synom for Args {
- named!(parse -> Self, map!(
- call!(Punctuated::<Ident, Token![,]>::parse_terminated_nonempty),
- |vars| Args {
+impl Parse for Args {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let vars = Punctuated::<Ident, Token![,]>::parse_terminated(input)?;
+ Ok(Args {
vars: vars.into_iter().collect(),
- }
- ));
+ })
+ }
}
impl Args {
diff --git a/rustfmt.toml b/rustfmt.toml
deleted file mode 100644
index b2715b2..0000000
--- a/rustfmt.toml
+++ /dev/null
@@ -1 +0,0 @@
-wrap_comments = true
diff --git a/src/attr.rs b/src/attr.rs
index d818b4f..595f12a 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -13,6 +13,8 @@
use proc_macro2::{Delimiter, Spacing, TokenStream, TokenTree};
+#[cfg(feature = "parsing")]
+use parse::{ParseStream, Result};
#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
#[cfg(feature = "extra-traits")]
@@ -39,8 +41,8 @@
///
/// The `style` field of type `AttrStyle` distinguishes whether an attribute
/// is outer or inner. Doc comments and block comments are promoted to
- /// attributes that have `is_sugared_doc` set to true, as this is how they
- /// are processed by the compiler and by `macro_rules!` macros.
+ /// attributes, as this is how they are processed by the compiler and by
+ /// `macro_rules!` macros.
///
/// The `path` field gives the possibly colon-delimited path against which
/// the attribute is resolved. It is equal to `"doc"` for desugared doc
@@ -58,13 +60,57 @@
/// across most Rust libraries.
///
/// [`interpret_meta`]: #method.interpret_meta
+ ///
+ /// # Parsing
+ ///
+ /// This type does not implement the [`Parse`] trait and thus cannot be
+ /// parsed directly by [`ParseStream::parse`]. Instead use
+ /// [`ParseStream::call`] with one of the two parser functions
+ /// [`Attribute::parse_outer`] or [`Attribute::parse_inner`] depending on
+ /// which you intend to parse.
+ ///
+ /// [`Parse`]: parse/trait.Parse.html
+ /// [`ParseStream::parse`]: parse/struct.ParseBuffer.html#method.parse
+ /// [`ParseStream::call`]: parse/struct.ParseBuffer.html#method.call
+ /// [`Attribute::parse_outer`]: #method.parse_outer
+ /// [`Attribute::parse_inner`]: #method.parse_inner
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Attribute, Ident, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // Parses a unit struct with attributes.
+ /// //
+ /// // #[path = "s.tmpl"]
+ /// // struct S;
+ /// struct UnitStruct {
+ /// attrs: Vec<Attribute>,
+ /// struct_token: Token![struct],
+ /// name: Ident,
+ /// semi_token: Token![;],
+ /// }
+ ///
+ /// impl Parse for UnitStruct {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(UnitStruct {
+ /// attrs: input.call(Attribute::parse_outer)?,
+ /// struct_token: input.parse()?,
+ /// name: input.parse()?,
+ /// semi_token: input.parse()?,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
pub struct Attribute #manual_extra_traits {
pub pound_token: Token![#],
pub style: AttrStyle,
pub bracket_token: token::Bracket,
pub path: Path,
pub tts: TokenStream,
- pub is_sugared_doc: bool,
}
}
@@ -79,7 +125,6 @@
&& self.bracket_token == other.bracket_token
&& self.path == other.path
&& TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
- && self.is_sugared_doc == other.is_sugared_doc
}
}
@@ -94,7 +139,6 @@
self.bracket_token.hash(state);
self.path.hash(state);
TokenStreamHelper(&self.tts).hash(state);
- self.is_sugared_doc.hash(state);
}
}
@@ -129,6 +173,32 @@
None
}
+ /// Parses zero or more outer attributes from the stream.
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ #[cfg(feature = "parsing")]
+ pub fn parse_outer(input: ParseStream) -> Result<Vec<Self>> {
+ let mut attrs = Vec::new();
+ while input.peek(Token![#]) {
+ attrs.push(input.call(parsing::single_parse_outer)?);
+ }
+ Ok(attrs)
+ }
+
+ /// Parses zero or more inner attributes from the stream.
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ #[cfg(feature = "parsing")]
+ pub fn parse_inner(input: ParseStream) -> Result<Vec<Self>> {
+ let mut attrs = Vec::new();
+ while input.peek(Token![#]) && input.peek2(Token![!]) {
+ attrs.push(input.call(parsing::single_parse_inner)?);
+ }
+ Ok(attrs)
+ }
+
fn extract_meta_list(ident: Ident, tt: &TokenTree) -> Option<Meta> {
let g = match *tt {
TokenTree::Group(ref g) => g,
@@ -396,122 +466,39 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use buffer::Cursor;
- use parse_error;
- use proc_macro2::{Literal, Punct, Spacing, Span, TokenTree};
- use synom::PResult;
- fn eq(span: Span) -> TokenTree {
- let mut op = Punct::new('=', Spacing::Alone);
- op.set_span(span);
- op.into()
+ use parse::{ParseStream, Result};
+ #[cfg(feature = "full")]
+ use private;
+
+ pub fn single_parse_inner(input: ParseStream) -> Result<Attribute> {
+ let content;
+ Ok(Attribute {
+ pound_token: input.parse()?,
+ style: AttrStyle::Inner(input.parse()?),
+ bracket_token: bracketed!(content in input),
+ path: content.call(Path::parse_mod_style)?,
+ tts: content.parse()?,
+ })
}
- impl Attribute {
- named!(pub parse_inner -> Self, alt!(
- do_parse!(
- pound: punct!(#) >>
- bang: punct!(!) >>
- path_and_tts: brackets!(tuple!(
- call!(Path::parse_mod_style),
- syn!(TokenStream),
- )) >>
- ({
- let (bracket, (path, tts)) = path_and_tts;
-
- Attribute {
- style: AttrStyle::Inner(bang),
- path: path,
- tts: tts,
- is_sugared_doc: false,
- pound_token: pound,
- bracket_token: bracket,
- }
- })
- )
- |
- map!(
- call!(lit_doc_comment, Comment::Inner),
- |lit| {
- let span = lit.span();
- Attribute {
- style: AttrStyle::Inner(<Token![!]>::new(span)),
- path: Ident::new("doc", span).into(),
- tts: vec![
- eq(span),
- lit,
- ].into_iter().collect(),
- is_sugared_doc: true,
- pound_token: <Token![#]>::new(span),
- bracket_token: token::Bracket(span),
- }
- }
- )
- ));
-
- named!(pub parse_outer -> Self, alt!(
- do_parse!(
- pound: punct!(#) >>
- path_and_tts: brackets!(tuple!(
- call!(Path::parse_mod_style),
- syn!(TokenStream),
- )) >>
- ({
- let (bracket, (path, tts)) = path_and_tts;
-
- Attribute {
- style: AttrStyle::Outer,
- path: path,
- tts: tts,
- is_sugared_doc: false,
- pound_token: pound,
- bracket_token: bracket,
- }
- })
- )
- |
- map!(
- call!(lit_doc_comment, Comment::Outer),
- |lit| {
- let span = lit.span();
- Attribute {
- style: AttrStyle::Outer,
- path: Ident::new("doc", span).into(),
- tts: vec![
- eq(span),
- lit,
- ].into_iter().collect(),
- is_sugared_doc: true,
- pound_token: <Token![#]>::new(span),
- bracket_token: token::Bracket(span),
- }
- }
- )
- ));
+ pub fn single_parse_outer(input: ParseStream) -> Result<Attribute> {
+ let content;
+ Ok(Attribute {
+ pound_token: input.parse()?,
+ style: AttrStyle::Outer,
+ bracket_token: bracketed!(content in input),
+ path: content.call(Path::parse_mod_style)?,
+ tts: content.parse()?,
+ })
}
- enum Comment {
- Inner,
- Outer,
- }
-
- fn lit_doc_comment(input: Cursor, style: Comment) -> PResult<TokenTree> {
- match input.literal() {
- Some((lit, rest)) => {
- let string = lit.to_string();
- let ok = match style {
- Comment::Inner => string.starts_with("//!") || string.starts_with("/*!"),
- Comment::Outer => string.starts_with("///") || string.starts_with("/**"),
- };
- if ok {
- let mut new = Literal::string(&string);
- new.set_span(lit.span());
- Ok((new.into(), rest))
- } else {
- parse_error()
- }
- }
- _ => parse_error(),
+ #[cfg(feature = "full")]
+ impl private {
+ pub fn attrs(outer: Vec<Attribute>, inner: Vec<Attribute>) -> Vec<Attribute> {
+ let mut attrs = outer;
+ attrs.extend(inner);
+ attrs
}
}
}
diff --git a/src/buffer.rs b/src/buffer.rs
index 499c4f1..b918a9a 100644
--- a/src/buffer.rs
+++ b/src/buffer.rs
@@ -9,119 +9,7 @@
//! A stably addressed token buffer supporting efficient traversal based on a
//! cheaply copyable cursor.
//!
-//! The [`Synom`] trait is implemented for syntax tree types that can be parsed
-//! from one of these token cursors.
-//!
-//! [`Synom`]: ../synom/trait.Synom.html
-//!
//! *This module is available if Syn is built with the `"parsing"` feature.*
-//!
-//! # Example
-//!
-//! This example shows a basic token parser for parsing a token stream without
-//! using Syn's parser combinator macros.
-//!
-//! ```
-//! #![feature(proc_macro_diagnostic)]
-//!
-//! extern crate syn;
-//! extern crate proc_macro;
-//!
-//! #[macro_use]
-//! extern crate quote;
-//!
-//! use syn::{token, ExprTuple};
-//! use syn::buffer::{Cursor, TokenBuffer};
-//! use syn::spanned::Spanned;
-//! use syn::synom::Synom;
-//! use proc_macro::{Diagnostic, Span, TokenStream};
-//!
-//! /// A basic token parser for parsing a token stream without using Syn's
-//! /// parser combinator macros.
-//! pub struct Parser<'a> {
-//! cursor: Cursor<'a>,
-//! }
-//!
-//! impl<'a> Parser<'a> {
-//! pub fn new(cursor: Cursor<'a>) -> Self {
-//! Parser { cursor }
-//! }
-//!
-//! pub fn current_span(&self) -> Span {
-//! self.cursor.span().unstable()
-//! }
-//!
-//! pub fn parse<T: Synom>(&mut self) -> Result<T, Diagnostic> {
-//! let (val, rest) = T::parse(self.cursor)
-//! .map_err(|e| match T::description() {
-//! Some(desc) => {
-//! self.current_span().error(format!("{}: expected {}", e, desc))
-//! }
-//! None => {
-//! self.current_span().error(e.to_string())
-//! }
-//! })?;
-//!
-//! self.cursor = rest;
-//! Ok(val)
-//! }
-//!
-//! pub fn expect_eof(&mut self) -> Result<(), Diagnostic> {
-//! if !self.cursor.eof() {
-//! return Err(self.current_span().error("trailing characters; expected eof"));
-//! }
-//!
-//! Ok(())
-//! }
-//! }
-//!
-//! fn eval(input: TokenStream) -> Result<TokenStream, Diagnostic> {
-//! let buffer = TokenBuffer::new(input);
-//! let mut parser = Parser::new(buffer.begin());
-//!
-//! // Parse some syntax tree types out of the input tokens. In this case we
-//! // expect something like:
-//! //
-//! // (a, b, c) = (1, 2, 3)
-//! let a = parser.parse::<ExprTuple>()?;
-//! parser.parse::<token::Eq>()?;
-//! let b = parser.parse::<ExprTuple>()?;
-//! parser.expect_eof()?;
-//!
-//! // Perform some validation and report errors.
-//! let (a_len, b_len) = (a.elems.len(), b.elems.len());
-//! if a_len != b_len {
-//! let diag = b.span().unstable()
-//! .error(format!("expected {} element(s), got {}", a_len, b_len))
-//! .span_note(a.span().unstable(), "because of this");
-//!
-//! return Err(diag);
-//! }
-//!
-//! // Build the output tokens.
-//! let out = quote! {
-//! println!("All good! Received two tuples of size {}", #a_len);
-//! };
-//!
-//! Ok(out.into())
-//! }
-//! #
-//! # extern crate proc_macro2;
-//! #
-//! # // This method exists on proc_macro2::Span but is behind the "nightly"
-//! # // feature.
-//! # trait ToUnstableSpan {
-//! # fn unstable(&self) -> Span;
-//! # }
-//! #
-//! # impl ToUnstableSpan for proc_macro2::Span {
-//! # fn unstable(&self) -> Span {
-//! # unimplemented!()
-//! # }
-//! # }
-//! #
-//! # fn main() {}
-//! ```
// This module is heavily commented as it contains the only unsafe code in Syn,
// and caution should be used when editing it. The public-facing interface is
@@ -132,14 +20,12 @@
feature = "proc-macro"
))]
use proc_macro as pm;
-use proc_macro2::{Delimiter, Ident, Literal, Span, TokenStream};
-use proc_macro2::{Group, Punct, TokenTree};
+use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
use std::marker::PhantomData;
use std::ptr;
-#[cfg(synom_verbose_trace)]
-use std::fmt::{self, Debug};
+use Lifetime;
/// Internal type which is used instead of `TokenTree` to represent a token tree
/// within a `TokenBuffer`.
@@ -158,10 +44,6 @@
/// `TokenStream` which requires a deep copy in order to traverse more than
/// once.
///
-/// See the [module documentation] for an example of `TokenBuffer` in action.
-///
-/// [module documentation]: index.html
-///
/// *This type is available if Syn is built with the `"parsing"` feature.*
pub struct TokenBuffer {
// NOTE: Do not derive clone on this - there are raw pointers inside which
@@ -259,10 +141,6 @@
/// Two cursors are equal if they have the same location in the same input
/// stream, and have the same scope.
///
-/// See the [module documentation] for an example of a `Cursor` in action.
-///
-/// [module documentation]: index.html
-///
/// *This type is available if Syn is built with the `"parsing"` feature.*
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Cursor<'a> {
@@ -389,7 +267,9 @@
pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> {
self.ignore_none();
match *self.entry() {
- Entry::Punct(ref op) => Some((op.clone(), unsafe { self.bump() })),
+ Entry::Punct(ref op) if op.as_char() != '\'' => {
+ Some((op.clone(), unsafe { self.bump() }))
+ }
_ => None,
}
}
@@ -404,6 +284,28 @@
}
}
+ /// If the cursor is pointing at a `Lifetime`, returns it along with a
+ /// cursor pointing at the next `TokenTree`.
+ pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> {
+ self.ignore_none();
+ match *self.entry() {
+ Entry::Punct(ref op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
+ let next = unsafe { self.bump() };
+ match next.ident() {
+ Some((ident, rest)) => {
+ let lifetime = Lifetime {
+ apostrophe: op.span(),
+ ident: ident,
+ };
+ Some((lifetime, rest))
+ }
+ None => None,
+ }
+ }
+ _ => None,
+ }
+ }
+
/// Copies all remaining tokens visible from this cursor into a
/// `TokenStream`.
pub fn token_stream(self) -> TokenStream {
@@ -454,16 +356,3 @@
}
}
}
-
-// We do a custom implementation for `Debug` as the default implementation is
-// pretty useless.
-#[cfg(synom_verbose_trace)]
-impl<'a> Debug for Cursor<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // Print what the cursor is currently looking at.
- // This will look like Cursor("some remaining tokens here")
- f.debug_tuple("Cursor")
- .field(&self.token_stream().to_string())
- .finish()
- }
-}
diff --git a/src/data.rs b/src/data.rs
index 8ffc8a4..4f0986a 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -73,7 +73,7 @@
/// [`Field`]: struct.Field.html
pub fn iter(&self) -> punctuated::Iter<Field> {
match *self {
- Fields::Unit => punctuated::Iter::private_empty(),
+ Fields::Unit => private::empty_punctuated_iter(),
Fields::Named(ref f) => f.named.iter(),
Fields::Unnamed(ref f) => f.unnamed.iter(),
}
@@ -86,7 +86,7 @@
/// [`Field`]: struct.Field.html
pub fn iter_mut(&mut self) -> punctuated::IterMut<Field> {
match *self {
- Fields::Unit => punctuated::IterMut::private_empty(),
+ Fields::Unit => private::empty_punctuated_iter_mut(),
Fields::Named(ref mut f) => f.named.iter_mut(),
Fields::Unnamed(ref mut f) => f.unnamed.iter_mut(),
}
@@ -185,160 +185,134 @@
pub mod parsing {
use super::*;
- use synom::Synom;
+ use ext::IdentExt;
+ use parse::{Parse, ParseStream, Result};
- impl Synom for Variant {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- id: syn!(Ident) >>
- fields: alt!(
- syn!(FieldsNamed) => { Fields::Named }
- |
- syn!(FieldsUnnamed) => { Fields::Unnamed }
- |
- epsilon!() => { |_| Fields::Unit }
- ) >>
- disr: option!(tuple!(punct!(=), syn!(Expr))) >>
- (Variant {
- ident: id,
- attrs: attrs,
- fields: fields,
- discriminant: disr,
+ impl Parse for Variant {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Variant {
+ attrs: input.call(Attribute::parse_outer)?,
+ ident: input.parse()?,
+ fields: {
+ if input.peek(token::Brace) {
+ Fields::Named(input.parse()?)
+ } else if input.peek(token::Paren) {
+ Fields::Unnamed(input.parse()?)
+ } else {
+ Fields::Unit
+ }
+ },
+ discriminant: {
+ if input.peek(Token![=]) {
+ let eq_token: Token![=] = input.parse()?;
+ let discriminant: Expr = input.parse()?;
+ Some((eq_token, discriminant))
+ } else {
+ None
+ }
+ },
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("enum variant")
}
}
- impl Synom for FieldsNamed {
- named!(parse -> Self, map!(
- braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
- |(brace, fields)| FieldsNamed {
- brace_token: brace,
- named: fields,
- }
- ));
-
- fn description() -> Option<&'static str> {
- Some("named fields in a struct or struct variant")
+ impl Parse for FieldsNamed {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(FieldsNamed {
+ brace_token: braced!(content in input),
+ named: content.parse_terminated(Field::parse_named)?,
+ })
}
}
- impl Synom for FieldsUnnamed {
- named!(parse -> Self, map!(
- parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
- |(paren, fields)| FieldsUnnamed {
- paren_token: paren,
- unnamed: fields,
- }
- ));
-
- fn description() -> Option<&'static str> {
- Some("unnamed fields in a tuple struct or tuple variant")
+ impl Parse for FieldsUnnamed {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(FieldsUnnamed {
+ paren_token: parenthesized!(content in input),
+ unnamed: content.parse_terminated(Field::parse_unnamed)?,
+ })
}
}
impl Field {
- named!(pub parse_named -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- id: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- (Field {
- ident: Some(id),
- vis: vis,
- attrs: attrs,
- ty: ty,
- colon_token: Some(colon),
+ /// Parses a named (braced struct) field.
+ pub fn parse_named(input: ParseStream) -> Result<Self> {
+ Ok(Field {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ ident: Some(input.parse()?),
+ colon_token: Some(input.parse()?),
+ ty: input.parse()?,
})
- ));
+ }
- named!(pub parse_unnamed -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- ty: syn!(Type) >>
- (Field {
+ /// Parses an unnamed (tuple struct) field.
+ pub fn parse_unnamed(input: ParseStream) -> Result<Self> {
+ Ok(Field {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
ident: None,
colon_token: None,
- vis: vis,
- attrs: attrs,
- ty: ty,
+ ty: input.parse()?,
})
- ));
+ }
}
- impl Synom for Visibility {
- named!(parse -> Self, alt!(
- do_parse!(
- pub_token: keyword!(pub) >>
- other: parens!(keyword!(crate)) >>
- (Visibility::Restricted(VisRestricted {
- pub_token: pub_token,
- paren_token: other.0,
- in_token: None,
- path: Box::new(other.1.into()),
- }))
- )
- |
- do_parse!(
- crate_token: keyword!(crate) >>
- not!(punct!(::)) >>
- (Visibility::Crate(VisCrate {
- crate_token: crate_token,
- }))
- )
- |
- do_parse!(
- pub_token: keyword!(pub) >>
- other: parens!(keyword!(self)) >>
- (Visibility::Restricted(VisRestricted {
- pub_token: pub_token,
- paren_token: other.0,
- in_token: None,
- path: Box::new(other.1.into()),
- }))
- )
- |
- do_parse!(
- pub_token: keyword!(pub) >>
- other: parens!(keyword!(super)) >>
- (Visibility::Restricted(VisRestricted {
- pub_token: pub_token,
- paren_token: other.0,
- in_token: None,
- path: Box::new(other.1.into()),
- }))
- )
- |
- do_parse!(
- pub_token: keyword!(pub) >>
- other: parens!(do_parse!(
- in_tok: keyword!(in) >>
- restricted: call!(Path::parse_mod_style) >>
- (in_tok, restricted)
- )) >>
- (Visibility::Restricted(VisRestricted {
- pub_token: pub_token,
- paren_token: other.0,
- in_token: Some((other.1).0),
- path: Box::new((other.1).1),
- }))
- )
- |
- keyword!(pub) => { |tok| {
- Visibility::Public(VisPublic {
- pub_token: tok,
- })
- } }
- |
- epsilon!() => { |_| Visibility::Inherited }
- ));
+ impl Parse for Visibility {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![pub]) {
+ Self::parse_pub(input)
+ } else if input.peek(Token![crate]) {
+ Self::parse_crate(input)
+ } else {
+ Ok(Visibility::Inherited)
+ }
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("visibility qualifier such as `pub`")
+ impl Visibility {
+ fn parse_pub(input: ParseStream) -> Result<Self> {
+ let pub_token = input.parse::<Token![pub]>()?;
+
+ if input.peek(token::Paren) {
+ let ahead = input.fork();
+ let mut content;
+ parenthesized!(content in ahead);
+
+ if content.peek(Token![crate])
+ || content.peek(Token![self])
+ || content.peek(Token![super])
+ {
+ return Ok(Visibility::Restricted(VisRestricted {
+ pub_token: pub_token,
+ paren_token: parenthesized!(content in input),
+ in_token: None,
+ path: Box::new(Path::from(content.call(Ident::parse_any)?)),
+ }));
+ } else if content.peek(Token![in]) {
+ return Ok(Visibility::Restricted(VisRestricted {
+ pub_token: pub_token,
+ paren_token: parenthesized!(content in input),
+ in_token: Some(content.parse()?),
+ path: Box::new(content.call(Path::parse_mod_style)?),
+ }));
+ }
+ }
+
+ Ok(Visibility::Public(VisPublic {
+ pub_token: pub_token,
+ }))
+ }
+
+ fn parse_crate(input: ParseStream) -> Result<Self> {
+ if input.peek2(Token![::]) {
+ Ok(Visibility::Inherited)
+ } else {
+ Ok(Visibility::Crate(VisCrate {
+ crate_token: input.parse()?,
+ }))
+ }
}
}
}
@@ -346,9 +320,12 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
+
use proc_macro2::TokenStream;
use quote::{ToTokens, TokenStreamExt};
+ use print::TokensOrDefault;
+
impl ToTokens for Variant {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(&self.attrs);
@@ -405,7 +382,7 @@
fn to_tokens(&self, tokens: &mut TokenStream) {
self.pub_token.to_tokens(tokens);
self.paren_token.surround(tokens, |tokens| {
- // XXX: If we have a path which is not "self" or "super" or
+ // TODO: If we have a path which is not "self" or "super" or
// "crate", automatically add the "in" token.
self.in_token.to_tokens(tokens);
self.path.to_tokens(tokens);
diff --git a/src/derive.rs b/src/derive.rs
index ecef776..5c1bb17 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -79,124 +79,145 @@
pub mod parsing {
use super::*;
- use synom::Synom;
+ use parse::{Parse, ParseStream, Result};
- enum DeriveInputKind {
- Struct(Token![struct]),
- Enum(Token![enum]),
- Union(Token![union]),
- }
+ impl Parse for DeriveInput {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
- impl Synom for DeriveInputKind {
- named!(parse -> Self, alt!(
- keyword!(struct) => { DeriveInputKind::Struct }
- |
- keyword!(enum) => { DeriveInputKind::Enum }
- |
- keyword!(union) => { DeriveInputKind::Union }
- ));
- }
-
- impl Synom for DeriveInput {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- which: syn!(DeriveInputKind) >>
- id: syn!(Ident) >>
- generics: syn!(Generics) >>
- item: switch!(value!(which),
- DeriveInputKind::Struct(s) => map!(data_struct, move |(wh, fields, semi)| DeriveInput {
- ident: id,
- vis: vis,
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![struct]) {
+ let struct_token = input.parse::<Token![struct]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, fields, semi) = data_struct(input)?;
+ Ok(DeriveInput {
attrs: attrs,
+ vis: vis,
+ ident: ident,
generics: Generics {
- where_clause: wh,
+ where_clause: where_clause,
..generics
},
data: Data::Struct(DataStruct {
- struct_token: s,
+ struct_token: struct_token,
fields: fields,
semi_token: semi,
}),
})
- |
- DeriveInputKind::Enum(e) => map!(data_enum, move |(wh, brace, variants)| DeriveInput {
- ident: id,
- vis: vis,
+ } else if lookahead.peek(Token![enum]) {
+ let enum_token = input.parse::<Token![enum]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, brace, variants) = data_enum(input)?;
+ Ok(DeriveInput {
attrs: attrs,
+ vis: vis,
+ ident: ident,
generics: Generics {
- where_clause: wh,
+ where_clause: where_clause,
..generics
},
data: Data::Enum(DataEnum {
- variants: variants,
+ enum_token: enum_token,
brace_token: brace,
- enum_token: e,
+ variants: variants,
}),
})
- |
- DeriveInputKind::Union(u) => map!(data_union, move |(wh, fields)| DeriveInput {
- ident: id,
- vis: vis,
+ } else if lookahead.peek(Token![union]) {
+ let union_token = input.parse::<Token![union]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, fields) = data_union(input)?;
+ Ok(DeriveInput {
attrs: attrs,
+ vis: vis,
+ ident: ident,
generics: Generics {
- where_clause: wh,
+ where_clause: where_clause,
..generics
},
data: Data::Union(DataUnion {
- union_token: u,
+ union_token: union_token,
fields: fields,
}),
})
- ) >>
- (item)
- ));
-
- fn description() -> Option<&'static str> {
- Some("derive input")
+ } else {
+ Err(lookahead.error())
+ }
}
}
- named!(data_struct -> (Option<WhereClause>, Fields, Option<Token![;]>), alt!(
- do_parse!(
- wh: option!(syn!(WhereClause)) >>
- fields: syn!(FieldsNamed) >>
- (wh, Fields::Named(fields), None)
- )
- |
- do_parse!(
- fields: syn!(FieldsUnnamed) >>
- wh: option!(syn!(WhereClause)) >>
- semi: punct!(;) >>
- (wh, Fields::Unnamed(fields), Some(semi))
- )
- |
- do_parse!(
- wh: option!(syn!(WhereClause)) >>
- semi: punct!(;) >>
- (wh, Fields::Unit, Some(semi))
- )
- ));
+ pub fn data_struct(
+ input: ParseStream,
+ ) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)> {
+ let mut lookahead = input.lookahead1();
+ let mut where_clause = None;
+ if lookahead.peek(Token![where]) {
+ where_clause = Some(input.parse()?);
+ lookahead = input.lookahead1();
+ }
- named!(data_enum -> (Option<WhereClause>, token::Brace, Punctuated<Variant, Token![,]>), do_parse!(
- wh: option!(syn!(WhereClause)) >>
- data: braces!(Punctuated::parse_terminated) >>
- (wh, data.0, data.1)
- ));
+ if where_clause.is_none() && lookahead.peek(token::Paren) {
+ let fields = input.parse()?;
- named!(data_union -> (Option<WhereClause>, FieldsNamed), tuple!(
- option!(syn!(WhereClause)),
- syn!(FieldsNamed),
- ));
+ lookahead = input.lookahead1();
+ if lookahead.peek(Token![where]) {
+ where_clause = Some(input.parse()?);
+ lookahead = input.lookahead1();
+ }
+
+ if lookahead.peek(Token![;]) {
+ let semi = input.parse()?;
+ Ok((where_clause, Fields::Unnamed(fields), Some(semi)))
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(token::Brace) {
+ let fields = input.parse()?;
+ Ok((where_clause, Fields::Named(fields), None))
+ } else if lookahead.peek(Token![;]) {
+ let semi = input.parse()?;
+ Ok((where_clause, Fields::Unit, Some(semi)))
+ } else {
+ Err(lookahead.error())
+ }
+ }
+
+ pub fn data_enum(
+ input: ParseStream,
+ ) -> Result<(
+ Option<WhereClause>,
+ token::Brace,
+ Punctuated<Variant, Token![,]>,
+ )> {
+ let where_clause = input.parse()?;
+
+ let content;
+ let brace = braced!(content in input);
+ let variants = content.parse_terminated(Variant::parse)?;
+
+ Ok((where_clause, brace, variants))
+ }
+
+ pub fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
+ let where_clause = input.parse()?;
+ let fields = input.parse()?;
+ Ok((where_clause, fields))
+ }
}
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use attr::FilterAttrs;
+
use proc_macro2::TokenStream;
use quote::ToTokens;
+ use attr::FilterAttrs;
+ use print::TokensOrDefault;
+
impl ToTokens for DeriveInput {
fn to_tokens(&self, tokens: &mut TokenStream) {
for attr in self.attrs.outer() {
diff --git a/src/error.rs b/src/error.rs
index 6673aa3..67e3939 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -6,27 +6,20 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use buffer::Cursor;
-use std::error::Error;
+use std;
use std::fmt::{self, Display};
+use std::iter::FromIterator;
-/// The result of a `Synom` parser.
-///
-/// Refer to the [module documentation] for details about parsing in Syn.
-///
-/// [module documentation]: index.html
-///
-/// *This type is available if Syn is built with the `"parsing"` feature.*
-pub type PResult<'a, O> = Result<(O, Cursor<'a>), ParseError>;
+use proc_macro2::{
+ Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
+};
-/// An error with a default error message.
-///
-/// NOTE: We should provide better error messages in the future.
-pub fn parse_error<'a, O>() -> PResult<'a, O> {
- Err(ParseError(None))
-}
+use buffer::Cursor;
-/// Error returned when a `Synom` parser cannot parse the input tokens.
+/// The result of a Syn parser.
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Error returned when a Syn parser cannot parse the input tokens.
///
/// Refer to the [module documentation] for details about parsing in Syn.
///
@@ -34,27 +27,110 @@
///
/// *This type is available if Syn is built with the `"parsing"` feature.*
#[derive(Debug)]
-pub struct ParseError(Option<String>);
+pub struct Error {
+ span: Span,
+ message: String,
+}
-impl Error for ParseError {
- fn description(&self) -> &str {
- match self.0 {
- Some(ref desc) => desc,
- None => "failed to parse",
+impl Error {
+ /// Usually the [`ParseStream::error`] method will be used instead, which
+ /// automatically uses the correct span from the current position of the
+ /// parse stream.
+ ///
+ /// Use `Error::new` when the error needs to be triggered on some span other
+ /// than where the parse stream is currently positioned.
+ ///
+ /// [`ParseStream::error`]: struct.ParseBuffer.html#method.error
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Ident, LitStr, Token};
+ /// use syn::parse::{Error, ParseStream, Result};
+ ///
+ /// // Parses input that looks like `name = "string"` where the key must be
+ /// // the identifier `name` and the value may be any string literal.
+ /// // Returns the string literal.
+ /// fn parse_name(input: ParseStream) -> Result<LitStr> {
+ /// let name_token: Ident = input.parse()?;
+ /// if name_token != "name" {
+ /// // Trigger an error not on the current position of the stream,
+ /// // but on the position of the unexpected identifier.
+ /// return Err(Error::new(name_token.span(), "expected `name`"));
+ /// }
+ /// input.parse::<Token![=]>()?;
+ /// let s: LitStr = input.parse()?;
+ /// Ok(s)
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn new<T: Display>(span: Span, message: T) -> Self {
+ Error {
+ span: span,
+ message: message.to_string(),
}
}
-}
-impl Display for ParseError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Display::fmt(self.description(), f)
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ /// Render the error as an invocation of [`compile_error!`].
+ ///
+ /// The [`parse_macro_input!`] macro provides a convenient way to invoke
+ /// this method correctly in a procedural macro.
+ ///
+ /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
+ /// [`parse_macro_input!`]: ../macro.parse_macro_input.html
+ pub fn into_compile_error(self) -> TokenStream {
+ // compile_error!($message)
+ TokenStream::from_iter(vec![
+ TokenTree::Ident(Ident::new("compile_error", self.span)),
+ TokenTree::Punct({
+ let mut punct = Punct::new('!', Spacing::Alone);
+ punct.set_span(self.span);
+ punct
+ }),
+ TokenTree::Group({
+ let mut group = Group::new(Delimiter::Brace, {
+ TokenStream::from_iter(vec![TokenTree::Literal({
+ let mut string = Literal::string(&self.message);
+ string.set_span(self.span);
+ string
+ })])
+ });
+ group.set_span(self.span);
+ group
+ }),
+ ])
}
}
-impl ParseError {
- // For syn use only. Not public API.
- #[doc(hidden)]
- pub fn new<T: Into<String>>(msg: T) -> Self {
- ParseError(Some(msg.into()))
+pub fn new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error {
+ if cursor.eof() {
+ Error::new(scope, format!("unexpected end of input, {}", message))
+ } else {
+ Error::new(cursor.span(), message)
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(&self.message)
+ }
+}
+
+impl std::error::Error for Error {
+ fn description(&self) -> &str {
+ "parse error"
+ }
+}
+
+impl From<LexError> for Error {
+ fn from(err: LexError) -> Self {
+ Error::new(Span::call_site(), format!("{:?}", err))
}
}
diff --git a/src/export.rs b/src/export.rs
new file mode 100644
index 0000000..9608a01
--- /dev/null
+++ b/src/export.rs
@@ -0,0 +1,7 @@
+pub use std::result::Result::{Err, Ok};
+
+#[cfg(feature = "parsing")]
+pub use std::convert::From;
+
+#[cfg(feature = "proc-macro")]
+pub use proc_macro::TokenStream;
diff --git a/src/expr.rs b/src/expr.rs
index 3742fb4..9440c1c 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -11,7 +11,7 @@
use punctuated::Punctuated;
#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
-#[cfg(feature = "full")]
+#[cfg(all(feature = "parsing", feature = "full"))]
use std::mem;
#[cfg(feature = "extra-traits")]
use tt::TokenStreamHelper;
@@ -313,6 +313,7 @@
/// *This type is available if Syn is built with the `"full"` feature.*
pub Closure(ExprClosure #full {
pub attrs: Vec<Attribute>,
+ pub asyncness: Option<Token![async]>,
pub movability: Option<Token![static]>,
pub capture: Option<Token![move]>,
pub or1_token: Token![|],
@@ -336,6 +337,7 @@
/// *This type is available if Syn is built with the `"full"` feature.*
pub Block(ExprBlock #full {
pub attrs: Vec<Attribute>,
+ pub label: Option<Label>,
pub block: Block,
}),
@@ -508,13 +510,22 @@
pub question_token: Token![?],
}),
- /// A catch expression: `do catch { ... }`.
+ /// An async block: `async { ... }`.
///
/// *This type is available if Syn is built with the `"full"` feature.*
- pub Catch(ExprCatch #full {
+ pub Async(ExprAsync #full {
pub attrs: Vec<Attribute>,
- pub do_token: Token![do],
- pub catch_token: Token![catch],
+ pub async_token: Token![async],
+ pub capture: Option<Token![move]>,
+ pub block: Block,
+ }),
+
+ /// A try block: `try { ... }`.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub TryBlock(ExprTryBlock #full {
+ pub attrs: Vec<Attribute>,
+ pub try_token: Token![try],
pub block: Block,
}),
@@ -558,10 +569,8 @@
}
impl Expr {
- // Not public API.
- #[doc(hidden)]
- #[cfg(feature = "full")]
- pub fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
+ #[cfg(all(feature = "parsing", feature = "full"))]
+ fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
match *self {
Expr::Box(ExprBox { ref mut attrs, .. })
| Expr::InPlace(ExprInPlace { ref mut attrs, .. })
@@ -600,12 +609,10 @@
| Expr::Paren(ExprParen { ref mut attrs, .. })
| Expr::Group(ExprGroup { ref mut attrs, .. })
| Expr::Try(ExprTry { ref mut attrs, .. })
- | Expr::Catch(ExprCatch { ref mut attrs, .. })
+ | Expr::Async(ExprAsync { ref mut attrs, .. })
+ | Expr::TryBlock(ExprTryBlock { ref mut attrs, .. })
| Expr::Yield(ExprYield { ref mut attrs, .. }) => mem::replace(attrs, new),
- Expr::Verbatim(_) => {
- // TODO
- Vec::new()
- }
+ Expr::Verbatim(_) => Vec::new(),
}
}
}
@@ -995,9 +1002,8 @@
#[cfg(any(feature = "parsing", feature = "printing"))]
#[cfg(feature = "full")]
-fn arm_expr_requires_comma(expr: &Expr) -> bool {
- // see https://github.com/rust-lang/rust/blob/eb8f2586e
- // /src/libsyntax/parse/classify.rs#L17-L37
+fn requires_terminator(expr: &Expr) -> bool {
+ // see https://github.com/rust-lang/rust/blob/eb8f2586e/src/libsyntax/parse/classify.rs#L17-L37
match *expr {
Expr::Unsafe(..)
| Expr::Block(..)
@@ -1008,7 +1014,8 @@
| Expr::WhileLet(..)
| Expr::Loop(..)
| Expr::ForLoop(..)
- | Expr::Catch(..) => false,
+ | Expr::Async(..)
+ | Expr::TryBlock(..) => false,
_ => true,
}
}
@@ -1016,446 +1023,331 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use path::parsing::mod_style_path_segment;
- #[cfg(feature = "full")]
- use path::parsing::ty_no_eq_after;
- use buffer::Cursor;
#[cfg(feature = "full")]
- use parse_error;
- #[cfg(feature = "full")]
- use proc_macro2::TokenStream;
- use synom::PResult;
- use synom::Synom;
+ use ext::IdentExt;
+ use parse::{Parse, ParseStream, Result};
+ use path;
// When we're parsing expressions which occur before blocks, like in an if
// statement's condition, we cannot parse a struct literal.
//
// Struct literals are ambiguous in certain positions
// https://github.com/rust-lang/rfcs/pull/92
- macro_rules! ambiguous_expr {
- ($i:expr, $allow_struct:ident) => {
- ambiguous_expr($i, $allow_struct, true)
- };
+ #[derive(Copy, Clone)]
+ pub struct AllowStruct(bool);
+
+ #[derive(Copy, Clone, PartialEq, PartialOrd)]
+ enum Precedence {
+ Any,
+ Assign,
+ Placement,
+ Range,
+ Or,
+ And,
+ Compare,
+ BitOr,
+ BitXor,
+ BitAnd,
+ Shift,
+ Arithmetic,
+ Term,
+ Cast,
}
- // When we are parsing an optional suffix expression, we cannot allow blocks
- // if structs are not allowed.
- //
- // Example:
- //
- // if break {} {}
- //
- // is ambiguous between:
- //
- // if (break {}) {}
- // if (break) {} {}
- #[cfg(feature = "full")]
- macro_rules! opt_ambiguous_expr {
- ($i:expr, $allow_struct:ident) => {
- option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
- };
+ impl Precedence {
+ fn of(op: &BinOp) -> Self {
+ match *op {
+ BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
+ BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
+ BinOp::And(_) => Precedence::And,
+ BinOp::Or(_) => Precedence::Or,
+ BinOp::BitXor(_) => Precedence::BitXor,
+ BinOp::BitAnd(_) => Precedence::BitAnd,
+ BinOp::BitOr(_) => Precedence::BitOr,
+ BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
+ BinOp::Eq(_)
+ | BinOp::Lt(_)
+ | BinOp::Le(_)
+ | BinOp::Ne(_)
+ | BinOp::Ge(_)
+ | BinOp::Gt(_) => Precedence::Compare,
+ BinOp::AddEq(_)
+ | BinOp::SubEq(_)
+ | BinOp::MulEq(_)
+ | BinOp::DivEq(_)
+ | BinOp::RemEq(_)
+ | BinOp::BitXorEq(_)
+ | BinOp::BitAndEq(_)
+ | BinOp::BitOrEq(_)
+ | BinOp::ShlEq(_)
+ | BinOp::ShrEq(_) => Precedence::Assign,
+ }
+ }
}
- impl Synom for Expr {
- named!(parse -> Self, ambiguous_expr!(true));
-
- fn description() -> Option<&'static str> {
- Some("expression")
+ impl Parse for Expr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ ambiguous_expr(input, AllowStruct(true))
}
}
#[cfg(feature = "full")]
- named!(expr_no_struct -> Expr, ambiguous_expr!(false));
+ fn expr_no_struct(input: ParseStream) -> Result<Expr> {
+ ambiguous_expr(input, AllowStruct(false))
+ }
- // Parse an arbitrary expression.
#[cfg(feature = "full")]
- fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
- call!(i, assign_expr, allow_struct, allow_block)
- }
-
- #[cfg(not(feature = "full"))]
- fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
- // NOTE: We intentionally skip assign_expr, placement_expr, and
- // range_expr, as they are not parsed in non-full mode.
- call!(i, or_expr, allow_struct, allow_block)
- }
-
- // Parse a left-associative binary operator.
- macro_rules! binop {
- (
- $name: ident,
- $next: ident,
- $submac: ident!( $($args:tt)* )
- ) => {
- named!($name(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!($next, allow_struct, allow_block) >>
- many0!(do_parse!(
- op: $submac!($($args)*) >>
- rhs: call!($next, allow_struct, true) >>
- ({
- e = ExprBinary {
- attrs: Vec::new(),
- left: Box::new(e.into()),
- op: op,
- right: Box::new(rhs.into()),
- }.into();
- })
- )) >>
- (e)
- ));
- }
- }
-
- // <placement> = <placement> ..
- // <placement> += <placement> ..
- // <placement> -= <placement> ..
- // <placement> *= <placement> ..
- // <placement> /= <placement> ..
- // <placement> %= <placement> ..
- // <placement> ^= <placement> ..
- // <placement> &= <placement> ..
- // <placement> |= <placement> ..
- // <placement> <<= <placement> ..
- // <placement> >>= <placement> ..
- //
- // NOTE: This operator is right-associative.
- #[cfg(feature = "full")]
- named!(assign_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(placement_expr, allow_struct, allow_block) >>
- alt!(
- do_parse!(
- eq: punct!(=) >>
- // Recurse into self to parse right-associative operator.
- rhs: call!(assign_expr, allow_struct, true) >>
- ({
- e = ExprAssign {
+ fn parse_expr(
+ input: ParseStream,
+ mut lhs: Expr,
+ allow_struct: AllowStruct,
+ base: Precedence,
+ ) -> Result<Expr> {
+ loop {
+ if input
+ .fork()
+ .parse::<BinOp>()
+ .ok()
+ .map_or(false, |op| Precedence::of(&op) >= base)
+ {
+ let op: BinOp = input.parse()?;
+ let precedence = Precedence::of(&op);
+ let mut rhs = unary_expr(input, allow_struct)?;
+ loop {
+ let next = peek_precedence(input);
+ if next > precedence || next == precedence && precedence == Precedence::Assign {
+ rhs = parse_expr(input, rhs, allow_struct, next)?;
+ } else {
+ break;
+ }
+ }
+ lhs = if precedence == Precedence::Assign {
+ Expr::AssignOp(ExprAssignOp {
attrs: Vec::new(),
- left: Box::new(e),
- eq_token: eq,
- right: Box::new(rhs),
- }.into();
- })
- )
- |
- do_parse!(
- op: call!(BinOp::parse_assign_op) >>
- // Recurse into self to parse right-associative operator.
- rhs: call!(assign_expr, allow_struct, true) >>
- ({
- e = ExprAssignOp {
- attrs: Vec::new(),
- left: Box::new(e),
+ left: Box::new(lhs),
op: op,
right: Box::new(rhs),
- }.into();
- })
- )
- |
- epsilon!()
- ) >>
- (e)
- ));
-
- // <range> <- <range> ..
- //
- // NOTE: The `in place { expr }` version of this syntax is parsed in
- // `atom_expr`, not here.
- //
- // NOTE: This operator is right-associative.
- #[cfg(feature = "full")]
- named!(placement_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(range_expr, allow_struct, allow_block) >>
- alt!(
- do_parse!(
- arrow: punct!(<-) >>
- // Recurse into self to parse right-associative operator.
- rhs: call!(placement_expr, allow_struct, true) >>
- ({
- e = ExprInPlace {
+ })
+ } else {
+ Expr::Binary(ExprBinary {
attrs: Vec::new(),
- // op: BinOp::Place(larrow),
- place: Box::new(e),
- arrow_token: arrow,
- value: Box::new(rhs),
- }.into();
- })
- )
- |
- epsilon!()
- ) >>
- (e)
- ));
-
- // <or> ... <or> ..
- // <or> .. <or> ..
- // <or> ..
- //
- // NOTE: This is currently parsed oddly - I'm not sure of what the exact
- // rules are for parsing these expressions are, but this is not correct.
- // For example, `a .. b .. c` is not a legal expression. It should not
- // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
- //
- // NOTE: The form of ranges which don't include a preceding expression are
- // parsed by `atom_expr`, rather than by this function.
- #[cfg(feature = "full")]
- named!(range_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(or_expr, allow_struct, allow_block) >>
- many0!(do_parse!(
- limits: syn!(RangeLimits) >>
- // We don't want to allow blocks here if we don't allow structs. See
- // the reasoning for `opt_ambiguous_expr!` above.
- hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
- ({
- e = ExprRange {
+ left: Box::new(lhs),
+ op: op,
+ right: Box::new(rhs),
+ })
+ };
+ } else if Precedence::Assign >= base
+ && input.peek(Token![=])
+ && !input.peek(Token![==])
+ && !input.peek(Token![=>])
+ {
+ let eq_token: Token![=] = input.parse()?;
+ let mut rhs = unary_expr(input, allow_struct)?;
+ loop {
+ let next = peek_precedence(input);
+ if next >= Precedence::Assign {
+ rhs = parse_expr(input, rhs, allow_struct, next)?;
+ } else {
+ break;
+ }
+ }
+ lhs = Expr::Assign(ExprAssign {
attrs: Vec::new(),
- from: Some(Box::new(e)),
+ left: Box::new(lhs),
+ eq_token: eq_token,
+ right: Box::new(rhs),
+ });
+ } else if Precedence::Placement >= base && input.peek(Token![<-]) {
+ let arrow_token: Token![<-] = input.parse()?;
+ let mut rhs = unary_expr(input, allow_struct)?;
+ loop {
+ let next = peek_precedence(input);
+ if next > Precedence::Placement {
+ rhs = parse_expr(input, rhs, allow_struct, next)?;
+ } else {
+ break;
+ }
+ }
+ lhs = Expr::InPlace(ExprInPlace {
+ attrs: Vec::new(),
+ place: Box::new(lhs),
+ arrow_token: arrow_token,
+ value: Box::new(rhs),
+ });
+ } else if Precedence::Range >= base && input.peek(Token![..]) {
+ let limits: RangeLimits = input.parse()?;
+ let rhs = if input.is_empty()
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || !allow_struct.0 && input.peek(token::Brace)
+ {
+ None
+ } else {
+ let mut rhs = unary_expr(input, allow_struct)?;
+ loop {
+ let next = peek_precedence(input);
+ if next > Precedence::Range {
+ rhs = parse_expr(input, rhs, allow_struct, next)?;
+ } else {
+ break;
+ }
+ }
+ Some(rhs)
+ };
+ lhs = Expr::Range(ExprRange {
+ attrs: Vec::new(),
+ from: Some(Box::new(lhs)),
limits: limits,
- to: hi.map(|e| Box::new(e)),
- }.into();
- })
- )) >>
- (e)
- ));
-
- // <and> || <and> ...
- binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
-
- // <compare> && <compare> ...
- binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
-
- // <bitor> == <bitor> ...
- // <bitor> != <bitor> ...
- // <bitor> >= <bitor> ...
- // <bitor> <= <bitor> ...
- // <bitor> > <bitor> ...
- // <bitor> < <bitor> ...
- //
- // NOTE: This operator appears to be parsed as left-associative, but errors
- // if it is used in a non-associative manner.
- binop!(
- compare_expr,
- bitor_expr,
- alt!(
- punct!(==) => { BinOp::Eq }
- |
- punct!(!=) => { BinOp::Ne }
- |
- // must be above Lt
- punct!(<=) => { BinOp::Le }
- |
- // must be above Gt
- punct!(>=) => { BinOp::Ge }
- |
- do_parse!(
- // Make sure that we don't eat the < part of a <- operator
- not!(punct!(<-)) >>
- t: punct!(<) >>
- (BinOp::Lt(t))
- )
- |
- punct!(>) => { BinOp::Gt }
- )
- );
-
- // <bitxor> | <bitxor> ...
- binop!(
- bitor_expr,
- bitxor_expr,
- do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
- );
-
- // <bitand> ^ <bitand> ...
- binop!(
- bitxor_expr,
- bitand_expr,
- do_parse!(
- // NOTE: Make sure we aren't looking at ^=.
- not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
- )
- );
-
- // <shift> & <shift> ...
- binop!(
- bitand_expr,
- shift_expr,
- do_parse!(
- // NOTE: Make sure we aren't looking at && or &=.
- not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
- )
- );
-
- // <arith> << <arith> ...
- // <arith> >> <arith> ...
- binop!(
- shift_expr,
- arith_expr,
- alt!(
- punct!(<<) => { BinOp::Shl }
- |
- punct!(>>) => { BinOp::Shr }
- )
- );
-
- // <term> + <term> ...
- // <term> - <term> ...
- binop!(
- arith_expr,
- term_expr,
- alt!(
- punct!(+) => { BinOp::Add }
- |
- punct!(-) => { BinOp::Sub }
- )
- );
-
- // <cast> * <cast> ...
- // <cast> / <cast> ...
- // <cast> % <cast> ...
- binop!(
- term_expr,
- cast_expr,
- alt!(
- punct!(*) => { BinOp::Mul }
- |
- punct!(/) => { BinOp::Div }
- |
- punct!(%) => { BinOp::Rem }
- )
- );
-
- // <unary> as <ty>
- // <unary> : <ty>
- #[cfg(feature = "full")]
- named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(unary_expr, allow_struct, allow_block) >>
- many0!(alt!(
- do_parse!(
- as_: keyword!(as) >>
- // We can't accept `A + B` in cast expressions, as it's
- // ambiguous with the + expression.
- ty: call!(Type::without_plus) >>
- ({
- e = ExprCast {
- attrs: Vec::new(),
- expr: Box::new(e),
- as_token: as_,
- ty: Box::new(ty),
- }.into();
- })
- )
- |
- do_parse!(
- colon: punct!(:) >>
- // We can't accept `A + B` in cast expressions, as it's
- // ambiguous with the + expression.
- ty: call!(Type::without_plus) >>
- ({
- e = ExprType {
- attrs: Vec::new(),
- expr: Box::new(e),
- colon_token: colon,
- ty: Box::new(ty),
- }.into();
- })
- )
- )) >>
- (e)
- ));
-
- // <unary> as <ty>
- #[cfg(not(feature = "full"))]
- named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(unary_expr, allow_struct, allow_block) >>
- many0!(do_parse!(
- as_: keyword!(as) >>
- // We can't accept `A + B` in cast expressions, as it's
- // ambiguous with the + expression.
- ty: call!(Type::without_plus) >>
- ({
- e = ExprCast {
+ to: rhs.map(Box::new),
+ });
+ } else if Precedence::Cast >= base && input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let ty = input.call(Type::without_plus)?;
+ lhs = Expr::Cast(ExprCast {
attrs: Vec::new(),
- expr: Box::new(e),
- as_token: as_,
+ expr: Box::new(lhs),
+ as_token: as_token,
ty: Box::new(ty),
- }.into();
- })
- )) >>
- (e)
- ));
+ });
+ } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
+ let colon_token: Token![:] = input.parse()?;
+ let ty = input.call(Type::without_plus)?;
+ lhs = Expr::Type(ExprType {
+ attrs: Vec::new(),
+ expr: Box::new(lhs),
+ colon_token: colon_token,
+ ty: Box::new(ty),
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(lhs)
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn parse_expr(
+ input: ParseStream,
+ mut lhs: Expr,
+ allow_struct: AllowStruct,
+ base: Precedence,
+ ) -> Result<Expr> {
+ loop {
+ if input
+ .fork()
+ .parse::<BinOp>()
+ .ok()
+ .map_or(false, |op| Precedence::of(&op) >= base)
+ {
+ let op: BinOp = input.parse()?;
+ let precedence = Precedence::of(&op);
+ let mut rhs = unary_expr(input, allow_struct)?;
+ loop {
+ let next = peek_precedence(input);
+ if next > precedence || next == precedence && precedence == Precedence::Assign {
+ rhs = parse_expr(input, rhs, allow_struct, next)?;
+ } else {
+ break;
+ }
+ }
+ lhs = Expr::Binary(ExprBinary {
+ attrs: Vec::new(),
+ left: Box::new(lhs),
+ op: op,
+ right: Box::new(rhs),
+ });
+ } else if Precedence::Cast >= base && input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let ty = input.call(Type::without_plus)?;
+ lhs = Expr::Cast(ExprCast {
+ attrs: Vec::new(),
+ expr: Box::new(lhs),
+ as_token: as_token,
+ ty: Box::new(ty),
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(lhs)
+ }
+
+ fn peek_precedence(input: ParseStream) -> Precedence {
+ if let Ok(op) = input.fork().parse() {
+ Precedence::of(&op)
+ } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
+ Precedence::Assign
+ } else if input.peek(Token![<-]) {
+ Precedence::Placement
+ } else if input.peek(Token![..]) {
+ Precedence::Range
+ } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
+ Precedence::Cast
+ } else {
+ Precedence::Any
+ }
+ }
+
+ // Parse an arbitrary expression.
+ fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ let lhs = unary_expr(input, allow_struct)?;
+ parse_expr(input, lhs, allow_struct, Precedence::Any)
+ }
// <UnOp> <trailer>
// & <trailer>
// &mut <trailer>
// box <trailer>
#[cfg(feature = "full")]
- named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
- do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- op: syn!(UnOp) >>
- expr: call!(unary_expr, allow_struct, true) >>
- (ExprUnary {
- attrs: attrs,
- op: op,
- expr: Box::new(expr),
- }.into())
- )
- |
- do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- and: punct!(&) >>
- mutability: option!(keyword!(mut)) >>
- expr: call!(unary_expr, allow_struct, true) >>
- (ExprReference {
- attrs: attrs,
- and_token: and,
- mutability: mutability,
- expr: Box::new(expr),
- }.into())
- )
- |
- do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- box_: keyword!(box) >>
- expr: call!(unary_expr, allow_struct, true) >>
- (ExprBox {
- attrs: attrs,
- box_token: box_,
- expr: Box::new(expr),
- }.into())
- )
- |
- call!(trailer_expr, allow_struct, allow_block)
- ));
-
- // XXX: This duplication is ugly
- #[cfg(not(feature = "full"))]
- named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
- do_parse!(
- op: syn!(UnOp) >>
- expr: call!(unary_expr, allow_struct, true) >>
- (ExprUnary {
- attrs: Vec::new(),
- op: op,
- expr: Box::new(expr),
- }.into())
- )
- |
- call!(trailer_expr, allow_struct, allow_block)
- ));
-
- #[cfg(feature = "full")]
- fn take_outer(attrs: &mut Vec<Attribute>) -> Vec<Attribute> {
- let mut outer = Vec::new();
- let mut inner = Vec::new();
- for attr in mem::replace(attrs, Vec::new()) {
- match attr.style {
- AttrStyle::Outer => outer.push(attr),
- AttrStyle::Inner(_) => inner.push(attr),
+ fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+ if ahead.peek(Token![&])
+ || ahead.peek(Token![box])
+ || ahead.peek(Token![*])
+ || ahead.peek(Token![!])
+ || ahead.peek(Token![-])
+ {
+ let attrs = input.call(Attribute::parse_outer)?;
+ if input.peek(Token![&]) {
+ Ok(Expr::Reference(ExprReference {
+ attrs: attrs,
+ and_token: input.parse()?,
+ mutability: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ }))
+ } else if input.peek(Token![box]) {
+ Ok(Expr::Box(ExprBox {
+ attrs: attrs,
+ box_token: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ }))
+ } else {
+ Ok(Expr::Unary(ExprUnary {
+ attrs: attrs,
+ op: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ }))
}
+ } else {
+ trailer_expr(input, allow_struct)
}
- *attrs = inner;
- outer
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+ if ahead.peek(Token![*]) || ahead.peek(Token![!]) || ahead.peek(Token![-]) {
+ Ok(Expr::Unary(ExprUnary {
+ attrs: input.call(Attribute::parse_outer)?,
+ op: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ }))
+ } else {
+ trailer_expr(input, allow_struct)
+ }
}
// <atom> (..<args>) ...
@@ -1465,1673 +1357,1667 @@
// <atom> [ <expr> ] ...
// <atom> ? ...
#[cfg(feature = "full")]
- named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(atom_expr, allow_struct, allow_block) >>
- outer_attrs: value!({
- let mut attrs = e.replace_attrs(Vec::new());
- let outer_attrs = take_outer(&mut attrs);
- e.replace_attrs(attrs);
- outer_attrs
- }) >>
- many0!(alt!(
- tap!(args: and_call => {
- let (paren, args) = args;
- e = ExprCall {
- attrs: Vec::new(),
- func: Box::new(e),
- args: args,
- paren_token: paren,
- }.into();
- })
- |
- tap!(more: and_method_call => {
- let mut call = more;
- call.receiver = Box::new(e);
- e = call.into();
- })
- |
- tap!(field: and_field => {
- let (token, member) = field;
- e = ExprField {
- attrs: Vec::new(),
- base: Box::new(e),
- dot_token: token,
- member: member,
- }.into();
- })
- |
- tap!(i: and_index => {
- let (bracket, i) = i;
- e = ExprIndex {
- attrs: Vec::new(),
- expr: Box::new(e),
- bracket_token: bracket,
- index: Box::new(i),
- }.into();
- })
- |
- tap!(question: punct!(?) => {
- e = ExprTry {
- attrs: Vec::new(),
- expr: Box::new(e),
- question_token: question,
- }.into();
- })
- )) >>
- ({
- let mut attrs = outer_attrs;
- attrs.extend(e.replace_attrs(Vec::new()));
- e.replace_attrs(attrs);
- e
- })
- ));
+ fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ if input.peek(token::Group) {
+ return input.call(expr_group).map(Expr::Group);
+ }
- // XXX: Duplication == ugly
- #[cfg(not(feature = "full"))]
- named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
- mut e: call!(atom_expr, allow_struct, allow_block) >>
- many0!(alt!(
- tap!(args: and_call => {
- e = ExprCall {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+
+ let atom = atom_expr(input, allow_struct)?;
+ let mut e = trailer_helper(input, atom)?;
+
+ let inner_attrs = e.replace_attrs(Vec::new());
+ let attrs = private::attrs(outer_attrs, inner_attrs);
+ e.replace_attrs(attrs);
+ Ok(e)
+ }
+
+ #[cfg(feature = "full")]
+ fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
+ loop {
+ if input.peek(token::Paren) {
+ let content;
+ e = Expr::Call(ExprCall {
attrs: Vec::new(),
func: Box::new(e),
- paren_token: args.0,
- args: args.1,
- }.into();
- })
- |
- tap!(field: and_field => {
- let (token, member) = field;
- e = ExprField {
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse)?,
+ });
+ } else if input.peek(Token![.]) && !input.peek(Token![..]) {
+ let dot_token: Token![.] = input.parse()?;
+ let member: Member = input.parse()?;
+ let turbofish = if member.is_named() && input.peek(Token![::]) {
+ Some(MethodTurbofish {
+ colon2_token: input.parse()?,
+ lt_token: input.parse()?,
+ args: {
+ let mut args = Punctuated::new();
+ loop {
+ if input.peek(Token![>]) {
+ break;
+ }
+ let value = input.call(generic_method_argument)?;
+ args.push_value(value);
+ if input.peek(Token![>]) {
+ break;
+ }
+ let punct = input.parse()?;
+ args.push_punct(punct);
+ }
+ args
+ },
+ gt_token: input.parse()?,
+ })
+ } else {
+ None
+ };
+
+ if turbofish.is_some() || input.peek(token::Paren) {
+ if let Member::Named(method) = member {
+ let content;
+ e = Expr::MethodCall(ExprMethodCall {
+ attrs: Vec::new(),
+ receiver: Box::new(e),
+ dot_token: dot_token,
+ method: method,
+ turbofish: turbofish,
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse)?,
+ });
+ continue;
+ }
+ }
+
+ e = Expr::Field(ExprField {
attrs: Vec::new(),
base: Box::new(e),
- dot_token: token,
+ dot_token: dot_token,
member: member,
- }.into();
- })
- |
- tap!(i: and_index => {
- e = ExprIndex {
+ });
+ } else if input.peek(token::Bracket) {
+ let content;
+ e = Expr::Index(ExprIndex {
attrs: Vec::new(),
expr: Box::new(e),
- bracket_token: i.0,
- index: Box::new(i.1),
- }.into();
- })
- )) >>
- (e)
- ));
+ bracket_token: bracketed!(content in input),
+ index: content.parse()?,
+ });
+ } else if input.peek(Token![?]) {
+ e = Expr::Try(ExprTry {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ question_token: input.parse()?,
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(e)
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ let mut e = atom_expr(input, allow_struct)?;
+
+ loop {
+ if input.peek(token::Paren) {
+ let content;
+ e = Expr::Call(ExprCall {
+ attrs: Vec::new(),
+ func: Box::new(e),
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse)?,
+ });
+ } else if input.peek(Token![.]) {
+ e = Expr::Field(ExprField {
+ attrs: Vec::new(),
+ base: Box::new(e),
+ dot_token: input.parse()?,
+ member: input.parse()?,
+ });
+ } else if input.peek(token::Bracket) {
+ let content;
+ e = Expr::Index(ExprIndex {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ bracket_token: bracketed!(content in input),
+ index: content.parse()?,
+ });
+ } else {
+ break;
+ }
+ }
+
+ Ok(e)
+ }
// Parse all atomic expressions which don't have to worry about precedence
// interactions, as they are fully contained.
#[cfg(feature = "full")]
- named!(atom_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
- syn!(ExprGroup) => { Expr::Group } // must be placed first
- |
- syn!(ExprLit) => { Expr::Lit } // must be before expr_struct
- |
- // must be before ExprStruct
- call!(unstable_async_block) => { Expr::Verbatim }
- |
- // must be before ExprStruct
- call!(unstable_try_block) => { Expr::Verbatim }
- |
- // must be before expr_path
- cond_reduce!(allow_struct, syn!(ExprStruct)) => { Expr::Struct }
- |
- syn!(ExprParen) => { Expr::Paren } // must be before expr_tup
- |
- syn!(ExprMacro) => { Expr::Macro } // must be before expr_path
- |
- call!(expr_break, allow_struct) // must be before expr_path
- |
- syn!(ExprContinue) => { Expr::Continue } // must be before expr_path
- |
- call!(expr_ret, allow_struct) // must be before expr_path
- |
- syn!(ExprArray) => { Expr::Array }
- |
- syn!(ExprTuple) => { Expr::Tuple }
- |
- syn!(ExprIf) => { Expr::If }
- |
- syn!(ExprIfLet) => { Expr::IfLet }
- |
- syn!(ExprWhile) => { Expr::While }
- |
- syn!(ExprWhileLet) => { Expr::WhileLet }
- |
- syn!(ExprForLoop) => { Expr::ForLoop }
- |
- syn!(ExprLoop) => { Expr::Loop }
- |
- syn!(ExprMatch) => { Expr::Match }
- |
- syn!(ExprCatch) => { Expr::Catch }
- |
- syn!(ExprYield) => { Expr::Yield }
- |
- syn!(ExprUnsafe) => { Expr::Unsafe }
- |
- call!(expr_closure, allow_struct)
- |
- cond_reduce!(allow_block, syn!(ExprBlock)) => { Expr::Block }
- |
- call!(unstable_labeled_block) => { Expr::Verbatim }
- |
- // NOTE: This is the prefix-form of range
- call!(expr_range, allow_struct)
- |
- syn!(ExprPath) => { Expr::Path }
- |
- syn!(ExprRepeat) => { Expr::Repeat }
- ));
+ fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ if input.peek(token::Group) {
+ input.call(expr_group).map(Expr::Group)
+ } else if input.peek(Lit) {
+ input.call(expr_lit).map(Expr::Lit)
+ } else if input.peek(Token![async])
+ && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
+ {
+ input.call(expr_async).map(Expr::Async)
+ } else if input.peek(Token![try]) && input.peek2(token::Brace) {
+ input.call(expr_try_block).map(Expr::TryBlock)
+ } else if input.peek(Token![|])
+ || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
+ || input.peek(Token![static])
+ || input.peek(Token![move])
+ {
+ expr_closure(input, allow_struct).map(Expr::Closure)
+ } else if input.peek(Ident)
+ || input.peek(Token![::])
+ || input.peek(Token![<])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![super])
+ || input.peek(Token![extern])
+ || input.peek(Token![crate])
+ {
+ path_or_macro_or_struct(input, allow_struct)
+ } else if input.peek(token::Paren) {
+ paren_or_tuple(input)
+ } else if input.peek(Token![break]) {
+ expr_break(input, allow_struct).map(Expr::Break)
+ } else if input.peek(Token![continue]) {
+ input.call(expr_continue).map(Expr::Continue)
+ } else if input.peek(Token![return]) {
+ expr_ret(input, allow_struct).map(Expr::Return)
+ } else if input.peek(token::Bracket) {
+ array_or_repeat(input)
+ } else if input.peek(Token![if]) {
+ if input.peek2(Token![let]) {
+ input.call(expr_if_let).map(Expr::IfLet)
+ } else {
+ input.call(expr_if).map(Expr::If)
+ }
+ } else if input.peek(Token![while]) {
+ if input.peek2(Token![let]) {
+ input.call(expr_while_let).map(Expr::WhileLet)
+ } else {
+ input.call(expr_while).map(Expr::While)
+ }
+ } else if input.peek(Token![for]) {
+ input.call(expr_for_loop).map(Expr::ForLoop)
+ } else if input.peek(Token![loop]) {
+ input.call(expr_loop).map(Expr::Loop)
+ } else if input.peek(Token![match]) {
+ input.call(expr_match).map(Expr::Match)
+ } else if input.peek(Token![yield]) {
+ input.call(expr_yield).map(Expr::Yield)
+ } else if input.peek(Token![unsafe]) {
+ input.call(expr_unsafe).map(Expr::Unsafe)
+ } else if input.peek(token::Brace) {
+ input.call(expr_block).map(Expr::Block)
+ } else if input.peek(Token![..]) {
+ expr_range(input, allow_struct).map(Expr::Range)
+ } else if input.peek(Lifetime) {
+ let the_label: Label = input.parse()?;
+ let mut expr = if input.peek(Token![while]) {
+ if input.peek2(Token![let]) {
+ Expr::WhileLet(input.call(expr_while_let)?)
+ } else {
+ Expr::While(input.call(expr_while)?)
+ }
+ } else if input.peek(Token![for]) {
+ Expr::ForLoop(input.call(expr_for_loop)?)
+ } else if input.peek(Token![loop]) {
+ Expr::Loop(input.call(expr_loop)?)
+ } else if input.peek(token::Brace) {
+ Expr::Block(input.call(expr_block)?)
+ } else {
+ return Err(input.error("expected loop or block expression"));
+ };
+ match expr {
+ Expr::WhileLet(ExprWhileLet { ref mut label, .. })
+ | Expr::While(ExprWhile { ref mut label, .. })
+ | Expr::ForLoop(ExprForLoop { ref mut label, .. })
+ | Expr::Loop(ExprLoop { ref mut label, .. })
+ | Expr::Block(ExprBlock { ref mut label, .. }) => *label = Some(the_label),
+ _ => unreachable!(),
+ }
+ Ok(expr)
+ } else {
+ Err(input.error("expected expression"))
+ }
+ }
#[cfg(not(feature = "full"))]
- named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> Expr, alt!(
- syn!(ExprLit) => { Expr::Lit }
- |
- syn!(ExprParen) => { Expr::Paren }
- |
- syn!(ExprPath) => { Expr::Path }
- ));
-
- #[cfg(feature = "full")]
- named!(expr_nosemi -> Expr, do_parse!(
- nosemi: alt!(
- syn!(ExprIf) => { Expr::If }
- |
- syn!(ExprIfLet) => { Expr::IfLet }
- |
- syn!(ExprWhile) => { Expr::While }
- |
- syn!(ExprWhileLet) => { Expr::WhileLet }
- |
- syn!(ExprForLoop) => { Expr::ForLoop }
- |
- syn!(ExprLoop) => { Expr::Loop }
- |
- syn!(ExprMatch) => { Expr::Match }
- |
- syn!(ExprCatch) => { Expr::Catch }
- |
- syn!(ExprYield) => { Expr::Yield }
- |
- syn!(ExprUnsafe) => { Expr::Unsafe }
- |
- syn!(ExprBlock) => { Expr::Block }
- |
- call!(unstable_labeled_block) => { Expr::Verbatim }
- ) >>
- // If the next token is a `.` or a `?` it is special-cased to parse
- // as an expression instead of a blockexpression.
- not!(punct!(.)) >>
- not!(punct!(?)) >>
- (nosemi)
- ));
-
- impl Synom for ExprLit {
- #[cfg(not(feature = "full"))]
- named!(parse -> Self, do_parse!(
- lit: syn!(Lit) >>
- (ExprLit {
- attrs: Vec::new(),
- lit: lit,
- })
- ));
-
- #[cfg(feature = "full")]
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- lit: syn!(Lit) >>
- (ExprLit {
- attrs: attrs,
- lit: lit,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("literal")
+ fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
+ if input.peek(Lit) {
+ input.call(expr_lit).map(Expr::Lit)
+ } else if input.peek(token::Paren) {
+ input.call(expr_paren).map(Expr::Paren)
+ } else if input.peek(Ident)
+ || input.peek(Token![::])
+ || input.peek(Token![<])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![super])
+ || input.peek(Token![extern])
+ || input.peek(Token![crate])
+ {
+ input.parse().map(Expr::Path)
+ } else {
+ Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
}
}
#[cfg(feature = "full")]
- impl Synom for ExprMacro {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- mac: syn!(Macro) >>
- (ExprMacro {
- attrs: attrs,
- mac: mac,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("macro invocation expression")
+ fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ let expr: ExprPath = input.parse()?;
+ if expr.qself.is_some() {
+ return Ok(Expr::Path(expr));
}
- }
- #[cfg(feature = "full")]
- impl Synom for ExprGroup {
- named!(parse -> Self, do_parse!(
- e: grouped!(syn!(Expr)) >>
- (ExprGroup {
- attrs: Vec::new(),
- expr: Box::new(e.1),
- group_token: e.0,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("expression surrounded by invisible delimiters")
- }
- }
-
- impl Synom for ExprParen {
- #[cfg(not(feature = "full"))]
- named!(parse -> Self, do_parse!(
- e: parens!(syn!(Expr)) >>
- (ExprParen {
- attrs: Vec::new(),
- paren_token: e.0,
- expr: Box::new(e.1),
- })
- ));
-
- #[cfg(feature = "full")]
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- e: parens!(tuple!(
- many0!(Attribute::parse_inner),
- syn!(Expr),
- )) >>
- (ExprParen {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((e.1).0);
- attrs
- },
- paren_token: e.0,
- expr: Box::new((e.1).1),
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("parenthesized expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprArray {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- elems: brackets!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Punctuated::parse_terminated),
- )) >>
- (ExprArray {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((elems.1).0);
- attrs
- },
- bracket_token: elems.0,
- elems: (elems.1).1,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("array expression")
- }
- }
-
- named!(and_call -> (token::Paren, Punctuated<Expr, Token![,]>),
- parens!(Punctuated::parse_terminated)
- );
-
- #[cfg(feature = "full")]
- named!(and_method_call -> ExprMethodCall, do_parse!(
- dot: punct!(.) >>
- method: syn!(Ident) >>
- turbofish: option!(tuple!(
- punct!(::),
- punct!(<),
- call!(Punctuated::parse_terminated),
- punct!(>),
- )) >>
- args: parens!(Punctuated::parse_terminated) >>
- ({
- ExprMethodCall {
- attrs: Vec::new(),
- // this expr will get overwritten after being returned
- receiver: Box::new(Expr::Verbatim(ExprVerbatim {
- tts: TokenStream::new(),
- })),
-
- method: method,
- turbofish: turbofish.map(|fish| MethodTurbofish {
- colon2_token: fish.0,
- lt_token: fish.1,
- args: fish.2,
- gt_token: fish.3,
- }),
- args: args.1,
- paren_token: args.0,
- dot_token: dot,
- }
- })
- ));
-
- #[cfg(feature = "full")]
- impl Synom for GenericMethodArgument {
- // TODO parse const generics as well
- named!(parse -> Self, map!(ty_no_eq_after, GenericMethodArgument::Type));
-
- fn description() -> Option<&'static str> {
- Some("generic method argument")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprTuple {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- elems: parens!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Punctuated::parse_terminated),
- )) >>
- (ExprTuple {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((elems.1).0);
- attrs
- },
- elems: (elems.1).1,
- paren_token: elems.0,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("tuple")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprIfLet {
- named!(parse -> Self, do_parse!(
- if_: keyword!(if) >>
- let_: keyword!(let) >>
- pats: call!(Punctuated::parse_separated_nonempty) >>
- eq: punct!(=) >>
- cond: expr_no_struct >>
- then_block: braces!(Block::parse_within) >>
- else_block: option!(else_block) >>
- (ExprIfLet {
- attrs: Vec::new(),
- pats: pats,
- let_token: let_,
- eq_token: eq,
- expr: Box::new(cond),
- then_branch: Block {
- brace_token: then_block.0,
- stmts: then_block.1,
- },
- if_token: if_,
- else_branch: else_block,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`if let` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprIf {
- named!(parse -> Self, do_parse!(
- if_: keyword!(if) >>
- cond: expr_no_struct >>
- then_block: braces!(Block::parse_within) >>
- else_block: option!(else_block) >>
- (ExprIf {
- attrs: Vec::new(),
- cond: Box::new(cond),
- then_branch: Block {
- brace_token: then_block.0,
- stmts: then_block.1,
- },
- if_token: if_,
- else_branch: else_block,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`if` expression")
- }
- }
-
- #[cfg(feature = "full")]
- named!(else_block -> (Token![else], Box<Expr>), do_parse!(
- else_: keyword!(else) >>
- expr: alt!(
- syn!(ExprIf) => { Expr::If }
- |
- syn!(ExprIfLet) => { Expr::IfLet }
- |
- do_parse!(
- else_block: braces!(Block::parse_within) >>
- (Expr::Block(ExprBlock {
- attrs: Vec::new(),
- block: Block {
- brace_token: else_block.0,
- stmts: else_block.1,
- },
- }))
- )
- ) >>
- (else_, Box::new(expr))
- ));
-
- #[cfg(feature = "full")]
- impl Synom for ExprForLoop {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- label: option!(syn!(Label)) >>
- for_: keyword!(for) >>
- pat: syn!(Pat) >>
- in_: keyword!(in) >>
- expr: expr_no_struct >>
- block: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ExprForLoop {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((block.1).0);
- attrs
- },
- label: label,
- for_token: for_,
- pat: Box::new(pat),
- in_token: in_,
- expr: Box::new(expr),
- body: Block {
- brace_token: block.0,
- stmts: (block.1).1,
- },
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`for` loop")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprLoop {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- label: option!(syn!(Label)) >>
- loop_: keyword!(loop) >>
- block: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ExprLoop {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((block.1).0);
- attrs
- },
- label: label,
- loop_token: loop_,
- body: Block {
- brace_token: block.0,
- stmts: (block.1).1,
- },
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`loop`")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprMatch {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- match_: keyword!(match) >>
- obj: expr_no_struct >>
- braced_content: braces!(tuple!(
- many0!(Attribute::parse_inner),
- many0!(syn!(Arm)),
- )) >>
- (ExprMatch {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((braced_content.1).0);
- attrs
- },
- expr: Box::new(obj),
- match_token: match_,
- brace_token: braced_content.0,
- arms: (braced_content.1).1,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`match` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprCatch {
- named!(parse -> Self, do_parse!(
- do_: keyword!(do) >>
- catch_: keyword!(catch) >>
- catch_block: syn!(Block) >>
- (ExprCatch {
- attrs: Vec::new(),
- block: catch_block,
- do_token: do_,
- catch_token: catch_,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`catch` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprYield {
- named!(parse -> Self, do_parse!(
- yield_: keyword!(yield) >>
- expr: option!(syn!(Expr)) >>
- (ExprYield {
- attrs: Vec::new(),
- yield_token: yield_,
- expr: expr.map(Box::new),
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`yield` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for Arm {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- leading_vert: option!(punct!(|)) >>
- pats: call!(Punctuated::parse_separated_nonempty) >>
- guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
- fat_arrow: punct!(=>) >>
- body: do_parse!(
- expr: alt!(expr_nosemi | syn!(Expr)) >>
- comma: switch!(value!(arm_expr_requires_comma(&expr)),
- true => alt!(
- input_end!() => { |_| None }
- |
- punct!(,) => { Some }
- )
- |
- false => option!(punct!(,))
- ) >>
- (expr, comma)
- ) >>
- (Arm {
- fat_arrow_token: fat_arrow,
- attrs: attrs,
- leading_vert: leading_vert,
- pats: pats,
- guard: guard.map(|(if_, guard)| (if_, Box::new(guard))),
- body: Box::new(body.0),
- comma: body.1,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`match` arm")
- }
- }
-
- #[cfg(feature = "full")]
- named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- attrs: many0!(Attribute::parse_outer) >>
- asyncness: option!(keyword!(async)) >>
- movability: option!(cond_reduce!(asyncness.is_none(), keyword!(static))) >>
- capture: option!(keyword!(move)) >>
- or1: punct!(|) >>
- inputs: call!(Punctuated::parse_terminated_with, fn_arg) >>
- or2: punct!(|) >>
- ret_and_body: alt!(
- do_parse!(
- arrow: punct!(->) >>
- ty: syn!(Type) >>
- body: syn!(Block) >>
- (
- ReturnType::Type(arrow, Box::new(ty)),
- Expr::Block(ExprBlock {
- attrs: Vec::new(),
- block: body,
- },
- ))
- )
- |
- map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
- ) >>
- end: call!(verbatim::grab_cursor) >>
- ({
- if asyncness.is_some() {
- // TODO: include asyncness in ExprClosure
- // https://github.com/dtolnay/syn/issues/396
- Expr::Verbatim(ExprVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- } else {
- Expr::Closure(ExprClosure {
- attrs: attrs,
- movability: movability,
- capture: capture,
- or1_token: or1,
- inputs: inputs,
- or2_token: or2,
- output: ret_and_body.0,
- body: Box::new(ret_and_body.1),
- })
- }
- })
- ));
-
- #[cfg(feature = "full")]
- named!(unstable_async_block -> ExprVerbatim, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- keyword!(async) >>
- option!(keyword!(move)) >>
- syn!(Block) >>
- end: call!(verbatim::grab_cursor) >>
- (ExprVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- ));
-
- #[cfg(feature = "full")]
- named!(unstable_try_block -> ExprVerbatim, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- keyword!(try) >>
- syn!(Block) >>
- end: call!(verbatim::grab_cursor) >>
- (ExprVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- ));
-
- #[cfg(feature = "full")]
- named!(fn_arg -> FnArg, do_parse!(
- pat: syn!(Pat) >>
- ty: option!(tuple!(punct!(:), syn!(Type))) >>
- ({
- if let Some((colon, ty)) = ty {
- FnArg::Captured(ArgCaptured {
- pat: pat,
- colon_token: colon,
- ty: ty,
- })
- } else {
- FnArg::Inferred(pat)
- }
- })
- ));
-
- #[cfg(feature = "full")]
- impl Synom for ExprWhile {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- label: option!(syn!(Label)) >>
- while_: keyword!(while) >>
- cond: expr_no_struct >>
- block: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ExprWhile {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((block.1).0);
- attrs
- },
- label: label,
- while_token: while_,
- cond: Box::new(cond),
- body: Block {
- brace_token: block.0,
- stmts: (block.1).1,
- },
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`while` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprWhileLet {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- label: option!(syn!(Label)) >>
- while_: keyword!(while) >>
- let_: keyword!(let) >>
- pats: call!(Punctuated::parse_separated_nonempty) >>
- eq: punct!(=) >>
- value: expr_no_struct >>
- block: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ExprWhileLet {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((block.1).0);
- attrs
- },
- label: label,
- while_token: while_,
- let_token: let_,
- pats: pats,
- eq_token: eq,
- expr: Box::new(value),
- body: Block {
- brace_token: block.0,
- stmts: (block.1).1,
- },
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`while let` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for Label {
- named!(parse -> Self, do_parse!(
- name: syn!(Lifetime) >>
- colon: punct!(:) >>
- (Label {
- name: name,
- colon_token: colon,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`while let` expression")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprContinue {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- cont: keyword!(continue) >>
- label: option!(syn!(Lifetime)) >>
- (ExprContinue {
- attrs: attrs,
- continue_token: cont,
- label: label,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`continue`")
- }
- }
-
- #[cfg(feature = "full")]
- named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- break_: keyword!(break) >>
- label: option!(syn!(Lifetime)) >>
- // We can't allow blocks after a `break` expression when we wouldn't
- // allow structs, as this expression is ambiguous.
- val: opt_ambiguous_expr!(allow_struct) >>
- (ExprBreak {
- attrs: attrs,
- label: label,
- expr: val.map(Box::new),
- break_token: break_,
- }.into())
- ));
-
- #[cfg(feature = "full")]
- named!(expr_ret(allow_struct: bool) -> Expr, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- return_: keyword!(return) >>
- // NOTE: return is greedy and eats blocks after it even when in a
- // position where structs are not allowed, such as in if statement
- // conditions. For example:
- //
- // if return { println!("A") } {} // Prints "A"
- ret_value: option!(ambiguous_expr!(allow_struct)) >>
- (ExprReturn {
- attrs: attrs,
- expr: ret_value.map(Box::new),
- return_token: return_,
- }.into())
- ));
-
- #[cfg(feature = "full")]
- impl Synom for ExprStruct {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- path: syn!(Path) >>
- data: braces!(do_parse!(
- inner_attrs: many0!(Attribute::parse_inner) >>
- fields: call!(Punctuated::parse_terminated) >>
- base: option!(cond!(fields.empty_or_trailing(), do_parse!(
- dots: punct!(..) >>
- base: syn!(Expr) >>
- (dots, base)
- ))) >>
- (inner_attrs, fields, base)
- )) >>
- ({
- let (brace, (inner_attrs, fields, base)) = data;
- let (dots, rest) = match base.and_then(|b| b) {
- Some((dots, base)) => (Some(dots), Some(base)),
- None => (None, None),
- };
- ExprStruct {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend(inner_attrs);
- attrs
- },
- brace_token: brace,
- path: path,
- fields: fields,
- dot2_token: dots,
- rest: rest.map(Box::new),
+ if input.peek(Token![!]) && !input.peek(Token![!=]) {
+ let mut contains_arguments = false;
+ for segment in &expr.path.segments {
+ match segment.arguments {
+ PathArguments::None => {}
+ PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
+ contains_arguments = true;
+ }
}
- })
- ));
+ }
- fn description() -> Option<&'static str> {
- Some("struct literal expression")
+ if !contains_arguments {
+ let bang_token: Token![!] = input.parse()?;
+ let (delimiter, tts) = mac::parse_delimiter(input)?;
+ return Ok(Expr::Macro(ExprMacro {
+ attrs: Vec::new(),
+ mac: Macro {
+ path: expr.path,
+ bang_token: bang_token,
+ delimiter: delimiter,
+ tts: tts,
+ },
+ }));
+ }
+ }
+
+ if allow_struct.0 && input.peek(token::Brace) {
+ let outer_attrs = Vec::new();
+ expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
+ } else {
+ Ok(Expr::Path(expr))
}
}
#[cfg(feature = "full")]
- impl Synom for FieldValue {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- field_value: alt!(
- tuple!(syn!(Member), map!(punct!(:), Some), syn!(Expr))
- |
- map!(syn!(Ident), |name| (
- Member::Named(name.clone()),
- None,
- Expr::Path(ExprPath {
- attrs: Vec::new(),
- qself: None,
- path: name.into(),
- }),
- ))
- ) >>
- (FieldValue {
- attrs: attrs,
- member: field_value.0,
- colon_token: field_value.1,
- expr: field_value.2,
- })
- ));
+ fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ if content.is_empty() {
+ return Ok(Expr::Tuple(ExprTuple {
+ attrs: inner_attrs,
+ paren_token: paren_token,
+ elems: Punctuated::new(),
+ }));
+ }
- fn description() -> Option<&'static str> {
- Some("field-value pair: `field: value`")
+ let first: Expr = content.parse()?;
+ if content.is_empty() {
+ return Ok(Expr::Paren(ExprParen {
+ attrs: inner_attrs,
+ paren_token: paren_token,
+ expr: Box::new(first),
+ }));
+ }
+
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ while !content.is_empty() {
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ if content.is_empty() {
+ break;
+ }
+ let value = content.parse()?;
+ elems.push_value(value);
+ }
+ Ok(Expr::Tuple(ExprTuple {
+ attrs: inner_attrs,
+ paren_token: paren_token,
+ elems: elems,
+ }))
+ }
+
+ #[cfg(feature = "full")]
+ fn array_or_repeat(input: ParseStream) -> Result<Expr> {
+ let content;
+ let bracket_token = bracketed!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ if content.is_empty() {
+ return Ok(Expr::Array(ExprArray {
+ attrs: inner_attrs,
+ bracket_token: bracket_token,
+ elems: Punctuated::new(),
+ }));
+ }
+
+ let first: Expr = content.parse()?;
+ if content.is_empty() || content.peek(Token![,]) {
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ while !content.is_empty() {
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ if content.is_empty() {
+ break;
+ }
+ let value = content.parse()?;
+ elems.push_value(value);
+ }
+ Ok(Expr::Array(ExprArray {
+ attrs: inner_attrs,
+ bracket_token: bracket_token,
+ elems: elems,
+ }))
+ } else if content.peek(Token![;]) {
+ let semi_token: Token![;] = content.parse()?;
+ let len: Expr = content.parse()?;
+ Ok(Expr::Repeat(ExprRepeat {
+ attrs: inner_attrs,
+ bracket_token: bracket_token,
+ expr: Box::new(first),
+ semi_token: semi_token,
+ len: Box::new(len),
+ }))
+ } else {
+ Err(content.error("expected `,` or `;`"))
}
}
#[cfg(feature = "full")]
- impl Synom for ExprRepeat {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- data: brackets!(tuple!(
- many0!(Attribute::parse_inner),
- syn!(Expr),
- punct!(;),
- syn!(Expr),
- )) >>
- (ExprRepeat {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((data.1).0);
- attrs
- },
- expr: Box::new((data.1).1),
- len: Box::new((data.1).3),
- bracket_token: data.0,
- semi_token: (data.1).2,
- })
- ));
+ fn expr_early(input: ParseStream) -> Result<Expr> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let mut expr = if input.peek(Token![if]) {
+ if input.peek2(Token![let]) {
+ Expr::IfLet(input.call(expr_if_let)?)
+ } else {
+ Expr::If(input.call(expr_if)?)
+ }
+ } else if input.peek(Token![while]) {
+ if input.peek2(Token![let]) {
+ Expr::WhileLet(input.call(expr_while_let)?)
+ } else {
+ Expr::While(input.call(expr_while)?)
+ }
+ } else if input.peek(Token![for]) {
+ Expr::ForLoop(input.call(expr_for_loop)?)
+ } else if input.peek(Token![loop]) {
+ Expr::Loop(input.call(expr_loop)?)
+ } else if input.peek(Token![match]) {
+ Expr::Match(input.call(expr_match)?)
+ } else if input.peek(Token![try]) && input.peek2(token::Brace) {
+ Expr::TryBlock(input.call(expr_try_block)?)
+ } else if input.peek(Token![unsafe]) {
+ Expr::Unsafe(input.call(expr_unsafe)?)
+ } else if input.peek(token::Brace) {
+ Expr::Block(input.call(expr_block)?)
+ } else {
+ let allow_struct = AllowStruct(true);
+ let mut expr = unary_expr(input, allow_struct)?;
- fn description() -> Option<&'static str> {
- Some("repeated array literal: `[val; N]`")
+ attrs.extend(expr.replace_attrs(Vec::new()));
+ expr.replace_attrs(attrs);
+
+ return parse_expr(input, expr, allow_struct, Precedence::Any);
+ };
+
+ if input.peek(Token![.]) || input.peek(Token![?]) {
+ expr = trailer_helper(input, expr)?;
+
+ attrs.extend(expr.replace_attrs(Vec::new()));
+ expr.replace_attrs(attrs);
+
+ let allow_struct = AllowStruct(true);
+ return parse_expr(input, expr, allow_struct, Precedence::Any);
}
+
+ attrs.extend(expr.replace_attrs(Vec::new()));
+ expr.replace_attrs(attrs);
+ Ok(expr)
}
- #[cfg(feature = "full")]
- impl Synom for ExprUnsafe {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- unsafe_: keyword!(unsafe) >>
- block: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ExprUnsafe {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((block.1).0);
- attrs
- },
- unsafe_token: unsafe_,
- block: Block {
- brace_token: block.0,
- stmts: (block.1).1,
- },
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("unsafe block: `unsafe { .. }`")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for ExprBlock {
- named!(parse -> Self, do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- block: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ExprBlock {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((block.1).0);
- attrs
- },
- block: Block {
- brace_token: block.0,
- stmts: (block.1).1,
- },
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("block: `{ .. }`")
- }
- }
-
- #[cfg(feature = "full")]
- named!(unstable_labeled_block -> ExprVerbatim, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- syn!(Label) >>
- braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- end: call!(verbatim::grab_cursor) >>
- (ExprVerbatim {
- tts: verbatim::token_range(begin..end),
+ pub fn expr_lit(input: ParseStream) -> Result<ExprLit> {
+ Ok(ExprLit {
+ attrs: Vec::new(),
+ lit: input.parse()?,
})
- ));
+ }
#[cfg(feature = "full")]
- named!(expr_range(allow_struct: bool) -> Expr, do_parse!(
- limits: syn!(RangeLimits) >>
- hi: opt_ambiguous_expr!(allow_struct) >>
- (ExprRange {
+ fn expr_group(input: ParseStream) -> Result<ExprGroup> {
+ let group = private::parse_group(input)?;
+ Ok(ExprGroup {
+ attrs: Vec::new(),
+ group_token: group.token,
+ expr: group.content.parse()?,
+ })
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn expr_paren(input: ParseStream) -> Result<ExprParen> {
+ let content;
+ Ok(ExprParen {
+ attrs: Vec::new(),
+ paren_token: parenthesized!(content in input),
+ expr: content.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
+ // TODO parse const generics as well
+ input.parse().map(GenericMethodArgument::Type)
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_if_let(input: ParseStream) -> Result<ExprIfLet> {
+ Ok(ExprIfLet {
+ attrs: Vec::new(),
+ if_token: input.parse()?,
+ let_token: input.parse()?,
+ pats: {
+ let mut pats = Punctuated::new();
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
+ let punct = input.parse()?;
+ pats.push_punct(punct);
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ }
+ pats
+ },
+ eq_token: input.parse()?,
+ expr: Box::new(input.call(expr_no_struct)?),
+ then_branch: input.parse()?,
+ else_branch: {
+ if input.peek(Token![else]) {
+ Some(input.call(else_block)?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_if(input: ParseStream) -> Result<ExprIf> {
+ Ok(ExprIf {
+ attrs: Vec::new(),
+ if_token: input.parse()?,
+ cond: Box::new(input.call(expr_no_struct)?),
+ then_branch: input.parse()?,
+ else_branch: {
+ if input.peek(Token![else]) {
+ Some(input.call(else_block)?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
+ let else_token: Token![else] = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let else_branch = if input.peek(Token![if]) {
+ if input.peek2(Token![let]) {
+ input.call(expr_if_let).map(Expr::IfLet)?
+ } else {
+ input.call(expr_if).map(Expr::If)?
+ }
+ } else if input.peek(token::Brace) {
+ Expr::Block(ExprBlock {
+ attrs: Vec::new(),
+ label: None,
+ block: input.parse()?,
+ })
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok((else_token, Box::new(else_branch)))
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_for_loop(input: ParseStream) -> Result<ExprForLoop> {
+ let label: Option<Label> = input.parse()?;
+ let for_token: Token![for] = input.parse()?;
+ let pat: Pat = input.parse()?;
+ let in_token: Token![in] = input.parse()?;
+ let expr: Expr = input.call(expr_no_struct)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprForLoop {
+ attrs: inner_attrs,
+ label: label,
+ for_token: for_token,
+ pat: Box::new(pat),
+ in_token: in_token,
+ expr: Box::new(expr),
+ body: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_loop(input: ParseStream) -> Result<ExprLoop> {
+ let label: Option<Label> = input.parse()?;
+ let loop_token: Token![loop] = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprLoop {
+ attrs: inner_attrs,
+ label: label,
+ loop_token: loop_token,
+ body: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_match(input: ParseStream) -> Result<ExprMatch> {
+ let match_token: Token![match] = input.parse()?;
+ let expr = expr_no_struct(input)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+
+ let mut arms = Vec::new();
+ while !content.is_empty() {
+ arms.push(content.call(match_arm)?);
+ }
+
+ Ok(ExprMatch {
+ attrs: inner_attrs,
+ match_token: match_token,
+ expr: Box::new(expr),
+ brace_token: brace_token,
+ arms: arms,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
+ Ok(ExprTryBlock {
+ attrs: Vec::new(),
+ try_token: input.parse()?,
+ block: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_yield(input: ParseStream) -> Result<ExprYield> {
+ Ok(ExprYield {
+ attrs: Vec::new(),
+ yield_token: input.parse()?,
+ expr: {
+ if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
+ Some(input.parse()?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn match_arm(input: ParseStream) -> Result<Arm> {
+ let requires_comma;
+ Ok(Arm {
+ attrs: input.call(Attribute::parse_outer)?,
+ leading_vert: input.parse()?,
+ pats: {
+ let mut pats = Punctuated::new();
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ loop {
+ if !input.peek(Token![|]) {
+ break;
+ }
+ let punct = input.parse()?;
+ pats.push_punct(punct);
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ }
+ pats
+ },
+ guard: {
+ if input.peek(Token![if]) {
+ let if_token: Token![if] = input.parse()?;
+ let guard: Expr = input.parse()?;
+ Some((if_token, Box::new(guard)))
+ } else {
+ None
+ }
+ },
+ fat_arrow_token: input.parse()?,
+ body: {
+ let body = input.call(expr_early)?;
+ requires_comma = requires_terminator(&body);
+ Box::new(body)
+ },
+ comma: {
+ if requires_comma && !input.is_empty() {
+ Some(input.parse()?)
+ } else {
+ input.parse()?
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
+ let asyncness: Option<Token![async]> = input.parse()?;
+ let movability: Option<Token![static]> = if asyncness.is_none() {
+ input.parse()?
+ } else {
+ None
+ };
+ let capture: Option<Token![move]> = input.parse()?;
+ let or1_token: Token![|] = input.parse()?;
+
+ let mut inputs = Punctuated::new();
+ loop {
+ if input.peek(Token![|]) {
+ break;
+ }
+ let value = fn_arg(input)?;
+ inputs.push_value(value);
+ if input.peek(Token![|]) {
+ break;
+ }
+ let punct: Token![,] = input.parse()?;
+ inputs.push_punct(punct);
+ }
+
+ let or2_token: Token![|] = input.parse()?;
+
+ let (output, body) = if input.peek(Token![->]) {
+ let arrow_token: Token![->] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let body: Block = input.parse()?;
+ let output = ReturnType::Type(arrow_token, Box::new(ty));
+ let block = Expr::Block(ExprBlock {
+ attrs: Vec::new(),
+ label: None,
+ block: body,
+ });
+ (output, block)
+ } else {
+ let body = ambiguous_expr(input, allow_struct)?;
+ (ReturnType::Default, body)
+ };
+
+ Ok(ExprClosure {
+ attrs: Vec::new(),
+ asyncness: asyncness,
+ movability: movability,
+ capture: capture,
+ or1_token: or1_token,
+ inputs: inputs,
+ or2_token: or2_token,
+ output: output,
+ body: Box::new(body),
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_async(input: ParseStream) -> Result<ExprAsync> {
+ Ok(ExprAsync {
+ attrs: Vec::new(),
+ async_token: input.parse()?,
+ capture: input.parse()?,
+ block: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn fn_arg(input: ParseStream) -> Result<FnArg> {
+ let pat: Pat = input.parse()?;
+
+ if input.peek(Token![:]) {
+ Ok(FnArg::Captured(ArgCaptured {
+ pat: pat,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ }))
+ } else {
+ Ok(FnArg::Inferred(pat))
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_while(input: ParseStream) -> Result<ExprWhile> {
+ let label: Option<Label> = input.parse()?;
+ let while_token: Token![while] = input.parse()?;
+ let cond = expr_no_struct(input)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprWhile {
+ attrs: inner_attrs,
+ label: label,
+ while_token: while_token,
+ cond: Box::new(cond),
+ body: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_while_let(input: ParseStream) -> Result<ExprWhileLet> {
+ let label: Option<Label> = input.parse()?;
+ let while_token: Token![while] = input.parse()?;
+ let let_token: Token![let] = input.parse()?;
+
+ let mut pats = Punctuated::new();
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
+ let punct = input.parse()?;
+ pats.push_punct(punct);
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ }
+
+ let eq_token: Token![=] = input.parse()?;
+ let expr = expr_no_struct(input)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprWhileLet {
+ attrs: inner_attrs,
+ label: label,
+ while_token: while_token,
+ let_token: let_token,
+ pats: pats,
+ eq_token: eq_token,
+ expr: Box::new(expr),
+ body: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ impl Parse for Label {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Label {
+ name: input.parse()?,
+ colon_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ impl Parse for Option<Label> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
+ Ok(ExprContinue {
+ attrs: Vec::new(),
+ continue_token: input.parse()?,
+ label: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
+ Ok(ExprBreak {
+ attrs: Vec::new(),
+ break_token: input.parse()?,
+ label: input.parse()?,
+ expr: {
+ if input.is_empty()
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || !allow_struct.0 && input.peek(token::Brace)
+ {
+ None
+ } else {
+ let expr = ambiguous_expr(input, allow_struct)?;
+ Some(Box::new(expr))
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
+ Ok(ExprReturn {
+ attrs: Vec::new(),
+ return_token: input.parse()?,
+ expr: {
+ if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
+ None
+ } else {
+ // NOTE: return is greedy and eats blocks after it even when in a
+ // position where structs are not allowed, such as in if statement
+ // conditions. For example:
+ //
+ // if return { println!("A") } {} // Prints "A"
+ let expr = ambiguous_expr(input, allow_struct)?;
+ Some(Box::new(expr))
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_struct_helper(
+ input: ParseStream,
+ outer_attrs: Vec<Attribute>,
+ path: Path,
+ ) -> Result<ExprStruct> {
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+
+ let mut fields = Punctuated::new();
+ loop {
+ let attrs = content.call(Attribute::parse_outer)?;
+ if content.fork().parse::<Member>().is_err() {
+ if attrs.is_empty() {
+ break;
+ } else {
+ return Err(content.error("expected struct field"));
+ }
+ }
+
+ let member: Member = content.parse()?;
+ let (colon_token, value) = if content.peek(Token![:]) || !member.is_named() {
+ let colon_token: Token![:] = content.parse()?;
+ let value: Expr = content.parse()?;
+ (Some(colon_token), value)
+ } else if let Member::Named(ref ident) = member {
+ let value = Expr::Path(ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ path: Path::from(ident.clone()),
+ });
+ (None, value)
+ } else {
+ unreachable!()
+ };
+
+ fields.push(FieldValue {
+ attrs: attrs,
+ member: member,
+ colon_token: colon_token,
+ expr: value,
+ });
+
+ if !content.peek(Token![,]) {
+ break;
+ }
+ let punct: Token![,] = content.parse()?;
+ fields.push_punct(punct);
+ }
+
+ let (dot2_token, rest) = if fields.empty_or_trailing() && content.peek(Token![..]) {
+ let dot2_token: Token![..] = content.parse()?;
+ let rest: Expr = content.parse()?;
+ (Some(dot2_token), Some(Box::new(rest)))
+ } else {
+ (None, None)
+ };
+
+ Ok(ExprStruct {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ brace_token: brace_token,
+ path: path,
+ fields: fields,
+ dot2_token: dot2_token,
+ rest: rest,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
+ let unsafe_token: Token![unsafe] = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprUnsafe {
+ attrs: inner_attrs,
+ unsafe_token: unsafe_token,
+ block: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
+ let label: Option<Label> = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprBlock {
+ attrs: inner_attrs,
+ label: label,
+ block: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
+ Ok(ExprRange {
attrs: Vec::new(),
from: None,
- to: hi.map(Box::new),
- limits: limits,
- }.into())
- ));
-
- #[cfg(feature = "full")]
- impl Synom for RangeLimits {
- named!(parse -> Self, alt!(
- // Must come before Dot2
- punct!(..=) => { RangeLimits::Closed }
- |
- // Must come before Dot2
- punct!(...) => { |dot3| RangeLimits::Closed(Token) }
- |
- punct!(..) => { RangeLimits::HalfOpen }
- ));
-
- fn description() -> Option<&'static str> {
- Some("range limit: `..`, `...` or `..=`")
- }
- }
-
- impl Synom for ExprPath {
- #[cfg(not(feature = "full"))]
- named!(parse -> Self, do_parse!(
- pair: qpath >>
- (ExprPath {
- attrs: Vec::new(),
- qself: pair.0,
- path: pair.1,
- })
- ));
-
- #[cfg(feature = "full")]
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- pair: qpath >>
- (ExprPath {
- attrs: attrs,
- qself: pair.0,
- path: pair.1,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("path: `a::b::c`")
- }
- }
-
- named!(path -> Path, do_parse!(
- colon: option!(punct!(::)) >>
- segments: call!(Punctuated::<_, Token![::]>::parse_separated_nonempty_with, path_segment) >>
- cond_reduce!(segments.first().map_or(true, |seg| seg.value().ident != "dyn")) >>
- (Path {
- leading_colon: colon,
- segments: segments,
+ limits: input.parse()?,
+ to: {
+ if input.is_empty()
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || !allow_struct.0 && input.peek(token::Brace)
+ {
+ None
+ } else {
+ let to = ambiguous_expr(input, allow_struct)?;
+ Some(Box::new(to))
+ }
+ },
})
- ));
-
- named!(path_segment -> PathSegment, alt!(
- do_parse!(
- ident: syn!(Ident) >>
- colon2: punct!(::) >>
- lt: punct!(<) >>
- args: call!(Punctuated::parse_terminated) >>
- gt: punct!(>) >>
- (PathSegment {
- ident: ident,
- arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
- colon2_token: Some(colon2),
- lt_token: lt,
- args: args,
- gt_token: gt,
- }),
- })
- )
- |
- mod_style_path_segment
- ));
-
- named!(qpath -> (Option<QSelf>, Path), alt!(
- map!(path, |p| (None, p))
- |
- do_parse!(
- lt: punct!(<) >>
- this: syn!(Type) >>
- path: option!(tuple!(keyword!(as), syn!(Path))) >>
- gt: punct!(>) >>
- colon2: punct!(::) >>
- rest: call!(Punctuated::parse_separated_nonempty_with, path_segment) >>
- ({
- let (pos, as_, path) = match path {
- Some((as_, mut path)) => {
- let pos = path.segments.len();
- path.segments.push_punct(colon2);
- path.segments.extend(rest.into_pairs());
- (pos, Some(as_), path)
- }
- None => {
- (0, None, Path {
- leading_colon: Some(colon2),
- segments: rest,
- })
- }
- };
- (Some(QSelf {
- lt_token: lt,
- ty: Box::new(this),
- position: pos,
- as_token: as_,
- gt_token: gt,
- }), path)
- })
- )
- |
- map!(keyword!(self), |s| (None, s.into()))
- ));
-
- named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
-
- named!(and_index -> (token::Bracket, Expr), brackets!(syn!(Expr)));
+ }
#[cfg(feature = "full")]
- impl Synom for Block {
- named!(parse -> Self, do_parse!(
- stmts: braces!(Block::parse_within) >>
- (Block {
- brace_token: stmts.0,
- stmts: stmts.1,
- })
- ));
+ impl Parse for RangeLimits {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![..=]) {
+ input.parse().map(RangeLimits::Closed)
+ } else if lookahead.peek(Token![...]) {
+ let dot3: Token![...] = input.parse()?;
+ Ok(RangeLimits::Closed(Token))
+ } else if lookahead.peek(Token![..]) {
+ input.parse().map(RangeLimits::HalfOpen)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("block: `{ .. }`")
+ impl Parse for ExprPath {
+ fn parse(input: ParseStream) -> Result<Self> {
+ #[cfg(not(feature = "full"))]
+ let attrs = Vec::new();
+ #[cfg(feature = "full")]
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let (qself, path) = path::parsing::qpath(input, true)?;
+
+ Ok(ExprPath {
+ attrs: attrs,
+ qself: qself,
+ path: path,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ impl Parse for Block {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(Block {
+ brace_token: braced!(content in input),
+ stmts: content.call(Block::parse_within)?,
+ })
}
}
#[cfg(feature = "full")]
impl Block {
- named!(pub parse_within -> Vec<Stmt>, do_parse!(
- many0!(punct!(;)) >>
- mut standalone: many0!(do_parse!(
- stmt: syn!(Stmt) >>
- many0!(punct!(;)) >>
- (stmt)
- )) >>
- last: option!(do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- mut e: syn!(Expr) >>
- ({
- e.replace_attrs(attrs);
- Stmt::Expr(e)
- })
- )) >>
- (match last {
- None => standalone,
- Some(last) => {
- standalone.push(last);
- standalone
+ /// Parse the body of a block as zero or more statements, possibly
+ /// including one trailing expression.
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{braced, token, Attribute, Block, Ident, Stmt, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // Parse a function with no generics or parameter list.
+ /// struct MiniFunction {
+ /// attrs: Vec<Attribute>,
+ /// fn_token: Token![fn],
+ /// name: Ident,
+ /// brace_token: token::Brace,
+ /// stmts: Vec<Stmt>,
+ /// }
+ ///
+ /// impl Parse for MiniFunction {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let outer_attrs = input.call(Attribute::parse_outer)?;
+ /// let fn_token: Token![fn] = input.parse()?;
+ /// let name: Ident = input.parse()?;
+ ///
+ /// let content;
+ /// let brace_token = braced!(content in input);
+ /// let inner_attrs = content.call(Attribute::parse_inner)?;
+ /// let stmts = content.call(Block::parse_within)?;
+ ///
+ /// Ok(MiniFunction {
+ /// attrs: {
+ /// let mut attrs = outer_attrs;
+ /// attrs.extend(inner_attrs);
+ /// attrs
+ /// },
+ /// fn_token: fn_token,
+ /// name: name,
+ /// brace_token: brace_token,
+ /// stmts: stmts,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn parse_within(input: ParseStream) -> Result<Vec<Stmt>> {
+ let mut stmts = Vec::new();
+ loop {
+ while input.peek(Token![;]) {
+ input.parse::<Token![;]>()?;
}
- })
- ));
- }
-
- #[cfg(feature = "full")]
- impl Synom for Stmt {
- named!(parse -> Self, alt!(
- stmt_mac
- |
- stmt_local
- |
- stmt_item
- |
- stmt_blockexpr
- |
- stmt_expr
- ));
-
- fn description() -> Option<&'static str> {
- Some("statement")
- }
- }
-
- #[cfg(feature = "full")]
- named!(stmt_mac -> Stmt, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- what: call!(Path::parse_mod_style) >>
- bang: punct!(!) >>
- // Only parse braces here; paren and bracket will get parsed as
- // expression statements
- data: braces!(syn!(TokenStream)) >>
- semi: option!(punct!(;)) >>
- (Stmt::Item(Item::Macro(ItemMacro {
- attrs: attrs,
- ident: None,
- mac: Macro {
- path: what,
- bang_token: bang,
- delimiter: MacroDelimiter::Brace(data.0),
- tts: data.1,
- },
- semi_token: semi,
- })))
- ));
-
- #[cfg(feature = "full")]
- named!(stmt_local -> Stmt, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- let_: keyword!(let) >>
- pats: call!(Punctuated::parse_separated_nonempty) >>
- ty: option!(tuple!(punct!(:), syn!(Type))) >>
- init: option!(tuple!(punct!(=), syn!(Expr))) >>
- semi: punct!(;) >>
- (Stmt::Local(Local {
- attrs: attrs,
- let_token: let_,
- pats: pats,
- ty: ty.map(|(colon, ty)| (colon, Box::new(ty))),
- init: init.map(|(eq, expr)| (eq, Box::new(expr))),
- semi_token: semi,
- }))
- ));
-
- #[cfg(feature = "full")]
- named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(i)));
-
- #[cfg(feature = "full")]
- named!(stmt_blockexpr -> Stmt, do_parse!(
- mut attrs: many0!(Attribute::parse_outer) >>
- mut e: expr_nosemi >>
- semi: option!(punct!(;)) >>
- ({
- attrs.extend(e.replace_attrs(Vec::new()));
- e.replace_attrs(attrs);
- if let Some(semi) = semi {
- Stmt::Semi(e, semi)
- } else {
- Stmt::Expr(e)
+ if input.is_empty() {
+ break;
+ }
+ let s = parse_stmt(input, true)?;
+ let requires_semicolon = if let Stmt::Expr(ref s) = s {
+ requires_terminator(s)
+ } else {
+ false
+ };
+ stmts.push(s);
+ if input.is_empty() {
+ break;
+ } else if requires_semicolon {
+ return Err(input.error("unexpected token"));
+ }
}
- })
- ));
-
- #[cfg(feature = "full")]
- named!(stmt_expr -> Stmt, do_parse!(
- mut attrs: many0!(Attribute::parse_outer) >>
- mut e: syn!(Expr) >>
- semi: punct!(;) >>
- ({
- attrs.extend(e.replace_attrs(Vec::new()));
- e.replace_attrs(attrs);
- Stmt::Semi(e, semi)
- })
- ));
-
- #[cfg(feature = "full")]
- impl Synom for Pat {
- named!(parse -> Self, alt!(
- syn!(PatWild) => { Pat::Wild } // must be before pat_ident
- |
- syn!(PatBox) => { Pat::Box } // must be before pat_ident
- |
- syn!(PatRange) => { Pat::Range } // must be before pat_lit
- |
- syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
- |
- syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
- |
- syn!(PatMacro) => { Pat::Macro } // must be before pat_ident
- |
- syn!(PatLit) => { Pat::Lit } // must be before pat_ident
- |
- syn!(PatIdent) => { Pat::Ident } // must be before pat_path
- |
- syn!(PatPath) => { Pat::Path }
- |
- syn!(PatTuple) => { Pat::Tuple }
- |
- syn!(PatRef) => { Pat::Ref }
- |
- syn!(PatSlice) => { Pat::Slice }
- ));
-
- fn description() -> Option<&'static str> {
- Some("pattern")
+ Ok(stmts)
}
}
#[cfg(feature = "full")]
- impl Synom for PatWild {
- named!(parse -> Self, map!(
- punct!(_),
- |u| PatWild { underscore_token: u }
- ));
-
- fn description() -> Option<&'static str> {
- Some("wild pattern: `_`")
+ impl Parse for Stmt {
+ fn parse(input: ParseStream) -> Result<Self> {
+ parse_stmt(input, false)
}
}
#[cfg(feature = "full")]
- impl Synom for PatBox {
- named!(parse -> Self, do_parse!(
- boxed: keyword!(box) >>
- pat: syn!(Pat) >>
- (PatBox {
+ fn parse_stmt(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+
+ if {
+ let ahead = ahead.fork();
+ // Only parse braces here; paren and bracket will get parsed as
+ // expression statements
+ ahead.call(Path::parse_mod_style).is_ok()
+ && ahead.parse::<Token![!]>().is_ok()
+ && (ahead.peek(token::Brace) || ahead.peek(Ident))
+ } {
+ stmt_mac(input)
+ } else if ahead.peek(Token![let]) {
+ stmt_local(input).map(Stmt::Local)
+ } else if ahead.peek(Token![pub])
+ || ahead.peek(Token![crate]) && !ahead.peek2(Token![::])
+ || ahead.peek(Token![extern]) && !ahead.peek2(Token![::])
+ || ahead.peek(Token![use])
+ || ahead.peek(Token![static]) && (ahead.peek2(Token![mut]) || ahead.peek2(Ident))
+ || ahead.peek(Token![const])
+ || ahead.peek(Token![unsafe]) && !ahead.peek2(token::Brace)
+ || ahead.peek(Token![async]) && (ahead.peek2(Token![extern]) || ahead.peek2(Token![fn]))
+ || ahead.peek(Token![fn])
+ || ahead.peek(Token![mod])
+ || ahead.peek(Token![type])
+ || ahead.peek(Token![existential]) && ahead.peek2(Token![type])
+ || ahead.peek(Token![struct])
+ || ahead.peek(Token![enum])
+ || ahead.peek(Token![union]) && ahead.peek2(Ident)
+ || ahead.peek(Token![auto]) && ahead.peek2(Token![trait])
+ || ahead.peek(Token![trait])
+ || ahead.peek(Token![default])
+ && (ahead.peek2(Token![unsafe]) || ahead.peek2(Token![impl ]))
+ || ahead.peek(Token![impl ])
+ || ahead.peek(Token![macro])
+ {
+ input.parse().map(Stmt::Item)
+ } else {
+ stmt_expr(input, allow_nosemi)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn stmt_mac(input: ParseStream) -> Result<Stmt> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let path = input.call(Path::parse_mod_style)?;
+ let bang_token: Token![!] = input.parse()?;
+ let ident: Option<Ident> = input.parse()?;
+ let (delimiter, tts) = mac::parse_delimiter(input)?;
+ let semi_token: Option<Token![;]> = input.parse()?;
+
+ Ok(Stmt::Item(Item::Macro(ItemMacro {
+ attrs: attrs,
+ ident: ident,
+ mac: Macro {
+ path: path,
+ bang_token: bang_token,
+ delimiter: delimiter,
+ tts: tts,
+ },
+ semi_token: semi_token,
+ })))
+ }
+
+ #[cfg(feature = "full")]
+ fn stmt_local(input: ParseStream) -> Result<Local> {
+ Ok(Local {
+ attrs: input.call(Attribute::parse_outer)?,
+ let_token: input.parse()?,
+ pats: {
+ let mut pats = Punctuated::new();
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
+ let punct = input.parse()?;
+ pats.push_punct(punct);
+ let value: Pat = input.parse()?;
+ pats.push_value(value);
+ }
+ pats
+ },
+ ty: {
+ if input.peek(Token![:]) {
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ Some((colon_token, Box::new(ty)))
+ } else {
+ None
+ }
+ },
+ init: {
+ if input.peek(Token![=]) {
+ let eq_token: Token![=] = input.parse()?;
+ let init: Expr = input.parse()?;
+ Some((eq_token, Box::new(init)))
+ } else {
+ None
+ }
+ },
+ semi_token: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn stmt_expr(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let mut e = expr_early(input)?;
+
+ attrs.extend(e.replace_attrs(Vec::new()));
+ e.replace_attrs(attrs);
+
+ if input.peek(Token![;]) {
+ return Ok(Stmt::Semi(e, input.parse()?));
+ }
+
+ if allow_nosemi || !requires_terminator(&e) {
+ Ok(Stmt::Expr(e))
+ } else {
+ Err(input.error("expected semicolon"))
+ }
+ }
+
+ #[cfg(feature = "full")]
+ impl Parse for Pat {
+ fn parse(input: ParseStream) -> Result<Self> {
+ // TODO: better error messages
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![_]) {
+ input.call(pat_wild).map(Pat::Wild)
+ } else if lookahead.peek(Token![box]) {
+ input.call(pat_box).map(Pat::Box)
+ } else if input.fork().call(pat_range).is_ok() {
+ // must be before Pat::Lit
+ input.call(pat_range).map(Pat::Range)
+ } else if input.fork().call(pat_tuple_struct).is_ok() {
+ // must be before Pat::Ident
+ input.call(pat_tuple_struct).map(Pat::TupleStruct)
+ } else if input.fork().call(pat_struct).is_ok() {
+ // must be before Pat::Ident
+ input.call(pat_struct).map(Pat::Struct)
+ } else if input.fork().call(pat_macro).is_ok() {
+ // must be before Pat::Ident
+ input.call(pat_macro).map(Pat::Macro)
+ } else if input.fork().call(pat_lit).is_ok() {
+ // must be before Pat::Ident
+ input.call(pat_lit).map(Pat::Lit)
+ } else if input.fork().call(pat_ident).is_ok() {
+ input.call(pat_ident).map(Pat::Ident)
+ } else if input.fork().call(pat_path).is_ok() {
+ input.call(pat_path).map(Pat::Path)
+ } else if lookahead.peek(token::Paren) {
+ input.call(pat_tuple).map(Pat::Tuple)
+ } else if lookahead.peek(Token![&]) {
+ input.call(pat_ref).map(Pat::Ref)
+ } else if lookahead.peek(token::Bracket) {
+ input.call(pat_slice).map(Pat::Slice)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_wild(input: ParseStream) -> Result<PatWild> {
+ Ok(PatWild {
+ underscore_token: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_box(input: ParseStream) -> Result<PatBox> {
+ Ok(PatBox {
+ box_token: input.parse()?,
+ pat: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_ident(input: ParseStream) -> Result<PatIdent> {
+ Ok(PatIdent {
+ by_ref: input.parse()?,
+ mutability: input.parse()?,
+ ident: {
+ let ident = if input.peek(Ident) || input.peek(Token![self]) {
+ input.call(Ident::parse_any)?
+ } else {
+ return Err(input.error("expected identifier or `self`"));
+ };
+ if input.peek(Token![<]) || input.peek(Token![::]) {
+ return Err(input.error("unexpected token"));
+ }
+ ident
+ },
+ subpat: {
+ if input.peek(Token![@]) {
+ let at_token: Token![@] = input.parse()?;
+ let subpat: Pat = input.parse()?;
+ Some((at_token, Box::new(subpat)))
+ } else {
+ None
+ }
+ },
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_tuple_struct(input: ParseStream) -> Result<PatTupleStruct> {
+ Ok(PatTupleStruct {
+ path: input.parse()?,
+ pat: input.call(pat_tuple)?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_struct(input: ParseStream) -> Result<PatStruct> {
+ let path: Path = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+
+ let mut fields = Punctuated::new();
+ while !content.is_empty() && !content.peek(Token![..]) {
+ let value = content.call(field_pat)?;
+ fields.push_value(value);
+ if !content.peek(Token![,]) {
+ break;
+ }
+ let punct: Token![,] = content.parse()?;
+ fields.push_punct(punct);
+ }
+
+ let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
+ Some(content.parse()?)
+ } else {
+ None
+ };
+
+ Ok(PatStruct {
+ path: path,
+ brace_token: brace_token,
+ fields: fields,
+ dot2_token: dot2_token,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn field_pat(input: ParseStream) -> Result<FieldPat> {
+ let boxed: Option<Token![box]> = input.parse()?;
+ let by_ref: Option<Token![ref]> = input.parse()?;
+ let mutability: Option<Token![mut]> = input.parse()?;
+ let member: Member = input.parse()?;
+
+ if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
+ || member.is_unnamed()
+ {
+ return Ok(FieldPat {
+ attrs: Vec::new(),
+ member: member,
+ colon_token: input.parse()?,
+ pat: input.parse()?,
+ });
+ }
+
+ let ident = match member {
+ Member::Named(ident) => ident,
+ Member::Unnamed(_) => unreachable!(),
+ };
+
+ let mut pat = Pat::Ident(PatIdent {
+ by_ref: by_ref,
+ mutability: mutability,
+ ident: ident.clone(),
+ subpat: None,
+ });
+
+ if let Some(boxed) = boxed {
+ pat = Pat::Box(PatBox {
pat: Box::new(pat),
box_token: boxed,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("box pattern")
+ });
}
+
+ Ok(FieldPat {
+ member: Member::Named(ident),
+ pat: Box::new(pat),
+ attrs: Vec::new(),
+ colon_token: None,
+ })
}
- #[cfg(feature = "full")]
- impl Synom for PatIdent {
- named!(parse -> Self, do_parse!(
- by_ref: option!(keyword!(ref)) >>
- mutability: option!(keyword!(mut)) >>
- name: alt!(
- syn!(Ident)
- |
- keyword!(self) => { Into::into }
- ) >>
- not!(punct!(<)) >>
- not!(punct!(::)) >>
- subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
- (PatIdent {
- by_ref: by_ref,
- mutability: mutability,
- ident: name,
- subpat: subpat.map(|(at, pat)| (at, Box::new(pat))),
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("pattern identifier binding")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for PatTupleStruct {
- named!(parse -> Self, do_parse!(
- path: syn!(Path) >>
- tuple: syn!(PatTuple) >>
- (PatTupleStruct {
- path: path,
- pat: tuple,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("tuple struct pattern")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for PatStruct {
- named!(parse -> Self, do_parse!(
- path: syn!(Path) >>
- data: braces!(do_parse!(
- fields: call!(Punctuated::parse_terminated) >>
- base: option!(cond!(fields.empty_or_trailing(), punct!(..))) >>
- (fields, base)
- )) >>
- (PatStruct {
- path: path,
- fields: (data.1).0,
- brace_token: data.0,
- dot2_token: (data.1).1.and_then(|m| m),
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("struct pattern")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for FieldPat {
- named!(parse -> Self, alt!(
- do_parse!(
- member: syn!(Member) >>
- colon: punct!(:) >>
- pat: syn!(Pat) >>
- (FieldPat {
- member: member,
- pat: Box::new(pat),
- attrs: Vec::new(),
- colon_token: Some(colon),
- })
- )
- |
- do_parse!(
- boxed: option!(keyword!(box)) >>
- by_ref: option!(keyword!(ref)) >>
- mutability: option!(keyword!(mut)) >>
- ident: syn!(Ident) >>
- ({
- let mut pat: Pat = PatIdent {
- by_ref: by_ref,
- mutability: mutability,
- ident: ident.clone(),
- subpat: None,
- }.into();
- if let Some(boxed) = boxed {
- pat = PatBox {
- pat: Box::new(pat),
- box_token: boxed,
- }.into();
- }
- FieldPat {
- member: Member::Named(ident),
- pat: Box::new(pat),
- attrs: Vec::new(),
- colon_token: None,
- }
- })
- )
- ));
-
- fn description() -> Option<&'static str> {
- Some("field pattern")
- }
- }
-
- impl Synom for Member {
- named!(parse -> Self, alt!(
- syn!(Ident) => { Member::Named }
- |
- syn!(Index) => { Member::Unnamed }
- ));
-
- fn description() -> Option<&'static str> {
- Some("field member")
- }
- }
-
- impl Synom for Index {
- named!(parse -> Self, do_parse!(
- lit: syn!(LitInt) >>
- ({
- if let IntSuffix::None = lit.suffix() {
- Index { index: lit.value() as u32, span: lit.span() }
- } else {
- return parse_error();
- }
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("field index")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for PatPath {
- named!(parse -> Self, map!(
- syn!(ExprPath),
- |p| PatPath { qself: p.qself, path: p.path }
- ));
-
- fn description() -> Option<&'static str> {
- Some("path pattern")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for PatTuple {
- named!(parse -> Self, do_parse!(
- data: parens!(do_parse!(
- front: call!(Punctuated::parse_terminated) >>
- dotdot: option!(cond_reduce!(front.empty_or_trailing(),
- tuple!(punct!(..), option!(punct!(,)))
- )) >>
- back: cond!(match dotdot {
- Some((_, Some(_))) => true,
- _ => false,
- },
- Punctuated::parse_terminated) >>
- (front, dotdot, back)
- )) >>
- ({
- let (parens, (front, dotdot, back)) = data;
- let (dotdot, trailing) = match dotdot {
- Some((a, b)) => (Some(a), Some(b)),
- None => (None, None),
- };
- PatTuple {
- paren_token: parens,
- front: front,
- dot2_token: dotdot,
- comma_token: trailing.unwrap_or_default(),
- back: back.unwrap_or_default(),
- }
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("tuple pattern")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for PatRef {
- named!(parse -> Self, do_parse!(
- and: punct!(&) >>
- mutability: option!(keyword!(mut)) >>
- pat: syn!(Pat) >>
- (PatRef {
- pat: Box::new(pat),
- mutability: mutability,
- and_token: and,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("reference pattern")
- }
- }
-
- #[cfg(feature = "full")]
- impl Synom for PatLit {
- named!(parse -> Self, do_parse!(
- lit: pat_lit_expr >>
- (if let Expr::Path(_) = lit {
- return parse_error(); // these need to be parsed by pat_path
+ impl Parse for Member {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Ident) {
+ input.parse().map(Member::Named)
+ } else if input.peek(LitInt) {
+ input.parse().map(Member::Unnamed)
} else {
- PatLit {
- expr: Box::new(lit),
- }
- })
- ));
+ Err(input.error("expected identifier or integer"))
+ }
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("literal pattern")
+ impl Parse for Index {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lit: LitInt = input.parse()?;
+ if let IntSuffix::None = lit.suffix() {
+ Ok(Index {
+ index: lit.value() as u32,
+ span: lit.span(),
+ })
+ } else {
+ Err(Error::new(lit.span(), "expected unsuffixed integer"))
+ }
}
}
#[cfg(feature = "full")]
- impl Synom for PatRange {
- named!(parse -> Self, do_parse!(
- lo: pat_lit_expr >>
- limits: syn!(RangeLimits) >>
- hi: pat_lit_expr >>
- (PatRange {
- lo: Box::new(lo),
- hi: Box::new(hi),
- limits: limits,
- })
- ));
+ fn pat_path(input: ParseStream) -> Result<PatPath> {
+ let p: ExprPath = input.parse()?;
+ Ok(PatPath {
+ qself: p.qself,
+ path: p.path,
+ })
+ }
- fn description() -> Option<&'static str> {
- Some("range pattern")
+ #[cfg(feature = "full")]
+ fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
+ let content;
+ let paren_token = parenthesized!(content in input);
+
+ let mut front = Punctuated::new();
+ let mut dot2_token = None::<Token![..]>;
+ let mut comma_token = None::<Token![,]>;
+ loop {
+ if content.is_empty() {
+ break;
+ }
+ if content.peek(Token![..]) {
+ dot2_token = Some(content.parse()?);
+ comma_token = content.parse()?;
+ break;
+ }
+ let value: Pat = content.parse()?;
+ front.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ front.push_punct(punct);
+ }
+
+ let mut back = Punctuated::new();
+ while !content.is_empty() {
+ let value: Pat = content.parse()?;
+ back.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ back.push_punct(punct);
+ }
+
+ Ok(PatTuple {
+ paren_token: paren_token,
+ front: front,
+ dot2_token: dot2_token,
+ comma_token: comma_token,
+ back: back,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_ref(input: ParseStream) -> Result<PatRef> {
+ Ok(PatRef {
+ and_token: input.parse()?,
+ mutability: input.parse()?,
+ pat: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_lit(input: ParseStream) -> Result<PatLit> {
+ if input.peek(Lit) || input.peek(Token![-]) && input.peek2(Lit) {
+ Ok(PatLit {
+ expr: input.call(pat_lit_expr)?,
+ })
+ } else {
+ Err(input.error("expected literal pattern"))
}
}
#[cfg(feature = "full")]
- named!(pat_lit_expr -> Expr, do_parse!(
- neg: option!(punct!(-)) >>
- v: alt!(
- syn!(ExprLit) => { Expr::Lit }
- |
- syn!(ExprPath) => { Expr::Path }
- ) >>
- (if let Some(neg) = neg {
+ fn pat_range(input: ParseStream) -> Result<PatRange> {
+ Ok(PatRange {
+ lo: input.call(pat_lit_expr)?,
+ limits: input.parse()?,
+ hi: input.call(pat_lit_expr)?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_lit_expr(input: ParseStream) -> Result<Box<Expr>> {
+ let neg: Option<Token![-]> = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let expr = if lookahead.peek(Lit) {
+ Expr::Lit(input.call(expr_lit)?)
+ } else if lookahead.peek(Ident)
+ || lookahead.peek(Token![::])
+ || lookahead.peek(Token![<])
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![Self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![crate])
+ {
+ Expr::Path(input.parse()?)
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok(Box::new(if let Some(neg) = neg {
Expr::Unary(ExprUnary {
attrs: Vec::new(),
op: UnOp::Neg(neg),
- expr: Box::new(v)
+ expr: Box::new(expr),
})
} else {
- v
- })
- ));
-
- #[cfg(feature = "full")]
- impl Synom for PatSlice {
- named!(parse -> Self, map!(
- brackets!(do_parse!(
- before: call!(Punctuated::parse_terminated) >>
- middle: option!(do_parse!(
- dots: punct!(..) >>
- trailing: option!(punct!(,)) >>
- (dots, trailing)
- )) >>
- after: cond!(
- match middle {
- Some((_, ref trailing)) => trailing.is_some(),
- _ => false,
- },
- Punctuated::parse_terminated
- ) >>
- (before, middle, after)
- )),
- |(brackets, (before, middle, after))| {
- let mut before: Punctuated<Pat, Token![,]> = before;
- let after: Option<Punctuated<Pat, Token![,]>> = after;
- let middle: Option<(Token![..], Option<Token![,]>)> = middle;
- PatSlice {
- dot2_token: middle.as_ref().map(|m| Token.0)),
- comma_token: middle.as_ref().and_then(|m| {
- m.1.as_ref().map(|m| Token)
- }),
- bracket_token: brackets,
- middle: middle.and_then(|_| {
- if before.empty_or_trailing() {
- None
- } else {
- Some(Box::new(before.pop().unwrap().into_value()))
- }
- }),
- front: before,
- back: after.unwrap_or_default(),
- }
- }
- ));
-
- fn description() -> Option<&'static str> {
- Some("slice pattern")
- }
+ expr
+ }))
}
#[cfg(feature = "full")]
- impl Synom for PatMacro {
- named!(parse -> Self, map!(syn!(Macro), |mac| PatMacro { mac: mac }));
+ fn pat_slice(input: ParseStream) -> Result<PatSlice> {
+ let content;
+ let bracket_token = bracketed!(content in input);
- fn description() -> Option<&'static str> {
- Some("macro pattern")
+ let mut front = Punctuated::new();
+ let mut middle = None;
+ loop {
+ if content.is_empty() || content.peek(Token![..]) {
+ break;
+ }
+ let value: Pat = content.parse()?;
+ if content.peek(Token![..]) {
+ middle = Some(Box::new(value));
+ break;
+ }
+ front.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ front.push_punct(punct);
+ }
+
+ let dot2_token: Option<Token![..]> = content.parse()?;
+ let mut comma_token = None::<Token![,]>;
+ let mut back = Punctuated::new();
+ if dot2_token.is_some() {
+ comma_token = content.parse()?;
+ if comma_token.is_some() {
+ loop {
+ if content.is_empty() {
+ break;
+ }
+ let value: Pat = content.parse()?;
+ back.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ back.push_punct(punct);
+ }
+ }
+ }
+
+ Ok(PatSlice {
+ bracket_token: bracket_token,
+ front: front,
+ middle: middle,
+ dot2_token: dot2_token,
+ comma_token: comma_token,
+ back: back,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn pat_macro(input: ParseStream) -> Result<PatMacro> {
+ Ok(PatMacro {
+ mac: input.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ impl Member {
+ fn is_named(&self) -> bool {
+ match *self {
+ Member::Named(_) => true,
+ Member::Unnamed(_) => false,
+ }
+ }
+
+ fn is_unnamed(&self) -> bool {
+ match *self {
+ Member::Named(_) => false,
+ Member::Unnamed(_) => true,
+ }
}
}
}
@@ -3139,11 +3025,15 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- #[cfg(feature = "full")]
- use attr::FilterAttrs;
+
use proc_macro2::{Literal, TokenStream};
use quote::{ToTokens, TokenStreamExt};
+ #[cfg(feature = "full")]
+ use attr::FilterAttrs;
+ #[cfg(feature = "full")]
+ use print::TokensOrDefault;
+
// If the given expression is a bare `ExprStruct`, wraps it in parenthesis
// before appending it to `TokenStream`.
#[cfg(feature = "full")]
@@ -3424,7 +3314,7 @@
// Ensure that we have a comma after a non-block arm, except
// for the last one.
let is_last = i == self.arms.len() - 1;
- if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
+ if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
<Token![,]>::default().to_tokens(tokens);
}
}
@@ -3433,11 +3323,20 @@
}
#[cfg(feature = "full")]
- impl ToTokens for ExprCatch {
+ impl ToTokens for ExprAsync {
fn to_tokens(&self, tokens: &mut TokenStream) {
outer_attrs_to_tokens(&self.attrs, tokens);
- self.do_token.to_tokens(tokens);
- self.catch_token.to_tokens(tokens);
+ self.async_token.to_tokens(tokens);
+ self.capture.to_tokens(tokens);
+ self.block.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ impl ToTokens for ExprTryBlock {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.try_token.to_tokens(tokens);
self.block.to_tokens(tokens);
}
}
@@ -3455,6 +3354,7 @@
impl ToTokens for ExprClosure {
fn to_tokens(&self, tokens: &mut TokenStream) {
outer_attrs_to_tokens(&self.attrs, tokens);
+ self.asyncness.to_tokens(tokens);
self.movability.to_tokens(tokens);
self.capture.to_tokens(tokens);
self.or1_token.to_tokens(tokens);
@@ -3493,6 +3393,7 @@
impl ToTokens for ExprBlock {
fn to_tokens(&self, tokens: &mut TokenStream) {
outer_attrs_to_tokens(&self.attrs, tokens);
+ self.label.to_tokens(tokens);
self.block.brace_token.surround(tokens, |tokens| {
inner_attrs_to_tokens(&self.attrs, tokens);
tokens.append_all(&self.block.stmts);
@@ -3572,7 +3473,7 @@
impl ToTokens for ExprPath {
fn to_tokens(&self, tokens: &mut TokenStream) {
outer_attrs_to_tokens(&self.attrs, tokens);
- ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
+ private::print_path(tokens, &self.qself, &self.path);
}
}
@@ -3768,7 +3669,7 @@
#[cfg(feature = "full")]
impl ToTokens for PatPath {
fn to_tokens(&self, tokens: &mut TokenStream) {
- ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
+ private::print_path(tokens, &self.qself, &self.path);
}
}
@@ -3824,7 +3725,7 @@
self.lo.to_tokens(tokens);
match self.limits {
RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
- RangeLimits::Closed(ref t) => Token.to_tokens(tokens),
+ RangeLimits::Closed(ref t) => Token.to_tokens(tokens),
}
self.hi.to_tokens(tokens);
}
@@ -3833,8 +3734,6 @@
#[cfg(feature = "full")]
impl ToTokens for PatSlice {
fn to_tokens(&self, tokens: &mut TokenStream) {
- // XXX: This is a mess, and it will be so easy to screw it up. How
- // do we make this correct itself better?
self.bracket_token.surround(tokens, |tokens| {
self.front.to_tokens(tokens);
diff --git a/src/ext.rs b/src/ext.rs
new file mode 100644
index 0000000..0a412e4
--- /dev/null
+++ b/src/ext.rs
@@ -0,0 +1,64 @@
+//! Extension traits to provide parsing methods on foreign types.
+//!
+//! *This module is available if Syn is built with the `"parsing"` feature.*
+
+use proc_macro2::Ident;
+
+use parse::{ParseStream, Result};
+
+/// Additional parsing methods for `Ident`.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+///
+/// *This trait is available if Syn is built with the `"parsing"` feature.*
+pub trait IdentExt: Sized + private::Sealed {
+ /// Parses any identifier including keywords.
+ ///
+ /// This is useful when parsing a DSL which allows Rust keywords as
+ /// identifiers.
+ ///
+ /// ```rust
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Ident, Token};
+ /// use syn::ext::IdentExt;
+ /// use syn::parse::{Error, ParseStream, Result};
+ ///
+ /// // Parses input that looks like `name = NAME` where `NAME` can be
+ /// // any identifier.
+ /// //
+ /// // Examples:
+ /// //
+ /// // name = anything
+ /// // name = impl
+ /// fn parse_dsl(input: ParseStream) -> Result<Ident> {
+ /// let name_token: Ident = input.parse()?;
+ /// if name_token != "name" {
+ /// return Err(Error::new(name_token.span(), "expected `name`"));
+ /// }
+ /// input.parse::<Token![=]>()?;
+ /// let name = input.call(Ident::parse_any)?;
+ /// Ok(name)
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ fn parse_any(input: ParseStream) -> Result<Self>;
+}
+
+impl IdentExt for Ident {
+ fn parse_any(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.ident() {
+ Some((ident, rest)) => Ok((ident, rest)),
+ None => Err(cursor.error("expected ident")),
+ })
+ }
+}
+
+mod private {
+ use proc_macro2::Ident;
+
+ pub trait Sealed {}
+
+ impl Sealed for Ident {}
+}
diff --git a/src/file.rs b/src/file.rs
index 9b5b11f..1f6054a 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -19,8 +19,8 @@
/// representation of the syntax tree.
///
/// ```
- /// extern crate syn;
- ///
+ /// # extern crate syn;
+ /// #
/// use std::env;
/// use std::fs::File;
/// use std::io::Read;
@@ -88,21 +88,21 @@
pub mod parsing {
use super::*;
- use synom::Synom;
+ use parse::{Parse, ParseStream, Result};
- impl Synom for File {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_inner) >>
- items: many0!(Item::parse) >>
- (File {
+ impl Parse for File {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(File {
shebang: None,
- attrs: attrs,
- items: items,
+ attrs: input.call(Attribute::parse_inner)?,
+ items: {
+ let mut items = Vec::new();
+ while !input.is_empty() {
+ items.push(input.parse()?);
+ }
+ items
+ },
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("crate")
}
}
}
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 54eb51a..31d1cf3 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -132,6 +132,11 @@
fn fold_expr_assign_op(&mut self, i: ExprAssignOp) -> ExprAssignOp {
fold_expr_assign_op(self, i)
}
+ #[cfg(feature = "full")]
+ #[cfg(any(feature = "full", feature = "derive"))]
+ fn fold_expr_async(&mut self, i: ExprAsync) -> ExprAsync {
+ fold_expr_async(self, i)
+ }
#[cfg(any(feature = "full", feature = "derive"))]
fn fold_expr_binary(&mut self, i: ExprBinary) -> ExprBinary {
fold_expr_binary(self, i)
@@ -161,11 +166,6 @@
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
- fn fold_expr_catch(&mut self, i: ExprCatch) -> ExprCatch {
- fold_expr_catch(self, i)
- }
- #[cfg(feature = "full")]
- #[cfg(any(feature = "full", feature = "derive"))]
fn fold_expr_closure(&mut self, i: ExprClosure) -> ExprClosure {
fold_expr_closure(self, i)
}
@@ -271,6 +271,11 @@
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
+ fn fold_expr_try_block(&mut self, i: ExprTryBlock) -> ExprTryBlock {
+ fold_expr_try_block(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg(any(feature = "full", feature = "derive"))]
fn fold_expr_tuple(&mut self, i: ExprTuple) -> ExprTuple {
fold_expr_tuple(self, i)
}
@@ -354,6 +359,10 @@
fold_foreign_item_fn(self, i)
}
#[cfg(feature = "full")]
+ fn fold_foreign_item_macro(&mut self, i: ForeignItemMacro) -> ForeignItemMacro {
+ fold_foreign_item_macro(self, i)
+ }
+ #[cfg(feature = "full")]
fn fold_foreign_item_static(&mut self, i: ForeignItemStatic) -> ForeignItemStatic {
fold_foreign_item_static(self, i)
}
@@ -394,6 +403,10 @@
fold_impl_item_const(self, i)
}
#[cfg(feature = "full")]
+ fn fold_impl_item_existential(&mut self, i: ImplItemExistential) -> ImplItemExistential {
+ fold_impl_item_existential(self, i)
+ }
+ #[cfg(feature = "full")]
fn fold_impl_item_macro(&mut self, i: ImplItemMacro) -> ImplItemMacro {
fold_impl_item_macro(self, i)
}
@@ -426,6 +439,10 @@
fold_item_enum(self, i)
}
#[cfg(feature = "full")]
+ fn fold_item_existential(&mut self, i: ItemExistential) -> ItemExistential {
+ fold_item_existential(self, i)
+ }
+ #[cfg(feature = "full")]
fn fold_item_extern_crate(&mut self, i: ItemExternCrate) -> ItemExternCrate {
fold_item_extern_crate(self, i)
}
@@ -466,6 +483,10 @@
fold_item_trait(self, i)
}
#[cfg(feature = "full")]
+ fn fold_item_trait_alias(&mut self, i: ItemTraitAlias) -> ItemTraitAlias {
+ fold_item_trait_alias(self, i)
+ }
+ #[cfg(feature = "full")]
fn fold_item_type(&mut self, i: ItemType) -> ItemType {
fold_item_type(self, i)
}
@@ -486,7 +507,6 @@
fn fold_label(&mut self, i: Label) -> Label {
fold_label(self, i)
}
- #[cfg(any(feature = "full", feature = "derive"))]
fn fold_lifetime(&mut self, i: Lifetime) -> Lifetime {
fold_lifetime(self, i)
}
@@ -880,7 +900,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_abi<V: Fold + ?Sized>(_visitor: &mut V, _i: Abi) -> Abi {
Abi {
- extern_token: Token.0)),
+ extern_token: Token),
name: (_i.name).map(|it| _visitor.fold_lit_str(it)),
}
}
@@ -890,34 +910,35 @@
_i: AngleBracketedGenericArguments,
) -> AngleBracketedGenericArguments {
AngleBracketedGenericArguments {
- colon2_token: (_i.colon2_token).map(|it| Token ! [ :: ](tokens_helper(_visitor, &(it).0))),
- lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+ colon2_token: (_i.colon2_token)
+ .map(|it| Token ! [ :: ](tokens_helper(_visitor, &it.spans))),
+ lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
args: FoldHelper::lift(_i.args, |it| _visitor.fold_generic_argument(it)),
- gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+ gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
}
}
#[cfg(feature = "full")]
pub fn fold_arg_captured<V: Fold + ?Sized>(_visitor: &mut V, _i: ArgCaptured) -> ArgCaptured {
ArgCaptured {
pat: _visitor.fold_pat(_i.pat),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: _visitor.fold_type(_i.ty),
}
}
#[cfg(feature = "full")]
pub fn fold_arg_self<V: Fold + ?Sized>(_visitor: &mut V, _i: ArgSelf) -> ArgSelf {
ArgSelf {
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
- self_token: Token.0)),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
+ self_token: Token),
}
}
#[cfg(feature = "full")]
pub fn fold_arg_self_ref<V: Fold + ?Sized>(_visitor: &mut V, _i: ArgSelfRef) -> ArgSelfRef {
ArgSelfRef {
- and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
+ and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
lifetime: (_i.lifetime).map(|it| _visitor.fold_lifetime(it)),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
- self_token: Token.0)),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
+ self_token: Token),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -925,17 +946,17 @@
pub fn fold_arm<V: Fold + ?Sized>(_visitor: &mut V, _i: Arm) -> Arm {
Arm {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- leading_vert: (_i.leading_vert).map(|it| Token ! [ | ](tokens_helper(_visitor, &(it).0))),
+ leading_vert: (_i.leading_vert).map(|it| Token ! [ | ](tokens_helper(_visitor, &it.spans))),
pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
guard: (_i.guard).map(|it| {
(
- Token ! [ if ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ if ](tokens_helper(_visitor, &(it).0.span)),
Box::new(_visitor.fold_expr(*(it).1)),
)
}),
- fat_arrow_token: Token ! [ => ](tokens_helper(_visitor, &(_i.fat_arrow_token).0)),
+ fat_arrow_token: Token ! [ => ](tokens_helper(_visitor, &_i.fat_arrow_token.spans)),
body: Box::new(_visitor.fold_expr(*_i.body)),
- comma: (_i.comma).map(|it| Token ! [ , ](tokens_helper(_visitor, &(it).0))),
+ comma: (_i.comma).map(|it| Token ! [ , ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -943,19 +964,18 @@
match _i {
AttrStyle::Outer => AttrStyle::Outer,
AttrStyle::Inner(_binding_0) => {
- AttrStyle::Inner(Token.0)))
+ AttrStyle::Inner(Token))
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_attribute<V: Fold + ?Sized>(_visitor: &mut V, _i: Attribute) -> Attribute {
Attribute {
- pound_token: Token ! [ # ](tokens_helper(_visitor, &(_i.pound_token).0)),
+ pound_token: Token ! [ # ](tokens_helper(_visitor, &_i.pound_token.spans)),
style: _visitor.fold_attr_style(_i.style),
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
path: _visitor.fold_path(_i.path),
tts: _i.tts,
- is_sugared_doc: _i.is_sugared_doc,
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -964,7 +984,7 @@
name: (_i.name).map(|it| {
(
_visitor.fold_bare_fn_arg_name((it).0),
- Token ! [ : ](tokens_helper(_visitor, &((it).1).0)),
+ Token ! [ : ](tokens_helper(_visitor, &(it).1.spans)),
)
}),
ty: _visitor.fold_type(_i.ty),
@@ -978,7 +998,7 @@
match _i {
BareFnArgName::Named(_binding_0) => BareFnArgName::Named(_visitor.fold_ident(_binding_0)),
BareFnArgName::Wild(_binding_0) => {
- BareFnArgName::Wild(Token.0)))
+ BareFnArgName::Wild(Token))
}
}
}
@@ -986,84 +1006,88 @@
pub fn fold_bin_op<V: Fold + ?Sized>(_visitor: &mut V, _i: BinOp) -> BinOp {
match _i {
BinOp::Add(_binding_0) => {
- BinOp::Add(Token ! [ + ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Add(Token ! [ + ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Sub(_binding_0) => {
- BinOp::Sub(Token ! [ - ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Sub(Token ! [ - ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Mul(_binding_0) => {
- BinOp::Mul(Token ! [ * ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Mul(Token ! [ * ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Div(_binding_0) => {
- BinOp::Div(Token ! [ / ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Div(Token ! [ / ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Rem(_binding_0) => {
- BinOp::Rem(Token ! [ % ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Rem(Token ! [ % ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::And(_binding_0) => {
- BinOp::And(Token ! [ && ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::And(Token ! [ && ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Or(_binding_0) => {
- BinOp::Or(Token ! [ || ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Or(Token ! [ || ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::BitXor(_binding_0) => {
- BinOp::BitXor(Token ! [ ^ ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::BitXor(Token ! [ ^ ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::BitAnd(_binding_0) => {
- BinOp::BitAnd(Token ! [ & ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::BitAnd(Token ! [ & ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::BitOr(_binding_0) => {
- BinOp::BitOr(Token ! [ | ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::BitOr(Token ! [ | ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Shl(_binding_0) => {
- BinOp::Shl(Token ! [ << ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Shl(Token ! [ << ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Shr(_binding_0) => {
- BinOp::Shr(Token ! [ >> ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Shr(Token ! [ >> ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Eq(_binding_0) => {
- BinOp::Eq(Token ! [ == ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Eq(Token ! [ == ](tokens_helper(_visitor, &_binding_0.spans)))
}
- BinOp::Lt(_binding_0) => BinOp::Lt(Token ! [ < ](tokens_helper(_visitor, &(_binding_0).0))),
+ BinOp::Lt(_binding_0) => {
+ BinOp::Lt(Token ! [ < ](tokens_helper(_visitor, &_binding_0.spans)))
+ }
BinOp::Le(_binding_0) => {
- BinOp::Le(Token ! [ <= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Le(Token ! [ <= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Ne(_binding_0) => {
- BinOp::Ne(Token ! [ != ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Ne(Token ! [ != ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::Ge(_binding_0) => {
- BinOp::Ge(Token ! [ >= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::Ge(Token ! [ >= ](tokens_helper(_visitor, &_binding_0.spans)))
}
- BinOp::Gt(_binding_0) => BinOp::Gt(Token ! [ > ](tokens_helper(_visitor, &(_binding_0).0))),
+ BinOp::Gt(_binding_0) => {
+ BinOp::Gt(Token ! [ > ](tokens_helper(_visitor, &_binding_0.spans)))
+ }
BinOp::AddEq(_binding_0) => {
- BinOp::AddEq(Token ! [ += ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::AddEq(Token ! [ += ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::SubEq(_binding_0) => {
- BinOp::SubEq(Token ! [ -= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::SubEq(Token ! [ -= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::MulEq(_binding_0) => {
- BinOp::MulEq(Token ! [ *= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::MulEq(Token ! [ *= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::DivEq(_binding_0) => {
- BinOp::DivEq(Token ! [ /= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::DivEq(Token ! [ /= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::RemEq(_binding_0) => {
- BinOp::RemEq(Token ! [ %= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::RemEq(Token ! [ %= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::BitXorEq(_binding_0) => {
- BinOp::BitXorEq(Token ! [ ^= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::BitXorEq(Token ! [ ^= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::BitAndEq(_binding_0) => {
- BinOp::BitAndEq(Token ! [ &= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::BitAndEq(Token ! [ &= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::BitOrEq(_binding_0) => {
- BinOp::BitOrEq(Token ! [ |= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::BitOrEq(Token ! [ |= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::ShlEq(_binding_0) => {
- BinOp::ShlEq(Token ! [ <<= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::ShlEq(Token ! [ <<= ](tokens_helper(_visitor, &_binding_0.spans)))
}
BinOp::ShrEq(_binding_0) => {
- BinOp::ShrEq(Token ! [ >>= ](tokens_helper(_visitor, &(_binding_0).0)))
+ BinOp::ShrEq(Token ! [ >>= ](tokens_helper(_visitor, &_binding_0.spans)))
}
}
}
@@ -1071,7 +1095,7 @@
pub fn fold_binding<V: Fold + ?Sized>(_visitor: &mut V, _i: Binding) -> Binding {
Binding {
ident: _visitor.fold_ident(_i.ident),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
ty: _visitor.fold_type(_i.ty),
}
}
@@ -1079,7 +1103,7 @@
#[cfg(feature = "full")]
pub fn fold_block<V: Fold + ?Sized>(_visitor: &mut V, _i: Block) -> Block {
Block {
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
stmts: FoldHelper::lift(_i.stmts, |it| _visitor.fold_stmt(it)),
}
}
@@ -1089,21 +1113,21 @@
_i: BoundLifetimes,
) -> BoundLifetimes {
BoundLifetimes {
- for_token: Token ! [ for ](tokens_helper(_visitor, &(_i.for_token).0)),
- lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+ for_token: Token ! [ for ](tokens_helper(_visitor, &_i.for_token.span)),
+ lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
lifetimes: FoldHelper::lift(_i.lifetimes, |it| _visitor.fold_lifetime_def(it)),
- gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+ gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_const_param<V: Fold + ?Sized>(_visitor: &mut V, _i: ConstParam) -> ConstParam {
ConstParam {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+ const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
ident: _visitor.fold_ident(_i.ident),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: _visitor.fold_type(_i.ty),
- eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &(it).0))),
+ eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &it.spans))),
default: (_i.default).map(|it| _visitor.fold_expr(it)),
}
}
@@ -1118,23 +1142,23 @@
#[cfg(feature = "derive")]
pub fn fold_data_enum<V: Fold + ?Sized>(_visitor: &mut V, _i: DataEnum) -> DataEnum {
DataEnum {
- enum_token: Token ! [ enum ](tokens_helper(_visitor, &(_i.enum_token).0)),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ enum_token: Token ! [ enum ](tokens_helper(_visitor, &_i.enum_token.span)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
variants: FoldHelper::lift(_i.variants, |it| _visitor.fold_variant(it)),
}
}
#[cfg(feature = "derive")]
pub fn fold_data_struct<V: Fold + ?Sized>(_visitor: &mut V, _i: DataStruct) -> DataStruct {
DataStruct {
- struct_token: Token ! [ struct ](tokens_helper(_visitor, &(_i.struct_token).0)),
+ struct_token: Token ! [ struct ](tokens_helper(_visitor, &_i.struct_token.span)),
fields: _visitor.fold_fields(_i.fields),
- semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "derive")]
pub fn fold_data_union<V: Fold + ?Sized>(_visitor: &mut V, _i: DataUnion) -> DataUnion {
DataUnion {
- union_token: Token.0)),
+ union_token: Token),
fields: _visitor.fold_fields_named(_i.fields),
}
}
@@ -1198,7 +1222,10 @@
Expr::Paren(_binding_0) => Expr::Paren(_visitor.fold_expr_paren(_binding_0)),
Expr::Group(_binding_0) => Expr::Group(full!(_visitor.fold_expr_group(_binding_0))),
Expr::Try(_binding_0) => Expr::Try(full!(_visitor.fold_expr_try(_binding_0))),
- Expr::Catch(_binding_0) => Expr::Catch(full!(_visitor.fold_expr_catch(_binding_0))),
+ Expr::Async(_binding_0) => Expr::Async(full!(_visitor.fold_expr_async(_binding_0))),
+ Expr::TryBlock(_binding_0) => {
+ Expr::TryBlock(full!(_visitor.fold_expr_try_block(_binding_0)))
+ }
Expr::Yield(_binding_0) => Expr::Yield(full!(_visitor.fold_expr_yield(_binding_0))),
Expr::Verbatim(_binding_0) => Expr::Verbatim(_visitor.fold_expr_verbatim(_binding_0)),
}
@@ -1208,7 +1235,7 @@
pub fn fold_expr_array<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprArray) -> ExprArray {
ExprArray {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
elems: FoldHelper::lift(_i.elems, |it| _visitor.fold_expr(it)),
}
}
@@ -1218,7 +1245,7 @@
ExprAssign {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
left: Box::new(_visitor.fold_expr(*_i.left)),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
right: Box::new(_visitor.fold_expr(*_i.right)),
}
}
@@ -1232,6 +1259,16 @@
right: Box::new(_visitor.fold_expr(*_i.right)),
}
}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn fold_expr_async<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprAsync) -> ExprAsync {
+ ExprAsync {
+ attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ async_token: Token),
+ capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &it.span))),
+ block: _visitor.fold_block(_i.block),
+ }
+}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_expr_binary<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBinary) -> ExprBinary {
ExprBinary {
@@ -1246,6 +1283,7 @@
pub fn fold_expr_block<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBlock) -> ExprBlock {
ExprBlock {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ label: (_i.label).map(|it| _visitor.fold_label(it)),
block: _visitor.fold_block(_i.block),
}
}
@@ -1254,7 +1292,7 @@
pub fn fold_expr_box<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBox) -> ExprBox {
ExprBox {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- box_token: Token ! [ box ](tokens_helper(_visitor, &(_i.box_token).0)),
+ box_token: Token ! [ box ](tokens_helper(_visitor, &_i.box_token.span)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
}
}
@@ -1263,7 +1301,7 @@
pub fn fold_expr_break<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprBreak) -> ExprBreak {
ExprBreak {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- break_token: Token.0)),
+ break_token: Token),
label: (_i.label).map(|it| _visitor.fold_lifetime(it)),
expr: (_i.expr).map(|it| Box::new(_visitor.fold_expr(*it))),
}
@@ -1273,7 +1311,7 @@
ExprCall {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
func: Box::new(_visitor.fold_expr(*_i.func)),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
args: FoldHelper::lift(_i.args, |it| _visitor.fold_expr(it)),
}
}
@@ -1282,30 +1320,21 @@
ExprCast {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- as_token: Token ! [ as ](tokens_helper(_visitor, &(_i.as_token).0)),
+ as_token: Token ! [ as ](tokens_helper(_visitor, &_i.as_token.span)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
}
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
-pub fn fold_expr_catch<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprCatch) -> ExprCatch {
- ExprCatch {
- attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- do_token: Token ! [ do ](tokens_helper(_visitor, &(_i.do_token).0)),
- catch_token: Token.0)),
- block: _visitor.fold_block(_i.block),
- }
-}
-#[cfg(feature = "full")]
-#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_expr_closure<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprClosure) -> ExprClosure {
ExprClosure {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- movability: (_i.movability).map(|it| Token ! [ static ](tokens_helper(_visitor, &(it).0))),
- capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &(it).0))),
- or1_token: Token ! [ | ](tokens_helper(_visitor, &(_i.or1_token).0)),
+ asyncness: (_i.asyncness).map(|it| Token)),
+ movability: (_i.movability).map(|it| Token ! [ static ](tokens_helper(_visitor, &it.span))),
+ capture: (_i.capture).map(|it| Token ! [ move ](tokens_helper(_visitor, &it.span))),
+ or1_token: Token ! [ | ](tokens_helper(_visitor, &_i.or1_token.spans)),
inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_fn_arg(it)),
- or2_token: Token ! [ | ](tokens_helper(_visitor, &(_i.or2_token).0)),
+ or2_token: Token ! [ | ](tokens_helper(_visitor, &_i.or2_token.spans)),
output: _visitor.fold_return_type(_i.output),
body: Box::new(_visitor.fold_expr(*_i.body)),
}
@@ -1315,7 +1344,7 @@
pub fn fold_expr_continue<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprContinue) -> ExprContinue {
ExprContinue {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- continue_token: Token.0)),
+ continue_token: Token),
label: (_i.label).map(|it| _visitor.fold_lifetime(it)),
}
}
@@ -1324,7 +1353,7 @@
ExprField {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
base: Box::new(_visitor.fold_expr(*_i.base)),
- dot_token: Token ! [ . ](tokens_helper(_visitor, &(_i.dot_token).0)),
+ dot_token: Token ! [ . ](tokens_helper(_visitor, &_i.dot_token.spans)),
member: _visitor.fold_member(_i.member),
}
}
@@ -1334,9 +1363,9 @@
ExprForLoop {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
label: (_i.label).map(|it| _visitor.fold_label(it)),
- for_token: Token ! [ for ](tokens_helper(_visitor, &(_i.for_token).0)),
+ for_token: Token ! [ for ](tokens_helper(_visitor, &_i.for_token.span)),
pat: Box::new(_visitor.fold_pat(*_i.pat)),
- in_token: Token ! [ in ](tokens_helper(_visitor, &(_i.in_token).0)),
+ in_token: Token ! [ in ](tokens_helper(_visitor, &_i.in_token.span)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
body: _visitor.fold_block(_i.body),
}
@@ -1346,7 +1375,7 @@
pub fn fold_expr_group<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprGroup) -> ExprGroup {
ExprGroup {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- group_token: Group(tokens_helper(_visitor, &(_i.group_token).0)),
+ group_token: Group(tokens_helper(_visitor, &_i.group_token.span)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
}
}
@@ -1355,12 +1384,12 @@
pub fn fold_expr_if<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprIf) -> ExprIf {
ExprIf {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- if_token: Token ! [ if ](tokens_helper(_visitor, &(_i.if_token).0)),
+ if_token: Token ! [ if ](tokens_helper(_visitor, &_i.if_token.span)),
cond: Box::new(_visitor.fold_expr(*_i.cond)),
then_branch: _visitor.fold_block(_i.then_branch),
else_branch: (_i.else_branch).map(|it| {
(
- Token ! [ else ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ else ](tokens_helper(_visitor, &(it).0.span)),
Box::new(_visitor.fold_expr(*(it).1)),
)
}),
@@ -1371,15 +1400,15 @@
pub fn fold_expr_if_let<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprIfLet) -> ExprIfLet {
ExprIfLet {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- if_token: Token ! [ if ](tokens_helper(_visitor, &(_i.if_token).0)),
- let_token: Token ! [ let ](tokens_helper(_visitor, &(_i.let_token).0)),
+ if_token: Token ! [ if ](tokens_helper(_visitor, &_i.if_token.span)),
+ let_token: Token ! [ let ](tokens_helper(_visitor, &_i.let_token.span)),
pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
then_branch: _visitor.fold_block(_i.then_branch),
else_branch: (_i.else_branch).map(|it| {
(
- Token ! [ else ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ else ](tokens_helper(_visitor, &(it).0.span)),
Box::new(_visitor.fold_expr(*(it).1)),
)
}),
@@ -1391,7 +1420,7 @@
ExprInPlace {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
place: Box::new(_visitor.fold_expr(*_i.place)),
- arrow_token: Token ! [ <- ](tokens_helper(_visitor, &(_i.arrow_token).0)),
+ arrow_token: Token ! [ <- ](tokens_helper(_visitor, &_i.arrow_token.spans)),
value: Box::new(_visitor.fold_expr(*_i.value)),
}
}
@@ -1400,7 +1429,7 @@
ExprIndex {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
index: Box::new(_visitor.fold_expr(*_i.index)),
}
}
@@ -1417,7 +1446,7 @@
ExprLoop {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
label: (_i.label).map(|it| _visitor.fold_label(it)),
- loop_token: Token ! [ loop ](tokens_helper(_visitor, &(_i.loop_token).0)),
+ loop_token: Token ! [ loop ](tokens_helper(_visitor, &_i.loop_token.span)),
body: _visitor.fold_block(_i.body),
}
}
@@ -1434,9 +1463,9 @@
pub fn fold_expr_match<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprMatch) -> ExprMatch {
ExprMatch {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- match_token: Token ! [ match ](tokens_helper(_visitor, &(_i.match_token).0)),
+ match_token: Token ! [ match ](tokens_helper(_visitor, &_i.match_token.span)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
arms: FoldHelper::lift(_i.arms, |it| _visitor.fold_arm(it)),
}
}
@@ -1449,10 +1478,10 @@
ExprMethodCall {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
receiver: Box::new(_visitor.fold_expr(*_i.receiver)),
- dot_token: Token ! [ . ](tokens_helper(_visitor, &(_i.dot_token).0)),
+ dot_token: Token ! [ . ](tokens_helper(_visitor, &_i.dot_token.spans)),
method: _visitor.fold_ident(_i.method),
turbofish: (_i.turbofish).map(|it| _visitor.fold_method_turbofish(it)),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
args: FoldHelper::lift(_i.args, |it| _visitor.fold_expr(it)),
}
}
@@ -1460,7 +1489,7 @@
pub fn fold_expr_paren<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprParen) -> ExprParen {
ExprParen {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
}
}
@@ -1487,8 +1516,8 @@
pub fn fold_expr_reference<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprReference) -> ExprReference {
ExprReference {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
}
}
@@ -1497,9 +1526,9 @@
pub fn fold_expr_repeat<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprRepeat) -> ExprRepeat {
ExprRepeat {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
len: Box::new(_visitor.fold_expr(*_i.len)),
}
}
@@ -1508,7 +1537,7 @@
pub fn fold_expr_return<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprReturn) -> ExprReturn {
ExprReturn {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- return_token: Token.0)),
+ return_token: Token),
expr: (_i.expr).map(|it| Box::new(_visitor.fold_expr(*it))),
}
}
@@ -1518,9 +1547,9 @@
ExprStruct {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
path: _visitor.fold_path(_i.path),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
fields: FoldHelper::lift(_i.fields, |it| _visitor.fold_field_value(it)),
- dot2_token: (_i.dot2_token).map(|it| Token.0))),
+ dot2_token: (_i.dot2_token).map(|it| Token)),
rest: (_i.rest).map(|it| Box::new(_visitor.fold_expr(*it))),
}
}
@@ -1530,7 +1559,16 @@
ExprTry {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- question_token: Token ! [ ? ](tokens_helper(_visitor, &(_i.question_token).0)),
+ question_token: Token ! [ ? ](tokens_helper(_visitor, &_i.question_token.spans)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn fold_expr_try_block<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprTryBlock) -> ExprTryBlock {
+ ExprTryBlock {
+ attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ try_token: Token),
+ block: _visitor.fold_block(_i.block),
}
}
#[cfg(feature = "full")]
@@ -1538,7 +1576,7 @@
pub fn fold_expr_tuple<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprTuple) -> ExprTuple {
ExprTuple {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
elems: FoldHelper::lift(_i.elems, |it| _visitor.fold_expr(it)),
}
}
@@ -1548,7 +1586,7 @@
ExprType {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
}
}
@@ -1565,7 +1603,7 @@
pub fn fold_expr_unsafe<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprUnsafe) -> ExprUnsafe {
ExprUnsafe {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- unsafe_token: Token ! [ unsafe ](tokens_helper(_visitor, &(_i.unsafe_token).0)),
+ unsafe_token: Token ! [ unsafe ](tokens_helper(_visitor, &_i.unsafe_token.span)),
block: _visitor.fold_block(_i.block),
}
}
@@ -1579,7 +1617,7 @@
ExprWhile {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
label: (_i.label).map(|it| _visitor.fold_label(it)),
- while_token: Token ! [ while ](tokens_helper(_visitor, &(_i.while_token).0)),
+ while_token: Token ! [ while ](tokens_helper(_visitor, &_i.while_token.span)),
cond: Box::new(_visitor.fold_expr(*_i.cond)),
body: _visitor.fold_block(_i.body),
}
@@ -1590,10 +1628,10 @@
ExprWhileLet {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
label: (_i.label).map(|it| _visitor.fold_label(it)),
- while_token: Token ! [ while ](tokens_helper(_visitor, &(_i.while_token).0)),
- let_token: Token ! [ let ](tokens_helper(_visitor, &(_i.let_token).0)),
+ while_token: Token ! [ while ](tokens_helper(_visitor, &_i.while_token.span)),
+ let_token: Token ! [ let ](tokens_helper(_visitor, &_i.let_token.span)),
pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
body: _visitor.fold_block(_i.body),
}
@@ -1603,7 +1641,7 @@
pub fn fold_expr_yield<V: Fold + ?Sized>(_visitor: &mut V, _i: ExprYield) -> ExprYield {
ExprYield {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- yield_token: Token.0)),
+ yield_token: Token),
expr: (_i.expr).map(|it| Box::new(_visitor.fold_expr(*it))),
}
}
@@ -1613,7 +1651,7 @@
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
ident: (_i.ident).map(|it| _visitor.fold_ident(it)),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
ty: _visitor.fold_type(_i.ty),
}
}
@@ -1623,7 +1661,7 @@
FieldPat {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
member: _visitor.fold_member(_i.member),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
pat: Box::new(_visitor.fold_pat(*_i.pat)),
}
}
@@ -1633,7 +1671,7 @@
FieldValue {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
member: _visitor.fold_member(_i.member),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
expr: _visitor.fold_expr(_i.expr),
}
}
@@ -1648,14 +1686,14 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_fields_named<V: Fold + ?Sized>(_visitor: &mut V, _i: FieldsNamed) -> FieldsNamed {
FieldsNamed {
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
named: FoldHelper::lift(_i.named, |it| _visitor.fold_field(it)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_fields_unnamed<V: Fold + ?Sized>(_visitor: &mut V, _i: FieldsUnnamed) -> FieldsUnnamed {
FieldsUnnamed {
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
unnamed: FoldHelper::lift(_i.unnamed, |it| _visitor.fold_field(it)),
}
}
@@ -1680,11 +1718,11 @@
#[cfg(feature = "full")]
pub fn fold_fn_decl<V: Fold + ?Sized>(_visitor: &mut V, _i: FnDecl) -> FnDecl {
FnDecl {
- fn_token: Token ! [ fn ](tokens_helper(_visitor, &(_i.fn_token).0)),
+ fn_token: Token ! [ fn ](tokens_helper(_visitor, &_i.fn_token.span)),
generics: _visitor.fold_generics(_i.generics),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_fn_arg(it)),
- variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &(it).0))),
+ variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &it.spans))),
output: _visitor.fold_return_type(_i.output),
}
}
@@ -1698,6 +1736,9 @@
ForeignItem::Type(_binding_0) => {
ForeignItem::Type(_visitor.fold_foreign_item_type(_binding_0))
}
+ ForeignItem::Macro(_binding_0) => {
+ ForeignItem::Macro(_visitor.fold_foreign_item_macro(_binding_0))
+ }
ForeignItem::Verbatim(_binding_0) => {
ForeignItem::Verbatim(_visitor.fold_foreign_item_verbatim(_binding_0))
}
@@ -1713,7 +1754,18 @@
vis: _visitor.fold_visibility(_i.vis),
ident: _visitor.fold_ident(_i.ident),
decl: Box::new(_visitor.fold_fn_decl(*_i.decl)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+ }
+}
+#[cfg(feature = "full")]
+pub fn fold_foreign_item_macro<V: Fold + ?Sized>(
+ _visitor: &mut V,
+ _i: ForeignItemMacro,
+) -> ForeignItemMacro {
+ ForeignItemMacro {
+ attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ mac: _visitor.fold_macro(_i.mac),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -1724,12 +1776,12 @@
ForeignItemStatic {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- static_token: Token ! [ static ](tokens_helper(_visitor, &(_i.static_token).0)),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ static_token: Token ! [ static ](tokens_helper(_visitor, &_i.static_token.span)),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
ident: _visitor.fold_ident(_i.ident),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -1740,9 +1792,9 @@
ForeignItemType {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+ type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
ident: _visitor.fold_ident(_i.ident),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -1800,9 +1852,9 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_generics<V: Fold + ?Sized>(_visitor: &mut V, _i: Generics) -> Generics {
Generics {
- lt_token: (_i.lt_token).map(|it| Token ! [ < ](tokens_helper(_visitor, &(it).0))),
+ lt_token: (_i.lt_token).map(|it| Token ! [ < ](tokens_helper(_visitor, &it.spans))),
params: FoldHelper::lift(_i.params, |it| _visitor.fold_generic_param(it)),
- gt_token: (_i.gt_token).map(|it| Token ! [ > ](tokens_helper(_visitor, &(it).0))),
+ gt_token: (_i.gt_token).map(|it| Token ! [ > ](tokens_helper(_visitor, &it.spans))),
where_clause: (_i.where_clause).map(|it| _visitor.fold_where_clause(it)),
}
}
@@ -1820,6 +1872,9 @@
ImplItem::Method(_visitor.fold_impl_item_method(_binding_0))
}
ImplItem::Type(_binding_0) => ImplItem::Type(_visitor.fold_impl_item_type(_binding_0)),
+ ImplItem::Existential(_binding_0) => {
+ ImplItem::Existential(_visitor.fold_impl_item_existential(_binding_0))
+ }
ImplItem::Macro(_binding_0) => ImplItem::Macro(_visitor.fold_impl_item_macro(_binding_0)),
ImplItem::Verbatim(_binding_0) => {
ImplItem::Verbatim(_visitor.fold_impl_item_verbatim(_binding_0))
@@ -1834,14 +1889,30 @@
ImplItemConst {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- defaultness: (_i.defaultness).map(|it| Token.0))),
- const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+ defaultness: (_i.defaultness).map(|it| Token)),
+ const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
ident: _visitor.fold_ident(_i.ident),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: _visitor.fold_type(_i.ty),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
expr: _visitor.fold_expr(_i.expr),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+ }
+}
+#[cfg(feature = "full")]
+pub fn fold_impl_item_existential<V: Fold + ?Sized>(
+ _visitor: &mut V,
+ _i: ImplItemExistential,
+) -> ImplItemExistential {
+ ImplItemExistential {
+ attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ existential_token: Token),
+ type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+ ident: _visitor.fold_ident(_i.ident),
+ generics: _visitor.fold_generics(_i.generics),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+ bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -1852,7 +1923,7 @@
ImplItemMacro {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
mac: _visitor.fold_macro(_i.mac),
- semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -1863,7 +1934,7 @@
ImplItemMethod {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- defaultness: (_i.defaultness).map(|it| Token.0))),
+ defaultness: (_i.defaultness).map(|it| Token)),
sig: _visitor.fold_method_sig(_i.sig),
block: _visitor.fold_block(_i.block),
}
@@ -1873,13 +1944,13 @@
ImplItemType {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- defaultness: (_i.defaultness).map(|it| Token.0))),
- type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+ defaultness: (_i.defaultness).map(|it| Token)),
+ type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
ty: _visitor.fold_type(_i.ty),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -1911,10 +1982,16 @@
Item::ForeignMod(_visitor.fold_item_foreign_mod(_binding_0))
}
Item::Type(_binding_0) => Item::Type(_visitor.fold_item_type(_binding_0)),
+ Item::Existential(_binding_0) => {
+ Item::Existential(_visitor.fold_item_existential(_binding_0))
+ }
Item::Struct(_binding_0) => Item::Struct(_visitor.fold_item_struct(_binding_0)),
Item::Enum(_binding_0) => Item::Enum(_visitor.fold_item_enum(_binding_0)),
Item::Union(_binding_0) => Item::Union(_visitor.fold_item_union(_binding_0)),
Item::Trait(_binding_0) => Item::Trait(_visitor.fold_item_trait(_binding_0)),
+ Item::TraitAlias(_binding_0) => {
+ Item::TraitAlias(_visitor.fold_item_trait_alias(_binding_0))
+ }
Item::Impl(_binding_0) => Item::Impl(_visitor.fold_item_impl(_binding_0)),
Item::Macro(_binding_0) => Item::Macro(_visitor.fold_item_macro(_binding_0)),
Item::Macro2(_binding_0) => Item::Macro2(_visitor.fold_item_macro2(_binding_0)),
@@ -1926,13 +2003,13 @@
ItemConst {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+ const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
ident: _visitor.fold_ident(_i.ident),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -1940,14 +2017,31 @@
ItemEnum {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- enum_token: Token ! [ enum ](tokens_helper(_visitor, &(_i.enum_token).0)),
+ enum_token: Token ! [ enum ](tokens_helper(_visitor, &_i.enum_token.span)),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
variants: FoldHelper::lift(_i.variants, |it| _visitor.fold_variant(it)),
}
}
#[cfg(feature = "full")]
+pub fn fold_item_existential<V: Fold + ?Sized>(
+ _visitor: &mut V,
+ _i: ItemExistential,
+) -> ItemExistential {
+ ItemExistential {
+ attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ vis: _visitor.fold_visibility(_i.vis),
+ existential_token: Token),
+ type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
+ ident: _visitor.fold_ident(_i.ident),
+ generics: _visitor.fold_generics(_i.generics),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
+ bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+ }
+}
+#[cfg(feature = "full")]
pub fn fold_item_extern_crate<V: Fold + ?Sized>(
_visitor: &mut V,
_i: ItemExternCrate,
@@ -1955,16 +2049,16 @@
ItemExternCrate {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- extern_token: Token.0)),
- crate_token: Token.0)),
+ extern_token: Token),
+ crate_token: Token),
ident: _visitor.fold_ident(_i.ident),
rename: (_i.rename).map(|it| {
(
- Token ! [ as ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ as ](tokens_helper(_visitor, &(it).0.span)),
_visitor.fold_ident((it).1),
)
}),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -1972,8 +2066,9 @@
ItemFn {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &(it).0))),
- unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
+ constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &it.span))),
+ unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+ asyncness: (_i.asyncness).map(|it| Token)),
abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
ident: _visitor.fold_ident(_i.ident),
decl: Box::new(_visitor.fold_fn_decl(*_i.decl)),
@@ -1988,7 +2083,7 @@
ItemForeignMod {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
abi: _visitor.fold_abi(_i.abi),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
items: FoldHelper::lift(_i.items, |it| _visitor.fold_foreign_item(it)),
}
}
@@ -1996,19 +2091,19 @@
pub fn fold_item_impl<V: Fold + ?Sized>(_visitor: &mut V, _i: ItemImpl) -> ItemImpl {
ItemImpl {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- defaultness: (_i.defaultness).map(|it| Token.0))),
- unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
- impl_token: Token.0)),
+ defaultness: (_i.defaultness).map(|it| Token)),
+ unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+ impl_token: Token),
generics: _visitor.fold_generics(_i.generics),
trait_: (_i.trait_).map(|it| {
(
- ((it).0).map(|it| Token.0))),
+ ((it).0).map(|it| Token)),
_visitor.fold_path((it).1),
- Token ! [ for ](tokens_helper(_visitor, &((it).2).0)),
+ Token ! [ for ](tokens_helper(_visitor, &(it).2.span)),
)
}),
self_ty: Box::new(_visitor.fold_type(*_i.self_ty)),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
items: FoldHelper::lift(_i.items, |it| _visitor.fold_impl_item(it)),
}
}
@@ -2018,7 +2113,7 @@
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
ident: (_i.ident).map(|it| _visitor.fold_ident(it)),
mac: _visitor.fold_macro(_i.mac),
- semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -2026,11 +2121,11 @@
ItemMacro2 {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- macro_token: Token ! [ macro ](tokens_helper(_visitor, &(_i.macro_token).0)),
+ macro_token: Token ! [ macro ](tokens_helper(_visitor, &_i.macro_token.span)),
ident: _visitor.fold_ident(_i.ident),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
args: _i.args,
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
body: _i.body,
}
}
@@ -2039,15 +2134,15 @@
ItemMod {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- mod_token: Token ! [ mod ](tokens_helper(_visitor, &(_i.mod_token).0)),
+ mod_token: Token ! [ mod ](tokens_helper(_visitor, &_i.mod_token.span)),
ident: _visitor.fold_ident(_i.ident),
content: (_i.content).map(|it| {
(
- Brace(tokens_helper(_visitor, &((it).0).0)),
+ Brace(tokens_helper(_visitor, &(it).0.span)),
FoldHelper::lift((it).1, |it| _visitor.fold_item(it)),
)
}),
- semi: (_i.semi).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi: (_i.semi).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -2055,14 +2150,14 @@
ItemStatic {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- static_token: Token ! [ static ](tokens_helper(_visitor, &(_i.static_token).0)),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ static_token: Token ! [ static ](tokens_helper(_visitor, &_i.static_token.span)),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
ident: _visitor.fold_ident(_i.ident),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
expr: Box::new(_visitor.fold_expr(*_i.expr)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -2070,11 +2165,11 @@
ItemStruct {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- struct_token: Token ! [ struct ](tokens_helper(_visitor, &(_i.struct_token).0)),
+ struct_token: Token ! [ struct ](tokens_helper(_visitor, &_i.struct_token.span)),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
fields: _visitor.fold_fields(_i.fields),
- semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -2082,28 +2177,44 @@
ItemTrait {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
- auto_token: (_i.auto_token).map(|it| Token.0))),
- trait_token: Token ! [ trait ](tokens_helper(_visitor, &(_i.trait_token).0)),
+ unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+ auto_token: (_i.auto_token).map(|it| Token)),
+ trait_token: Token ! [ trait ](tokens_helper(_visitor, &_i.trait_token.span)),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
supertraits: FoldHelper::lift(_i.supertraits, |it| _visitor.fold_type_param_bound(it)),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
items: FoldHelper::lift(_i.items, |it| _visitor.fold_trait_item(it)),
}
}
#[cfg(feature = "full")]
+pub fn fold_item_trait_alias<V: Fold + ?Sized>(
+ _visitor: &mut V,
+ _i: ItemTraitAlias,
+) -> ItemTraitAlias {
+ ItemTraitAlias {
+ attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
+ vis: _visitor.fold_visibility(_i.vis),
+ trait_token: Token ! [ trait ](tokens_helper(_visitor, &_i.trait_token.span)),
+ ident: _visitor.fold_ident(_i.ident),
+ generics: _visitor.fold_generics(_i.generics),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
+ bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
+ }
+}
+#[cfg(feature = "full")]
pub fn fold_item_type<V: Fold + ?Sized>(_visitor: &mut V, _i: ItemType) -> ItemType {
ItemType {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+ type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -2111,7 +2222,7 @@
ItemUnion {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- union_token: Token.0)),
+ union_token: Token),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
fields: _visitor.fold_fields_named(_i.fields),
@@ -2122,11 +2233,11 @@
ItemUse {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
vis: _visitor.fold_visibility(_i.vis),
- use_token: Token ! [ use ](tokens_helper(_visitor, &(_i.use_token).0)),
+ use_token: Token ! [ use ](tokens_helper(_visitor, &_i.use_token.span)),
leading_colon: (_i.leading_colon)
- .map(|it| Token ! [ :: ](tokens_helper(_visitor, &(it).0))),
+ .map(|it| Token ! [ :: ](tokens_helper(_visitor, &it.spans))),
tree: _visitor.fold_use_tree(_i.tree),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -2138,13 +2249,12 @@
pub fn fold_label<V: Fold + ?Sized>(_visitor: &mut V, _i: Label) -> Label {
Label {
name: _visitor.fold_lifetime(_i.name),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
}
}
-#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_lifetime<V: Fold + ?Sized>(_visitor: &mut V, _i: Lifetime) -> Lifetime {
Lifetime {
- apostrophe: _i.apostrophe,
+ apostrophe: _visitor.fold_span(_i.apostrophe),
ident: _visitor.fold_ident(_i.ident),
}
}
@@ -2153,7 +2263,7 @@
LifetimeDef {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
lifetime: _visitor.fold_lifetime(_i.lifetime),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_lifetime(it)),
}
}
@@ -2186,28 +2296,28 @@
pub fn fold_local<V: Fold + ?Sized>(_visitor: &mut V, _i: Local) -> Local {
Local {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- let_token: Token ! [ let ](tokens_helper(_visitor, &(_i.let_token).0)),
+ let_token: Token ! [ let ](tokens_helper(_visitor, &_i.let_token.span)),
pats: FoldHelper::lift(_i.pats, |it| _visitor.fold_pat(it)),
ty: (_i.ty).map(|it| {
(
- Token ! [ : ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ : ](tokens_helper(_visitor, &(it).0.spans)),
Box::new(_visitor.fold_type(*(it).1)),
)
}),
init: (_i.init).map(|it| {
(
- Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
Box::new(_visitor.fold_expr(*(it).1)),
)
}),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_macro<V: Fold + ?Sized>(_visitor: &mut V, _i: Macro) -> Macro {
Macro {
path: _visitor.fold_path(_i.path),
- bang_token: Token.0)),
+ bang_token: Token),
delimiter: _visitor.fold_macro_delimiter(_i.delimiter),
tts: _i.tts,
}
@@ -2219,13 +2329,13 @@
) -> MacroDelimiter {
match _i {
MacroDelimiter::Paren(_binding_0) => {
- MacroDelimiter::Paren(Paren(tokens_helper(_visitor, &(_binding_0).0)))
+ MacroDelimiter::Paren(Paren(tokens_helper(_visitor, &_binding_0.span)))
}
MacroDelimiter::Brace(_binding_0) => {
- MacroDelimiter::Brace(Brace(tokens_helper(_visitor, &(_binding_0).0)))
+ MacroDelimiter::Brace(Brace(tokens_helper(_visitor, &_binding_0.span)))
}
MacroDelimiter::Bracket(_binding_0) => {
- MacroDelimiter::Bracket(Bracket(tokens_helper(_visitor, &(_binding_0).0)))
+ MacroDelimiter::Bracket(Bracket(tokens_helper(_visitor, &_binding_0.span)))
}
}
}
@@ -2248,7 +2358,7 @@
pub fn fold_meta_list<V: Fold + ?Sized>(_visitor: &mut V, _i: MetaList) -> MetaList {
MetaList {
ident: _visitor.fold_ident(_i.ident),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
nested: FoldHelper::lift(_i.nested, |it| _visitor.fold_nested_meta(it)),
}
}
@@ -2259,15 +2369,16 @@
) -> MetaNameValue {
MetaNameValue {
ident: _visitor.fold_ident(_i.ident),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
lit: _visitor.fold_lit(_i.lit),
}
}
#[cfg(feature = "full")]
pub fn fold_method_sig<V: Fold + ?Sized>(_visitor: &mut V, _i: MethodSig) -> MethodSig {
MethodSig {
- constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &(it).0))),
- unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
+ constness: (_i.constness).map(|it| Token ! [ const ](tokens_helper(_visitor, &it.span))),
+ unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+ asyncness: (_i.asyncness).map(|it| Token)),
abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
ident: _visitor.fold_ident(_i.ident),
decl: _visitor.fold_fn_decl(_i.decl),
@@ -2280,10 +2391,10 @@
_i: MethodTurbofish,
) -> MethodTurbofish {
MethodTurbofish {
- colon2_token: Token ! [ :: ](tokens_helper(_visitor, &(_i.colon2_token).0)),
- lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+ colon2_token: Token ! [ :: ](tokens_helper(_visitor, &_i.colon2_token.spans)),
+ lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
args: FoldHelper::lift(_i.args, |it| _visitor.fold_generic_method_argument(it)),
- gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+ gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2299,7 +2410,7 @@
_i: ParenthesizedGenericArguments,
) -> ParenthesizedGenericArguments {
ParenthesizedGenericArguments {
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_type(it)),
output: _visitor.fold_return_type(_i.output),
}
@@ -2329,7 +2440,7 @@
#[cfg(feature = "full")]
pub fn fold_pat_box<V: Fold + ?Sized>(_visitor: &mut V, _i: PatBox) -> PatBox {
PatBox {
- box_token: Token ! [ box ](tokens_helper(_visitor, &(_i.box_token).0)),
+ box_token: Token ! [ box ](tokens_helper(_visitor, &_i.box_token.span)),
pat: Box::new(_visitor.fold_pat(*_i.pat)),
}
}
@@ -2337,12 +2448,12 @@
#[cfg(feature = "full")]
pub fn fold_pat_ident<V: Fold + ?Sized>(_visitor: &mut V, _i: PatIdent) -> PatIdent {
PatIdent {
- by_ref: (_i.by_ref).map(|it| Token ! [ ref ](tokens_helper(_visitor, &(it).0))),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ by_ref: (_i.by_ref).map(|it| Token ! [ ref ](tokens_helper(_visitor, &it.span))),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
ident: _visitor.fold_ident(_i.ident),
subpat: (_i.subpat).map(|it| {
(
- Token ! [ @ ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ @ ](tokens_helper(_visitor, &(it).0.spans)),
Box::new(_visitor.fold_pat(*(it).1)),
)
}),
@@ -2383,8 +2494,8 @@
#[cfg(feature = "full")]
pub fn fold_pat_ref<V: Fold + ?Sized>(_visitor: &mut V, _i: PatRef) -> PatRef {
PatRef {
- and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
pat: Box::new(_visitor.fold_pat(*_i.pat)),
}
}
@@ -2392,11 +2503,11 @@
#[cfg(feature = "full")]
pub fn fold_pat_slice<V: Fold + ?Sized>(_visitor: &mut V, _i: PatSlice) -> PatSlice {
PatSlice {
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
front: FoldHelper::lift(_i.front, |it| _visitor.fold_pat(it)),
middle: (_i.middle).map(|it| Box::new(_visitor.fold_pat(*it))),
- dot2_token: (_i.dot2_token).map(|it| Token.0))),
- comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &(it).0))),
+ dot2_token: (_i.dot2_token).map(|it| Token)),
+ comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &it.spans))),
back: FoldHelper::lift(_i.back, |it| _visitor.fold_pat(it)),
}
}
@@ -2405,19 +2516,19 @@
pub fn fold_pat_struct<V: Fold + ?Sized>(_visitor: &mut V, _i: PatStruct) -> PatStruct {
PatStruct {
path: _visitor.fold_path(_i.path),
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
fields: FoldHelper::lift(_i.fields, |it| _visitor.fold_field_pat(it)),
- dot2_token: (_i.dot2_token).map(|it| Token.0))),
+ dot2_token: (_i.dot2_token).map(|it| Token)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn fold_pat_tuple<V: Fold + ?Sized>(_visitor: &mut V, _i: PatTuple) -> PatTuple {
PatTuple {
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
front: FoldHelper::lift(_i.front, |it| _visitor.fold_pat(it)),
- dot2_token: (_i.dot2_token).map(|it| Token.0))),
- comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &(it).0))),
+ dot2_token: (_i.dot2_token).map(|it| Token)),
+ comma_token: (_i.comma_token).map(|it| Token ! [ , ](tokens_helper(_visitor, &it.spans))),
back: FoldHelper::lift(_i.back, |it| _visitor.fold_pat(it)),
}
}
@@ -2441,14 +2552,14 @@
#[cfg(feature = "full")]
pub fn fold_pat_wild<V: Fold + ?Sized>(_visitor: &mut V, _i: PatWild) -> PatWild {
PatWild {
- underscore_token: Token.0)),
+ underscore_token: Token),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_path<V: Fold + ?Sized>(_visitor: &mut V, _i: Path) -> Path {
Path {
leading_colon: (_i.leading_colon)
- .map(|it| Token ! [ :: ](tokens_helper(_visitor, &(it).0))),
+ .map(|it| Token ! [ :: ](tokens_helper(_visitor, &it.spans))),
segments: FoldHelper::lift(_i.segments, |it| _visitor.fold_path_segment(it)),
}
}
@@ -2475,7 +2586,7 @@
pub fn fold_predicate_eq<V: Fold + ?Sized>(_visitor: &mut V, _i: PredicateEq) -> PredicateEq {
PredicateEq {
lhs_ty: _visitor.fold_type(_i.lhs_ty),
- eq_token: Token ! [ = ](tokens_helper(_visitor, &(_i.eq_token).0)),
+ eq_token: Token ! [ = ](tokens_helper(_visitor, &_i.eq_token.spans)),
rhs_ty: _visitor.fold_type(_i.rhs_ty),
}
}
@@ -2486,7 +2597,7 @@
) -> PredicateLifetime {
PredicateLifetime {
lifetime: _visitor.fold_lifetime(_i.lifetime),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_lifetime(it)),
}
}
@@ -2495,18 +2606,18 @@
PredicateType {
lifetimes: (_i.lifetimes).map(|it| _visitor.fold_bound_lifetimes(it)),
bounded_ty: _visitor.fold_type(_i.bounded_ty),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_qself<V: Fold + ?Sized>(_visitor: &mut V, _i: QSelf) -> QSelf {
QSelf {
- lt_token: Token ! [ < ](tokens_helper(_visitor, &(_i.lt_token).0)),
+ lt_token: Token ! [ < ](tokens_helper(_visitor, &_i.lt_token.spans)),
ty: Box::new(_visitor.fold_type(*_i.ty)),
position: _i.position,
- as_token: (_i.as_token).map(|it| Token ! [ as ](tokens_helper(_visitor, &(it).0))),
- gt_token: Token ! [ > ](tokens_helper(_visitor, &(_i.gt_token).0)),
+ as_token: (_i.as_token).map(|it| Token ! [ as ](tokens_helper(_visitor, &it.span))),
+ gt_token: Token ! [ > ](tokens_helper(_visitor, &_i.gt_token.spans)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2514,10 +2625,10 @@
pub fn fold_range_limits<V: Fold + ?Sized>(_visitor: &mut V, _i: RangeLimits) -> RangeLimits {
match _i {
RangeLimits::HalfOpen(_binding_0) => {
- RangeLimits::HalfOpen(Token.0)))
+ RangeLimits::HalfOpen(Token))
}
RangeLimits::Closed(_binding_0) => {
- RangeLimits::Closed(Token ! [ ..= ](tokens_helper(_visitor, &(_binding_0).0)))
+ RangeLimits::Closed(Token ! [ ..= ](tokens_helper(_visitor, &_binding_0.spans)))
}
}
}
@@ -2526,7 +2637,7 @@
match _i {
ReturnType::Default => ReturnType::Default,
ReturnType::Type(_binding_0, _binding_1) => ReturnType::Type(
- Token ! [ -> ](tokens_helper(_visitor, &(_binding_0).0)),
+ Token ! [ -> ](tokens_helper(_visitor, &_binding_0.spans)),
Box::new(_visitor.fold_type(*_binding_1)),
),
}
@@ -2543,14 +2654,14 @@
Stmt::Expr(_binding_0) => Stmt::Expr(_visitor.fold_expr(_binding_0)),
Stmt::Semi(_binding_0, _binding_1) => Stmt::Semi(
_visitor.fold_expr(_binding_0),
- Token ! [ ; ](tokens_helper(_visitor, &(_binding_1).0)),
+ Token ! [ ; ](tokens_helper(_visitor, &_binding_1.spans)),
),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_trait_bound<V: Fold + ?Sized>(_visitor: &mut V, _i: TraitBound) -> TraitBound {
TraitBound {
- paren_token: (_i.paren_token).map(|it| Paren(tokens_helper(_visitor, &(it).0))),
+ paren_token: (_i.paren_token).map(|it| Paren(tokens_helper(_visitor, &it.span))),
modifier: _visitor.fold_trait_bound_modifier(_i.modifier),
lifetimes: (_i.lifetimes).map(|it| _visitor.fold_bound_lifetimes(it)),
path: _visitor.fold_path(_i.path),
@@ -2564,7 +2675,7 @@
match _i {
TraitBoundModifier::None => TraitBoundModifier::None,
TraitBoundModifier::Maybe(_binding_0) => {
- TraitBoundModifier::Maybe(Token ! [ ? ](tokens_helper(_visitor, &(_binding_0).0)))
+ TraitBoundModifier::Maybe(Token ! [ ? ](tokens_helper(_visitor, &_binding_0.spans)))
}
}
}
@@ -2593,17 +2704,17 @@
) -> TraitItemConst {
TraitItemConst {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- const_token: Token ! [ const ](tokens_helper(_visitor, &(_i.const_token).0)),
+ const_token: Token ! [ const ](tokens_helper(_visitor, &_i.const_token.span)),
ident: _visitor.fold_ident(_i.ident),
- colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i.colon_token).0)),
+ colon_token: Token ! [ : ](tokens_helper(_visitor, &_i.colon_token.spans)),
ty: _visitor.fold_type(_i.ty),
default: (_i.default).map(|it| {
(
- Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
_visitor.fold_expr((it).1),
)
}),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -2614,7 +2725,7 @@
TraitItemMacro {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
mac: _visitor.fold_macro(_i.mac),
- semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -2626,7 +2737,7 @@
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
sig: _visitor.fold_method_sig(_i.sig),
default: (_i.default).map(|it| _visitor.fold_block(it)),
- semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &(it).0))),
+ semi_token: (_i.semi_token).map(|it| Token ! [ ; ](tokens_helper(_visitor, &it.spans))),
}
}
#[cfg(feature = "full")]
@@ -2636,18 +2747,18 @@
) -> TraitItemType {
TraitItemType {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
- type_token: Token ! [ type ](tokens_helper(_visitor, &(_i.type_token).0)),
+ type_token: Token ! [ type ](tokens_helper(_visitor, &_i.type_token.span)),
ident: _visitor.fold_ident(_i.ident),
generics: _visitor.fold_generics(_i.generics),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
default: (_i.default).map(|it| {
(
- Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
_visitor.fold_type((it).1),
)
}),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
}
}
#[cfg(feature = "full")]
@@ -2682,29 +2793,29 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_array<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeArray) -> TypeArray {
TypeArray {
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
elem: Box::new(_visitor.fold_type(*_i.elem)),
- semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i.semi_token).0)),
+ semi_token: Token ! [ ; ](tokens_helper(_visitor, &_i.semi_token.spans)),
len: _visitor.fold_expr(_i.len),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_bare_fn<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeBareFn) -> TypeBareFn {
TypeBareFn {
- unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &(it).0))),
- abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
- fn_token: Token ! [ fn ](tokens_helper(_visitor, &(_i.fn_token).0)),
lifetimes: (_i.lifetimes).map(|it| _visitor.fold_bound_lifetimes(it)),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ unsafety: (_i.unsafety).map(|it| Token ! [ unsafe ](tokens_helper(_visitor, &it.span))),
+ abi: (_i.abi).map(|it| _visitor.fold_abi(it)),
+ fn_token: Token ! [ fn ](tokens_helper(_visitor, &_i.fn_token.span)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
inputs: FoldHelper::lift(_i.inputs, |it| _visitor.fold_bare_fn_arg(it)),
- variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &(it).0))),
+ variadic: (_i.variadic).map(|it| Token ! [ ... ](tokens_helper(_visitor, &it.spans))),
output: _visitor.fold_return_type(_i.output),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_group<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeGroup) -> TypeGroup {
TypeGroup {
- group_token: Group(tokens_helper(_visitor, &(_i.group_token).0)),
+ group_token: Group(tokens_helper(_visitor, &_i.group_token.span)),
elem: Box::new(_visitor.fold_type(*_i.elem)),
}
}
@@ -2714,14 +2825,14 @@
_i: TypeImplTrait,
) -> TypeImplTrait {
TypeImplTrait {
- impl_token: Token.0)),
+ impl_token: Token),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_infer<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeInfer) -> TypeInfer {
TypeInfer {
- underscore_token: Token.0)),
+ underscore_token: Token),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2733,7 +2844,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_never<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeNever) -> TypeNever {
TypeNever {
- bang_token: Token.0)),
+ bang_token: Token),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2741,9 +2852,9 @@
TypeParam {
attrs: FoldHelper::lift(_i.attrs, |it| _visitor.fold_attribute(it)),
ident: _visitor.fold_ident(_i.ident),
- colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &(it).0))),
+ colon_token: (_i.colon_token).map(|it| Token ! [ : ](tokens_helper(_visitor, &it.spans))),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
- eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &(it).0))),
+ eq_token: (_i.eq_token).map(|it| Token ! [ = ](tokens_helper(_visitor, &it.spans))),
default: (_i.default).map(|it| _visitor.fold_type(it)),
}
}
@@ -2764,7 +2875,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_paren<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeParen) -> TypeParen {
TypeParen {
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
elem: Box::new(_visitor.fold_type(*_i.elem)),
}
}
@@ -2778,25 +2889,26 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_ptr<V: Fold + ?Sized>(_visitor: &mut V, _i: TypePtr) -> TypePtr {
TypePtr {
- star_token: Token ! [ * ](tokens_helper(_visitor, &(_i.star_token).0)),
- const_token: (_i.const_token).map(|it| Token ! [ const ](tokens_helper(_visitor, &(it).0))),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ star_token: Token ! [ * ](tokens_helper(_visitor, &_i.star_token.spans)),
+ const_token: (_i.const_token)
+ .map(|it| Token ! [ const ](tokens_helper(_visitor, &it.span))),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
elem: Box::new(_visitor.fold_type(*_i.elem)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_reference<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeReference) -> TypeReference {
TypeReference {
- and_token: Token ! [ & ](tokens_helper(_visitor, &(_i.and_token).0)),
+ and_token: Token ! [ & ](tokens_helper(_visitor, &_i.and_token.spans)),
lifetime: (_i.lifetime).map(|it| _visitor.fold_lifetime(it)),
- mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &(it).0))),
+ mutability: (_i.mutability).map(|it| Token ! [ mut ](tokens_helper(_visitor, &it.span))),
elem: Box::new(_visitor.fold_type(*_i.elem)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_slice<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeSlice) -> TypeSlice {
TypeSlice {
- bracket_token: Bracket(tokens_helper(_visitor, &(_i.bracket_token).0)),
+ bracket_token: Bracket(tokens_helper(_visitor, &_i.bracket_token.span)),
elem: Box::new(_visitor.fold_type(*_i.elem)),
}
}
@@ -2806,14 +2918,14 @@
_i: TypeTraitObject,
) -> TypeTraitObject {
TypeTraitObject {
- dyn_token: (_i.dyn_token).map(|it| Token.0))),
+ dyn_token: (_i.dyn_token).map(|it| Token)),
bounds: FoldHelper::lift(_i.bounds, |it| _visitor.fold_type_param_bound(it)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_type_tuple<V: Fold + ?Sized>(_visitor: &mut V, _i: TypeTuple) -> TypeTuple {
TypeTuple {
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
elems: FoldHelper::lift(_i.elems, |it| _visitor.fold_type(it)),
}
}
@@ -2825,22 +2937,24 @@
pub fn fold_un_op<V: Fold + ?Sized>(_visitor: &mut V, _i: UnOp) -> UnOp {
match _i {
UnOp::Deref(_binding_0) => {
- UnOp::Deref(Token ! [ * ](tokens_helper(_visitor, &(_binding_0).0)))
+ UnOp::Deref(Token ! [ * ](tokens_helper(_visitor, &_binding_0.spans)))
}
- UnOp::Not(_binding_0) => UnOp::Not(Token.0))),
- UnOp::Neg(_binding_0) => UnOp::Neg(Token ! [ - ](tokens_helper(_visitor, &(_binding_0).0))),
+ UnOp::Not(_binding_0) => UnOp::Not(Token)),
+ UnOp::Neg(_binding_0) => {
+ UnOp::Neg(Token ! [ - ](tokens_helper(_visitor, &_binding_0.spans)))
+ }
}
}
#[cfg(feature = "full")]
pub fn fold_use_glob<V: Fold + ?Sized>(_visitor: &mut V, _i: UseGlob) -> UseGlob {
UseGlob {
- star_token: Token ! [ * ](tokens_helper(_visitor, &(_i.star_token).0)),
+ star_token: Token ! [ * ](tokens_helper(_visitor, &_i.star_token.spans)),
}
}
#[cfg(feature = "full")]
pub fn fold_use_group<V: Fold + ?Sized>(_visitor: &mut V, _i: UseGroup) -> UseGroup {
UseGroup {
- brace_token: Brace(tokens_helper(_visitor, &(_i.brace_token).0)),
+ brace_token: Brace(tokens_helper(_visitor, &_i.brace_token.span)),
items: FoldHelper::lift(_i.items, |it| _visitor.fold_use_tree(it)),
}
}
@@ -2854,7 +2968,7 @@
pub fn fold_use_path<V: Fold + ?Sized>(_visitor: &mut V, _i: UsePath) -> UsePath {
UsePath {
ident: _visitor.fold_ident(_i.ident),
- colon2_token: Token ! [ :: ](tokens_helper(_visitor, &(_i.colon2_token).0)),
+ colon2_token: Token ! [ :: ](tokens_helper(_visitor, &_i.colon2_token.spans)),
tree: Box::new(_visitor.fold_use_tree(*_i.tree)),
}
}
@@ -2862,7 +2976,7 @@
pub fn fold_use_rename<V: Fold + ?Sized>(_visitor: &mut V, _i: UseRename) -> UseRename {
UseRename {
ident: _visitor.fold_ident(_i.ident),
- as_token: Token ! [ as ](tokens_helper(_visitor, &(_i.as_token).0)),
+ as_token: Token ! [ as ](tokens_helper(_visitor, &_i.as_token.span)),
rename: _visitor.fold_ident(_i.rename),
}
}
@@ -2884,7 +2998,7 @@
fields: _visitor.fold_fields(_i.fields),
discriminant: (_i.discriminant).map(|it| {
(
- Token ! [ = ](tokens_helper(_visitor, &((it).0).0)),
+ Token ! [ = ](tokens_helper(_visitor, &(it).0.spans)),
_visitor.fold_expr((it).1),
)
}),
@@ -2893,21 +3007,21 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_vis_crate<V: Fold + ?Sized>(_visitor: &mut V, _i: VisCrate) -> VisCrate {
VisCrate {
- crate_token: Token.0)),
+ crate_token: Token),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_vis_public<V: Fold + ?Sized>(_visitor: &mut V, _i: VisPublic) -> VisPublic {
VisPublic {
- pub_token: Token ! [ pub ](tokens_helper(_visitor, &(_i.pub_token).0)),
+ pub_token: Token ! [ pub ](tokens_helper(_visitor, &_i.pub_token.span)),
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_vis_restricted<V: Fold + ?Sized>(_visitor: &mut V, _i: VisRestricted) -> VisRestricted {
VisRestricted {
- pub_token: Token ! [ pub ](tokens_helper(_visitor, &(_i.pub_token).0)),
- paren_token: Paren(tokens_helper(_visitor, &(_i.paren_token).0)),
- in_token: (_i.in_token).map(|it| Token ! [ in ](tokens_helper(_visitor, &(it).0))),
+ pub_token: Token ! [ pub ](tokens_helper(_visitor, &_i.pub_token.span)),
+ paren_token: Paren(tokens_helper(_visitor, &_i.paren_token.span)),
+ in_token: (_i.in_token).map(|it| Token ! [ in ](tokens_helper(_visitor, &it.span))),
path: Box::new(_visitor.fold_path(*_i.path)),
}
}
@@ -2925,7 +3039,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn fold_where_clause<V: Fold + ?Sized>(_visitor: &mut V, _i: WhereClause) -> WhereClause {
WhereClause {
- where_token: Token ! [ where ](tokens_helper(_visitor, &(_i.where_token).0)),
+ where_token: Token ! [ where ](tokens_helper(_visitor, &_i.where_token.span)),
predicates: FoldHelper::lift(_i.predicates, |it| _visitor.fold_where_predicate(it)),
}
}
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index d501ac6..7ef88fd 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -132,6 +132,11 @@
fn visit_expr_assign_op(&mut self, i: &'ast ExprAssignOp) {
visit_expr_assign_op(self, i)
}
+ #[cfg(feature = "full")]
+ #[cfg(any(feature = "full", feature = "derive"))]
+ fn visit_expr_async(&mut self, i: &'ast ExprAsync) {
+ visit_expr_async(self, i)
+ }
#[cfg(any(feature = "full", feature = "derive"))]
fn visit_expr_binary(&mut self, i: &'ast ExprBinary) {
visit_expr_binary(self, i)
@@ -161,11 +166,6 @@
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
- fn visit_expr_catch(&mut self, i: &'ast ExprCatch) {
- visit_expr_catch(self, i)
- }
- #[cfg(feature = "full")]
- #[cfg(any(feature = "full", feature = "derive"))]
fn visit_expr_closure(&mut self, i: &'ast ExprClosure) {
visit_expr_closure(self, i)
}
@@ -271,6 +271,11 @@
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
+ fn visit_expr_try_block(&mut self, i: &'ast ExprTryBlock) {
+ visit_expr_try_block(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg(any(feature = "full", feature = "derive"))]
fn visit_expr_tuple(&mut self, i: &'ast ExprTuple) {
visit_expr_tuple(self, i)
}
@@ -354,6 +359,10 @@
visit_foreign_item_fn(self, i)
}
#[cfg(feature = "full")]
+ fn visit_foreign_item_macro(&mut self, i: &'ast ForeignItemMacro) {
+ visit_foreign_item_macro(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_foreign_item_static(&mut self, i: &'ast ForeignItemStatic) {
visit_foreign_item_static(self, i)
}
@@ -394,6 +403,10 @@
visit_impl_item_const(self, i)
}
#[cfg(feature = "full")]
+ fn visit_impl_item_existential(&mut self, i: &'ast ImplItemExistential) {
+ visit_impl_item_existential(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_impl_item_macro(&mut self, i: &'ast ImplItemMacro) {
visit_impl_item_macro(self, i)
}
@@ -426,6 +439,10 @@
visit_item_enum(self, i)
}
#[cfg(feature = "full")]
+ fn visit_item_existential(&mut self, i: &'ast ItemExistential) {
+ visit_item_existential(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_item_extern_crate(&mut self, i: &'ast ItemExternCrate) {
visit_item_extern_crate(self, i)
}
@@ -466,6 +483,10 @@
visit_item_trait(self, i)
}
#[cfg(feature = "full")]
+ fn visit_item_trait_alias(&mut self, i: &'ast ItemTraitAlias) {
+ visit_item_trait_alias(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_item_type(&mut self, i: &'ast ItemType) {
visit_item_type(self, i)
}
@@ -486,7 +507,6 @@
fn visit_label(&mut self, i: &'ast Label) {
visit_label(self, i)
}
- #[cfg(any(feature = "full", feature = "derive"))]
fn visit_lifetime(&mut self, i: &'ast Lifetime) {
visit_lifetime(self, i)
}
@@ -854,7 +874,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_abi<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Abi) {
- tokens_helper(_visitor, &(_i.extern_token).0);
+ tokens_helper(_visitor, &_i.extern_token.span);
if let Some(ref it) = _i.name {
_visitor.visit_lit_str(it)
};
@@ -865,38 +885,38 @@
_i: &'ast AngleBracketedGenericArguments,
) {
if let Some(ref it) = _i.colon2_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
- tokens_helper(_visitor, &(_i.lt_token).0);
+ tokens_helper(_visitor, &_i.lt_token.spans);
for el in Punctuated::pairs(&_i.args) {
let it = el.value();
_visitor.visit_generic_argument(it)
}
- tokens_helper(_visitor, &(_i.gt_token).0);
+ tokens_helper(_visitor, &_i.gt_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_arg_captured<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ArgCaptured) {
_visitor.visit_pat(&_i.pat);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&_i.ty);
}
#[cfg(feature = "full")]
pub fn visit_arg_self<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ArgSelf) {
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.self_token).0);
+ tokens_helper(_visitor, &_i.self_token.span);
}
#[cfg(feature = "full")]
pub fn visit_arg_self_ref<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ArgSelfRef) {
- tokens_helper(_visitor, &(_i.and_token).0);
+ tokens_helper(_visitor, &_i.and_token.spans);
if let Some(ref it) = _i.lifetime {
_visitor.visit_lifetime(it)
};
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.self_token).0);
+ tokens_helper(_visitor, &_i.self_token.span);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
@@ -905,20 +925,20 @@
_visitor.visit_attribute(it)
}
if let Some(ref it) = _i.leading_vert {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.pats) {
let it = el.value();
_visitor.visit_pat(it)
}
if let Some(ref it) = _i.guard {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.span);
_visitor.visit_expr(&*(it).1);
};
- tokens_helper(_visitor, &(_i.fat_arrow_token).0);
+ tokens_helper(_visitor, &_i.fat_arrow_token.spans);
_visitor.visit_expr(&*_i.body);
if let Some(ref it) = _i.comma {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -926,24 +946,23 @@
match *_i {
AttrStyle::Outer => {}
AttrStyle::Inner(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_attribute<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Attribute) {
- tokens_helper(_visitor, &(_i.pound_token).0);
+ tokens_helper(_visitor, &_i.pound_token.spans);
_visitor.visit_attr_style(&_i.style);
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
_visitor.visit_path(&_i.path);
skip!(_i.tts);
- skip!(_i.is_sugared_doc);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_bare_fn_arg<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast BareFnArg) {
if let Some(ref it) = _i.name {
_visitor.visit_bare_fn_arg_name(&(it).0);
- tokens_helper(_visitor, &((it).1).0);
+ tokens_helper(_visitor, &(it).1.spans);
};
_visitor.visit_type(&_i.ty);
}
@@ -957,7 +976,7 @@
_visitor.visit_ident(_binding_0);
}
BareFnArgName::Wild(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
}
}
@@ -965,101 +984,101 @@
pub fn visit_bin_op<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast BinOp) {
match *_i {
BinOp::Add(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Sub(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Mul(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Div(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Rem(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::And(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Or(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::BitXor(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::BitAnd(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::BitOr(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Shl(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Shr(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Eq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Lt(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Le(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Ne(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Ge(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::Gt(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::AddEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::SubEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::MulEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::DivEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::RemEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::BitXorEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::BitAndEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::BitOrEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::ShlEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
BinOp::ShrEq(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_binding<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Binding) {
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_type(&_i.ty);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_block<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Block) {
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for it in &_i.stmts {
_visitor.visit_stmt(it)
}
@@ -1069,25 +1088,25 @@
_visitor: &mut V,
_i: &'ast BoundLifetimes,
) {
- tokens_helper(_visitor, &(_i.for_token).0);
- tokens_helper(_visitor, &(_i.lt_token).0);
+ tokens_helper(_visitor, &_i.for_token.span);
+ tokens_helper(_visitor, &_i.lt_token.spans);
for el in Punctuated::pairs(&_i.lifetimes) {
let it = el.value();
_visitor.visit_lifetime_def(it)
}
- tokens_helper(_visitor, &(_i.gt_token).0);
+ tokens_helper(_visitor, &_i.gt_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_const_param<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ConstParam) {
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.const_token).0);
+ tokens_helper(_visitor, &_i.const_token.span);
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&_i.ty);
if let Some(ref it) = _i.eq_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
if let Some(ref it) = _i.default {
_visitor.visit_expr(it)
@@ -1109,8 +1128,8 @@
}
#[cfg(feature = "derive")]
pub fn visit_data_enum<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast DataEnum) {
- tokens_helper(_visitor, &(_i.enum_token).0);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.enum_token.span);
+ tokens_helper(_visitor, &_i.brace_token.span);
for el in Punctuated::pairs(&_i.variants) {
let it = el.value();
_visitor.visit_variant(it)
@@ -1118,15 +1137,15 @@
}
#[cfg(feature = "derive")]
pub fn visit_data_struct<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast DataStruct) {
- tokens_helper(_visitor, &(_i.struct_token).0);
+ tokens_helper(_visitor, &_i.struct_token.span);
_visitor.visit_fields(&_i.fields);
if let Some(ref it) = _i.semi_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "derive")]
pub fn visit_data_union<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast DataUnion) {
- tokens_helper(_visitor, &(_i.union_token).0);
+ tokens_helper(_visitor, &_i.union_token.span);
_visitor.visit_fields_named(&_i.fields);
}
#[cfg(feature = "derive")]
@@ -1253,8 +1272,11 @@
Expr::Try(ref _binding_0) => {
full!(_visitor.visit_expr_try(_binding_0));
}
- Expr::Catch(ref _binding_0) => {
- full!(_visitor.visit_expr_catch(_binding_0));
+ Expr::Async(ref _binding_0) => {
+ full!(_visitor.visit_expr_async(_binding_0));
+ }
+ Expr::TryBlock(ref _binding_0) => {
+ full!(_visitor.visit_expr_try_block(_binding_0));
}
Expr::Yield(ref _binding_0) => {
full!(_visitor.visit_expr_yield(_binding_0));
@@ -1270,7 +1292,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
for el in Punctuated::pairs(&_i.elems) {
let it = el.value();
_visitor.visit_expr(it)
@@ -1283,7 +1305,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.left);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_expr(&*_i.right);
}
#[cfg(feature = "full")]
@@ -1299,6 +1321,18 @@
_visitor.visit_bin_op(&_i.op);
_visitor.visit_expr(&*_i.right);
}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_async<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprAsync) {
+ for it in &_i.attrs {
+ _visitor.visit_attribute(it)
+ }
+ tokens_helper(_visitor, &_i.async_token.span);
+ if let Some(ref it) = _i.capture {
+ tokens_helper(_visitor, &it.span)
+ };
+ _visitor.visit_block(&_i.block);
+}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_expr_binary<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprBinary) {
for it in &_i.attrs {
@@ -1314,6 +1348,9 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
+ if let Some(ref it) = _i.label {
+ _visitor.visit_label(it)
+ };
_visitor.visit_block(&_i.block);
}
#[cfg(feature = "full")]
@@ -1322,7 +1359,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.box_token).0);
+ tokens_helper(_visitor, &_i.box_token.span);
_visitor.visit_expr(&*_i.expr);
}
#[cfg(feature = "full")]
@@ -1331,7 +1368,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.break_token).0);
+ tokens_helper(_visitor, &_i.break_token.span);
if let Some(ref it) = _i.label {
_visitor.visit_lifetime(it)
};
@@ -1345,7 +1382,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.func);
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.args) {
let it = el.value();
_visitor.visit_expr(it)
@@ -1357,37 +1394,30 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.as_token).0);
+ tokens_helper(_visitor, &_i.as_token.span);
_visitor.visit_type(&*_i.ty);
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
-pub fn visit_expr_catch<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprCatch) {
- for it in &_i.attrs {
- _visitor.visit_attribute(it)
- }
- tokens_helper(_visitor, &(_i.do_token).0);
- tokens_helper(_visitor, &(_i.catch_token).0);
- _visitor.visit_block(&_i.block);
-}
-#[cfg(feature = "full")]
-#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_expr_closure<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ExprClosure) {
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
+ if let Some(ref it) = _i.asyncness {
+ tokens_helper(_visitor, &it.span)
+ };
if let Some(ref it) = _i.movability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.capture {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.or1_token).0);
+ tokens_helper(_visitor, &_i.or1_token.spans);
for el in Punctuated::pairs(&_i.inputs) {
let it = el.value();
_visitor.visit_fn_arg(it)
}
- tokens_helper(_visitor, &(_i.or2_token).0);
+ tokens_helper(_visitor, &_i.or2_token.spans);
_visitor.visit_return_type(&_i.output);
_visitor.visit_expr(&*_i.body);
}
@@ -1400,7 +1430,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.continue_token).0);
+ tokens_helper(_visitor, &_i.continue_token.span);
if let Some(ref it) = _i.label {
_visitor.visit_lifetime(it)
};
@@ -1411,7 +1441,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.base);
- tokens_helper(_visitor, &(_i.dot_token).0);
+ tokens_helper(_visitor, &_i.dot_token.spans);
_visitor.visit_member(&_i.member);
}
#[cfg(feature = "full")]
@@ -1423,9 +1453,9 @@
if let Some(ref it) = _i.label {
_visitor.visit_label(it)
};
- tokens_helper(_visitor, &(_i.for_token).0);
+ tokens_helper(_visitor, &_i.for_token.span);
_visitor.visit_pat(&*_i.pat);
- tokens_helper(_visitor, &(_i.in_token).0);
+ tokens_helper(_visitor, &_i.in_token.span);
_visitor.visit_expr(&*_i.expr);
_visitor.visit_block(&_i.body);
}
@@ -1435,7 +1465,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.group_token).0);
+ tokens_helper(_visitor, &_i.group_token.span);
_visitor.visit_expr(&*_i.expr);
}
#[cfg(feature = "full")]
@@ -1444,11 +1474,11 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.if_token).0);
+ tokens_helper(_visitor, &_i.if_token.span);
_visitor.visit_expr(&*_i.cond);
_visitor.visit_block(&_i.then_branch);
if let Some(ref it) = _i.else_branch {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.span);
_visitor.visit_expr(&*(it).1);
};
}
@@ -1458,17 +1488,17 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.if_token).0);
- tokens_helper(_visitor, &(_i.let_token).0);
+ tokens_helper(_visitor, &_i.if_token.span);
+ tokens_helper(_visitor, &_i.let_token.span);
for el in Punctuated::pairs(&_i.pats) {
let it = el.value();
_visitor.visit_pat(it)
}
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_expr(&*_i.expr);
_visitor.visit_block(&_i.then_branch);
if let Some(ref it) = _i.else_branch {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.span);
_visitor.visit_expr(&*(it).1);
};
}
@@ -1479,7 +1509,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.place);
- tokens_helper(_visitor, &(_i.arrow_token).0);
+ tokens_helper(_visitor, &_i.arrow_token.spans);
_visitor.visit_expr(&*_i.value);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1488,7 +1518,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
_visitor.visit_expr(&*_i.index);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1507,7 +1537,7 @@
if let Some(ref it) = _i.label {
_visitor.visit_label(it)
};
- tokens_helper(_visitor, &(_i.loop_token).0);
+ tokens_helper(_visitor, &_i.loop_token.span);
_visitor.visit_block(&_i.body);
}
#[cfg(feature = "full")]
@@ -1524,9 +1554,9 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.match_token).0);
+ tokens_helper(_visitor, &_i.match_token.span);
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for it in &_i.arms {
_visitor.visit_arm(it)
}
@@ -1541,12 +1571,12 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.receiver);
- tokens_helper(_visitor, &(_i.dot_token).0);
+ tokens_helper(_visitor, &_i.dot_token.spans);
_visitor.visit_ident(&_i.method);
if let Some(ref it) = _i.turbofish {
_visitor.visit_method_turbofish(it)
};
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.args) {
let it = el.value();
_visitor.visit_expr(it)
@@ -1557,7 +1587,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
_visitor.visit_expr(&*_i.expr);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1593,9 +1623,9 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.and_token).0);
+ tokens_helper(_visitor, &_i.and_token.spans);
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_expr(&*_i.expr);
}
@@ -1605,9 +1635,9 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
_visitor.visit_expr(&*_i.len);
}
#[cfg(feature = "full")]
@@ -1616,7 +1646,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.return_token).0);
+ tokens_helper(_visitor, &_i.return_token.span);
if let Some(ref it) = _i.expr {
_visitor.visit_expr(&**it)
};
@@ -1628,13 +1658,13 @@
_visitor.visit_attribute(it)
}
_visitor.visit_path(&_i.path);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for el in Punctuated::pairs(&_i.fields) {
let it = el.value();
_visitor.visit_field_value(it)
}
if let Some(ref it) = _i.dot2_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
if let Some(ref it) = _i.rest {
_visitor.visit_expr(&**it)
@@ -1647,7 +1677,19 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.question_token).0);
+ tokens_helper(_visitor, &_i.question_token.spans);
+}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_try_block<'ast, V: Visit<'ast> + ?Sized>(
+ _visitor: &mut V,
+ _i: &'ast ExprTryBlock,
+) {
+ for it in &_i.attrs {
+ _visitor.visit_attribute(it)
+ }
+ tokens_helper(_visitor, &_i.try_token.span);
+ _visitor.visit_block(&_i.block);
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1655,7 +1697,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.elems) {
let it = el.value();
_visitor.visit_expr(it)
@@ -1668,7 +1710,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&*_i.ty);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1685,7 +1727,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.unsafe_token).0);
+ tokens_helper(_visitor, &_i.unsafe_token.span);
_visitor.visit_block(&_i.block);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1704,7 +1746,7 @@
if let Some(ref it) = _i.label {
_visitor.visit_label(it)
};
- tokens_helper(_visitor, &(_i.while_token).0);
+ tokens_helper(_visitor, &_i.while_token.span);
_visitor.visit_expr(&*_i.cond);
_visitor.visit_block(&_i.body);
}
@@ -1720,13 +1762,13 @@
if let Some(ref it) = _i.label {
_visitor.visit_label(it)
};
- tokens_helper(_visitor, &(_i.while_token).0);
- tokens_helper(_visitor, &(_i.let_token).0);
+ tokens_helper(_visitor, &_i.while_token.span);
+ tokens_helper(_visitor, &_i.let_token.span);
for el in Punctuated::pairs(&_i.pats) {
let it = el.value();
_visitor.visit_pat(it)
}
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_expr(&*_i.expr);
_visitor.visit_block(&_i.body);
}
@@ -1736,7 +1778,7 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.yield_token).0);
+ tokens_helper(_visitor, &_i.yield_token.span);
if let Some(ref it) = _i.expr {
_visitor.visit_expr(&**it)
};
@@ -1751,7 +1793,7 @@
_visitor.visit_ident(it)
};
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_type(&_i.ty);
}
@@ -1763,7 +1805,7 @@
}
_visitor.visit_member(&_i.member);
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_pat(&*_i.pat);
}
@@ -1775,7 +1817,7 @@
}
_visitor.visit_member(&_i.member);
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_expr(&_i.expr);
}
@@ -1793,7 +1835,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_fields_named<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast FieldsNamed) {
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for el in Punctuated::pairs(&_i.named) {
let it = el.value();
_visitor.visit_field(it)
@@ -1804,7 +1846,7 @@
_visitor: &mut V,
_i: &'ast FieldsUnnamed,
) {
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.unnamed) {
let it = el.value();
_visitor.visit_field(it)
@@ -1842,15 +1884,15 @@
}
#[cfg(feature = "full")]
pub fn visit_fn_decl<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast FnDecl) {
- tokens_helper(_visitor, &(_i.fn_token).0);
+ tokens_helper(_visitor, &_i.fn_token.span);
_visitor.visit_generics(&_i.generics);
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.inputs) {
let it = el.value();
_visitor.visit_fn_arg(it)
}
if let Some(ref it) = _i.variadic {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_return_type(&_i.output);
}
@@ -1866,6 +1908,9 @@
ForeignItem::Type(ref _binding_0) => {
_visitor.visit_foreign_item_type(_binding_0);
}
+ ForeignItem::Macro(ref _binding_0) => {
+ _visitor.visit_foreign_item_macro(_binding_0);
+ }
ForeignItem::Verbatim(ref _binding_0) => {
_visitor.visit_foreign_item_verbatim(_binding_0);
}
@@ -1882,7 +1927,20 @@
_visitor.visit_visibility(&_i.vis);
_visitor.visit_ident(&_i.ident);
_visitor.visit_fn_decl(&*_i.decl);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_foreign_item_macro<'ast, V: Visit<'ast> + ?Sized>(
+ _visitor: &mut V,
+ _i: &'ast ForeignItemMacro,
+) {
+ for it in &_i.attrs {
+ _visitor.visit_attribute(it)
+ }
+ _visitor.visit_macro(&_i.mac);
+ if let Some(ref it) = _i.semi_token {
+ tokens_helper(_visitor, &it.spans)
+ };
}
#[cfg(feature = "full")]
pub fn visit_foreign_item_static<'ast, V: Visit<'ast> + ?Sized>(
@@ -1893,14 +1951,14 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.static_token).0);
+ tokens_helper(_visitor, &_i.static_token.span);
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&*_i.ty);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_foreign_item_type<'ast, V: Visit<'ast> + ?Sized>(
@@ -1911,9 +1969,9 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.type_token).0);
+ tokens_helper(_visitor, &_i.type_token.span);
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_foreign_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -1977,14 +2035,14 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_generics<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Generics) {
if let Some(ref it) = _i.lt_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.params) {
let it = el.value();
_visitor.visit_generic_param(it)
}
if let Some(ref it) = _i.gt_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
if let Some(ref it) = _i.where_clause {
_visitor.visit_where_clause(it)
@@ -2003,6 +2061,9 @@
ImplItem::Type(ref _binding_0) => {
_visitor.visit_impl_item_type(_binding_0);
}
+ ImplItem::Existential(ref _binding_0) => {
+ _visitor.visit_impl_item_existential(_binding_0);
+ }
ImplItem::Macro(ref _binding_0) => {
_visitor.visit_impl_item_macro(_binding_0);
}
@@ -2021,15 +2082,36 @@
}
_visitor.visit_visibility(&_i.vis);
if let Some(ref it) = _i.defaultness {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.const_token).0);
+ tokens_helper(_visitor, &_i.const_token.span);
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&_i.ty);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_expr(&_i.expr);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_impl_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+ _visitor: &mut V,
+ _i: &'ast ImplItemExistential,
+) {
+ for it in &_i.attrs {
+ _visitor.visit_attribute(it)
+ }
+ tokens_helper(_visitor, &_i.existential_token.span);
+ tokens_helper(_visitor, &_i.type_token.span);
+ _visitor.visit_ident(&_i.ident);
+ _visitor.visit_generics(&_i.generics);
+ if let Some(ref it) = _i.colon_token {
+ tokens_helper(_visitor, &it.spans)
+ };
+ for el in Punctuated::pairs(&_i.bounds) {
+ let it = el.value();
+ _visitor.visit_type_param_bound(it)
+ }
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_impl_item_macro<'ast, V: Visit<'ast> + ?Sized>(
@@ -2041,7 +2123,7 @@
}
_visitor.visit_macro(&_i.mac);
if let Some(ref it) = _i.semi_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "full")]
@@ -2054,7 +2136,7 @@
}
_visitor.visit_visibility(&_i.vis);
if let Some(ref it) = _i.defaultness {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_method_sig(&_i.sig);
_visitor.visit_block(&_i.block);
@@ -2069,14 +2151,14 @@
}
_visitor.visit_visibility(&_i.vis);
if let Some(ref it) = _i.defaultness {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.type_token).0);
+ tokens_helper(_visitor, &_i.type_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_type(&_i.ty);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_impl_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -2117,6 +2199,9 @@
Item::Type(ref _binding_0) => {
_visitor.visit_item_type(_binding_0);
}
+ Item::Existential(ref _binding_0) => {
+ _visitor.visit_item_existential(_binding_0);
+ }
Item::Struct(ref _binding_0) => {
_visitor.visit_item_struct(_binding_0);
}
@@ -2129,6 +2214,9 @@
Item::Trait(ref _binding_0) => {
_visitor.visit_item_trait(_binding_0);
}
+ Item::TraitAlias(ref _binding_0) => {
+ _visitor.visit_item_trait_alias(_binding_0);
+ }
Item::Impl(ref _binding_0) => {
_visitor.visit_item_impl(_binding_0);
}
@@ -2149,13 +2237,13 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.const_token).0);
+ tokens_helper(_visitor, &_i.const_token.span);
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&*_i.ty);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_enum<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemEnum) {
@@ -2163,16 +2251,38 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.enum_token).0);
+ tokens_helper(_visitor, &_i.enum_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for el in Punctuated::pairs(&_i.variants) {
let it = el.value();
_visitor.visit_variant(it)
}
}
#[cfg(feature = "full")]
+pub fn visit_item_existential<'ast, V: Visit<'ast> + ?Sized>(
+ _visitor: &mut V,
+ _i: &'ast ItemExistential,
+) {
+ for it in &_i.attrs {
+ _visitor.visit_attribute(it)
+ }
+ _visitor.visit_visibility(&_i.vis);
+ tokens_helper(_visitor, &_i.existential_token.span);
+ tokens_helper(_visitor, &_i.type_token.span);
+ _visitor.visit_ident(&_i.ident);
+ _visitor.visit_generics(&_i.generics);
+ if let Some(ref it) = _i.colon_token {
+ tokens_helper(_visitor, &it.spans)
+ };
+ for el in Punctuated::pairs(&_i.bounds) {
+ let it = el.value();
+ _visitor.visit_type_param_bound(it)
+ }
+ tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
pub fn visit_item_extern_crate<'ast, V: Visit<'ast> + ?Sized>(
_visitor: &mut V,
_i: &'ast ItemExternCrate,
@@ -2181,14 +2291,14 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.extern_token).0);
- tokens_helper(_visitor, &(_i.crate_token).0);
+ tokens_helper(_visitor, &_i.extern_token.span);
+ tokens_helper(_visitor, &_i.crate_token.span);
_visitor.visit_ident(&_i.ident);
if let Some(ref it) = _i.rename {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.span);
_visitor.visit_ident(&(it).1);
};
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_fn<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemFn) {
@@ -2197,10 +2307,13 @@
}
_visitor.visit_visibility(&_i.vis);
if let Some(ref it) = _i.constness {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.unsafety {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
+ };
+ if let Some(ref it) = _i.asyncness {
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.abi {
_visitor.visit_abi(it)
@@ -2218,7 +2331,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_abi(&_i.abi);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for it in &_i.items {
_visitor.visit_foreign_item(it)
}
@@ -2229,22 +2342,22 @@
_visitor.visit_attribute(it)
}
if let Some(ref it) = _i.defaultness {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.unsafety {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.impl_token).0);
+ tokens_helper(_visitor, &_i.impl_token.span);
_visitor.visit_generics(&_i.generics);
if let Some(ref it) = _i.trait_ {
if let Some(ref it) = (it).0 {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_path(&(it).1);
- tokens_helper(_visitor, &((it).2).0);
+ tokens_helper(_visitor, &(it).2.span);
};
_visitor.visit_type(&*_i.self_ty);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for it in &_i.items {
_visitor.visit_impl_item(it)
}
@@ -2259,7 +2372,7 @@
};
_visitor.visit_macro(&_i.mac);
if let Some(ref it) = _i.semi_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "full")]
@@ -2268,11 +2381,11 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.macro_token).0);
+ tokens_helper(_visitor, &_i.macro_token.span);
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
skip!(_i.args);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
skip!(_i.body);
}
#[cfg(feature = "full")]
@@ -2281,16 +2394,16 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.mod_token).0);
+ tokens_helper(_visitor, &_i.mod_token.span);
_visitor.visit_ident(&_i.ident);
if let Some(ref it) = _i.content {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.span);
for it in &(it).1 {
_visitor.visit_item(it)
}
};
if let Some(ref it) = _i.semi {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "full")]
@@ -2299,16 +2412,16 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.static_token).0);
+ tokens_helper(_visitor, &_i.static_token.span);
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&*_i.ty);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_expr(&*_i.expr);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_struct<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemStruct) {
@@ -2316,12 +2429,12 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.struct_token).0);
+ tokens_helper(_visitor, &_i.struct_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
_visitor.visit_fields(&_i.fields);
if let Some(ref it) = _i.semi_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "full")]
@@ -2331,38 +2444,57 @@
}
_visitor.visit_visibility(&_i.vis);
if let Some(ref it) = _i.unsafety {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.auto_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.trait_token).0);
+ tokens_helper(_visitor, &_i.trait_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.supertraits) {
let it = el.value();
_visitor.visit_type_param_bound(it)
}
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for it in &_i.items {
_visitor.visit_trait_item(it)
}
}
#[cfg(feature = "full")]
+pub fn visit_item_trait_alias<'ast, V: Visit<'ast> + ?Sized>(
+ _visitor: &mut V,
+ _i: &'ast ItemTraitAlias,
+) {
+ for it in &_i.attrs {
+ _visitor.visit_attribute(it)
+ }
+ _visitor.visit_visibility(&_i.vis);
+ tokens_helper(_visitor, &_i.trait_token.span);
+ _visitor.visit_ident(&_i.ident);
+ _visitor.visit_generics(&_i.generics);
+ tokens_helper(_visitor, &_i.eq_token.spans);
+ for el in Punctuated::pairs(&_i.bounds) {
+ let it = el.value();
+ _visitor.visit_type_param_bound(it)
+ }
+ tokens_helper(_visitor, &_i.semi_token.spans);
+}
+#[cfg(feature = "full")]
pub fn visit_item_type<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemType) {
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.type_token).0);
+ tokens_helper(_visitor, &_i.type_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_type(&*_i.ty);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_union<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ItemUnion) {
@@ -2370,7 +2502,7 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.union_token).0);
+ tokens_helper(_visitor, &_i.union_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
_visitor.visit_fields_named(&_i.fields);
@@ -2381,12 +2513,12 @@
_visitor.visit_attribute(it)
}
_visitor.visit_visibility(&_i.vis);
- tokens_helper(_visitor, &(_i.use_token).0);
+ tokens_helper(_visitor, &_i.use_token.span);
if let Some(ref it) = _i.leading_colon {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_use_tree(&_i.tree);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -2399,11 +2531,10 @@
#[cfg(feature = "full")]
pub fn visit_label<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Label) {
_visitor.visit_lifetime(&_i.name);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
}
-#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_lifetime<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Lifetime) {
- skip!(_i.apostrophe);
+ _visitor.visit_span(&_i.apostrophe);
_visitor.visit_ident(&_i.ident);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2413,7 +2544,7 @@
}
_visitor.visit_lifetime(&_i.lifetime);
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
@@ -2488,25 +2619,25 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.let_token).0);
+ tokens_helper(_visitor, &_i.let_token.span);
for el in Punctuated::pairs(&_i.pats) {
let it = el.value();
_visitor.visit_pat(it)
}
if let Some(ref it) = _i.ty {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.spans);
_visitor.visit_type(&*(it).1);
};
if let Some(ref it) = _i.init {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.spans);
_visitor.visit_expr(&*(it).1);
};
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_macro<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Macro) {
_visitor.visit_path(&_i.path);
- tokens_helper(_visitor, &(_i.bang_token).0);
+ tokens_helper(_visitor, &_i.bang_token.spans);
_visitor.visit_macro_delimiter(&_i.delimiter);
skip!(_i.tts);
}
@@ -2517,13 +2648,13 @@
) {
match *_i {
MacroDelimiter::Paren(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.span);
}
MacroDelimiter::Brace(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.span);
}
MacroDelimiter::Bracket(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.span);
}
}
}
@@ -2555,7 +2686,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_meta_list<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast MetaList) {
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.nested) {
let it = el.value();
_visitor.visit_nested_meta(it)
@@ -2567,16 +2698,19 @@
_i: &'ast MetaNameValue,
) {
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_lit(&_i.lit);
}
#[cfg(feature = "full")]
pub fn visit_method_sig<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast MethodSig) {
if let Some(ref it) = _i.constness {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.unsafety {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
+ };
+ if let Some(ref it) = _i.asyncness {
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.abi {
_visitor.visit_abi(it)
@@ -2590,13 +2724,13 @@
_visitor: &mut V,
_i: &'ast MethodTurbofish,
) {
- tokens_helper(_visitor, &(_i.colon2_token).0);
- tokens_helper(_visitor, &(_i.lt_token).0);
+ tokens_helper(_visitor, &_i.colon2_token.spans);
+ tokens_helper(_visitor, &_i.lt_token.spans);
for el in Punctuated::pairs(&_i.args) {
let it = el.value();
_visitor.visit_generic_method_argument(it)
}
- tokens_helper(_visitor, &(_i.gt_token).0);
+ tokens_helper(_visitor, &_i.gt_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_nested_meta<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast NestedMeta) {
@@ -2614,7 +2748,7 @@
_visitor: &mut V,
_i: &'ast ParenthesizedGenericArguments,
) {
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.inputs) {
let it = el.value();
_visitor.visit_type(it)
@@ -2669,21 +2803,21 @@
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_box<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatBox) {
- tokens_helper(_visitor, &(_i.box_token).0);
+ tokens_helper(_visitor, &_i.box_token.span);
_visitor.visit_pat(&*_i.pat);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_ident<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatIdent) {
if let Some(ref it) = _i.by_ref {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_ident(&_i.ident);
if let Some(ref it) = _i.subpat {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.spans);
_visitor.visit_pat(&*(it).1);
};
}
@@ -2715,16 +2849,16 @@
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_ref<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatRef) {
- tokens_helper(_visitor, &(_i.and_token).0);
+ tokens_helper(_visitor, &_i.and_token.spans);
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_pat(&*_i.pat);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_slice<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatSlice) {
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
for el in Punctuated::pairs(&_i.front) {
let it = el.value();
_visitor.visit_pat(it)
@@ -2733,10 +2867,10 @@
_visitor.visit_pat(&**it)
};
if let Some(ref it) = _i.dot2_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
if let Some(ref it) = _i.comma_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.back) {
let it = el.value();
@@ -2747,28 +2881,28 @@
#[cfg(feature = "full")]
pub fn visit_pat_struct<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatStruct) {
_visitor.visit_path(&_i.path);
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for el in Punctuated::pairs(&_i.fields) {
let it = el.value();
_visitor.visit_field_pat(it)
}
if let Some(ref it) = _i.dot2_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_tuple<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatTuple) {
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.front) {
let it = el.value();
_visitor.visit_pat(it)
}
if let Some(ref it) = _i.dot2_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
if let Some(ref it) = _i.comma_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.back) {
let it = el.value();
@@ -2792,12 +2926,12 @@
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_wild<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PatWild) {
- tokens_helper(_visitor, &(_i.underscore_token).0);
+ tokens_helper(_visitor, &_i.underscore_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_path<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Path) {
if let Some(ref it) = _i.leading_colon {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.segments) {
let it = el.value();
@@ -2827,7 +2961,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_predicate_eq<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PredicateEq) {
_visitor.visit_type(&_i.lhs_ty);
- tokens_helper(_visitor, &(_i.eq_token).0);
+ tokens_helper(_visitor, &_i.eq_token.spans);
_visitor.visit_type(&_i.rhs_ty);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2836,9 +2970,7 @@
_i: &'ast PredicateLifetime,
) {
_visitor.visit_lifetime(&_i.lifetime);
- if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
- };
+ tokens_helper(_visitor, &_i.colon_token.spans);
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
_visitor.visit_lifetime(it)
@@ -2853,7 +2985,7 @@
_visitor.visit_bound_lifetimes(it)
};
_visitor.visit_type(&_i.bounded_ty);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
_visitor.visit_type_param_bound(it)
@@ -2861,23 +2993,23 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_qself<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast QSelf) {
- tokens_helper(_visitor, &(_i.lt_token).0);
+ tokens_helper(_visitor, &_i.lt_token.spans);
_visitor.visit_type(&*_i.ty);
skip!(_i.position);
if let Some(ref it) = _i.as_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
- tokens_helper(_visitor, &(_i.gt_token).0);
+ tokens_helper(_visitor, &_i.gt_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_range_limits<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast RangeLimits) {
match *_i {
RangeLimits::HalfOpen(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
RangeLimits::Closed(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
}
}
@@ -2886,7 +3018,7 @@
match *_i {
ReturnType::Default => {}
ReturnType::Type(ref _binding_0, ref _binding_1) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
_visitor.visit_type(&**_binding_1);
}
}
@@ -2907,14 +3039,14 @@
}
Stmt::Semi(ref _binding_0, ref _binding_1) => {
_visitor.visit_expr(_binding_0);
- tokens_helper(_visitor, &(_binding_1).0);
+ tokens_helper(_visitor, &_binding_1.spans);
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_trait_bound<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TraitBound) {
if let Some(ref it) = _i.paren_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_trait_bound_modifier(&_i.modifier);
if let Some(ref it) = _i.lifetimes {
@@ -2930,7 +3062,7 @@
match *_i {
TraitBoundModifier::None => {}
TraitBoundModifier::Maybe(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
}
}
@@ -2962,15 +3094,15 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.const_token).0);
+ tokens_helper(_visitor, &_i.const_token.span);
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon_token).0);
+ tokens_helper(_visitor, &_i.colon_token.spans);
_visitor.visit_type(&_i.ty);
if let Some(ref it) = _i.default {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.spans);
_visitor.visit_expr(&(it).1);
};
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_trait_item_macro<'ast, V: Visit<'ast> + ?Sized>(
@@ -2982,7 +3114,7 @@
}
_visitor.visit_macro(&_i.mac);
if let Some(ref it) = _i.semi_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "full")]
@@ -2998,7 +3130,7 @@
_visitor.visit_block(it)
};
if let Some(ref it) = _i.semi_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
}
#[cfg(feature = "full")]
@@ -3009,21 +3141,21 @@
for it in &_i.attrs {
_visitor.visit_attribute(it)
}
- tokens_helper(_visitor, &(_i.type_token).0);
+ tokens_helper(_visitor, &_i.type_token.span);
_visitor.visit_ident(&_i.ident);
_visitor.visit_generics(&_i.generics);
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
_visitor.visit_type_param_bound(it)
}
if let Some(ref it) = _i.default {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.spans);
_visitor.visit_type(&(it).1);
};
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_trait_item_verbatim<'ast, V: Visit<'ast> + ?Sized>(
@@ -3084,36 +3216,36 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_array<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeArray) {
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
_visitor.visit_type(&*_i.elem);
- tokens_helper(_visitor, &(_i.semi_token).0);
+ tokens_helper(_visitor, &_i.semi_token.spans);
_visitor.visit_expr(&_i.len);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_bare_fn<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeBareFn) {
+ if let Some(ref it) = _i.lifetimes {
+ _visitor.visit_bound_lifetimes(it)
+ };
if let Some(ref it) = _i.unsafety {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.abi {
_visitor.visit_abi(it)
};
- tokens_helper(_visitor, &(_i.fn_token).0);
- if let Some(ref it) = _i.lifetimes {
- _visitor.visit_bound_lifetimes(it)
- };
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.fn_token.span);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.inputs) {
let it = el.value();
_visitor.visit_bare_fn_arg(it)
}
if let Some(ref it) = _i.variadic {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
_visitor.visit_return_type(&_i.output);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_group<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeGroup) {
- tokens_helper(_visitor, &(_i.group_token).0);
+ tokens_helper(_visitor, &_i.group_token.span);
_visitor.visit_type(&*_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -3121,7 +3253,7 @@
_visitor: &mut V,
_i: &'ast TypeImplTrait,
) {
- tokens_helper(_visitor, &(_i.impl_token).0);
+ tokens_helper(_visitor, &_i.impl_token.span);
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
_visitor.visit_type_param_bound(it)
@@ -3129,7 +3261,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_infer<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeInfer) {
- tokens_helper(_visitor, &(_i.underscore_token).0);
+ tokens_helper(_visitor, &_i.underscore_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_macro<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeMacro) {
@@ -3137,7 +3269,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_never<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeNever) {
- tokens_helper(_visitor, &(_i.bang_token).0);
+ tokens_helper(_visitor, &_i.bang_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_param<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeParam) {
@@ -3146,14 +3278,14 @@
}
_visitor.visit_ident(&_i.ident);
if let Some(ref it) = _i.colon_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
_visitor.visit_type_param_bound(it)
}
if let Some(ref it) = _i.eq_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.spans)
};
if let Some(ref it) = _i.default {
_visitor.visit_type(it)
@@ -3175,7 +3307,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_paren<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeParen) {
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
_visitor.visit_type(&*_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -3187,12 +3319,12 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_ptr<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypePtr) {
- tokens_helper(_visitor, &(_i.star_token).0);
+ tokens_helper(_visitor, &_i.star_token.spans);
if let Some(ref it) = _i.const_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_type(&*_i.elem);
}
@@ -3201,18 +3333,18 @@
_visitor: &mut V,
_i: &'ast TypeReference,
) {
- tokens_helper(_visitor, &(_i.and_token).0);
+ tokens_helper(_visitor, &_i.and_token.spans);
if let Some(ref it) = _i.lifetime {
_visitor.visit_lifetime(it)
};
if let Some(ref it) = _i.mutability {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_type(&*_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_slice<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeSlice) {
- tokens_helper(_visitor, &(_i.bracket_token).0);
+ tokens_helper(_visitor, &_i.bracket_token.span);
_visitor.visit_type(&*_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -3221,7 +3353,7 @@
_i: &'ast TypeTraitObject,
) {
if let Some(ref it) = _i.dyn_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
for el in Punctuated::pairs(&_i.bounds) {
let it = el.value();
@@ -3230,7 +3362,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_tuple<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeTuple) {
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.paren_token.span);
for el in Punctuated::pairs(&_i.elems) {
let it = el.value();
_visitor.visit_type(it)
@@ -3247,23 +3379,23 @@
pub fn visit_un_op<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UnOp) {
match *_i {
UnOp::Deref(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
UnOp::Not(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
UnOp::Neg(ref _binding_0) => {
- tokens_helper(_visitor, &(_binding_0).0);
+ tokens_helper(_visitor, &_binding_0.spans);
}
}
}
#[cfg(feature = "full")]
pub fn visit_use_glob<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseGlob) {
- tokens_helper(_visitor, &(_i.star_token).0);
+ tokens_helper(_visitor, &_i.star_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_use_group<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseGroup) {
- tokens_helper(_visitor, &(_i.brace_token).0);
+ tokens_helper(_visitor, &_i.brace_token.span);
for el in Punctuated::pairs(&_i.items) {
let it = el.value();
_visitor.visit_use_tree(it)
@@ -3276,13 +3408,13 @@
#[cfg(feature = "full")]
pub fn visit_use_path<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UsePath) {
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.colon2_token).0);
+ tokens_helper(_visitor, &_i.colon2_token.spans);
_visitor.visit_use_tree(&*_i.tree);
}
#[cfg(feature = "full")]
pub fn visit_use_rename<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseRename) {
_visitor.visit_ident(&_i.ident);
- tokens_helper(_visitor, &(_i.as_token).0);
+ tokens_helper(_visitor, &_i.as_token.span);
_visitor.visit_ident(&_i.rename);
}
#[cfg(feature = "full")]
@@ -3313,27 +3445,27 @@
_visitor.visit_ident(&_i.ident);
_visitor.visit_fields(&_i.fields);
if let Some(ref it) = _i.discriminant {
- tokens_helper(_visitor, &((it).0).0);
+ tokens_helper(_visitor, &(it).0.spans);
_visitor.visit_expr(&(it).1);
};
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_vis_crate<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast VisCrate) {
- tokens_helper(_visitor, &(_i.crate_token).0);
+ tokens_helper(_visitor, &_i.crate_token.span);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_vis_public<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast VisPublic) {
- tokens_helper(_visitor, &(_i.pub_token).0);
+ tokens_helper(_visitor, &_i.pub_token.span);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_vis_restricted<'ast, V: Visit<'ast> + ?Sized>(
_visitor: &mut V,
_i: &'ast VisRestricted,
) {
- tokens_helper(_visitor, &(_i.pub_token).0);
- tokens_helper(_visitor, &(_i.paren_token).0);
+ tokens_helper(_visitor, &_i.pub_token.span);
+ tokens_helper(_visitor, &_i.paren_token.span);
if let Some(ref it) = _i.in_token {
- tokens_helper(_visitor, &(it).0)
+ tokens_helper(_visitor, &it.span)
};
_visitor.visit_path(&*_i.path);
}
@@ -3354,7 +3486,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_where_clause<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast WhereClause) {
- tokens_helper(_visitor, &(_i.where_token).0);
+ tokens_helper(_visitor, &_i.where_token.span);
for el in Punctuated::pairs(&_i.predicates) {
let it = el.value();
_visitor.visit_where_predicate(it)
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 14a7970..0795daf 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -136,6 +136,11 @@
fn visit_expr_assign_op_mut(&mut self, i: &mut ExprAssignOp) {
visit_expr_assign_op_mut(self, i)
}
+ #[cfg(feature = "full")]
+ #[cfg(any(feature = "full", feature = "derive"))]
+ fn visit_expr_async_mut(&mut self, i: &mut ExprAsync) {
+ visit_expr_async_mut(self, i)
+ }
#[cfg(any(feature = "full", feature = "derive"))]
fn visit_expr_binary_mut(&mut self, i: &mut ExprBinary) {
visit_expr_binary_mut(self, i)
@@ -165,11 +170,6 @@
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
- fn visit_expr_catch_mut(&mut self, i: &mut ExprCatch) {
- visit_expr_catch_mut(self, i)
- }
- #[cfg(feature = "full")]
- #[cfg(any(feature = "full", feature = "derive"))]
fn visit_expr_closure_mut(&mut self, i: &mut ExprClosure) {
visit_expr_closure_mut(self, i)
}
@@ -275,6 +275,11 @@
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
+ fn visit_expr_try_block_mut(&mut self, i: &mut ExprTryBlock) {
+ visit_expr_try_block_mut(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg(any(feature = "full", feature = "derive"))]
fn visit_expr_tuple_mut(&mut self, i: &mut ExprTuple) {
visit_expr_tuple_mut(self, i)
}
@@ -358,6 +363,10 @@
visit_foreign_item_fn_mut(self, i)
}
#[cfg(feature = "full")]
+ fn visit_foreign_item_macro_mut(&mut self, i: &mut ForeignItemMacro) {
+ visit_foreign_item_macro_mut(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_foreign_item_static_mut(&mut self, i: &mut ForeignItemStatic) {
visit_foreign_item_static_mut(self, i)
}
@@ -398,6 +407,10 @@
visit_impl_item_const_mut(self, i)
}
#[cfg(feature = "full")]
+ fn visit_impl_item_existential_mut(&mut self, i: &mut ImplItemExistential) {
+ visit_impl_item_existential_mut(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_impl_item_macro_mut(&mut self, i: &mut ImplItemMacro) {
visit_impl_item_macro_mut(self, i)
}
@@ -430,6 +443,10 @@
visit_item_enum_mut(self, i)
}
#[cfg(feature = "full")]
+ fn visit_item_existential_mut(&mut self, i: &mut ItemExistential) {
+ visit_item_existential_mut(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_item_extern_crate_mut(&mut self, i: &mut ItemExternCrate) {
visit_item_extern_crate_mut(self, i)
}
@@ -470,6 +487,10 @@
visit_item_trait_mut(self, i)
}
#[cfg(feature = "full")]
+ fn visit_item_trait_alias_mut(&mut self, i: &mut ItemTraitAlias) {
+ visit_item_trait_alias_mut(self, i)
+ }
+ #[cfg(feature = "full")]
fn visit_item_type_mut(&mut self, i: &mut ItemType) {
visit_item_type_mut(self, i)
}
@@ -490,7 +511,6 @@
fn visit_label_mut(&mut self, i: &mut Label) {
visit_label_mut(self, i)
}
- #[cfg(any(feature = "full", feature = "derive"))]
fn visit_lifetime_mut(&mut self, i: &mut Lifetime) {
visit_lifetime_mut(self, i)
}
@@ -858,7 +878,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_abi_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Abi) {
- tokens_helper(_visitor, &mut (_i.extern_token).0);
+ tokens_helper(_visitor, &mut _i.extern_token.span);
if let Some(ref mut it) = _i.name {
_visitor.visit_lit_str_mut(it)
};
@@ -869,38 +889,38 @@
_i: &mut AngleBracketedGenericArguments,
) {
if let Some(ref mut it) = _i.colon2_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
- tokens_helper(_visitor, &mut (_i.lt_token).0);
+ tokens_helper(_visitor, &mut _i.lt_token.spans);
for mut el in Punctuated::pairs_mut(&mut _i.args) {
let it = el.value_mut();
_visitor.visit_generic_argument_mut(it)
}
- tokens_helper(_visitor, &mut (_i.gt_token).0);
+ tokens_helper(_visitor, &mut _i.gt_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_arg_captured_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ArgCaptured) {
_visitor.visit_pat_mut(&mut _i.pat);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut _i.ty);
}
#[cfg(feature = "full")]
pub fn visit_arg_self_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ArgSelf) {
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.self_token).0);
+ tokens_helper(_visitor, &mut _i.self_token.span);
}
#[cfg(feature = "full")]
pub fn visit_arg_self_ref_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ArgSelfRef) {
- tokens_helper(_visitor, &mut (_i.and_token).0);
+ tokens_helper(_visitor, &mut _i.and_token.spans);
if let Some(ref mut it) = _i.lifetime {
_visitor.visit_lifetime_mut(it)
};
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.self_token).0);
+ tokens_helper(_visitor, &mut _i.self_token.span);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
@@ -909,20 +929,20 @@
_visitor.visit_attribute_mut(it)
}
if let Some(ref mut it) = _i.leading_vert {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.pats) {
let it = el.value_mut();
_visitor.visit_pat_mut(it)
}
if let Some(ref mut it) = _i.guard {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.span);
_visitor.visit_expr_mut(&mut *(it).1);
};
- tokens_helper(_visitor, &mut (_i.fat_arrow_token).0);
+ tokens_helper(_visitor, &mut _i.fat_arrow_token.spans);
_visitor.visit_expr_mut(&mut *_i.body);
if let Some(ref mut it) = _i.comma {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -930,24 +950,23 @@
match *_i {
AttrStyle::Outer => {}
AttrStyle::Inner(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_attribute_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Attribute) {
- tokens_helper(_visitor, &mut (_i.pound_token).0);
+ tokens_helper(_visitor, &mut _i.pound_token.spans);
_visitor.visit_attr_style_mut(&mut _i.style);
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
_visitor.visit_path_mut(&mut _i.path);
skip!(_i.tts);
- skip!(_i.is_sugared_doc);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_bare_fn_arg_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut BareFnArg) {
if let Some(ref mut it) = _i.name {
_visitor.visit_bare_fn_arg_name_mut(&mut (it).0);
- tokens_helper(_visitor, &mut ((it).1).0);
+ tokens_helper(_visitor, &mut (it).1.spans);
};
_visitor.visit_type_mut(&mut _i.ty);
}
@@ -958,7 +977,7 @@
_visitor.visit_ident_mut(_binding_0);
}
BareFnArgName::Wild(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
}
}
@@ -966,126 +985,126 @@
pub fn visit_bin_op_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut BinOp) {
match *_i {
BinOp::Add(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Sub(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Mul(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Div(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Rem(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::And(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Or(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::BitXor(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::BitAnd(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::BitOr(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Shl(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Shr(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Eq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Lt(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Le(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Ne(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Ge(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::Gt(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::AddEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::SubEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::MulEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::DivEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::RemEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::BitXorEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::BitAndEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::BitOrEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::ShlEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
BinOp::ShrEq(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_binding_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Binding) {
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_type_mut(&mut _i.ty);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_block_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Block) {
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for it in &mut _i.stmts {
_visitor.visit_stmt_mut(it)
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_bound_lifetimes_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut BoundLifetimes) {
- tokens_helper(_visitor, &mut (_i.for_token).0);
- tokens_helper(_visitor, &mut (_i.lt_token).0);
+ tokens_helper(_visitor, &mut _i.for_token.span);
+ tokens_helper(_visitor, &mut _i.lt_token.spans);
for mut el in Punctuated::pairs_mut(&mut _i.lifetimes) {
let it = el.value_mut();
_visitor.visit_lifetime_def_mut(it)
}
- tokens_helper(_visitor, &mut (_i.gt_token).0);
+ tokens_helper(_visitor, &mut _i.gt_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_const_param_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ConstParam) {
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.const_token).0);
+ tokens_helper(_visitor, &mut _i.const_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut _i.ty);
if let Some(ref mut it) = _i.eq_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
if let Some(ref mut it) = _i.default {
_visitor.visit_expr_mut(it)
@@ -1107,8 +1126,8 @@
}
#[cfg(feature = "derive")]
pub fn visit_data_enum_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut DataEnum) {
- tokens_helper(_visitor, &mut (_i.enum_token).0);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.enum_token.span);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.variants) {
let it = el.value_mut();
_visitor.visit_variant_mut(it)
@@ -1116,15 +1135,15 @@
}
#[cfg(feature = "derive")]
pub fn visit_data_struct_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut DataStruct) {
- tokens_helper(_visitor, &mut (_i.struct_token).0);
+ tokens_helper(_visitor, &mut _i.struct_token.span);
_visitor.visit_fields_mut(&mut _i.fields);
if let Some(ref mut it) = _i.semi_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "derive")]
pub fn visit_data_union_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut DataUnion) {
- tokens_helper(_visitor, &mut (_i.union_token).0);
+ tokens_helper(_visitor, &mut _i.union_token.span);
_visitor.visit_fields_named_mut(&mut _i.fields);
}
#[cfg(feature = "derive")]
@@ -1251,8 +1270,11 @@
Expr::Try(ref mut _binding_0) => {
full!(_visitor.visit_expr_try_mut(_binding_0));
}
- Expr::Catch(ref mut _binding_0) => {
- full!(_visitor.visit_expr_catch_mut(_binding_0));
+ Expr::Async(ref mut _binding_0) => {
+ full!(_visitor.visit_expr_async_mut(_binding_0));
+ }
+ Expr::TryBlock(ref mut _binding_0) => {
+ full!(_visitor.visit_expr_try_block_mut(_binding_0));
}
Expr::Yield(ref mut _binding_0) => {
full!(_visitor.visit_expr_yield_mut(_binding_0));
@@ -1268,7 +1290,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.elems) {
let it = el.value_mut();
_visitor.visit_expr_mut(it)
@@ -1281,7 +1303,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.left);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_expr_mut(&mut *_i.right);
}
#[cfg(feature = "full")]
@@ -1294,6 +1316,18 @@
_visitor.visit_bin_op_mut(&mut _i.op);
_visitor.visit_expr_mut(&mut *_i.right);
}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_async_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprAsync) {
+ for it in &mut _i.attrs {
+ _visitor.visit_attribute_mut(it)
+ }
+ tokens_helper(_visitor, &mut _i.async_token.span);
+ if let Some(ref mut it) = _i.capture {
+ tokens_helper(_visitor, &mut it.span)
+ };
+ _visitor.visit_block_mut(&mut _i.block);
+}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_expr_binary_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprBinary) {
for it in &mut _i.attrs {
@@ -1309,6 +1343,9 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
+ if let Some(ref mut it) = _i.label {
+ _visitor.visit_label_mut(it)
+ };
_visitor.visit_block_mut(&mut _i.block);
}
#[cfg(feature = "full")]
@@ -1317,7 +1354,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.box_token).0);
+ tokens_helper(_visitor, &mut _i.box_token.span);
_visitor.visit_expr_mut(&mut *_i.expr);
}
#[cfg(feature = "full")]
@@ -1326,7 +1363,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.break_token).0);
+ tokens_helper(_visitor, &mut _i.break_token.span);
if let Some(ref mut it) = _i.label {
_visitor.visit_lifetime_mut(it)
};
@@ -1340,7 +1377,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.func);
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.args) {
let it = el.value_mut();
_visitor.visit_expr_mut(it)
@@ -1352,37 +1389,30 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.as_token).0);
+ tokens_helper(_visitor, &mut _i.as_token.span);
_visitor.visit_type_mut(&mut *_i.ty);
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
-pub fn visit_expr_catch_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprCatch) {
- for it in &mut _i.attrs {
- _visitor.visit_attribute_mut(it)
- }
- tokens_helper(_visitor, &mut (_i.do_token).0);
- tokens_helper(_visitor, &mut (_i.catch_token).0);
- _visitor.visit_block_mut(&mut _i.block);
-}
-#[cfg(feature = "full")]
-#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_expr_closure_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprClosure) {
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
+ if let Some(ref mut it) = _i.asyncness {
+ tokens_helper(_visitor, &mut it.span)
+ };
if let Some(ref mut it) = _i.movability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.capture {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.or1_token).0);
+ tokens_helper(_visitor, &mut _i.or1_token.spans);
for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
let it = el.value_mut();
_visitor.visit_fn_arg_mut(it)
}
- tokens_helper(_visitor, &mut (_i.or2_token).0);
+ tokens_helper(_visitor, &mut _i.or2_token.spans);
_visitor.visit_return_type_mut(&mut _i.output);
_visitor.visit_expr_mut(&mut *_i.body);
}
@@ -1392,7 +1422,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.continue_token).0);
+ tokens_helper(_visitor, &mut _i.continue_token.span);
if let Some(ref mut it) = _i.label {
_visitor.visit_lifetime_mut(it)
};
@@ -1403,7 +1433,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.base);
- tokens_helper(_visitor, &mut (_i.dot_token).0);
+ tokens_helper(_visitor, &mut _i.dot_token.spans);
_visitor.visit_member_mut(&mut _i.member);
}
#[cfg(feature = "full")]
@@ -1415,9 +1445,9 @@
if let Some(ref mut it) = _i.label {
_visitor.visit_label_mut(it)
};
- tokens_helper(_visitor, &mut (_i.for_token).0);
+ tokens_helper(_visitor, &mut _i.for_token.span);
_visitor.visit_pat_mut(&mut *_i.pat);
- tokens_helper(_visitor, &mut (_i.in_token).0);
+ tokens_helper(_visitor, &mut _i.in_token.span);
_visitor.visit_expr_mut(&mut *_i.expr);
_visitor.visit_block_mut(&mut _i.body);
}
@@ -1427,7 +1457,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.group_token).0);
+ tokens_helper(_visitor, &mut _i.group_token.span);
_visitor.visit_expr_mut(&mut *_i.expr);
}
#[cfg(feature = "full")]
@@ -1436,11 +1466,11 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.if_token).0);
+ tokens_helper(_visitor, &mut _i.if_token.span);
_visitor.visit_expr_mut(&mut *_i.cond);
_visitor.visit_block_mut(&mut _i.then_branch);
if let Some(ref mut it) = _i.else_branch {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.span);
_visitor.visit_expr_mut(&mut *(it).1);
};
}
@@ -1450,17 +1480,17 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.if_token).0);
- tokens_helper(_visitor, &mut (_i.let_token).0);
+ tokens_helper(_visitor, &mut _i.if_token.span);
+ tokens_helper(_visitor, &mut _i.let_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.pats) {
let it = el.value_mut();
_visitor.visit_pat_mut(it)
}
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_expr_mut(&mut *_i.expr);
_visitor.visit_block_mut(&mut _i.then_branch);
if let Some(ref mut it) = _i.else_branch {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.span);
_visitor.visit_expr_mut(&mut *(it).1);
};
}
@@ -1471,7 +1501,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.place);
- tokens_helper(_visitor, &mut (_i.arrow_token).0);
+ tokens_helper(_visitor, &mut _i.arrow_token.spans);
_visitor.visit_expr_mut(&mut *_i.value);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1480,7 +1510,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
_visitor.visit_expr_mut(&mut *_i.index);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1499,7 +1529,7 @@
if let Some(ref mut it) = _i.label {
_visitor.visit_label_mut(it)
};
- tokens_helper(_visitor, &mut (_i.loop_token).0);
+ tokens_helper(_visitor, &mut _i.loop_token.span);
_visitor.visit_block_mut(&mut _i.body);
}
#[cfg(feature = "full")]
@@ -1516,9 +1546,9 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.match_token).0);
+ tokens_helper(_visitor, &mut _i.match_token.span);
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for it in &mut _i.arms {
_visitor.visit_arm_mut(it)
}
@@ -1530,12 +1560,12 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.receiver);
- tokens_helper(_visitor, &mut (_i.dot_token).0);
+ tokens_helper(_visitor, &mut _i.dot_token.spans);
_visitor.visit_ident_mut(&mut _i.method);
if let Some(ref mut it) = _i.turbofish {
_visitor.visit_method_turbofish_mut(it)
};
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.args) {
let it = el.value_mut();
_visitor.visit_expr_mut(it)
@@ -1546,7 +1576,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
_visitor.visit_expr_mut(&mut *_i.expr);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1579,9 +1609,9 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.and_token).0);
+ tokens_helper(_visitor, &mut _i.and_token.spans);
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_expr_mut(&mut *_i.expr);
}
@@ -1591,9 +1621,9 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
_visitor.visit_expr_mut(&mut *_i.len);
}
#[cfg(feature = "full")]
@@ -1602,7 +1632,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.return_token).0);
+ tokens_helper(_visitor, &mut _i.return_token.span);
if let Some(ref mut it) = _i.expr {
_visitor.visit_expr_mut(&mut **it)
};
@@ -1614,13 +1644,13 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_path_mut(&mut _i.path);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.fields) {
let it = el.value_mut();
_visitor.visit_field_value_mut(it)
}
if let Some(ref mut it) = _i.dot2_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
if let Some(ref mut it) = _i.rest {
_visitor.visit_expr_mut(&mut **it)
@@ -1633,7 +1663,16 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.question_token).0);
+ tokens_helper(_visitor, &mut _i.question_token.spans);
+}
+#[cfg(feature = "full")]
+#[cfg(any(feature = "full", feature = "derive"))]
+pub fn visit_expr_try_block_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ExprTryBlock) {
+ for it in &mut _i.attrs {
+ _visitor.visit_attribute_mut(it)
+ }
+ tokens_helper(_visitor, &mut _i.try_token.span);
+ _visitor.visit_block_mut(&mut _i.block);
}
#[cfg(feature = "full")]
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1641,7 +1680,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.elems) {
let it = el.value_mut();
_visitor.visit_expr_mut(it)
@@ -1654,7 +1693,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut *_i.ty);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1671,7 +1710,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.unsafe_token).0);
+ tokens_helper(_visitor, &mut _i.unsafe_token.span);
_visitor.visit_block_mut(&mut _i.block);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -1687,7 +1726,7 @@
if let Some(ref mut it) = _i.label {
_visitor.visit_label_mut(it)
};
- tokens_helper(_visitor, &mut (_i.while_token).0);
+ tokens_helper(_visitor, &mut _i.while_token.span);
_visitor.visit_expr_mut(&mut *_i.cond);
_visitor.visit_block_mut(&mut _i.body);
}
@@ -1700,13 +1739,13 @@
if let Some(ref mut it) = _i.label {
_visitor.visit_label_mut(it)
};
- tokens_helper(_visitor, &mut (_i.while_token).0);
- tokens_helper(_visitor, &mut (_i.let_token).0);
+ tokens_helper(_visitor, &mut _i.while_token.span);
+ tokens_helper(_visitor, &mut _i.let_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.pats) {
let it = el.value_mut();
_visitor.visit_pat_mut(it)
}
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_expr_mut(&mut *_i.expr);
_visitor.visit_block_mut(&mut _i.body);
}
@@ -1716,7 +1755,7 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.yield_token).0);
+ tokens_helper(_visitor, &mut _i.yield_token.span);
if let Some(ref mut it) = _i.expr {
_visitor.visit_expr_mut(&mut **it)
};
@@ -1731,7 +1770,7 @@
_visitor.visit_ident_mut(it)
};
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_type_mut(&mut _i.ty);
}
@@ -1743,7 +1782,7 @@
}
_visitor.visit_member_mut(&mut _i.member);
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_pat_mut(&mut *_i.pat);
}
@@ -1755,7 +1794,7 @@
}
_visitor.visit_member_mut(&mut _i.member);
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_expr_mut(&mut _i.expr);
}
@@ -1773,7 +1812,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_fields_named_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut FieldsNamed) {
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.named) {
let it = el.value_mut();
_visitor.visit_field_mut(it)
@@ -1781,7 +1820,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_fields_unnamed_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut FieldsUnnamed) {
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.unnamed) {
let it = el.value_mut();
_visitor.visit_field_mut(it)
@@ -1819,15 +1858,15 @@
}
#[cfg(feature = "full")]
pub fn visit_fn_decl_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut FnDecl) {
- tokens_helper(_visitor, &mut (_i.fn_token).0);
+ tokens_helper(_visitor, &mut _i.fn_token.span);
_visitor.visit_generics_mut(&mut _i.generics);
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
let it = el.value_mut();
_visitor.visit_fn_arg_mut(it)
}
if let Some(ref mut it) = _i.variadic {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_return_type_mut(&mut _i.output);
}
@@ -1843,6 +1882,9 @@
ForeignItem::Type(ref mut _binding_0) => {
_visitor.visit_foreign_item_type_mut(_binding_0);
}
+ ForeignItem::Macro(ref mut _binding_0) => {
+ _visitor.visit_foreign_item_macro_mut(_binding_0);
+ }
ForeignItem::Verbatim(ref mut _binding_0) => {
_visitor.visit_foreign_item_verbatim_mut(_binding_0);
}
@@ -1856,7 +1898,20 @@
_visitor.visit_visibility_mut(&mut _i.vis);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_fn_decl_mut(&mut *_i.decl);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_foreign_item_macro_mut<V: VisitMut + ?Sized>(
+ _visitor: &mut V,
+ _i: &mut ForeignItemMacro,
+) {
+ for it in &mut _i.attrs {
+ _visitor.visit_attribute_mut(it)
+ }
+ _visitor.visit_macro_mut(&mut _i.mac);
+ if let Some(ref mut it) = _i.semi_token {
+ tokens_helper(_visitor, &mut it.spans)
+ };
}
#[cfg(feature = "full")]
pub fn visit_foreign_item_static_mut<V: VisitMut + ?Sized>(
@@ -1867,14 +1922,14 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.static_token).0);
+ tokens_helper(_visitor, &mut _i.static_token.span);
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut *_i.ty);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_foreign_item_type_mut<V: VisitMut + ?Sized>(
@@ -1885,9 +1940,9 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.type_token).0);
+ tokens_helper(_visitor, &mut _i.type_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_foreign_item_verbatim_mut<V: VisitMut + ?Sized>(
@@ -1948,14 +2003,14 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_generics_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Generics) {
if let Some(ref mut it) = _i.lt_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.params) {
let it = el.value_mut();
_visitor.visit_generic_param_mut(it)
}
if let Some(ref mut it) = _i.gt_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
if let Some(ref mut it) = _i.where_clause {
_visitor.visit_where_clause_mut(it)
@@ -1974,6 +2029,9 @@
ImplItem::Type(ref mut _binding_0) => {
_visitor.visit_impl_item_type_mut(_binding_0);
}
+ ImplItem::Existential(ref mut _binding_0) => {
+ _visitor.visit_impl_item_existential_mut(_binding_0);
+ }
ImplItem::Macro(ref mut _binding_0) => {
_visitor.visit_impl_item_macro_mut(_binding_0);
}
@@ -1989,15 +2047,36 @@
}
_visitor.visit_visibility_mut(&mut _i.vis);
if let Some(ref mut it) = _i.defaultness {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.const_token).0);
+ tokens_helper(_visitor, &mut _i.const_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut _i.ty);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_expr_mut(&mut _i.expr);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
+pub fn visit_impl_item_existential_mut<V: VisitMut + ?Sized>(
+ _visitor: &mut V,
+ _i: &mut ImplItemExistential,
+) {
+ for it in &mut _i.attrs {
+ _visitor.visit_attribute_mut(it)
+ }
+ tokens_helper(_visitor, &mut _i.existential_token.span);
+ tokens_helper(_visitor, &mut _i.type_token.span);
+ _visitor.visit_ident_mut(&mut _i.ident);
+ _visitor.visit_generics_mut(&mut _i.generics);
+ if let Some(ref mut it) = _i.colon_token {
+ tokens_helper(_visitor, &mut it.spans)
+ };
+ for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+ let it = el.value_mut();
+ _visitor.visit_type_param_bound_mut(it)
+ }
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_impl_item_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ImplItemMacro) {
@@ -2006,7 +2085,7 @@
}
_visitor.visit_macro_mut(&mut _i.mac);
if let Some(ref mut it) = _i.semi_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "full")]
@@ -2016,7 +2095,7 @@
}
_visitor.visit_visibility_mut(&mut _i.vis);
if let Some(ref mut it) = _i.defaultness {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_method_sig_mut(&mut _i.sig);
_visitor.visit_block_mut(&mut _i.block);
@@ -2028,14 +2107,14 @@
}
_visitor.visit_visibility_mut(&mut _i.vis);
if let Some(ref mut it) = _i.defaultness {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.type_token).0);
+ tokens_helper(_visitor, &mut _i.type_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_type_mut(&mut _i.ty);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_impl_item_verbatim_mut<V: VisitMut + ?Sized>(
@@ -2076,6 +2155,9 @@
Item::Type(ref mut _binding_0) => {
_visitor.visit_item_type_mut(_binding_0);
}
+ Item::Existential(ref mut _binding_0) => {
+ _visitor.visit_item_existential_mut(_binding_0);
+ }
Item::Struct(ref mut _binding_0) => {
_visitor.visit_item_struct_mut(_binding_0);
}
@@ -2088,6 +2170,9 @@
Item::Trait(ref mut _binding_0) => {
_visitor.visit_item_trait_mut(_binding_0);
}
+ Item::TraitAlias(ref mut _binding_0) => {
+ _visitor.visit_item_trait_alias_mut(_binding_0);
+ }
Item::Impl(ref mut _binding_0) => {
_visitor.visit_item_impl_mut(_binding_0);
}
@@ -2108,13 +2193,13 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.const_token).0);
+ tokens_helper(_visitor, &mut _i.const_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut *_i.ty);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_enum_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemEnum) {
@@ -2122,16 +2207,38 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.enum_token).0);
+ tokens_helper(_visitor, &mut _i.enum_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.variants) {
let it = el.value_mut();
_visitor.visit_variant_mut(it)
}
}
#[cfg(feature = "full")]
+pub fn visit_item_existential_mut<V: VisitMut + ?Sized>(
+ _visitor: &mut V,
+ _i: &mut ItemExistential,
+) {
+ for it in &mut _i.attrs {
+ _visitor.visit_attribute_mut(it)
+ }
+ _visitor.visit_visibility_mut(&mut _i.vis);
+ tokens_helper(_visitor, &mut _i.existential_token.span);
+ tokens_helper(_visitor, &mut _i.type_token.span);
+ _visitor.visit_ident_mut(&mut _i.ident);
+ _visitor.visit_generics_mut(&mut _i.generics);
+ if let Some(ref mut it) = _i.colon_token {
+ tokens_helper(_visitor, &mut it.spans)
+ };
+ for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+ let it = el.value_mut();
+ _visitor.visit_type_param_bound_mut(it)
+ }
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
pub fn visit_item_extern_crate_mut<V: VisitMut + ?Sized>(
_visitor: &mut V,
_i: &mut ItemExternCrate,
@@ -2140,14 +2247,14 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.extern_token).0);
- tokens_helper(_visitor, &mut (_i.crate_token).0);
+ tokens_helper(_visitor, &mut _i.extern_token.span);
+ tokens_helper(_visitor, &mut _i.crate_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
if let Some(ref mut it) = _i.rename {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.span);
_visitor.visit_ident_mut(&mut (it).1);
};
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_fn_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemFn) {
@@ -2156,10 +2263,13 @@
}
_visitor.visit_visibility_mut(&mut _i.vis);
if let Some(ref mut it) = _i.constness {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.unsafety {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
+ };
+ if let Some(ref mut it) = _i.asyncness {
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.abi {
_visitor.visit_abi_mut(it)
@@ -2174,7 +2284,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_abi_mut(&mut _i.abi);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for it in &mut _i.items {
_visitor.visit_foreign_item_mut(it)
}
@@ -2185,22 +2295,22 @@
_visitor.visit_attribute_mut(it)
}
if let Some(ref mut it) = _i.defaultness {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.unsafety {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.impl_token).0);
+ tokens_helper(_visitor, &mut _i.impl_token.span);
_visitor.visit_generics_mut(&mut _i.generics);
if let Some(ref mut it) = _i.trait_ {
if let Some(ref mut it) = (it).0 {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_path_mut(&mut (it).1);
- tokens_helper(_visitor, &mut ((it).2).0);
+ tokens_helper(_visitor, &mut (it).2.span);
};
_visitor.visit_type_mut(&mut *_i.self_ty);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for it in &mut _i.items {
_visitor.visit_impl_item_mut(it)
}
@@ -2215,7 +2325,7 @@
};
_visitor.visit_macro_mut(&mut _i.mac);
if let Some(ref mut it) = _i.semi_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "full")]
@@ -2224,11 +2334,11 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.macro_token).0);
+ tokens_helper(_visitor, &mut _i.macro_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
skip!(_i.args);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
skip!(_i.body);
}
#[cfg(feature = "full")]
@@ -2237,16 +2347,16 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.mod_token).0);
+ tokens_helper(_visitor, &mut _i.mod_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
if let Some(ref mut it) = _i.content {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.span);
for it in &mut (it).1 {
_visitor.visit_item_mut(it)
}
};
if let Some(ref mut it) = _i.semi {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "full")]
@@ -2255,16 +2365,16 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.static_token).0);
+ tokens_helper(_visitor, &mut _i.static_token.span);
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut *_i.ty);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_expr_mut(&mut *_i.expr);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_struct_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemStruct) {
@@ -2272,12 +2382,12 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.struct_token).0);
+ tokens_helper(_visitor, &mut _i.struct_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
_visitor.visit_fields_mut(&mut _i.fields);
if let Some(ref mut it) = _i.semi_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "full")]
@@ -2287,38 +2397,54 @@
}
_visitor.visit_visibility_mut(&mut _i.vis);
if let Some(ref mut it) = _i.unsafety {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.auto_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.trait_token).0);
+ tokens_helper(_visitor, &mut _i.trait_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.supertraits) {
let it = el.value_mut();
_visitor.visit_type_param_bound_mut(it)
}
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for it in &mut _i.items {
_visitor.visit_trait_item_mut(it)
}
}
#[cfg(feature = "full")]
+pub fn visit_item_trait_alias_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemTraitAlias) {
+ for it in &mut _i.attrs {
+ _visitor.visit_attribute_mut(it)
+ }
+ _visitor.visit_visibility_mut(&mut _i.vis);
+ tokens_helper(_visitor, &mut _i.trait_token.span);
+ _visitor.visit_ident_mut(&mut _i.ident);
+ _visitor.visit_generics_mut(&mut _i.generics);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
+ for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
+ let it = el.value_mut();
+ _visitor.visit_type_param_bound_mut(it)
+ }
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
+}
+#[cfg(feature = "full")]
pub fn visit_item_type_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemType) {
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.type_token).0);
+ tokens_helper(_visitor, &mut _i.type_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_type_mut(&mut *_i.ty);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_union_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemUnion) {
@@ -2326,7 +2452,7 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.union_token).0);
+ tokens_helper(_visitor, &mut _i.union_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
_visitor.visit_fields_named_mut(&mut _i.fields);
@@ -2337,12 +2463,12 @@
_visitor.visit_attribute_mut(it)
}
_visitor.visit_visibility_mut(&mut _i.vis);
- tokens_helper(_visitor, &mut (_i.use_token).0);
+ tokens_helper(_visitor, &mut _i.use_token.span);
if let Some(ref mut it) = _i.leading_colon {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_use_tree_mut(&mut _i.tree);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_item_verbatim_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut ItemVerbatim) {
@@ -2352,11 +2478,10 @@
#[cfg(feature = "full")]
pub fn visit_label_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Label) {
_visitor.visit_lifetime_mut(&mut _i.name);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
}
-#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_lifetime_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Lifetime) {
- skip!(_i.apostrophe);
+ _visitor.visit_span_mut(&mut _i.apostrophe);
_visitor.visit_ident_mut(&mut _i.ident);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2366,7 +2491,7 @@
}
_visitor.visit_lifetime_mut(&mut _i.lifetime);
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
@@ -2441,25 +2566,25 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.let_token).0);
+ tokens_helper(_visitor, &mut _i.let_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.pats) {
let it = el.value_mut();
_visitor.visit_pat_mut(it)
}
if let Some(ref mut it) = _i.ty {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.spans);
_visitor.visit_type_mut(&mut *(it).1);
};
if let Some(ref mut it) = _i.init {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.spans);
_visitor.visit_expr_mut(&mut *(it).1);
};
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Macro) {
_visitor.visit_path_mut(&mut _i.path);
- tokens_helper(_visitor, &mut (_i.bang_token).0);
+ tokens_helper(_visitor, &mut _i.bang_token.spans);
_visitor.visit_macro_delimiter_mut(&mut _i.delimiter);
skip!(_i.tts);
}
@@ -2467,13 +2592,13 @@
pub fn visit_macro_delimiter_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MacroDelimiter) {
match *_i {
MacroDelimiter::Paren(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.span);
}
MacroDelimiter::Brace(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.span);
}
MacroDelimiter::Bracket(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.span);
}
}
}
@@ -2505,7 +2630,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_meta_list_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MetaList) {
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.nested) {
let it = el.value_mut();
_visitor.visit_nested_meta_mut(it)
@@ -2514,16 +2639,19 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_meta_name_value_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MetaNameValue) {
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_lit_mut(&mut _i.lit);
}
#[cfg(feature = "full")]
pub fn visit_method_sig_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut MethodSig) {
if let Some(ref mut it) = _i.constness {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.unsafety {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
+ };
+ if let Some(ref mut it) = _i.asyncness {
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.abi {
_visitor.visit_abi_mut(it)
@@ -2537,13 +2665,13 @@
_visitor: &mut V,
_i: &mut MethodTurbofish,
) {
- tokens_helper(_visitor, &mut (_i.colon2_token).0);
- tokens_helper(_visitor, &mut (_i.lt_token).0);
+ tokens_helper(_visitor, &mut _i.colon2_token.spans);
+ tokens_helper(_visitor, &mut _i.lt_token.spans);
for mut el in Punctuated::pairs_mut(&mut _i.args) {
let it = el.value_mut();
_visitor.visit_generic_method_argument_mut(it)
}
- tokens_helper(_visitor, &mut (_i.gt_token).0);
+ tokens_helper(_visitor, &mut _i.gt_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_nested_meta_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut NestedMeta) {
@@ -2561,7 +2689,7 @@
_visitor: &mut V,
_i: &mut ParenthesizedGenericArguments,
) {
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
let it = el.value_mut();
_visitor.visit_type_mut(it)
@@ -2616,21 +2744,21 @@
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_box_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatBox) {
- tokens_helper(_visitor, &mut (_i.box_token).0);
+ tokens_helper(_visitor, &mut _i.box_token.span);
_visitor.visit_pat_mut(&mut *_i.pat);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_ident_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatIdent) {
if let Some(ref mut it) = _i.by_ref {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_ident_mut(&mut _i.ident);
if let Some(ref mut it) = _i.subpat {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.spans);
_visitor.visit_pat_mut(&mut *(it).1);
};
}
@@ -2662,16 +2790,16 @@
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_ref_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatRef) {
- tokens_helper(_visitor, &mut (_i.and_token).0);
+ tokens_helper(_visitor, &mut _i.and_token.spans);
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_pat_mut(&mut *_i.pat);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_slice_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatSlice) {
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.front) {
let it = el.value_mut();
_visitor.visit_pat_mut(it)
@@ -2680,10 +2808,10 @@
_visitor.visit_pat_mut(&mut **it)
};
if let Some(ref mut it) = _i.dot2_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
if let Some(ref mut it) = _i.comma_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.back) {
let it = el.value_mut();
@@ -2694,28 +2822,28 @@
#[cfg(feature = "full")]
pub fn visit_pat_struct_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatStruct) {
_visitor.visit_path_mut(&mut _i.path);
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.fields) {
let it = el.value_mut();
_visitor.visit_field_pat_mut(it)
}
if let Some(ref mut it) = _i.dot2_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_tuple_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatTuple) {
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.front) {
let it = el.value_mut();
_visitor.visit_pat_mut(it)
}
if let Some(ref mut it) = _i.dot2_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
if let Some(ref mut it) = _i.comma_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.back) {
let it = el.value_mut();
@@ -2736,12 +2864,12 @@
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_pat_wild_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PatWild) {
- tokens_helper(_visitor, &mut (_i.underscore_token).0);
+ tokens_helper(_visitor, &mut _i.underscore_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_path_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut Path) {
if let Some(ref mut it) = _i.leading_colon {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.segments) {
let it = el.value_mut();
@@ -2768,7 +2896,7 @@
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_predicate_eq_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut PredicateEq) {
_visitor.visit_type_mut(&mut _i.lhs_ty);
- tokens_helper(_visitor, &mut (_i.eq_token).0);
+ tokens_helper(_visitor, &mut _i.eq_token.spans);
_visitor.visit_type_mut(&mut _i.rhs_ty);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -2777,9 +2905,7 @@
_i: &mut PredicateLifetime,
) {
_visitor.visit_lifetime_mut(&mut _i.lifetime);
- if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
- };
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
_visitor.visit_lifetime_mut(it)
@@ -2791,7 +2917,7 @@
_visitor.visit_bound_lifetimes_mut(it)
};
_visitor.visit_type_mut(&mut _i.bounded_ty);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
_visitor.visit_type_param_bound_mut(it)
@@ -2799,23 +2925,23 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_qself_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut QSelf) {
- tokens_helper(_visitor, &mut (_i.lt_token).0);
+ tokens_helper(_visitor, &mut _i.lt_token.spans);
_visitor.visit_type_mut(&mut *_i.ty);
skip!(_i.position);
if let Some(ref mut it) = _i.as_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
- tokens_helper(_visitor, &mut (_i.gt_token).0);
+ tokens_helper(_visitor, &mut _i.gt_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
#[cfg(feature = "full")]
pub fn visit_range_limits_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut RangeLimits) {
match *_i {
RangeLimits::HalfOpen(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
RangeLimits::Closed(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
}
}
@@ -2824,7 +2950,7 @@
match *_i {
ReturnType::Default => {}
ReturnType::Type(ref mut _binding_0, ref mut _binding_1) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
_visitor.visit_type_mut(&mut **_binding_1);
}
}
@@ -2845,14 +2971,14 @@
}
Stmt::Semi(ref mut _binding_0, ref mut _binding_1) => {
_visitor.visit_expr_mut(_binding_0);
- tokens_helper(_visitor, &mut (_binding_1).0);
+ tokens_helper(_visitor, &mut _binding_1.spans);
}
}
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_trait_bound_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TraitBound) {
if let Some(ref mut it) = _i.paren_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_trait_bound_modifier_mut(&mut _i.modifier);
if let Some(ref mut it) = _i.lifetimes {
@@ -2868,7 +2994,7 @@
match *_i {
TraitBoundModifier::None => {}
TraitBoundModifier::Maybe(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
}
}
@@ -2897,15 +3023,15 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.const_token).0);
+ tokens_helper(_visitor, &mut _i.const_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon_token).0);
+ tokens_helper(_visitor, &mut _i.colon_token.spans);
_visitor.visit_type_mut(&mut _i.ty);
if let Some(ref mut it) = _i.default {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.spans);
_visitor.visit_expr_mut(&mut (it).1);
};
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_trait_item_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TraitItemMacro) {
@@ -2914,7 +3040,7 @@
}
_visitor.visit_macro_mut(&mut _i.mac);
if let Some(ref mut it) = _i.semi_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "full")]
@@ -2930,7 +3056,7 @@
_visitor.visit_block_mut(it)
};
if let Some(ref mut it) = _i.semi_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
}
#[cfg(feature = "full")]
@@ -2938,21 +3064,21 @@
for it in &mut _i.attrs {
_visitor.visit_attribute_mut(it)
}
- tokens_helper(_visitor, &mut (_i.type_token).0);
+ tokens_helper(_visitor, &mut _i.type_token.span);
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_generics_mut(&mut _i.generics);
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
_visitor.visit_type_param_bound_mut(it)
}
if let Some(ref mut it) = _i.default {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.spans);
_visitor.visit_type_mut(&mut (it).1);
};
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_trait_item_verbatim_mut<V: VisitMut + ?Sized>(
@@ -3013,41 +3139,41 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_array_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeArray) {
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
_visitor.visit_type_mut(&mut *_i.elem);
- tokens_helper(_visitor, &mut (_i.semi_token).0);
+ tokens_helper(_visitor, &mut _i.semi_token.spans);
_visitor.visit_expr_mut(&mut _i.len);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_bare_fn_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeBareFn) {
+ if let Some(ref mut it) = _i.lifetimes {
+ _visitor.visit_bound_lifetimes_mut(it)
+ };
if let Some(ref mut it) = _i.unsafety {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.abi {
_visitor.visit_abi_mut(it)
};
- tokens_helper(_visitor, &mut (_i.fn_token).0);
- if let Some(ref mut it) = _i.lifetimes {
- _visitor.visit_bound_lifetimes_mut(it)
- };
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.fn_token.span);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.inputs) {
let it = el.value_mut();
_visitor.visit_bare_fn_arg_mut(it)
}
if let Some(ref mut it) = _i.variadic {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
_visitor.visit_return_type_mut(&mut _i.output);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_group_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeGroup) {
- tokens_helper(_visitor, &mut (_i.group_token).0);
+ tokens_helper(_visitor, &mut _i.group_token.span);
_visitor.visit_type_mut(&mut *_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_impl_trait_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeImplTrait) {
- tokens_helper(_visitor, &mut (_i.impl_token).0);
+ tokens_helper(_visitor, &mut _i.impl_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
_visitor.visit_type_param_bound_mut(it)
@@ -3055,7 +3181,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_infer_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeInfer) {
- tokens_helper(_visitor, &mut (_i.underscore_token).0);
+ tokens_helper(_visitor, &mut _i.underscore_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_macro_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeMacro) {
@@ -3063,7 +3189,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_never_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeNever) {
- tokens_helper(_visitor, &mut (_i.bang_token).0);
+ tokens_helper(_visitor, &mut _i.bang_token.spans);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_param_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeParam) {
@@ -3072,14 +3198,14 @@
}
_visitor.visit_ident_mut(&mut _i.ident);
if let Some(ref mut it) = _i.colon_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
_visitor.visit_type_param_bound_mut(it)
}
if let Some(ref mut it) = _i.eq_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.spans)
};
if let Some(ref mut it) = _i.default {
_visitor.visit_type_mut(it)
@@ -3098,7 +3224,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_paren_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeParen) {
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
_visitor.visit_type_mut(&mut *_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -3110,29 +3236,29 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_ptr_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypePtr) {
- tokens_helper(_visitor, &mut (_i.star_token).0);
+ tokens_helper(_visitor, &mut _i.star_token.spans);
if let Some(ref mut it) = _i.const_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_type_mut(&mut *_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_reference_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeReference) {
- tokens_helper(_visitor, &mut (_i.and_token).0);
+ tokens_helper(_visitor, &mut _i.and_token.spans);
if let Some(ref mut it) = _i.lifetime {
_visitor.visit_lifetime_mut(it)
};
if let Some(ref mut it) = _i.mutability {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_type_mut(&mut *_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_slice_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeSlice) {
- tokens_helper(_visitor, &mut (_i.bracket_token).0);
+ tokens_helper(_visitor, &mut _i.bracket_token.span);
_visitor.visit_type_mut(&mut *_i.elem);
}
#[cfg(any(feature = "full", feature = "derive"))]
@@ -3141,7 +3267,7 @@
_i: &mut TypeTraitObject,
) {
if let Some(ref mut it) = _i.dyn_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
for mut el in Punctuated::pairs_mut(&mut _i.bounds) {
let it = el.value_mut();
@@ -3150,7 +3276,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_type_tuple_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut TypeTuple) {
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.elems) {
let it = el.value_mut();
_visitor.visit_type_mut(it)
@@ -3164,23 +3290,23 @@
pub fn visit_un_op_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UnOp) {
match *_i {
UnOp::Deref(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
UnOp::Not(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
UnOp::Neg(ref mut _binding_0) => {
- tokens_helper(_visitor, &mut (_binding_0).0);
+ tokens_helper(_visitor, &mut _binding_0.spans);
}
}
}
#[cfg(feature = "full")]
pub fn visit_use_glob_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseGlob) {
- tokens_helper(_visitor, &mut (_i.star_token).0);
+ tokens_helper(_visitor, &mut _i.star_token.spans);
}
#[cfg(feature = "full")]
pub fn visit_use_group_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseGroup) {
- tokens_helper(_visitor, &mut (_i.brace_token).0);
+ tokens_helper(_visitor, &mut _i.brace_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.items) {
let it = el.value_mut();
_visitor.visit_use_tree_mut(it)
@@ -3193,13 +3319,13 @@
#[cfg(feature = "full")]
pub fn visit_use_path_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UsePath) {
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.colon2_token).0);
+ tokens_helper(_visitor, &mut _i.colon2_token.spans);
_visitor.visit_use_tree_mut(&mut *_i.tree);
}
#[cfg(feature = "full")]
pub fn visit_use_rename_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseRename) {
_visitor.visit_ident_mut(&mut _i.ident);
- tokens_helper(_visitor, &mut (_i.as_token).0);
+ tokens_helper(_visitor, &mut _i.as_token.span);
_visitor.visit_ident_mut(&mut _i.rename);
}
#[cfg(feature = "full")]
@@ -3230,24 +3356,24 @@
_visitor.visit_ident_mut(&mut _i.ident);
_visitor.visit_fields_mut(&mut _i.fields);
if let Some(ref mut it) = _i.discriminant {
- tokens_helper(_visitor, &mut ((it).0).0);
+ tokens_helper(_visitor, &mut (it).0.spans);
_visitor.visit_expr_mut(&mut (it).1);
};
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_vis_crate_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut VisCrate) {
- tokens_helper(_visitor, &mut (_i.crate_token).0);
+ tokens_helper(_visitor, &mut _i.crate_token.span);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_vis_public_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut VisPublic) {
- tokens_helper(_visitor, &mut (_i.pub_token).0);
+ tokens_helper(_visitor, &mut _i.pub_token.span);
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_vis_restricted_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut VisRestricted) {
- tokens_helper(_visitor, &mut (_i.pub_token).0);
- tokens_helper(_visitor, &mut (_i.paren_token).0);
+ tokens_helper(_visitor, &mut _i.pub_token.span);
+ tokens_helper(_visitor, &mut _i.paren_token.span);
if let Some(ref mut it) = _i.in_token {
- tokens_helper(_visitor, &mut (it).0)
+ tokens_helper(_visitor, &mut it.span)
};
_visitor.visit_path_mut(&mut *_i.path);
}
@@ -3268,7 +3394,7 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
pub fn visit_where_clause_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut WhereClause) {
- tokens_helper(_visitor, &mut (_i.where_token).0);
+ tokens_helper(_visitor, &mut _i.where_token.span);
for mut el in Punctuated::pairs_mut(&mut _i.predicates) {
let it = el.value_mut();
_visitor.visit_where_predicate_mut(it)
diff --git a/src/generics.rs b/src/generics.rs
index d1f4fa2..07ea86b 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -166,7 +166,6 @@
type Item = &'a TypeParam;
fn next(&mut self) -> Option<Self::Item> {
- // FIXME: Remove this when ? on Option is stable
let next = match self.0.next() {
Some(item) => item,
None => return None,
@@ -185,7 +184,6 @@
type Item = &'a mut TypeParam;
fn next(&mut self) -> Option<Self::Item> {
- // FIXME: Remove this when ? on Option is stable
let next = match self.0.next() {
Some(item) => item,
None => return None,
@@ -204,7 +202,6 @@
type Item = &'a LifetimeDef;
fn next(&mut self) -> Option<Self::Item> {
- // FIXME: Remove this when ? on Option is stable
let next = match self.0.next() {
Some(item) => item,
None => return None,
@@ -223,7 +220,6 @@
type Item = &'a mut LifetimeDef;
fn next(&mut self) -> Option<Self::Item> {
- // FIXME: Remove this when ? on Option is stable
let next = match self.0.next() {
Some(item) => item,
None => return None,
@@ -242,7 +238,6 @@
type Item = &'a ConstParam;
fn next(&mut self) -> Option<Self::Item> {
- // FIXME: Remove this when ? on Option is stable
let next = match self.0.next() {
Some(item) => item,
None => return None,
@@ -261,7 +256,6 @@
type Item = &'a mut ConstParam;
fn next(&mut self) -> Option<Self::Item> {
- // FIXME: Remove this when ? on Option is stable
let next = match self.0.next() {
Some(item) => item,
None => return None,
@@ -309,19 +303,22 @@
/// ```
/// # extern crate proc_macro2;
/// # extern crate syn;
- /// # #[macro_use]
/// # extern crate quote;
+ /// #
/// # use proc_macro2::{Span, Ident};
+ /// # use quote::quote;
+ /// #
/// # fn main() {
- /// # let generics: syn::Generics = Default::default();
- /// # let name = Ident::new("MyType", Span::call_site());
+ /// # let generics: syn::Generics = Default::default();
+ /// # let name = Ident::new("MyType", Span::call_site());
+ /// #
/// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
/// quote! {
/// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
/// // ...
/// }
/// }
- /// # ;
+ /// # ;
/// # }
/// ```
///
@@ -468,7 +465,7 @@
/// `"full"` feature.*
pub Lifetime(PredicateLifetime {
pub lifetime: Lifetime,
- pub colon_token: Option<Token![:]>,
+ pub colon_token: Token![:],
pub bounds: Punctuated<Lifetime, Token![+]>,
}),
@@ -488,263 +485,380 @@
pub mod parsing {
use super::*;
- use punctuated::Pair;
- use synom::Synom;
+ use parse::{Parse, ParseStream, Result};
- impl Synom for Generics {
- named!(parse -> Self, map!(
- alt!(
- do_parse!(
- lt: punct!(<) >>
- lifetimes: call!(Punctuated::<LifetimeDef, Token![,]>::parse_terminated) >>
- ty_params: cond!(
- lifetimes.empty_or_trailing(),
- Punctuated::<TypeParam, Token![,]>::parse_terminated
- ) >>
- gt: punct!(>) >>
- (lifetimes, ty_params, Some(lt), Some(gt))
- )
- |
- epsilon!() => { |_| (Punctuated::new(), None, None, None) }
- ),
- |(lifetimes, ty_params, lt, gt)| Generics {
- lt_token: lt,
- params: lifetimes.into_pairs()
- .map(Pair::into_tuple)
- .map(|(life, comma)| Pair::new(GenericParam::Lifetime(life), comma))
- .chain(ty_params.unwrap_or_default()
- .into_pairs()
- .map(Pair::into_tuple)
- .map(|(ty, comma)| Pair::new(GenericParam::Type(ty), comma)))
- .collect(),
- gt_token: gt,
- where_clause: None,
+ impl Parse for Generics {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut params = Punctuated::new();
+
+ if !input.peek(Token![<]) {
+ return Ok(Generics {
+ lt_token: None,
+ params: params,
+ gt_token: None,
+ where_clause: None,
+ });
}
- ));
- fn description() -> Option<&'static str> {
- Some("generic parameters in declaration")
- }
- }
+ let lt_token: Token![<] = input.parse()?;
- impl Synom for GenericParam {
- named!(parse -> Self, alt!(
- syn!(TypeParam) => { GenericParam::Type }
- |
- syn!(LifetimeDef) => { GenericParam::Lifetime }
- |
- syn!(ConstParam) => { GenericParam::Const }
- ));
-
- fn description() -> Option<&'static str> {
- Some("generic parameter")
- }
- }
-
- impl Synom for LifetimeDef {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- life: syn!(Lifetime) >>
- colon: option!(punct!(:)) >>
- bounds: cond!(
- colon.is_some(),
- Punctuated::parse_separated_nonempty
- ) >>
- (LifetimeDef {
- attrs: attrs,
- lifetime: life,
- bounds: bounds.unwrap_or_default(),
- colon_token: colon,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("lifetime definition")
- }
- }
-
- impl Synom for BoundLifetimes {
- named!(parse -> Self, do_parse!(
- for_: keyword!(for) >>
- lt: punct!(<) >>
- lifetimes: call!(Punctuated::parse_terminated) >>
- gt: punct!(>) >>
- (BoundLifetimes {
- for_token: for_,
- lt_token: lt,
- gt_token: gt,
- lifetimes: lifetimes,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("bound lifetimes")
- }
- }
-
- impl Synom for TypeParam {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- id: syn!(Ident) >>
- colon: option!(punct!(:)) >>
- bounds: cond!(
- colon.is_some(),
- Punctuated::parse_separated_nonempty
- ) >>
- default: option!(do_parse!(
- eq: punct!(=) >>
- ty: syn!(Type) >>
- (eq, ty)
- )) >>
- (TypeParam {
- attrs: attrs,
- ident: id,
- bounds: bounds.unwrap_or_default(),
- colon_token: colon,
- eq_token: default.as_ref().map(|d| Token.0)),
- default: default.map(|d| d.1),
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("type parameter")
- }
- }
-
- impl Synom for TypeParamBound {
- named!(parse -> Self, alt!(
- syn!(Lifetime) => { TypeParamBound::Lifetime }
- |
- syn!(TraitBound) => { TypeParamBound::Trait }
- |
- parens!(syn!(TraitBound)) => {|(parens, mut bound)| {
- bound.paren_token = Some(parens);
- TypeParamBound::Trait(bound)
- }}
- ));
-
- fn description() -> Option<&'static str> {
- Some("type parameter bound")
- }
- }
-
- impl Synom for TraitBound {
- named!(parse -> Self, do_parse!(
- modifier: syn!(TraitBoundModifier) >>
- lifetimes: option!(syn!(BoundLifetimes)) >>
- mut path: syn!(Path) >>
- parenthesized: option!(cond_reduce!(
- path.segments.last().unwrap().value().arguments.is_empty(),
- syn!(ParenthesizedGenericArguments)
- )) >>
- ({
- if let Some(parenthesized) = parenthesized {
- let parenthesized = PathArguments::Parenthesized(parenthesized);
- path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
+ let mut has_type_param = false;
+ loop {
+ if input.peek(Token![>]) {
+ break;
}
- TraitBound {
- paren_token: None,
- modifier: modifier,
- lifetimes: lifetimes,
- path: path,
+
+ let attrs = input.call(Attribute::parse_outer)?;
+ let lookahead = input.lookahead1();
+ if !has_type_param && lookahead.peek(Lifetime) {
+ params.push_value(GenericParam::Lifetime(LifetimeDef {
+ attrs: attrs,
+ ..input.parse()?
+ }));
+ } else if lookahead.peek(Ident) {
+ has_type_param = true;
+ params.push_value(GenericParam::Type(TypeParam {
+ attrs: attrs,
+ ..input.parse()?
+ }));
+ } else {
+ return Err(lookahead.error());
}
+
+ if input.peek(Token![>]) {
+ break;
+ }
+ let punct = input.parse()?;
+ params.push_punct(punct);
+ }
+
+ let gt_token: Token![>] = input.parse()?;
+
+ Ok(Generics {
+ lt_token: Some(lt_token),
+ params: params,
+ gt_token: Some(gt_token),
+ where_clause: None,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("trait bound")
}
}
- impl Synom for TraitBoundModifier {
- named!(parse -> Self, alt!(
- punct!(?) => { TraitBoundModifier::Maybe }
- |
- epsilon!() => { |_| TraitBoundModifier::None }
- ));
+ impl Parse for GenericParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
- fn description() -> Option<&'static str> {
- Some("trait bound modifier")
- }
- }
-
- impl Synom for ConstParam {
- named!(parse -> Self, do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- const_: keyword!(const) >>
- ident: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- eq_def: option!(tuple!(punct!(=), syn!(Expr))) >>
- ({
- let (eq_token, default) = match eq_def {
- Some((eq_token, default)) => (Some(eq_token), Some(default)),
- None => (None, None),
- };
- ConstParam {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Ident) {
+ Ok(GenericParam::Type(TypeParam {
attrs: attrs,
- const_token: const_,
- ident: ident,
- colon_token: colon,
- ty: ty,
- eq_token: eq_token,
- default: default,
- }
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("generic `const` parameter")
+ ..input.parse()?
+ }))
+ } else if lookahead.peek(Lifetime) {
+ Ok(GenericParam::Lifetime(LifetimeDef {
+ attrs: attrs,
+ ..input.parse()?
+ }))
+ } else if lookahead.peek(Token![const]) {
+ Ok(GenericParam::Const(ConstParam {
+ attrs: attrs,
+ ..input.parse()?
+ }))
+ } else {
+ Err(lookahead.error())
+ }
}
}
- impl Synom for WhereClause {
- named!(parse -> Self, do_parse!(
- where_: keyword!(where) >>
- predicates: call!(Punctuated::parse_terminated) >>
- (WhereClause {
- predicates: predicates,
- where_token: where_,
+ impl Parse for LifetimeDef {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let has_colon;
+ Ok(LifetimeDef {
+ attrs: input.call(Attribute::parse_outer)?,
+ lifetime: input.parse()?,
+ colon_token: {
+ if input.peek(Token![:]) {
+ has_colon = true;
+ Some(input.parse()?)
+ } else {
+ has_colon = false;
+ None
+ }
+ },
+ bounds: {
+ let mut bounds = Punctuated::new();
+ if has_colon {
+ loop {
+ if input.peek(Token![,]) || input.peek(Token![>]) {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ }
+ bounds
+ },
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("where clause")
}
}
- impl Synom for WherePredicate {
- named!(parse -> Self, alt!(
- do_parse!(
- ident: syn!(Lifetime) >>
- colon: option!(punct!(:)) >>
- bounds: cond!(
- colon.is_some(),
- Punctuated::parse_separated
- ) >>
- (WherePredicate::Lifetime(PredicateLifetime {
- lifetime: ident,
- bounds: bounds.unwrap_or_default(),
- colon_token: colon,
- }))
- )
- |
- do_parse!(
- lifetimes: option!(syn!(BoundLifetimes)) >>
- bounded_ty: syn!(Type) >>
- colon: punct!(:) >>
- bounds: call!(Punctuated::parse_separated_nonempty) >>
- (WherePredicate::Type(PredicateType {
- lifetimes: lifetimes,
- bounded_ty: bounded_ty,
- bounds: bounds,
- colon_token: colon,
- }))
- )
- ));
+ impl Parse for BoundLifetimes {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(BoundLifetimes {
+ for_token: input.parse()?,
+ lt_token: input.parse()?,
+ lifetimes: {
+ let mut lifetimes = Punctuated::new();
+ while !input.peek(Token![>]) {
+ lifetimes.push_value(input.parse()?);
+ if input.peek(Token![>]) {
+ break;
+ }
+ lifetimes.push_punct(input.parse()?);
+ }
+ lifetimes
+ },
+ gt_token: input.parse()?,
+ })
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("predicate in where clause")
+ impl Parse for Option<BoundLifetimes> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![for]) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ impl Parse for TypeParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let has_colon;
+ let has_default;
+ Ok(TypeParam {
+ attrs: input.call(Attribute::parse_outer)?,
+ ident: input.parse()?,
+ colon_token: {
+ if input.peek(Token![:]) {
+ has_colon = true;
+ Some(input.parse()?)
+ } else {
+ has_colon = false;
+ None
+ }
+ },
+ bounds: {
+ let mut bounds = Punctuated::new();
+ if has_colon {
+ loop {
+ if input.peek(Token![,]) || input.peek(Token![>]) {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ }
+ bounds
+ },
+ eq_token: {
+ if input.peek(Token![=]) {
+ has_default = true;
+ Some(input.parse()?)
+ } else {
+ has_default = false;
+ None
+ }
+ },
+ default: {
+ if has_default {
+ Some(input.parse()?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+ }
+
+ impl Parse for TypeParamBound {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) {
+ return input.parse().map(TypeParamBound::Lifetime);
+ }
+
+ if input.peek(token::Paren) {
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let mut bound: TraitBound = content.parse()?;
+ bound.paren_token = Some(paren_token);
+ return Ok(TypeParamBound::Trait(bound));
+ }
+
+ input.parse().map(TypeParamBound::Trait)
+ }
+ }
+
+ impl Parse for TraitBound {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let modifier: TraitBoundModifier = input.parse()?;
+ let lifetimes: Option<BoundLifetimes> = input.parse()?;
+
+ let mut path: Path = input.parse()?;
+ if path.segments.last().unwrap().value().arguments.is_empty()
+ && input.peek(token::Paren)
+ {
+ let parenthesized = PathArguments::Parenthesized(input.parse()?);
+ path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
+ }
+
+ Ok(TraitBound {
+ paren_token: None,
+ modifier: modifier,
+ lifetimes: lifetimes,
+ path: path,
+ })
+ }
+ }
+
+ impl Parse for TraitBoundModifier {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![?]) {
+ input.parse().map(TraitBoundModifier::Maybe)
+ } else {
+ Ok(TraitBoundModifier::None)
+ }
+ }
+ }
+
+ impl Parse for ConstParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut default = None;
+ Ok(ConstParam {
+ attrs: input.call(Attribute::parse_outer)?,
+ const_token: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ eq_token: {
+ if input.peek(Token![=]) {
+ let eq_token = input.parse()?;
+ default = Some(input.parse::<Expr>()?);
+ Some(eq_token)
+ } else {
+ None
+ }
+ },
+ default: default,
+ })
+ }
+ }
+
+ impl Parse for WhereClause {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(WhereClause {
+ where_token: input.parse()?,
+ predicates: {
+ let mut predicates = Punctuated::new();
+ loop {
+ if input.peek(token::Brace)
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![:]) && !input.peek(Token![::])
+ || input.peek(Token![=])
+ {
+ break;
+ }
+ let value = input.parse()?;
+ predicates.push_value(value);
+ if !input.peek(Token![,]) {
+ break;
+ }
+ let punct = input.parse()?;
+ predicates.push_punct(punct);
+ }
+ predicates
+ },
+ })
+ }
+ }
+
+ impl Parse for Option<WhereClause> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![where]) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ impl Parse for WherePredicate {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) && input.peek2(Token![:]) {
+ Ok(WherePredicate::Lifetime(PredicateLifetime {
+ lifetime: input.parse()?,
+ colon_token: input.parse()?,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.peek(token::Brace)
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![:])
+ || input.peek(Token![=])
+ {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ bounds
+ },
+ }))
+ } else {
+ Ok(WherePredicate::Type(PredicateType {
+ lifetimes: input.parse()?,
+ bounded_ty: input.parse()?,
+ colon_token: input.parse()?,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.peek(token::Brace)
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![:]) && !input.peek(Token![::])
+ || input.peek(Token![=])
+ {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ bounds
+ },
+ }))
+ }
}
}
}
@@ -752,10 +866,13 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use attr::FilterAttrs;
+
use proc_macro2::TokenStream;
use quote::{ToTokens, TokenStreamExt};
+ use attr::FilterAttrs;
+ use print::TokensOrDefault;
+
impl ToTokens for Generics {
fn to_tokens(&self, tokens: &mut TokenStream) {
if self.params.is_empty() {
@@ -998,10 +1115,8 @@
impl ToTokens for PredicateLifetime {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.lifetime.to_tokens(tokens);
- if !self.bounds.is_empty() {
- TokensOrDefault(&self.colon_token).to_tokens(tokens);
- self.bounds.to_tokens(tokens);
- }
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
}
}
diff --git a/src/group.rs b/src/group.rs
new file mode 100644
index 0000000..b2e4659
--- /dev/null
+++ b/src/group.rs
@@ -0,0 +1,289 @@
+use proc_macro2::{Delimiter, Span};
+
+use error::Result;
+use parse::{ParseBuffer, ParseStream};
+use private;
+use token;
+
+// Not public API.
+#[doc(hidden)]
+pub struct Parens<'a> {
+ pub token: token::Paren,
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[doc(hidden)]
+pub struct Braces<'a> {
+ pub token: token::Brace,
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[doc(hidden)]
+pub struct Brackets<'a> {
+ pub token: token::Bracket,
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[cfg(any(feature = "full", feature = "derive"))]
+#[doc(hidden)]
+pub struct Group<'a> {
+ pub token: token::Group,
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse_parens(input: ParseStream) -> Result<Parens> {
+ parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
+ token: token::Paren(span),
+ content: content,
+ })
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse_braces(input: ParseStream) -> Result<Braces> {
+ parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
+ token: token::Brace(span),
+ content: content,
+ })
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse_brackets(input: ParseStream) -> Result<Brackets> {
+ parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
+ token: token::Bracket(span),
+ content: content,
+ })
+}
+
+#[cfg(any(feature = "full", feature = "derive"))]
+impl private {
+ pub fn parse_group(input: ParseStream) -> Result<Group> {
+ parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
+ token: token::Group(span),
+ content: content,
+ })
+ }
+}
+
+fn parse_delimited(input: ParseStream, delimiter: Delimiter) -> Result<(Span, ParseBuffer)> {
+ input.step(|cursor| {
+ if let Some((content, span, rest)) = cursor.group(delimiter) {
+ let unexpected = private::get_unexpected(input);
+ let nested = private::advance_step_cursor(cursor, content);
+ let content = private::new_parse_buffer(span, nested, unexpected);
+ Ok(((span, content), rest))
+ } else {
+ let message = match delimiter {
+ Delimiter::Parenthesis => "expected parentheses",
+ Delimiter::Brace => "expected curly braces",
+ Delimiter::Bracket => "expected square brackets",
+ Delimiter::None => "expected invisible group",
+ };
+ Err(cursor.error(message))
+ }
+ })
+}
+
+/// Parse a set of parentheses and expose their content to subsequent parsers.
+///
+/// # Example
+///
+/// ```rust
+/// # extern crate quote;
+/// # extern crate syn;
+/// #
+/// # use quote::quote;
+/// #
+/// use syn::{parenthesized, token, Ident, Token, Type};
+/// use syn::parse::{Parse, ParseStream, Result};
+/// use syn::punctuated::Punctuated;
+///
+/// // Parse a simplified tuple struct syntax like:
+/// //
+/// // struct S(A, B);
+/// struct TupleStruct {
+/// struct_token: Token![struct],
+/// ident: Ident,
+/// paren_token: token::Paren,
+/// fields: Punctuated<Type, Token![,]>,
+/// semi_token: Token![;],
+/// }
+///
+/// impl Parse for TupleStruct {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let content;
+/// Ok(TupleStruct {
+/// struct_token: input.parse()?,
+/// ident: input.parse()?,
+/// paren_token: parenthesized!(content in input),
+/// fields: content.parse_terminated(Type::parse)?,
+/// semi_token: input.parse()?,
+/// })
+/// }
+/// }
+/// #
+/// # fn main() {
+/// # let input = quote! {
+/// # struct S(A, B);
+/// # };
+/// # syn::parse2::<TupleStruct>(input).unwrap();
+/// # }
+/// ```
+#[macro_export]
+macro_rules! parenthesized {
+ ($content:ident in $cursor:expr) => {
+ match $crate::group::parse_parens(&$cursor) {
+ $crate::export::Ok(parens) => {
+ $content = parens.content;
+ parens.token
+ }
+ $crate::export::Err(error) => {
+ return $crate::export::Err(error);
+ }
+ }
+ };
+}
+
+/// Parse a set of curly braces and expose their content to subsequent parsers.
+///
+/// # Example
+///
+/// ```rust
+/// # extern crate quote;
+/// # extern crate syn;
+/// #
+/// # use quote::quote;
+/// #
+/// use syn::{braced, token, Ident, Token, Type};
+/// use syn::parse::{Parse, ParseStream, Result};
+/// use syn::punctuated::Punctuated;
+///
+/// // Parse a simplified struct syntax like:
+/// //
+/// // struct S {
+/// // a: A,
+/// // b: B,
+/// // }
+/// struct Struct {
+/// struct_token: Token![struct],
+/// ident: Ident,
+/// brace_token: token::Brace,
+/// fields: Punctuated<Field, Token![,]>,
+/// }
+///
+/// struct Field {
+/// name: Ident,
+/// colon_token: Token![:],
+/// ty: Type,
+/// }
+///
+/// impl Parse for Struct {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let content;
+/// Ok(Struct {
+/// struct_token: input.parse()?,
+/// ident: input.parse()?,
+/// brace_token: braced!(content in input),
+/// fields: content.parse_terminated(Field::parse)?,
+/// })
+/// }
+/// }
+///
+/// impl Parse for Field {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// Ok(Field {
+/// name: input.parse()?,
+/// colon_token: input.parse()?,
+/// ty: input.parse()?,
+/// })
+/// }
+/// }
+/// #
+/// # fn main() {
+/// # let input = quote! {
+/// # struct S {
+/// # a: A,
+/// # b: B,
+/// # }
+/// # };
+/// # syn::parse2::<Struct>(input).unwrap();
+/// # }
+/// ```
+#[macro_export]
+macro_rules! braced {
+ ($content:ident in $cursor:expr) => {
+ match $crate::group::parse_braces(&$cursor) {
+ $crate::export::Ok(braces) => {
+ $content = braces.content;
+ braces.token
+ }
+ $crate::export::Err(error) => {
+ return $crate::export::Err(error);
+ }
+ }
+ };
+}
+
+/// Parse a set of square brackets and expose their content to subsequent
+/// parsers.
+///
+/// # Example
+///
+/// ```rust
+/// # extern crate proc_macro2;
+/// # extern crate quote;
+/// # extern crate syn;
+/// #
+/// # use quote::quote;
+/// #
+/// use proc_macro2::TokenStream;
+/// use syn::{bracketed, token, Token};
+/// use syn::parse::{Parse, ParseStream, Result};
+///
+/// // Parse an outer attribute like:
+/// //
+/// // #[repr(C, packed)]
+/// struct OuterAttribute {
+/// pound_token: Token![#],
+/// bracket_token: token::Bracket,
+/// content: TokenStream,
+/// }
+///
+/// impl Parse for OuterAttribute {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let content;
+/// Ok(OuterAttribute {
+/// pound_token: input.parse()?,
+/// bracket_token: bracketed!(content in input),
+/// content: content.parse()?,
+/// })
+/// }
+/// }
+/// #
+/// # fn main() {
+/// # let input = quote! {
+/// # #[repr(C, packed)]
+/// # };
+/// # syn::parse2::<OuterAttribute>(input).unwrap();
+/// # }
+/// ```
+#[macro_export]
+macro_rules! bracketed {
+ ($content:ident in $cursor:expr) => {
+ match $crate::group::parse_brackets(&$cursor) {
+ $crate::export::Ok(brackets) => {
+ $content = brackets.content;
+ brackets.token
+ }
+ $crate::export::Err(error) => {
+ return $crate::export::Err(error);
+ }
+ }
+ };
+}
diff --git a/src/ident.rs b/src/ident.rs
new file mode 100644
index 0000000..368b0c3
--- /dev/null
+++ b/src/ident.rs
@@ -0,0 +1,37 @@
+#[cfg(feature = "parsing")]
+use lookahead;
+#[cfg(feature = "parsing")]
+use parse::{Parse, ParseStream, Result};
+
+pub use proc_macro2::Ident;
+
+#[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Ident(marker: lookahead::TokenMarker) -> Ident {
+ match marker {}
+}
+
+#[cfg(feature = "parsing")]
+impl Parse for Ident {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((ident, rest)) = cursor.ident() {
+ match ident.to_string().as_str() {
+ "_"
+ // Based on https://doc.rust-lang.org/grammar.html#keywords
+ // and https://github.com/rust-lang/rfcs/blob/master/text/2421-unreservations-2018.md
+ | "abstract" | "as" | "become" | "box" | "break" | "const"
+ | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
+ | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
+ | "mod" | "move" | "mut" | "override" | "priv" | "proc" | "pub"
+ | "ref" | "return" | "Self" | "self" | "static" | "struct"
+ | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
+ | "virtual" | "where" | "while" | "yield" => {}
+ _ => return Ok((ident, rest)),
+ }
+ }
+ Err(cursor.error("expected identifier"))
+ })
+ }
+}
diff --git a/src/item.rs b/src/item.rs
index 7e49a4a..c31bb9c 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -93,6 +93,7 @@
pub vis: Visibility,
pub constness: Option<Token![const]>,
pub unsafety: Option<Token![unsafe]>,
+ pub asyncness: Option<Token![async]>,
pub abi: Option<Abi>,
pub ident: Ident,
pub decl: Box<FnDecl>,
@@ -135,6 +136,21 @@
pub semi_token: Token![;],
}),
+ /// An existential type: `existential type Iter: Iterator<Item = u8>`.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub Existential(ItemExistential {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub existential_token: Token![existential],
+ pub type_token: Token![type],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Option<Token![:]>,
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ pub semi_token: Token![;],
+ }),
+
/// A struct definition: `struct Foo<A> { x: A }`.
///
/// *This type is available if Syn is built with the `"full"` feature.*
@@ -190,6 +206,20 @@
pub items: Vec<TraitItem>,
}),
+ /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub TraitAlias(ItemTraitAlias {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub trait_token: Token![trait],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub eq_token: Token![=],
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ pub semi_token: Token![;],
+ }),
+
/// An impl block providing trait or associated items: `impl<A> Trait
/// for Data<A> { ... }`.
///
@@ -429,6 +459,15 @@
pub semi_token: Token![;],
}),
+ /// A macro invocation within an extern block.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub Macro(ForeignItemMacro {
+ pub attrs: Vec<Attribute>,
+ pub mac: Macro,
+ pub semi_token: Option<Token![;]>,
+ }),
+
/// Tokens in an `extern` block not interpreted by Syn.
///
/// *This type is available if Syn is built with the `"full"` feature.*
@@ -597,6 +636,20 @@
pub semi_token: Token![;],
}),
+ /// An existential type within an impl block.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub Existential(ImplItemExistential {
+ pub attrs: Vec<Attribute>,
+ pub existential_token: Token![existential],
+ pub type_token: Token![type],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Option<Token![:]>,
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ pub semi_token: Token![;],
+ }),
+
/// A macro invocation within an impl block.
///
/// *This type is available if Syn is built with the `"full"` feature.*
@@ -643,6 +696,7 @@
pub struct MethodSig {
pub constness: Option<Token![const]>,
pub unsafety: Option<Token![unsafe]>,
+ pub asyncness: Option<Token![async]>,
pub abi: Option<Abi>,
pub ident: Ident,
pub decl: FnDecl,
@@ -714,681 +768,861 @@
pub mod parsing {
use super::*;
- use synom::Synom;
+ use ext::IdentExt;
+ use parse::{Parse, ParseStream, Result};
- impl_synom!(Item "item" alt!(
- syn!(ItemExternCrate) => { Item::ExternCrate }
- |
- syn!(ItemUse) => { Item::Use }
- |
- syn!(ItemStatic) => { Item::Static }
- |
- syn!(ItemConst) => { Item::Const }
- |
- syn!(ItemFn) => { Item::Fn }
- |
- call!(unstable_async_fn) => { Item::Verbatim }
- |
- syn!(ItemMod) => { Item::Mod }
- |
- syn!(ItemForeignMod) => { Item::ForeignMod }
- |
- syn!(ItemType) => { Item::Type }
- |
- call!(unstable_existential_type) => { Item::Verbatim }
- |
- syn!(ItemStruct) => { Item::Struct }
- |
- syn!(ItemEnum) => { Item::Enum }
- |
- syn!(ItemUnion) => { Item::Union }
- |
- syn!(ItemTrait) => { Item::Trait }
- |
- syn!(ItemImpl) => { Item::Impl }
- |
- syn!(ItemMacro) => { Item::Macro }
- |
- syn!(ItemMacro2) => { Item::Macro2 }
- ));
+ impl Parse for Item {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+ let vis: Visibility = ahead.parse()?;
- impl_synom!(ItemMacro "macro item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- what: call!(Path::parse_mod_style) >>
- bang: punct!(!) >>
- ident: option!(syn!(Ident)) >>
- body: call!(tt::delimited) >>
- semi: cond!(!is_brace(&body.0), punct!(;)) >>
- (ItemMacro {
- attrs: attrs,
- ident: ident,
- mac: Macro {
- path: what,
- bang_token: bang,
- delimiter: body.0,
- tts: body.1,
- },
- semi_token: semi,
- })
- ));
-
- // TODO: figure out the actual grammar; is body required to be braced?
- impl_synom!(ItemMacro2 "macro2 item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- macro_: keyword!(macro) >>
- ident: syn!(Ident) >>
- args: call!(tt::parenthesized) >>
- body: call!(tt::braced) >>
- (ItemMacro2 {
- attrs: attrs,
- vis: vis,
- macro_token: macro_,
- ident: ident,
- paren_token: args.0,
- args: args.1,
- brace_token: body.0,
- body: body.1,
- })
- ));
-
- impl_synom!(ItemExternCrate "extern crate item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- extern_: keyword!(extern) >>
- crate_: keyword!(crate) >>
- ident: syn!(Ident) >>
- rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
- semi: punct!(;) >>
- (ItemExternCrate {
- attrs: attrs,
- vis: vis,
- extern_token: extern_,
- crate_token: crate_,
- ident: ident,
- rename: rename,
- semi_token: semi,
- })
- ));
-
- impl_synom!(ItemUse "use item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- use_: keyword!(use) >>
- leading_colon: option!(punct!(::)) >>
- tree: syn!(UseTree) >>
- semi: punct!(;) >>
- (ItemUse {
- attrs: attrs,
- vis: vis,
- use_token: use_,
- leading_colon: leading_colon,
- tree: tree,
- semi_token: semi,
- })
- ));
-
- named!(use_element -> Ident, alt!(
- syn!(Ident)
- |
- keyword!(self) => { Into::into }
- |
- keyword!(super) => { Into::into }
- |
- keyword!(crate) => { Into::into }
- |
- keyword!(extern) => { Into::into }
- ));
-
- impl_synom!(UseTree "use tree" alt!(
- syn!(UseRename) => { UseTree::Rename }
- |
- syn!(UsePath) => { UseTree::Path }
- |
- syn!(UseName) => { UseTree::Name }
- |
- syn!(UseGlob) => { UseTree::Glob }
- |
- syn!(UseGroup) => { UseTree::Group }
- ));
-
- impl_synom!(UsePath "use path" do_parse!(
- ident: call!(use_element) >>
- colon2_token: punct!(::) >>
- tree: syn!(UseTree) >>
- (UsePath {
- ident: ident,
- colon2_token: colon2_token,
- tree: Box::new(tree),
- })
- ));
-
- impl_synom!(UseName "use name" do_parse!(
- ident: call!(use_element) >>
- (UseName {
- ident: ident,
- })
- ));
-
- impl_synom!(UseRename "use rename" do_parse!(
- ident: call!(use_element) >>
- as_token: keyword!(as) >>
- rename: syn!(Ident) >>
- (UseRename {
- ident: ident,
- as_token: as_token,
- rename: rename,
- })
- ));
-
- impl_synom!(UseGlob "use glob" do_parse!(
- star: punct!(*) >>
- (UseGlob {
- star_token: star,
- })
- ));
-
- impl_synom!(UseGroup "use group" do_parse!(
- list: braces!(Punctuated::parse_terminated) >>
- (UseGroup {
- brace_token: list.0,
- items: list.1,
- })
- ));
-
- impl_synom!(ItemStatic "static item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- static_: keyword!(static) >>
- mutability: option!(keyword!(mut)) >>
- ident: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- eq: punct!(=) >>
- value: syn!(Expr) >>
- semi: punct!(;) >>
- (ItemStatic {
- attrs: attrs,
- vis: vis,
- static_token: static_,
- mutability: mutability,
- ident: ident,
- colon_token: colon,
- ty: Box::new(ty),
- eq_token: eq,
- expr: Box::new(value),
- semi_token: semi,
- })
- ));
-
- impl_synom!(ItemConst "const item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- const_: keyword!(const) >>
- ident: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- eq: punct!(=) >>
- value: syn!(Expr) >>
- semi: punct!(;) >>
- (ItemConst {
- attrs: attrs,
- vis: vis,
- const_token: const_,
- ident: ident,
- colon_token: colon,
- ty: Box::new(ty),
- eq_token: eq,
- expr: Box::new(value),
- semi_token: semi,
- })
- ));
-
- impl_synom!(ItemFn "fn item" do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- constness: option!(keyword!(const)) >>
- unsafety: option!(keyword!(unsafe)) >>
- abi: option!(syn!(Abi)) >>
- fn_: keyword!(fn) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- inputs: parens!(Punctuated::parse_terminated) >>
- ret: syn!(ReturnType) >>
- where_clause: option!(syn!(WhereClause)) >>
- inner_attrs_stmts: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ItemFn {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((inner_attrs_stmts.1).0);
- attrs
- },
- vis: vis,
- constness: constness,
- unsafety: unsafety,
- abi: abi,
- decl: Box::new(FnDecl {
- fn_token: fn_,
- paren_token: inputs.0,
- inputs: inputs.1,
- output: ret,
- variadic: None,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- }),
- ident: ident,
- block: Box::new(Block {
- brace_token: inner_attrs_stmts.0,
- stmts: (inner_attrs_stmts.1).1,
- }),
- })
- ));
-
- named!(unstable_async_fn -> ItemVerbatim, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- syn!(Visibility) >>
- option!(keyword!(const)) >>
- option!(keyword!(unsafe)) >>
- keyword!(async) >>
- option!(syn!(Abi)) >>
- keyword!(fn) >>
- syn!(Ident) >>
- syn!(Generics) >>
- parens!(Punctuated::<FnArg, Token![,]>::parse_terminated) >>
- syn!(ReturnType) >>
- option!(syn!(WhereClause)) >>
- braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- end: call!(verbatim::grab_cursor) >>
- (ItemVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- ));
-
- impl Synom for FnArg {
- named!(parse -> Self, alt!(
- do_parse!(
- and: punct!(&) >>
- lt: option!(syn!(Lifetime)) >>
- mutability: option!(keyword!(mut)) >>
- self_: keyword!(self) >>
- not!(punct!(:)) >>
- (ArgSelfRef {
- lifetime: lt,
- mutability: mutability,
- and_token: and,
- self_token: self_,
- }.into())
- )
- |
- do_parse!(
- mutability: option!(keyword!(mut)) >>
- self_: keyword!(self) >>
- not!(punct!(:)) >>
- (ArgSelf {
- mutability: mutability,
- self_token: self_,
- }.into())
- )
- |
- do_parse!(
- pat: syn!(Pat) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- (ArgCaptured {
- pat: pat,
- ty: ty,
- colon_token: colon,
- }.into())
- )
- |
- syn!(Type) => { FnArg::Ignored }
- ));
-
- fn description() -> Option<&'static str> {
- Some("function argument")
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![extern]) {
+ ahead.parse::<Token![extern]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![crate]) {
+ input.parse().map(Item::ExternCrate)
+ } else if lookahead.peek(Token![fn]) {
+ input.parse().map(Item::Fn)
+ } else if lookahead.peek(token::Brace) {
+ input.parse().map(Item::ForeignMod)
+ } else if lookahead.peek(LitStr) {
+ ahead.parse::<LitStr>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(token::Brace) {
+ input.parse().map(Item::ForeignMod)
+ } else if lookahead.peek(Token![fn]) {
+ input.parse().map(Item::Fn)
+ } else {
+ Err(lookahead.error())
+ }
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![use]) {
+ input.parse().map(Item::Use)
+ } else if lookahead.peek(Token![static]) {
+ input.parse().map(Item::Static)
+ } else if lookahead.peek(Token![const]) {
+ ahead.parse::<Token![const]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Ident) {
+ input.parse().map(Item::Const)
+ } else if lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![async])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(Item::Fn)
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![unsafe]) {
+ ahead.parse::<Token![unsafe]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![trait])
+ || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
+ {
+ input.parse().map(Item::Trait)
+ } else if lookahead.peek(Token![impl ]) {
+ input.parse().map(Item::Impl)
+ } else if lookahead.peek(Token![async])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(Item::Fn)
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![async]) || lookahead.peek(Token![fn]) {
+ input.parse().map(Item::Fn)
+ } else if lookahead.peek(Token![mod]) {
+ input.parse().map(Item::Mod)
+ } else if lookahead.peek(Token![type]) {
+ input.parse().map(Item::Type)
+ } else if lookahead.peek(Token![existential]) {
+ input.parse().map(Item::Existential)
+ } else if lookahead.peek(Token![struct]) {
+ input.parse().map(Item::Struct)
+ } else if lookahead.peek(Token![enum]) {
+ input.parse().map(Item::Enum)
+ } else if lookahead.peek(Token![union]) && ahead.peek2(Ident) {
+ input.parse().map(Item::Union)
+ } else if lookahead.peek(Token![trait])
+ || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
+ {
+ input.parse().map(Item::Trait)
+ } else if lookahead.peek(Token![impl ])
+ || lookahead.peek(Token![default]) && !ahead.peek2(Token![!])
+ {
+ input.parse().map(Item::Impl)
+ } else if lookahead.peek(Token![macro]) {
+ input.parse().map(Item::Macro2)
+ } else if vis.is_inherited()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(Item::Macro)
+ } else {
+ Err(lookahead.error())
+ }
}
}
- impl_synom!(ItemMod "mod item" do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- mod_: keyword!(mod) >>
- ident: syn!(Ident) >>
- content_semi: alt!(
- punct!(;) => {|semi| (
- Vec::new(),
- None,
- Some(semi),
- )}
- |
- braces!(
- tuple!(
- many0!(Attribute::parse_inner),
- many0!(Item::parse),
- )
- ) => {|(brace, (inner_attrs, items))| (
- inner_attrs,
- Some((brace, items)),
- None,
- )}
- ) >>
- (ItemMod {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend(content_semi.0);
- attrs
- },
- vis: vis,
- mod_token: mod_,
- ident: ident,
- content: content_semi.1,
- semi: content_semi.2,
- })
- ));
-
- impl_synom!(ItemForeignMod "foreign mod item" do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- abi: syn!(Abi) >>
- braced_content: braces!(tuple!(
- many0!(Attribute::parse_inner),
- many0!(ForeignItem::parse),
- )) >>
- (ItemForeignMod {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((braced_content.1).0);
- attrs
- },
- abi: abi,
- brace_token: braced_content.0,
- items: (braced_content.1).1,
- })
- ));
-
- impl_synom!(ForeignItem "foreign item" alt!(
- syn!(ForeignItemFn) => { ForeignItem::Fn }
- |
- syn!(ForeignItemStatic) => { ForeignItem::Static }
- |
- syn!(ForeignItemType) => { ForeignItem::Type }
- |
- call!(foreign_item_macro) => { ForeignItem::Verbatim }
- ));
-
- impl_synom!(ForeignItemFn "foreign function" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- fn_: keyword!(fn) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- inputs: parens!(do_parse!(
- args: call!(Punctuated::parse_terminated) >>
- variadic: option!(cond_reduce!(args.empty_or_trailing(), punct!(...))) >>
- (args, variadic)
- )) >>
- ret: syn!(ReturnType) >>
- where_clause: option!(syn!(WhereClause)) >>
- semi: punct!(;) >>
- ({
- let (parens, (inputs, variadic)) = inputs;
- ForeignItemFn {
- ident: ident,
+ impl Parse for ItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let path = input.call(Path::parse_mod_style)?;
+ let bang_token: Token![!] = input.parse()?;
+ let ident: Option<Ident> = input.parse()?;
+ let (delimiter, tts) = input.call(mac::parse_delimiter)?;
+ let semi_token: Option<Token![;]> = if !delimiter.is_brace() {
+ Some(input.parse()?)
+ } else {
+ None
+ };
+ Ok(ItemMacro {
attrs: attrs,
- semi_token: semi,
+ ident: ident,
+ mac: Macro {
+ path: path,
+ bang_token: bang_token,
+ delimiter: delimiter,
+ tts: tts,
+ },
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ // TODO: figure out the actual grammar; is body required to be braced?
+ impl Parse for ItemMacro2 {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let args;
+ let body;
+ Ok(ItemMacro2 {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ macro_token: input.parse()?,
+ ident: input.parse()?,
+ paren_token: parenthesized!(args in input),
+ args: args.parse()?,
+ brace_token: braced!(body in input),
+ body: body.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ItemExternCrate {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemExternCrate {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ extern_token: input.parse()?,
+ crate_token: input.parse()?,
+ ident: input.parse()?,
+ rename: {
+ if input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let rename: Ident = input.parse()?;
+ Some((as_token, rename))
+ } else {
+ None
+ }
+ },
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ItemUse {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemUse {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ use_token: input.parse()?,
+ leading_colon: input.parse()?,
+ tree: input.call(use_tree)?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ fn use_tree(input: ParseStream) -> Result<UseTree> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![extern])
+ {
+ let ident = input.call(Ident::parse_any)?;
+ if input.peek(Token![::]) {
+ Ok(UseTree::Path(UsePath {
+ ident: ident,
+ colon2_token: input.parse()?,
+ tree: Box::new(input.call(use_tree)?),
+ }))
+ } else if input.peek(Token![as]) {
+ Ok(UseTree::Rename(UseRename {
+ ident: ident,
+ as_token: input.parse()?,
+ rename: input.parse()?,
+ }))
+ } else {
+ Ok(UseTree::Name(UseName { ident: ident }))
+ }
+ } else if lookahead.peek(Token![*]) {
+ Ok(UseTree::Glob(UseGlob {
+ star_token: input.parse()?,
+ }))
+ } else if lookahead.peek(token::Brace) {
+ let content;
+ Ok(UseTree::Group(UseGroup {
+ brace_token: braced!(content in input),
+ items: content.parse_terminated(use_tree)?,
+ }))
+ } else {
+ Err(lookahead.error())
+ }
+ }
+
+ impl Parse for ItemStatic {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemStatic {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ static_token: input.parse()?,
+ mutability: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ eq_token: input.parse()?,
+ expr: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ItemConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemConst {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ const_token: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ eq_token: input.parse()?,
+ expr: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ItemFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let constness: Option<Token![const]> = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let asyncness: Option<Token![async]> = input.parse()?;
+ let abi: Option<Abi> = input.parse()?;
+ let fn_token: Token![fn] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let generics: Generics = input.parse()?;
+
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let inputs = content.parse_terminated(FnArg::parse)?;
+
+ let output: ReturnType = input.parse()?;
+ let where_clause: Option<WhereClause> = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ItemFn {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ vis: vis,
+ constness: constness,
+ unsafety: unsafety,
+ asyncness: asyncness,
+ abi: abi,
+ ident: ident,
decl: Box::new(FnDecl {
- fn_token: fn_,
- paren_token: parens,
+ fn_token: fn_token,
+ paren_token: paren_token,
inputs: inputs,
- variadic: variadic,
- output: ret,
+ output: output,
+ variadic: None,
generics: Generics {
where_clause: where_clause,
..generics
},
}),
- vis: vis,
+ block: Box::new(Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ }),
+ })
+ }
+ }
+
+ impl Parse for FnArg {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![&]) {
+ let ahead = input.fork();
+ if ahead.call(arg_self_ref).is_ok() && !ahead.peek(Token![:]) {
+ return input.call(arg_self_ref).map(FnArg::SelfRef);
+ }
}
- })
- ));
- impl_synom!(ForeignItemStatic "foreign static" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- static_: keyword!(static) >>
- mutability: option!(keyword!(mut)) >>
- ident: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- semi: punct!(;) >>
- (ForeignItemStatic {
- ident: ident,
- attrs: attrs,
- semi_token: semi,
- ty: Box::new(ty),
- mutability: mutability,
- static_token: static_,
- colon_token: colon,
- vis: vis,
- })
- ));
+ if input.peek(Token![mut]) || input.peek(Token![self]) {
+ let ahead = input.fork();
+ if ahead.call(arg_self).is_ok() && !ahead.peek(Token![:]) {
+ return input.call(arg_self).map(FnArg::SelfValue);
+ }
+ }
- impl_synom!(ForeignItemType "foreign type" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- type_: keyword!(type) >>
- ident: syn!(Ident) >>
- semi: punct!(;) >>
- (ForeignItemType {
- attrs: attrs,
- vis: vis,
- type_token: type_,
- ident: ident,
- semi_token: semi,
- })
- ));
-
- named!(foreign_item_macro -> ForeignItemVerbatim, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- mac: syn!(Macro) >>
- cond!(!is_brace(&mac.delimiter), punct!(;)) >>
- end: call!(verbatim::grab_cursor) >>
- (ForeignItemVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- ));
-
- impl_synom!(ItemType "type item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- type_: keyword!(type) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- where_clause: option!(syn!(WhereClause)) >>
- eq: punct!(=) >>
- ty: syn!(Type) >>
- semi: punct!(;) >>
- (ItemType {
- attrs: attrs,
- vis: vis,
- type_token: type_,
- ident: ident,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- eq_token: eq,
- ty: Box::new(ty),
- semi_token: semi,
- })
- ));
-
- named!(existential_type_helper(vis: bool) -> TokenStream, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- cond_reduce!(vis, syn!(Visibility)) >>
- custom_keyword!(existential) >>
- keyword!(type) >>
- syn!(Ident) >>
- syn!(Generics) >>
- option!(syn!(WhereClause)) >>
- colon: option!(punct!(:)) >>
- cond!(
- colon.is_some(),
- Punctuated::<TypeParamBound, Token![+]>::parse_separated_nonempty
- ) >>
- punct!(;) >>
- end: call!(verbatim::grab_cursor) >>
- (verbatim::token_range(begin..end))
- ));
-
- named!(unstable_existential_type -> ItemVerbatim, map!(
- call!(existential_type_helper, true),
- |tts| ItemVerbatim { tts: tts }
- ));
-
- impl_synom!(ItemStruct "struct item" switch!(
- map!(syn!(DeriveInput), Into::into),
- Item::Struct(item) => value!(item)
- |
- _ => reject!()
- ));
-
- impl_synom!(ItemEnum "enum item" switch!(
- map!(syn!(DeriveInput), Into::into),
- Item::Enum(item) => value!(item)
- |
- _ => reject!()
- ));
-
- impl_synom!(ItemUnion "union item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- union_: keyword!(union) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- where_clause: option!(syn!(WhereClause)) >>
- fields: syn!(FieldsNamed) >>
- (ItemUnion {
- attrs: attrs,
- vis: vis,
- union_token: union_,
- ident: ident,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- fields: fields,
- })
- ));
-
- impl_synom!(ItemTrait "trait item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- unsafety: option!(keyword!(unsafe)) >>
- auto_: option!(keyword!(auto)) >>
- trait_: keyword!(trait) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- colon: option!(punct!(:)) >>
- bounds: cond!(colon.is_some(), Punctuated::parse_separated_nonempty) >>
- where_clause: option!(syn!(WhereClause)) >>
- body: braces!(many0!(TraitItem::parse)) >>
- (ItemTrait {
- attrs: attrs,
- vis: vis,
- unsafety: unsafety,
- auto_token: auto_,
- trait_token: trait_,
- ident: ident,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- colon_token: colon,
- supertraits: bounds.unwrap_or_default(),
- brace_token: body.0,
- items: body.1,
- })
- ));
-
- impl_synom!(TraitItem "trait item" alt!(
- syn!(TraitItemConst) => { TraitItem::Const }
- |
- syn!(TraitItemMethod) => { TraitItem::Method }
- |
- syn!(TraitItemType) => { TraitItem::Type }
- |
- call!(unstable_trait_existential_type) => { TraitItem::Verbatim }
- |
- syn!(TraitItemMacro) => { TraitItem::Macro }
- ));
-
- impl_synom!(TraitItemConst "const trait item" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- const_: keyword!(const) >>
- ident: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- default: option!(tuple!(punct!(=), syn!(Expr))) >>
- semi: punct!(;) >>
- (TraitItemConst {
- attrs: attrs,
- const_token: const_,
- ident: ident,
- colon_token: colon,
- ty: ty,
- default: default,
- semi_token: semi,
- })
- ));
-
- impl_synom!(TraitItemMethod "method trait item" do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- constness: option!(keyword!(const)) >>
- unsafety: option!(keyword!(unsafe)) >>
- abi: option!(syn!(Abi)) >>
- fn_: keyword!(fn) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- inputs: parens!(Punctuated::parse_terminated) >>
- ret: syn!(ReturnType) >>
- where_clause: option!(syn!(WhereClause)) >>
- body: option!(braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- ))) >>
- semi: cond!(body.is_none(), punct!(;)) >>
- ({
- let (inner_attrs, stmts) = match body {
- Some((b, (inner_attrs, stmts))) => (inner_attrs, Some((stmts, b))),
- None => (Vec::new(), None),
+ let ahead = input.fork();
+ let err = match ahead.call(arg_captured) {
+ Ok(_) => return input.call(arg_captured).map(FnArg::Captured),
+ Err(err) => err,
};
- TraitItemMethod {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend(inner_attrs);
- attrs
+
+ let ahead = input.fork();
+ if ahead.parse::<Type>().is_ok() {
+ return input.parse().map(FnArg::Ignored);
+ }
+
+ Err(err)
+ }
+ }
+
+ fn arg_self_ref(input: ParseStream) -> Result<ArgSelfRef> {
+ Ok(ArgSelfRef {
+ and_token: input.parse()?,
+ lifetime: input.parse()?,
+ mutability: input.parse()?,
+ self_token: input.parse()?,
+ })
+ }
+
+ fn arg_self(input: ParseStream) -> Result<ArgSelf> {
+ Ok(ArgSelf {
+ mutability: input.parse()?,
+ self_token: input.parse()?,
+ })
+ }
+
+ fn arg_captured(input: ParseStream) -> Result<ArgCaptured> {
+ Ok(ArgCaptured {
+ pat: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ })
+ }
+
+ impl Parse for ItemMod {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let mod_token: Token![mod] = input.parse()?;
+ let ident: Ident = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![;]) {
+ Ok(ItemMod {
+ attrs: outer_attrs,
+ vis: vis,
+ mod_token: mod_token,
+ ident: ident,
+ content: None,
+ semi: Some(input.parse()?),
+ })
+ } else if lookahead.peek(token::Brace) {
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemMod {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ vis: vis,
+ mod_token: mod_token,
+ ident: ident,
+ content: Some((brace_token, items)),
+ semi: None,
+ })
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ impl Parse for ItemForeignMod {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let abi: Abi = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemForeignMod {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ abi: abi,
+ brace_token: brace_token,
+ items: items,
+ })
+ }
+ }
+
+ impl Parse for ForeignItem {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+ let vis: Visibility = ahead.parse()?;
+
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![fn]) {
+ input.parse().map(ForeignItem::Fn)
+ } else if lookahead.peek(Token![static]) {
+ input.parse().map(ForeignItem::Static)
+ } else if lookahead.peek(Token![type]) {
+ input.parse().map(ForeignItem::Type)
+ } else if vis.is_inherited()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(ForeignItem::Macro)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ impl Parse for ForeignItemFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let fn_token: Token![fn] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let generics: Generics = input.parse()?;
+
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let mut inputs = Punctuated::new();
+ while !content.is_empty() && !content.peek(Token![...]) {
+ inputs.push_value(content.parse()?);
+ if content.is_empty() {
+ break;
+ }
+ inputs.push_punct(content.parse()?);
+ }
+ let variadic: Option<Token![...]> = if inputs.empty_or_trailing() {
+ content.parse()?
+ } else {
+ None
+ };
+
+ let output: ReturnType = input.parse()?;
+ let where_clause: Option<WhereClause> = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(ForeignItemFn {
+ attrs: attrs,
+ vis: vis,
+ ident: ident,
+ decl: Box::new(FnDecl {
+ fn_token: fn_token,
+ paren_token: paren_token,
+ inputs: inputs,
+ output: output,
+ variadic: variadic,
+ generics: Generics {
+ where_clause: where_clause,
+ ..generics
+ },
+ }),
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for ForeignItemStatic {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ForeignItemStatic {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ static_token: input.parse()?,
+ mutability: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ForeignItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ForeignItemType {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ type_token: input.parse()?,
+ ident: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ForeignItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mac: Macro = input.parse()?;
+ let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+ None
+ } else {
+ Some(input.parse()?)
+ };
+ Ok(ForeignItemMacro {
+ attrs: attrs,
+ mac: mac,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for ItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemType {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ type_token: input.parse()?,
+ ident: input.parse()?,
+ generics: {
+ let mut generics: Generics = input.parse()?;
+ generics.where_clause = input.parse()?;
+ generics
},
+ eq_token: input.parse()?,
+ ty: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ItemExistential {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemExistential {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ existential_token: input.parse()?,
+ type_token: input.parse()?,
+ ident: input.parse()?,
+ generics: {
+ let mut generics: Generics = input.parse()?;
+ generics.where_clause = input.parse()?;
+ generics
+ },
+ colon_token: Some(input.parse()?),
+ bounds: {
+ let mut bounds = Punctuated::new();
+ while !input.peek(Token![;]) {
+ if !bounds.is_empty() {
+ bounds.push_punct(input.parse()?);
+ }
+ bounds.push_value(input.parse()?);
+ }
+ bounds
+ },
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ItemStruct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+ let struct_token = input.parse::<Token![struct]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, fields, semi_token) = derive::parsing::data_struct(input)?;
+ Ok(ItemStruct {
+ attrs: attrs,
+ vis: vis,
+ struct_token: struct_token,
+ ident: ident,
+ generics: Generics {
+ where_clause: where_clause,
+ ..generics
+ },
+ fields: fields,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for ItemEnum {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+ let enum_token = input.parse::<Token![enum]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, brace_token, variants) = derive::parsing::data_enum(input)?;
+ Ok(ItemEnum {
+ attrs: attrs,
+ vis: vis,
+ enum_token: enum_token,
+ ident: ident,
+ generics: Generics {
+ where_clause: where_clause,
+ ..generics
+ },
+ brace_token: brace_token,
+ variants: variants,
+ })
+ }
+ }
+
+ impl Parse for ItemUnion {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+ let union_token = input.parse::<Token![union]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, fields) = derive::parsing::data_union(input)?;
+ Ok(ItemUnion {
+ attrs: attrs,
+ vis: vis,
+ union_token: union_token,
+ ident: ident,
+ generics: Generics {
+ where_clause: where_clause,
+ ..generics
+ },
+ fields: fields,
+ })
+ }
+ }
+
+ impl Parse for ItemTrait {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let auto_token: Option<Token![auto]> = input.parse()?;
+ let trait_token: Token![trait] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+ let colon_token: Option<Token![:]> = input.parse()?;
+
+ let mut supertraits = Punctuated::new();
+ if colon_token.is_some() {
+ loop {
+ supertraits.push_value(input.parse()?);
+ if input.peek(Token![where]) || input.peek(token::Brace) {
+ break;
+ }
+ supertraits.push_punct(input.parse()?);
+ if input.peek(Token![where]) || input.peek(token::Brace) {
+ break;
+ }
+ }
+ }
+
+ generics.where_clause = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemTrait {
+ attrs: attrs,
+ vis: vis,
+ unsafety: unsafety,
+ auto_token: auto_token,
+ trait_token: trait_token,
+ ident: ident,
+ generics: generics,
+ colon_token: colon_token,
+ supertraits: supertraits,
+ brace_token: brace_token,
+ items: items,
+ })
+ }
+ }
+
+ impl Parse for ItemTraitAlias {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let trait_token: Token![trait] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+ let eq_token: Token![=] = input.parse()?;
+
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.peek(Token![where]) || input.peek(Token![;]) {
+ break;
+ }
+ bounds.push_value(input.parse()?);
+ if input.peek(Token![where]) || input.peek(Token![;]) {
+ break;
+ }
+ bounds.push_punct(input.parse()?);
+ }
+
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(ItemTraitAlias {
+ attrs: attrs,
+ vis: vis,
+ trait_token: trait_token,
+ ident: ident,
+ generics: generics,
+ eq_token: eq_token,
+ bounds: bounds,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for TraitItem {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![const]) {
+ ahead.parse::<Token![const]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Ident) {
+ input.parse().map(TraitItem::Const)
+ } else if lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(TraitItem::Method)
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(TraitItem::Method)
+ } else if lookahead.peek(Token![type]) {
+ input.parse().map(TraitItem::Type)
+ } else if lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::])
+ {
+ input.parse().map(TraitItem::Macro)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ impl Parse for TraitItemConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TraitItemConst {
+ attrs: input.call(Attribute::parse_outer)?,
+ const_token: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ default: {
+ if input.peek(Token![=]) {
+ let eq_token: Token![=] = input.parse()?;
+ let default: Expr = input.parse()?;
+ Some((eq_token, default))
+ } else {
+ None
+ }
+ },
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for TraitItemMethod {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let constness: Option<Token![const]> = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let abi: Option<Abi> = input.parse()?;
+ let fn_token: Token![fn] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let generics: Generics = input.parse()?;
+
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let inputs = content.parse_terminated(FnArg::parse)?;
+
+ let output: ReturnType = input.parse()?;
+ let where_clause: Option<WhereClause> = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let (brace_token, inner_attrs, stmts, semi_token) = if lookahead.peek(token::Brace) {
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+ (Some(brace_token), inner_attrs, stmts, None)
+ } else if lookahead.peek(Token![;]) {
+ let semi_token: Token![;] = input.parse()?;
+ (None, Vec::new(), Vec::new(), Some(semi_token))
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok(TraitItemMethod {
+ attrs: private::attrs(outer_attrs, inner_attrs),
sig: MethodSig {
constness: constness,
unsafety: unsafety,
+ asyncness: None,
abi: abi,
ident: ident,
decl: FnDecl {
- inputs: inputs.1,
- output: ret,
- fn_token: fn_,
- paren_token: inputs.0,
+ fn_token: fn_token,
+ paren_token: paren_token,
+ inputs: inputs,
+ output: output,
variadic: None,
generics: Generics {
where_clause: where_clause,
@@ -1396,260 +1630,322 @@
},
},
},
- default: stmts.map(|stmts| {
- Block {
- stmts: stmts.0,
- brace_token: stmts.1,
- }
+ default: brace_token.map(|brace_token| Block {
+ brace_token: brace_token,
+ stmts: stmts,
}),
- semi_token: semi,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for TraitItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let type_token: Token![type] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+ let colon_token: Option<Token![:]> = input.parse()?;
+
+ let mut bounds = Punctuated::new();
+ if colon_token.is_some() {
+ while !input.peek(Token![where]) && !input.peek(Token![=]) && !input.peek(Token![;])
+ {
+ if !bounds.is_empty() {
+ bounds.push_punct(input.parse()?);
+ }
+ bounds.push_value(input.parse()?);
+ }
}
- })
- ));
- impl_synom!(TraitItemType "trait item type" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- type_: keyword!(type) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- colon: option!(punct!(:)) >>
- bounds: cond!(colon.is_some(), Punctuated::parse_separated_nonempty) >>
- where_clause: option!(syn!(WhereClause)) >>
- default: option!(tuple!(punct!(=), syn!(Type))) >>
- semi: punct!(;) >>
- (TraitItemType {
- attrs: attrs,
- type_token: type_,
- ident: ident,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- colon_token: colon,
- bounds: bounds.unwrap_or_default(),
- default: default,
- semi_token: semi,
- })
- ));
+ generics.where_clause = input.parse()?;
+ let default = if input.peek(Token![=]) {
+ let eq_token: Token![=] = input.parse()?;
+ let default: Type = input.parse()?;
+ Some((eq_token, default))
+ } else {
+ None
+ };
+ let semi_token: Token![;] = input.parse()?;
- named!(unstable_trait_existential_type -> TraitItemVerbatim, map!(
- call!(existential_type_helper, false),
- |tts| TraitItemVerbatim { tts: tts }
- ));
-
- impl_synom!(TraitItemMacro "trait item macro" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- mac: syn!(Macro) >>
- semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
- (TraitItemMacro {
- attrs: attrs,
- mac: mac,
- semi_token: semi,
- })
- ));
-
- impl_synom!(ItemImpl "impl item" do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- defaultness: option!(keyword!(default)) >>
- unsafety: option!(keyword!(unsafe)) >>
- impl_: keyword!(impl) >>
- generics: syn!(Generics) >>
- polarity_path: alt!(
- do_parse!(
- polarity: option!(punct!(!)) >>
- path: syn!(Path) >>
- for_: keyword!(for) >>
- (Some((polarity, path, for_)))
- )
- |
- epsilon!() => { |_| None }
- ) >>
- self_ty: syn!(Type) >>
- where_clause: option!(syn!(WhereClause)) >>
- inner: braces!(tuple!(
- many0!(Attribute::parse_inner),
- many0!(ImplItem::parse),
- )) >>
- (ItemImpl {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((inner.1).0);
- attrs
- },
- defaultness: defaultness,
- unsafety: unsafety,
- impl_token: impl_,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- trait_: polarity_path,
- self_ty: Box::new(self_ty),
- brace_token: inner.0,
- items: (inner.1).1,
- })
- ));
-
- impl_synom!(ImplItem "item in impl block" alt!(
- syn!(ImplItemConst) => { ImplItem::Const }
- |
- syn!(ImplItemMethod) => { ImplItem::Method }
- |
- call!(unstable_async_method) => { ImplItem::Verbatim }
- |
- syn!(ImplItemType) => { ImplItem::Type }
- |
- call!(unstable_impl_existential_type) => { ImplItem::Verbatim }
- |
- syn!(ImplItemMacro) => { ImplItem::Macro }
- ));
-
- impl_synom!(ImplItemConst "const item in impl block" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- defaultness: option!(keyword!(default)) >>
- const_: keyword!(const) >>
- ident: syn!(Ident) >>
- colon: punct!(:) >>
- ty: syn!(Type) >>
- eq: punct!(=) >>
- value: syn!(Expr) >>
- semi: punct!(;) >>
- (ImplItemConst {
- attrs: attrs,
- vis: vis,
- defaultness: defaultness,
- const_token: const_,
- ident: ident,
- colon_token: colon,
- ty: ty,
- eq_token: eq,
- expr: value,
- semi_token: semi,
- })
- ));
-
- impl_synom!(ImplItemMethod "method in impl block" do_parse!(
- outer_attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- defaultness: option!(keyword!(default)) >>
- constness: option!(keyword!(const)) >>
- unsafety: option!(keyword!(unsafe)) >>
- abi: option!(syn!(Abi)) >>
- fn_: keyword!(fn) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- inputs: parens!(Punctuated::parse_terminated) >>
- ret: syn!(ReturnType) >>
- where_clause: option!(syn!(WhereClause)) >>
- inner_attrs_stmts: braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- (ImplItemMethod {
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend((inner_attrs_stmts.1).0);
- attrs
- },
- vis: vis,
- defaultness: defaultness,
- sig: MethodSig {
- constness: constness,
- unsafety: unsafety,
- abi: abi,
+ Ok(TraitItemType {
+ attrs: attrs,
+ type_token: type_token,
ident: ident,
- decl: FnDecl {
- fn_token: fn_,
- paren_token: inputs.0,
- inputs: inputs.1,
- output: ret,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- variadic: None,
+ generics: generics,
+ colon_token: colon_token,
+ bounds: bounds,
+ default: default,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for TraitItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mac: Macro = input.parse()?;
+ let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+ None
+ } else {
+ Some(input.parse()?)
+ };
+ Ok(TraitItemMacro {
+ attrs: attrs,
+ mac: mac,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Parse for ItemImpl {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let impl_token: Token![impl ] = input.parse()?;
+ let generics: Generics = input.parse()?;
+ let trait_ = {
+ let ahead = input.fork();
+ if ahead.parse::<Option<Token![!]>>().is_ok()
+ && ahead.parse::<Path>().is_ok()
+ && ahead.parse::<Token![for]>().is_ok()
+ {
+ let polarity: Option<Token![!]> = input.parse()?;
+ let path: Path = input.parse()?;
+ let for_token: Token![for] = input.parse()?;
+ Some((polarity, path, for_token))
+ } else {
+ None
+ }
+ };
+ let self_ty: Type = input.parse()?;
+ let where_clause: Option<WhereClause> = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemImpl {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ defaultness: defaultness,
+ unsafety: unsafety,
+ impl_token: impl_token,
+ generics: Generics {
+ where_clause: where_clause,
+ ..generics
},
- },
- block: Block {
- brace_token: inner_attrs_stmts.0,
- stmts: (inner_attrs_stmts.1).1,
- },
- })
- ));
+ trait_: trait_,
+ self_ty: Box::new(self_ty),
+ brace_token: brace_token,
+ items: items,
+ })
+ }
+ }
- named!(unstable_async_method -> ImplItemVerbatim, do_parse!(
- begin: call!(verbatim::grab_cursor) >>
- many0!(Attribute::parse_outer) >>
- syn!(Visibility) >>
- option!(keyword!(default)) >>
- option!(keyword!(const)) >>
- option!(keyword!(unsafe)) >>
- keyword!(async) >>
- option!(syn!(Abi)) >>
- keyword!(fn) >>
- syn!(Ident) >>
- syn!(Generics) >>
- parens!(Punctuated::<FnArg, Token![,]>::parse_terminated) >>
- syn!(ReturnType) >>
- option!(syn!(WhereClause)) >>
- braces!(tuple!(
- many0!(Attribute::parse_inner),
- call!(Block::parse_within),
- )) >>
- end: call!(verbatim::grab_cursor) >>
- (ImplItemVerbatim {
- tts: verbatim::token_range(begin..end),
- })
- ));
+ impl Parse for ImplItem {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let ahead = input.fork();
+ ahead.call(Attribute::parse_outer)?;
+ let vis: Visibility = ahead.parse()?;
- impl_synom!(ImplItemType "type in impl block" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- vis: syn!(Visibility) >>
- defaultness: option!(keyword!(default)) >>
- type_: keyword!(type) >>
- ident: syn!(Ident) >>
- generics: syn!(Generics) >>
- where_clause: option!(syn!(WhereClause)) >>
- eq: punct!(=) >>
- ty: syn!(Type) >>
- semi: punct!(;) >>
- (ImplItemType {
- attrs: attrs,
- vis: vis,
- defaultness: defaultness,
- type_token: type_,
- ident: ident,
- generics: Generics {
- where_clause: where_clause,
- ..generics
- },
- eq_token: eq,
- ty: ty,
- semi_token: semi,
- })
- ));
+ let mut lookahead = ahead.lookahead1();
+ let defaultness = if lookahead.peek(Token![default]) && !ahead.peek2(Token![!]) {
+ let defaultness: Token![default] = ahead.parse()?;
+ lookahead = ahead.lookahead1();
+ Some(defaultness)
+ } else {
+ None
+ };
- named!(unstable_impl_existential_type -> ImplItemVerbatim, map!(
- call!(existential_type_helper, true),
- |tts| ImplItemVerbatim { tts: tts }
- ));
+ if lookahead.peek(Token![const]) {
+ ahead.parse::<Token![const]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Ident) {
+ input.parse().map(ImplItem::Const)
+ } else if lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![async])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(ImplItem::Method)
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![async])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(ImplItem::Method)
+ } else if lookahead.peek(Token![type]) {
+ input.parse().map(ImplItem::Type)
+ } else if vis.is_inherited()
+ && defaultness.is_none()
+ && lookahead.peek(Token![existential])
+ {
+ input.parse().map(ImplItem::Existential)
+ } else if vis.is_inherited()
+ && defaultness.is_none()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(ImplItem::Macro)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
- impl_synom!(ImplItemMacro "macro in impl block" do_parse!(
- attrs: many0!(Attribute::parse_outer) >>
- mac: syn!(Macro) >>
- semi: cond!(!is_brace(&mac.delimiter), punct!(;)) >>
- (ImplItemMacro {
- attrs: attrs,
- mac: mac,
- semi_token: semi,
- })
- ));
+ impl Parse for ImplItemConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ImplItemConst {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ defaultness: input.parse()?,
+ const_token: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ eq_token: input.parse()?,
+ expr: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
- fn is_brace(delimiter: &MacroDelimiter) -> bool {
- match *delimiter {
- MacroDelimiter::Brace(_) => true,
- MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
+ impl Parse for ImplItemMethod {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let constness: Option<Token![const]> = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let asyncness: Option<Token![async]> = input.parse()?;
+ let abi: Option<Abi> = input.parse()?;
+ let fn_token: Token![fn] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let generics: Generics = input.parse()?;
+
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let inputs = content.parse_terminated(FnArg::parse)?;
+
+ let output: ReturnType = input.parse()?;
+ let where_clause: Option<WhereClause> = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ImplItemMethod {
+ attrs: private::attrs(outer_attrs, inner_attrs),
+ vis: vis,
+ defaultness: defaultness,
+ sig: MethodSig {
+ constness: constness,
+ unsafety: unsafety,
+ asyncness: asyncness,
+ abi: abi,
+ ident: ident,
+ decl: FnDecl {
+ fn_token: fn_token,
+ paren_token: paren_token,
+ inputs: inputs,
+ output: output,
+ variadic: None,
+ generics: Generics {
+ where_clause: where_clause,
+ ..generics
+ },
+ },
+ },
+ block: Block {
+ brace_token: brace_token,
+ stmts: stmts,
+ },
+ })
+ }
+ }
+
+ impl Parse for ImplItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ImplItemType {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ defaultness: input.parse()?,
+ type_token: input.parse()?,
+ ident: input.parse()?,
+ generics: {
+ let mut generics: Generics = input.parse()?;
+ generics.where_clause = input.parse()?;
+ generics
+ },
+ eq_token: input.parse()?,
+ ty: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for ImplItemExistential {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let ety: ItemExistential = input.parse()?;
+ Ok(ImplItemExistential {
+ attrs: ety.attrs,
+ existential_token: ety.existential_token,
+ type_token: ety.type_token,
+ ident: ety.ident,
+ generics: ety.generics,
+ colon_token: ety.colon_token,
+ bounds: ety.bounds,
+ semi_token: ety.semi_token,
+ })
+ }
+ }
+
+ impl Parse for ImplItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mac: Macro = input.parse()?;
+ let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+ None
+ } else {
+ Some(input.parse()?)
+ };
+ Ok(ImplItemMacro {
+ attrs: attrs,
+ mac: mac,
+ semi_token: semi_token,
+ })
+ }
+ }
+
+ impl Visibility {
+ fn is_inherited(&self) -> bool {
+ match *self {
+ Visibility::Inherited => true,
+ _ => false,
+ }
+ }
+ }
+
+ impl MacroDelimiter {
+ fn is_brace(&self) -> bool {
+ match *self {
+ MacroDelimiter::Brace(_) => true,
+ MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
+ }
}
}
}
@@ -1657,10 +1953,13 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use attr::FilterAttrs;
+
use proc_macro2::TokenStream;
use quote::{ToTokens, TokenStreamExt};
+ use attr::FilterAttrs;
+ use print::TokensOrDefault;
+
impl ToTokens for ItemExternCrate {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
@@ -1722,6 +2021,7 @@
self.vis.to_tokens(tokens);
self.constness.to_tokens(tokens);
self.unsafety.to_tokens(tokens);
+ self.asyncness.to_tokens(tokens);
self.abi.to_tokens(tokens);
NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
self.block.brace_token.surround(tokens, |tokens| {
@@ -1773,6 +2073,23 @@
}
}
+ impl ToTokens for ItemExistential {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.existential_token.to_tokens(tokens);
+ self.type_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ if !self.bounds.is_empty() {
+ TokensOrDefault(&self.colon_token).to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
impl ToTokens for ItemEnum {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
@@ -1844,6 +2161,20 @@
}
}
+ impl ToTokens for ItemTraitAlias {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.trait_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
impl ToTokens for ItemImpl {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
@@ -2052,6 +2383,22 @@
}
}
+ impl ToTokens for ImplItemExistential {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.existential_token.to_tokens(tokens);
+ self.type_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ if !self.bounds.is_empty() {
+ TokensOrDefault(&self.colon_token).to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
impl ToTokens for ImplItemMacro {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append_all(self.attrs.outer());
@@ -2098,6 +2445,14 @@
}
}
+ impl ToTokens for ForeignItemMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.mac.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
impl ToTokens for ForeignItemVerbatim {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.tts.to_tokens(tokens);
@@ -2108,6 +2463,7 @@
fn to_tokens(&self, tokens: &mut TokenStream) {
self.constness.to_tokens(tokens);
self.unsafety.to_tokens(tokens);
+ self.asyncness.to_tokens(tokens);
self.abi.to_tokens(tokens);
NamedDecl(&self.decl, &self.ident).to_tokens(tokens);
}
diff --git a/src/lib.rs b/src/lib.rs
index debb5b0..d0a972e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -76,13 +76,12 @@
//! ```
//!
//! ```rust
-//! extern crate proc_macro;
-//! extern crate syn;
-//!
-//! #[macro_use]
-//! extern crate quote;
-//!
+//! # extern crate proc_macro;
+//! # extern crate quote;
+//! # extern crate syn;
+//! #
//! use proc_macro::TokenStream;
+//! use quote::quote;
//! use syn::DeriveInput;
//!
//! # const IGNORE_TOKENS: &str = stringify! {
@@ -264,10 +263,14 @@
#![cfg_attr(
feature = "cargo-clippy",
allow(
+ block_in_if_condition_stmt,
const_static_lifetime,
+ cyclomatic_complexity,
doc_markdown,
+ eval_order_dependence,
large_enum_variant,
match_bool,
+ never_loop,
redundant_closure,
needless_pass_by_value,
redundant_field_names,
@@ -280,6 +283,7 @@
allow(
cast_possible_truncation,
cast_possible_wrap,
+ empty_enum,
if_not_else,
indexing_slicing,
items_after_statements,
@@ -304,18 +308,20 @@
#[cfg(feature = "printing")]
extern crate quote;
-#[cfg(feature = "parsing")]
-#[macro_use]
-#[doc(hidden)]
-pub mod parsers;
-
#[macro_use]
mod macros;
+// Not public API.
+#[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[macro_use]
+pub mod group;
+
#[macro_use]
pub mod token;
-pub use proc_macro2::Ident;
+mod ident;
+pub use ident::Ident;
#[cfg(any(feature = "full", feature = "derive"))]
mod attr;
@@ -334,12 +340,12 @@
mod expr;
#[cfg(any(feature = "full", feature = "derive"))]
pub use expr::{
- Expr, ExprArray, ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox, ExprBreak, ExprCall,
- ExprCast, ExprCatch, ExprClosure, ExprContinue, ExprField, ExprForLoop, ExprGroup, ExprIf,
- ExprIfLet, ExprInPlace, ExprIndex, ExprLit, ExprLoop, ExprMacro, ExprMatch, ExprMethodCall,
- ExprParen, ExprPath, ExprRange, ExprReference, ExprRepeat, ExprReturn, ExprStruct, ExprTry,
- ExprTuple, ExprType, ExprUnary, ExprUnsafe, ExprVerbatim, ExprWhile, ExprWhileLet, ExprYield,
- Index, Member,
+ Expr, ExprArray, ExprAssign, ExprAssignOp, ExprAsync, ExprBinary, ExprBlock, ExprBox,
+ ExprBreak, ExprCall, ExprCast, ExprClosure, ExprContinue, ExprField, ExprForLoop, ExprGroup,
+ ExprIf, ExprIfLet, ExprInPlace, ExprIndex, ExprLit, ExprLoop, ExprMacro, ExprMatch,
+ ExprMethodCall, ExprParen, ExprPath, ExprRange, ExprReference, ExprRepeat, ExprReturn,
+ ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprType, ExprUnary, ExprUnsafe, ExprVerbatim,
+ ExprWhile, ExprWhileLet, ExprYield, Index, Member,
};
#[cfg(feature = "full")]
@@ -367,13 +373,14 @@
mod item;
#[cfg(feature = "full")]
pub use item::{
- ArgCaptured, ArgSelf, ArgSelfRef, FnArg, FnDecl, ForeignItem, ForeignItemFn, ForeignItemStatic,
- ForeignItemType, ForeignItemVerbatim, ImplItem, ImplItemConst, ImplItemMacro, ImplItemMethod,
- ImplItemType, ImplItemVerbatim, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
- ItemForeignMod, ItemImpl, ItemMacro, ItemMacro2, ItemMod, ItemStatic, ItemStruct, ItemTrait,
- ItemType, ItemUnion, ItemUse, ItemVerbatim, MethodSig, TraitItem, TraitItemConst,
- TraitItemMacro, TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName,
- UsePath, UseRename, UseTree,
+ ArgCaptured, ArgSelf, ArgSelfRef, FnArg, FnDecl, ForeignItem, ForeignItemFn, ForeignItemMacro,
+ ForeignItemStatic, ForeignItemType, ForeignItemVerbatim, ImplItem, ImplItemConst,
+ ImplItemExistential, ImplItemMacro, ImplItemMethod, ImplItemType, ImplItemVerbatim, Item,
+ ItemConst, ItemEnum, ItemExistential, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl,
+ ItemMacro, ItemMacro2, ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType,
+ ItemUnion, ItemUse, ItemVerbatim, MethodSig, TraitItem, TraitItemConst, TraitItemMacro,
+ TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName, UsePath,
+ UseRename, UseTree,
};
#[cfg(feature = "full")]
@@ -381,9 +388,7 @@
#[cfg(feature = "full")]
pub use file::File;
-#[cfg(any(feature = "full", feature = "derive"))]
mod lifetime;
-#[cfg(any(feature = "full", feature = "derive"))]
pub use lifetime::Lifetime;
#[cfg(any(feature = "full", feature = "derive"))]
@@ -420,11 +425,6 @@
#[cfg(any(feature = "full", feature = "derive"))]
mod path;
-#[cfg(all(
- any(feature = "full", feature = "derive"),
- feature = "printing"
-))]
-pub use path::PathTokens;
#[cfg(any(feature = "full", feature = "derive"))]
pub use path::{
AngleBracketedGenericArguments, Binding, GenericArgument, ParenthesizedGenericArguments, Path,
@@ -433,10 +433,13 @@
#[cfg(feature = "parsing")]
pub mod buffer;
-pub mod punctuated;
#[cfg(feature = "parsing")]
-pub mod synom;
-#[cfg(any(feature = "full", feature = "derive"))]
+pub mod ext;
+pub mod punctuated;
+#[cfg(all(
+ any(feature = "full", feature = "derive"),
+ feature = "extra-traits"
+))]
mod tt;
// Not public API except the `parse_quote!` macro.
@@ -447,9 +450,6 @@
#[cfg(all(feature = "parsing", feature = "printing"))]
pub mod spanned;
-#[cfg(all(feature = "parsing", feature = "full"))]
-mod verbatim;
-
mod gen {
/// Syntax tree traversal to walk a shared borrow of a syntax tree.
///
@@ -567,20 +567,36 @@
}
pub use gen::*;
-////////////////////////////////////////////////////////////////////////////////
+// Not public API.
+#[doc(hidden)]
+pub mod export;
#[cfg(feature = "parsing")]
-use synom::{Parser, Synom};
+mod lookahead;
+
+#[cfg(feature = "parsing")]
+pub mod parse;
+
+mod span;
+
+#[cfg(all(
+ any(feature = "full", feature = "derive"),
+ feature = "printing"
+))]
+mod print;
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "parsing", feature = "full", feature = "derive"))]
+#[allow(non_camel_case_types)]
+struct private;
+
+////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "parsing")]
mod error;
#[cfg(feature = "parsing")]
-use error::ParseError;
-
-// Not public API.
-#[cfg(feature = "parsing")]
-#[doc(hidden)]
-pub use error::parse_error;
+use error::Error;
/// Parse tokens of source code into the chosen syntax tree node.
///
@@ -601,14 +617,12 @@
/// # Examples
///
/// ```rust
-/// extern crate proc_macro;
+/// # extern crate proc_macro;
+/// # extern crate quote;
+/// # extern crate syn;
+/// #
/// use proc_macro::TokenStream;
-///
-/// extern crate syn;
-///
-/// #[macro_use]
-/// extern crate quote;
-///
+/// use quote::quote;
/// use syn::DeriveInput;
///
/// # const IGNORE_TOKENS: &str = stringify! {
@@ -634,11 +648,8 @@
feature = "parsing",
feature = "proc-macro"
))]
-pub fn parse<T>(tokens: proc_macro::TokenStream) -> Result<T, ParseError>
-where
- T: Synom,
-{
- parse2(tokens.into())
+pub fn parse<T: parse::Parse>(tokens: proc_macro::TokenStream) -> Result<T, Error> {
+ parse::Parser::parse(T::parse, tokens)
}
/// Parse a proc-macro2 token stream into the chosen syntax tree node.
@@ -654,15 +665,8 @@
///
/// *This function is available if Syn is built with the `"parsing"` feature.*
#[cfg(feature = "parsing")]
-pub fn parse2<T>(tokens: proc_macro2::TokenStream) -> Result<T, ParseError>
-where
- T: Synom,
-{
- let parser = T::parse;
- parser.parse2(tokens).map_err(|err| match T::description() {
- Some(s) => ParseError::new(format!("failed to parse {}: {}", s, err)),
- None => err,
- })
+pub fn parse2<T: parse::Parse>(tokens: proc_macro2::TokenStream) -> Result<T, Error> {
+ parse::Parser::parse2(T::parse, tokens)
}
/// Parse a string of Rust code into the chosen syntax tree node.
@@ -677,12 +681,10 @@
/// # Examples
///
/// ```rust
-/// extern crate syn;
+/// # extern crate syn;
/// #
-/// #
-/// # type Result<T> = std::result::Result<T, Box<std::error::Error>>;
-///
/// use syn::Expr;
+/// use syn::parse::Result;
///
/// fn run() -> Result<()> {
/// let code = "assert_eq!(u8::max_value(), 255)";
@@ -694,11 +696,8 @@
/// # fn main() { run().unwrap() }
/// ```
#[cfg(feature = "parsing")]
-pub fn parse_str<T: Synom>(s: &str) -> Result<T, ParseError> {
- match s.parse() {
- Ok(tts) => parse2(tts),
- Err(_) => Err(ParseError::new("error while lexing input string")),
- }
+pub fn parse_str<T: parse::Parse>(s: &str) -> Result<T, Error> {
+ parse::Parser::parse_str(T::parse, s)
}
// FIXME the name parse_file makes it sound like you might pass in a path to a
@@ -717,15 +716,13 @@
/// # Examples
///
/// ```rust,no_run
-/// extern crate syn;
+/// # extern crate syn;
/// #
-/// #
-/// # type Result<T> = std::result::Result<T, Box<std::error::Error>>;
-///
+/// use std::error::Error;
/// use std::fs::File;
/// use std::io::Read;
///
-/// fn run() -> Result<()> {
+/// fn run() -> Result<(), Box<Error>> {
/// let mut file = File::open("path/to/code.rs")?;
/// let mut content = String::new();
/// file.read_to_string(&mut content)?;
@@ -742,7 +739,7 @@
/// # fn main() { run().unwrap() }
/// ```
#[cfg(all(feature = "parsing", feature = "full"))]
-pub fn parse_file(mut content: &str) -> Result<File, ParseError> {
+pub fn parse_file(mut content: &str) -> Result<File, Error> {
// Strip the BOM if it is present
const BOM: &'static str = "\u{feff}";
if content.starts_with(BOM) {
@@ -765,24 +762,56 @@
Ok(file)
}
-#[cfg(all(
- any(feature = "full", feature = "derive"),
- feature = "printing"
-))]
-struct TokensOrDefault<'a, T: 'a>(&'a Option<T>);
-
-#[cfg(all(
- any(feature = "full", feature = "derive"),
- feature = "printing"
-))]
-impl<'a, T> quote::ToTokens for TokensOrDefault<'a, T>
-where
- T: quote::ToTokens + Default,
-{
- fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
- match *self.0 {
- Some(ref t) => t.to_tokens(tokens),
- None => T::default().to_tokens(tokens),
- }
- }
+/// Parse the input TokenStream of a macro, triggering a compile error if the
+/// tokens fail to parse.
+///
+/// Refer to the [`parse` module] documentation for more details about parsing
+/// in Syn.
+///
+/// [`parse` module]: parse/index.html
+///
+/// # Intended usage
+///
+/// ```rust
+/// # extern crate proc_macro;
+/// # extern crate syn;
+/// #
+/// use proc_macro::TokenStream;
+/// use syn::parse_macro_input;
+/// use syn::parse::{Parse, ParseStream, Result};
+///
+/// struct MyMacroInput {
+/// /* ... */
+/// }
+///
+/// impl Parse for MyMacroInput {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// /* ... */
+/// # Ok(MyMacroInput {})
+/// }
+/// }
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro]
+/// # };
+/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
+/// let input = parse_macro_input!(tokens as MyMacroInput);
+///
+/// /* ... */
+/// # "".parse().unwrap()
+/// }
+/// #
+/// # fn main() {}
+/// ```
+#[cfg(feature = "proc-macro")]
+#[macro_export]
+macro_rules! parse_macro_input {
+ ($tokenstream:ident as $ty:ty) => {
+ match $crate::parse::<$ty>($tokenstream) {
+ $crate::export::Ok(data) => data,
+ $crate::export::Err(err) => {
+ return $crate::export::TokenStream::from(err.into_compile_error());
+ }
+ };
+ };
}
diff --git a/src/lifetime.rs b/src/lifetime.rs
index 5ca876f..3f093c8 100644
--- a/src/lifetime.rs
+++ b/src/lifetime.rs
@@ -13,7 +13,8 @@
use proc_macro2::{Ident, Span};
use unicode_xid::UnicodeXID;
-use token::Apostrophe;
+#[cfg(feature = "parsing")]
+use lookahead;
/// A Rust lifetime: `'a`.
///
@@ -31,25 +32,42 @@
#[cfg_attr(feature = "extra-traits", derive(Debug))]
#[derive(Clone)]
pub struct Lifetime {
- pub apostrophe: Apostrophe,
+ pub apostrophe: Span,
pub ident: Ident,
}
impl Lifetime {
- pub fn new(s: &str, span: Span) -> Self {
- if !s.starts_with('\'') {
+ /// # Panics
+ ///
+ /// Panics if the lifetime does not conform to the bulleted rules above.
+ ///
+ /// # Invocation
+ ///
+ /// ```
+ /// # extern crate proc_macro2;
+ /// # extern crate syn;
+ /// #
+ /// # use proc_macro2::Span;
+ /// # use syn::Lifetime;
+ /// #
+ /// # fn f() -> Lifetime {
+ /// Lifetime::new("'a", Span::call_site())
+ /// # }
+ /// ```
+ pub fn new(symbol: &str, span: Span) -> Self {
+ if !symbol.starts_with('\'') {
panic!(
"lifetime name must start with apostrophe as in \"'a\", got {:?}",
- s
+ symbol
);
}
- if s == "'" {
+ if symbol == "'" {
panic!("lifetime name must not be empty");
}
- fn xid_ok(s: &str) -> bool {
- let mut chars = s.chars();
+ fn xid_ok(symbol: &str) -> bool {
+ let mut chars = symbol.chars();
let first = chars.next().unwrap();
if !(UnicodeXID::is_xid_start(first) || first == '_') {
return false;
@@ -62,13 +80,13 @@
true
}
- if !xid_ok(&s[1..]) {
- panic!("{:?} is not a valid lifetime name", s);
+ if !xid_ok(&symbol[1..]) {
+ panic!("{:?} is not a valid lifetime name", symbol);
}
Lifetime {
- apostrophe: Apostrophe::default(),
- ident: Ident::new(&s[1..], span),
+ apostrophe: span,
+ ident: Ident::new(&symbol[1..], span),
}
}
}
@@ -107,30 +125,25 @@
}
#[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Lifetime(marker: lookahead::TokenMarker) -> Lifetime {
+ match marker {}
+}
+
+#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use buffer::Cursor;
- use parse_error;
- use synom::PResult;
- use synom::Synom;
- impl Synom for Lifetime {
- fn parse(input: Cursor) -> PResult<Self> {
- let (apostrophe, rest) = Apostrophe::parse(input)?;
- let (ident, rest) = match rest.ident() {
- Some(pair) => pair,
- None => return parse_error(),
- };
+ use parse::{Parse, ParseStream, Result};
- let ret = Lifetime {
- ident: ident,
- apostrophe: apostrophe,
- };
- Ok((ret, rest))
- }
-
- fn description() -> Option<&'static str> {
- Some("lifetime")
+ impl Parse for Lifetime {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ cursor
+ .lifetime()
+ .ok_or_else(|| cursor.error("expected lifetime"))
+ })
}
}
}
@@ -138,12 +151,15 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use proc_macro2::TokenStream;
- use quote::ToTokens;
+
+ use proc_macro2::{Punct, Spacing, TokenStream};
+ use quote::{ToTokens, TokenStreamExt};
impl ToTokens for Lifetime {
fn to_tokens(&self, tokens: &mut TokenStream) {
- self.apostrophe.to_tokens(tokens);
+ let mut apostrophe = Punct::new('\'', Spacing::Joint);
+ apostrophe.set_span(self.apostrophe);
+ tokens.append(apostrophe);
self.ident.to_tokens(tokens);
}
}
diff --git a/src/lit.rs b/src/lit.rs
index 47555d4..52d1156 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -15,13 +15,18 @@
#[cfg(feature = "parsing")]
use proc_macro2::TokenStream;
#[cfg(feature = "parsing")]
-use {ParseError, Synom};
+use Error;
use proc_macro2::TokenTree;
#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
+#[cfg(feature = "parsing")]
+use lookahead;
+#[cfg(feature = "parsing")]
+use parse::Parse;
+
ast_enum_of_structs! {
/// A Rust literal such as a string or integer or boolean.
///
@@ -121,13 +126,54 @@
/// Parse a syntax tree node from the content of this string literal.
///
/// All spans in the syntax tree will point to the span of this `LitStr`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate proc_macro2;
+ /// # extern crate syn;
+ /// #
+ /// use proc_macro2::Span;
+ /// use syn::{Attribute, Ident, Lit, Meta, MetaNameValue, Path};
+ /// use syn::parse::{Error, Result};
+ ///
+ /// // Parses the path from an attribute that looks like:
+ /// //
+ /// // #[path = "a::b::c"]
+ /// //
+ /// // or returns the path `Self` as a default if the attribute is not of
+ /// // that form.
+ /// fn get_path(attr: &Attribute) -> Result<Path> {
+ /// let default = || Path::from(Ident::new("Self", Span::call_site()));
+ ///
+ /// let meta = match attr.interpret_meta() {
+ /// Some(meta) => meta,
+ /// None => return Ok(default()),
+ /// };
+ ///
+ /// if meta.name() != "path" {
+ /// return Ok(default());
+ /// }
+ ///
+ /// match meta {
+ /// Meta::NameValue(MetaNameValue { lit: Lit::Str(lit_str), .. }) => {
+ /// lit_str.parse()
+ /// }
+ /// _ => {
+ /// let error_span = attr.bracket_token.span;
+ /// let message = "expected #[path = \"...\"]";
+ /// Err(Error::new(error_span, message))
+ /// }
+ /// }
+ /// }
+ /// ```
#[cfg(feature = "parsing")]
- pub fn parse<T: Synom>(&self) -> Result<T, ParseError> {
+ pub fn parse<T: Parse>(&self) -> Result<T, Error> {
use proc_macro2::Group;
// Parse string literal into a token stream with every span equal to the
// original literal's span.
- fn spanned_tokens(s: &LitStr) -> Result<TokenStream, ParseError> {
+ fn spanned_tokens(s: &LitStr) -> Result<TokenStream, Error> {
let stream = ::parse_str(&s.value())?;
Ok(respan_token_stream(stream, s.span()))
}
@@ -337,6 +383,13 @@
self.$field.to_string().hash(state);
}
}
+
+ #[cfg(feature = "parsing")]
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $ty(marker: lookahead::TokenMarker) -> $ty {
+ match marker {}
+ }
};
}
@@ -411,96 +464,111 @@
}
#[cfg(feature = "parsing")]
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Lit(marker: lookahead::TokenMarker) -> Lit {
+ match marker {}
+}
+
+#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use buffer::Cursor;
- use parse_error;
- use synom::PResult;
- use synom::Synom;
+ use parse::{Parse, ParseStream, Result};
- impl Synom for Lit {
- fn parse(input: Cursor) -> PResult<Self> {
- match input.literal() {
- Some((lit, rest)) => {
- if lit.to_string().starts_with('/') {
- // Doc comment literal which is not a Syn literal
- parse_error()
- } else {
- Ok((Lit::new(lit), rest))
- }
+ impl Parse for Lit {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((lit, rest)) = cursor.literal() {
+ return Ok((Lit::new(lit), rest));
}
- _ => match input.ident() {
- Some((ident, rest)) => Ok((
- Lit::Bool(LitBool {
- value: if ident == "true" {
- true
- } else if ident == "false" {
- false
- } else {
- return parse_error();
- },
- span: ident.span(),
- }),
- rest,
- )),
- _ => parse_error(),
- },
- }
- }
-
- fn description() -> Option<&'static str> {
- Some("literal")
+ while let Some((ident, rest)) = cursor.ident() {
+ let value = if ident == "true" {
+ true
+ } else if ident == "false" {
+ false
+ } else {
+ break;
+ };
+ let lit_bool = LitBool {
+ value: value,
+ span: ident.span(),
+ };
+ return Ok((Lit::Bool(lit_bool), rest));
+ }
+ Err(cursor.error("expected literal"))
+ })
}
}
- impl_synom!(LitStr "string literal" switch!(
- syn!(Lit),
- Lit::Str(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitStr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::Str(lit) => Ok(lit),
+ _ => Err(head.error("expected string literal")),
+ }
+ }
+ }
- impl_synom!(LitByteStr "byte string literal" switch!(
- syn!(Lit),
- Lit::ByteStr(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitByteStr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::ByteStr(lit) => Ok(lit),
+ _ => Err(head.error("expected byte string literal")),
+ }
+ }
+ }
- impl_synom!(LitByte "byte literal" switch!(
- syn!(Lit),
- Lit::Byte(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitByte {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::Byte(lit) => Ok(lit),
+ _ => Err(head.error("expected byte literal")),
+ }
+ }
+ }
- impl_synom!(LitChar "character literal" switch!(
- syn!(Lit),
- Lit::Char(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitChar {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::Char(lit) => Ok(lit),
+ _ => Err(head.error("expected character literal")),
+ }
+ }
+ }
- impl_synom!(LitInt "integer literal" switch!(
- syn!(Lit),
- Lit::Int(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitInt {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::Int(lit) => Ok(lit),
+ _ => Err(head.error("expected integer literal")),
+ }
+ }
+ }
- impl_synom!(LitFloat "floating point literal" switch!(
- syn!(Lit),
- Lit::Float(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitFloat {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::Float(lit) => Ok(lit),
+ _ => Err(head.error("expected floating point literal")),
+ }
+ }
+ }
- impl_synom!(LitBool "boolean literal" switch!(
- syn!(Lit),
- Lit::Bool(lit) => value!(lit)
- |
- _ => reject!()
- ));
+ impl Parse for LitBool {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse()? {
+ Lit::Bool(lit) => Ok(lit),
+ _ => Err(head.error("expected boolean literal")),
+ }
+ }
+ }
}
#[cfg(feature = "printing")]
diff --git a/src/lookahead.rs b/src/lookahead.rs
new file mode 100644
index 0000000..5a3c901
--- /dev/null
+++ b/src/lookahead.rs
@@ -0,0 +1,168 @@
+use std::cell::RefCell;
+
+use proc_macro2::{Delimiter, Span};
+
+use buffer::Cursor;
+use error::{self, Error};
+use span::IntoSpans;
+use token::Token;
+
+/// Support for checking the next token in a stream to decide how to parse.
+///
+/// An important advantage over [`ParseStream::peek`] is that here we
+/// automatically construct an appropriate error message based on the token
+/// alternatives that get peeked. If you are producing your own error message,
+/// go ahead and use `ParseStream::peek` instead.
+///
+/// Use [`ParseStream::lookahead1`] to construct this object.
+///
+/// [`ParseStream::peek`]: struct.ParseBuffer.html#method.peek
+/// [`ParseStream::lookahead1`]: struct.ParseBuffer.html#method.lookahead1
+///
+/// # Example
+///
+/// ```
+/// # extern crate syn;
+/// #
+/// use syn::{ConstParam, Ident, Lifetime, LifetimeDef, Token, TypeParam};
+/// use syn::parse::{Parse, ParseStream, Result};
+///
+/// // A generic parameter, a single one of the comma-separated elements inside
+/// // angle brackets in:
+/// //
+/// // fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
+/// //
+/// // On invalid input, lookahead gives us a reasonable error message.
+/// //
+/// // error: expected one of: identifier, lifetime, `const`
+/// // |
+/// // 5 | fn f<!Sized>() {}
+/// // | ^
+/// enum GenericParam {
+/// Type(TypeParam),
+/// Lifetime(LifetimeDef),
+/// Const(ConstParam),
+/// }
+///
+/// impl Parse for GenericParam {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let lookahead = input.lookahead1();
+/// if lookahead.peek(Ident) {
+/// input.parse().map(GenericParam::Type)
+/// } else if lookahead.peek(Lifetime) {
+/// input.parse().map(GenericParam::Lifetime)
+/// } else if lookahead.peek(Token![const]) {
+/// input.parse().map(GenericParam::Const)
+/// } else {
+/// Err(lookahead.error())
+/// }
+/// }
+/// }
+/// #
+/// # fn main() {}
+/// ```
+pub struct Lookahead1<'a> {
+ scope: Span,
+ cursor: Cursor<'a>,
+ comparisons: RefCell<Vec<&'static str>>,
+}
+
+pub fn new(scope: Span, cursor: Cursor) -> Lookahead1 {
+ Lookahead1 {
+ scope: scope,
+ cursor: cursor,
+ comparisons: RefCell::new(Vec::new()),
+ }
+}
+
+fn peek_impl(
+ lookahead: &Lookahead1,
+ peek: fn(Cursor) -> bool,
+ display: fn() -> &'static str,
+) -> bool {
+ if peek(lookahead.cursor) {
+ return true;
+ }
+ lookahead.comparisons.borrow_mut().push(display());
+ false
+}
+
+impl<'a> Lookahead1<'a> {
+ /// Looks at the next token in the parse stream to determine whether it
+ /// matches the requested type of token.
+ ///
+ /// # Syntax
+ ///
+ /// Note that this method does not use turbofish syntax. Pass the peek type
+ /// inside of parentheses.
+ ///
+ /// - `input.peek(Token![struct])`
+ /// - `input.peek(Token![==])`
+ /// - `input.peek(Ident)`
+ /// - `input.peek(Lifetime)`
+ /// - `input.peek(token::Brace)`
+ pub fn peek<T: Peek>(&self, token: T) -> bool {
+ let _ = token;
+ peek_impl(self, T::Token::peek, T::Token::display)
+ }
+
+ /// Triggers an error at the current position of the parse stream.
+ ///
+ /// The error message will identify all of the expected token types that
+ /// have been peeked against this lookahead instance.
+ pub fn error(self) -> Error {
+ let comparisons = self.comparisons.borrow();
+ match comparisons.len() {
+ 0 => if self.cursor.eof() {
+ Error::new(self.scope, "unexpected end of input")
+ } else {
+ Error::new(self.cursor.span(), "unexpected token")
+ },
+ 1 => {
+ let message = format!("expected {}", comparisons[0]);
+ error::new_at(self.scope, self.cursor, message)
+ }
+ _ => {
+ let join = comparisons.join(", ");
+ let message = format!("expected one of: {}", join);
+ error::new_at(self.scope, self.cursor, message)
+ }
+ }
+ }
+}
+
+/// Types that can be parsed by looking at just one token.
+///
+/// Use [`ParseStream::peek`] to peek one of these types in a parse stream
+/// without consuming it from the stream.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+///
+/// [`ParseStream::peek`]: struct.ParseBuffer.html#method.peek
+pub trait Peek: private::Sealed {
+ // Not public API.
+ #[doc(hidden)]
+ type Token: Token;
+}
+
+impl<F: FnOnce(TokenMarker) -> T, T: Token> Peek for F {
+ type Token = T;
+}
+
+pub enum TokenMarker {}
+
+impl<S> IntoSpans<S> for TokenMarker {
+ fn into_spans(self) -> S {
+ match self {}
+ }
+}
+
+pub fn is_delimiter(cursor: Cursor, delimiter: Delimiter) -> bool {
+ cursor.group(delimiter).is_some()
+}
+
+mod private {
+ use super::{Token, TokenMarker};
+ pub trait Sealed {}
+ impl<F: FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
+}
diff --git a/src/mac.rs b/src/mac.rs
index a9219fe..4bffb55 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -8,8 +8,12 @@
use super::*;
use proc_macro2::TokenStream;
+#[cfg(feature = "parsing")]
+use proc_macro2::{Delimiter, TokenTree};
use token::{Brace, Bracket, Paren};
+#[cfg(feature = "parsing")]
+use parse::{ParseStream, Result};
#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
#[cfg(feature = "extra-traits")]
@@ -67,26 +71,44 @@
}
#[cfg(feature = "parsing")]
+pub fn parse_delimiter(input: ParseStream) -> Result<(MacroDelimiter, TokenStream)> {
+ input.step(|cursor| {
+ if let Some((TokenTree::Group(g), rest)) = cursor.token_tree() {
+ let span = g.span();
+ let delimiter = match g.delimiter() {
+ Delimiter::Parenthesis => MacroDelimiter::Paren(Paren(span)),
+ Delimiter::Brace => MacroDelimiter::Brace(Brace(span)),
+ Delimiter::Bracket => MacroDelimiter::Bracket(Bracket(span)),
+ Delimiter::None => {
+ return Err(cursor.error("expected delimiter"));
+ }
+ };
+ Ok(((delimiter, g.stream().clone()), rest))
+ } else {
+ Err(cursor.error("expected delimiter"))
+ }
+ })
+}
+
+#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use synom::Synom;
+ use parse::{Parse, ParseStream, Result};
- impl Synom for Macro {
- named!(parse -> Self, do_parse!(
- what: call!(Path::parse_mod_style) >>
- bang: punct!(!) >>
- body: call!(tt::delimited) >>
- (Macro {
- path: what,
- bang_token: bang,
- delimiter: body.0,
- tts: body.1,
+ impl Parse for Macro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let tts;
+ Ok(Macro {
+ path: input.call(Path::parse_mod_style)?,
+ bang_token: input.parse()?,
+ delimiter: {
+ let (delimiter, content) = parse_delimiter(input)?;
+ tts = content;
+ delimiter
+ },
+ tts: tts,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("macro invocation")
}
}
}
diff --git a/src/macros.rs b/src/macros.rs
index f4e7d0a..519c73c 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -178,19 +178,3 @@
($($rest:tt)*) => (ast_struct! { $($rest)* });
}
-
-#[cfg(all(
- feature = "parsing",
- any(feature = "full", feature = "derive")
-))]
-macro_rules! impl_synom {
- ($t:ident $description:tt $($parser:tt)+) => {
- impl Synom for $t {
- named!(parse -> Self, $($parser)+);
-
- fn description() -> Option<&'static str> {
- Some($description)
- }
- }
- }
-}
diff --git a/src/op.rs b/src/op.rs
index a5188d0..c777242 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -91,82 +91,97 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use synom::Synom;
- impl BinOp {
- named!(pub parse_binop -> Self, alt!(
- punct!(&&) => { BinOp::And }
- |
- punct!(||) => { BinOp::Or }
- |
- punct!(<<) => { BinOp::Shl }
- |
- punct!(>>) => { BinOp::Shr }
- |
- punct!(==) => { BinOp::Eq }
- |
- punct!(<=) => { BinOp::Le }
- |
- punct!(!=) => { BinOp::Ne }
- |
- punct!(>=) => { BinOp::Ge }
- |
- punct!(+) => { BinOp::Add }
- |
- punct!(-) => { BinOp::Sub }
- |
- punct!(*) => { BinOp::Mul }
- |
- punct!(/) => { BinOp::Div }
- |
- punct!(%) => { BinOp::Rem }
- |
- punct!(^) => { BinOp::BitXor }
- |
- punct!(&) => { BinOp::BitAnd }
- |
- punct!(|) => { BinOp::BitOr }
- |
- punct!(<) => { BinOp::Lt }
- |
- punct!(>) => { BinOp::Gt }
- ));
+ use parse::{Parse, ParseStream, Result};
- #[cfg(feature = "full")]
- named!(pub parse_assign_op -> Self, alt!(
- punct!(+=) => { BinOp::AddEq }
- |
- punct!(-=) => { BinOp::SubEq }
- |
- punct!(*=) => { BinOp::MulEq }
- |
- punct!(/=) => { BinOp::DivEq }
- |
- punct!(%=) => { BinOp::RemEq }
- |
- punct!(^=) => { BinOp::BitXorEq }
- |
- punct!(&=) => { BinOp::BitAndEq }
- |
- punct!(|=) => { BinOp::BitOrEq }
- |
- punct!(<<=) => { BinOp::ShlEq }
- |
- punct!(>>=) => { BinOp::ShrEq }
- ));
+ fn parse_binop(input: ParseStream) -> Result<BinOp> {
+ if input.peek(Token![&&]) {
+ input.parse().map(BinOp::And)
+ } else if input.peek(Token![||]) {
+ input.parse().map(BinOp::Or)
+ } else if input.peek(Token![<<]) {
+ input.parse().map(BinOp::Shl)
+ } else if input.peek(Token![>>]) {
+ input.parse().map(BinOp::Shr)
+ } else if input.peek(Token![==]) {
+ input.parse().map(BinOp::Eq)
+ } else if input.peek(Token![<=]) {
+ input.parse().map(BinOp::Le)
+ } else if input.peek(Token![!=]) {
+ input.parse().map(BinOp::Ne)
+ } else if input.peek(Token![>=]) {
+ input.parse().map(BinOp::Ge)
+ } else if input.peek(Token![+]) {
+ input.parse().map(BinOp::Add)
+ } else if input.peek(Token![-]) {
+ input.parse().map(BinOp::Sub)
+ } else if input.peek(Token![*]) {
+ input.parse().map(BinOp::Mul)
+ } else if input.peek(Token![/]) {
+ input.parse().map(BinOp::Div)
+ } else if input.peek(Token![%]) {
+ input.parse().map(BinOp::Rem)
+ } else if input.peek(Token![^]) {
+ input.parse().map(BinOp::BitXor)
+ } else if input.peek(Token![&]) {
+ input.parse().map(BinOp::BitAnd)
+ } else if input.peek(Token![|]) {
+ input.parse().map(BinOp::BitOr)
+ } else if input.peek(Token![<]) {
+ input.parse().map(BinOp::Lt)
+ } else if input.peek(Token![>]) {
+ input.parse().map(BinOp::Gt)
+ } else {
+ Err(input.error("expected binary operator"))
+ }
}
- impl Synom for UnOp {
- named!(parse -> Self, alt!(
- punct!(*) => { UnOp::Deref }
- |
- punct!(!) => { UnOp::Not }
- |
- punct!(-) => { UnOp::Neg }
- ));
+ impl Parse for BinOp {
+ #[cfg(not(feature = "full"))]
+ fn parse(input: ParseStream) -> Result<Self> {
+ parse_binop(input)
+ }
- fn description() -> Option<&'static str> {
- Some("unary operator: `*`, `!`, or `-`")
+ #[cfg(feature = "full")]
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![+=]) {
+ input.parse().map(BinOp::AddEq)
+ } else if input.peek(Token![-=]) {
+ input.parse().map(BinOp::SubEq)
+ } else if input.peek(Token![*=]) {
+ input.parse().map(BinOp::MulEq)
+ } else if input.peek(Token![/=]) {
+ input.parse().map(BinOp::DivEq)
+ } else if input.peek(Token![%=]) {
+ input.parse().map(BinOp::RemEq)
+ } else if input.peek(Token![^=]) {
+ input.parse().map(BinOp::BitXorEq)
+ } else if input.peek(Token![&=]) {
+ input.parse().map(BinOp::BitAndEq)
+ } else if input.peek(Token![|=]) {
+ input.parse().map(BinOp::BitOrEq)
+ } else if input.peek(Token![<<=]) {
+ input.parse().map(BinOp::ShlEq)
+ } else if input.peek(Token![>>=]) {
+ input.parse().map(BinOp::ShrEq)
+ } else {
+ parse_binop(input)
+ }
+ }
+ }
+
+ impl Parse for UnOp {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![*]) {
+ input.parse().map(UnOp::Deref)
+ } else if lookahead.peek(Token![!]) {
+ input.parse().map(UnOp::Not)
+ } else if lookahead.peek(Token![-]) {
+ input.parse().map(UnOp::Neg)
+ } else {
+ Err(lookahead.error())
+ }
}
}
}
diff --git a/src/parse.rs b/src/parse.rs
new file mode 100644
index 0000000..c063d4e
--- /dev/null
+++ b/src/parse.rs
@@ -0,0 +1,1043 @@
+// Copyright 2018 Syn Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Parsing interface for parsing a token stream into a syntax tree node.
+//!
+//! Parsing in Syn is built on parser functions that take in a [`ParseStream`]
+//! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying
+//! these parser functions is a lower level mechanism built around the
+//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of
+//! tokens in a token stream.
+//!
+//! [`ParseStream`]: type.ParseStream.html
+//! [`Result<T>`]: type.Result.html
+//! [`Cursor`]: ../buffer/index.html
+//!
+//! # Example
+//!
+//! Here is a snippet of parsing code to get a feel for the style of the
+//! library. We define data structures for a subset of Rust syntax including
+//! enums (not shown) and structs, then provide implementations of the [`Parse`]
+//! trait to parse these syntax tree data structures from a token stream.
+//!
+//! Once `Parse` impls have been defined, they can be called conveniently from a
+//! procedural macro as shown at the bottom of the snippet. If the caller
+//! provides syntactically invalid input to the procedural macro, they will
+//! receive a helpful compiler error message pointing out the exact token that
+//! triggered the failure to parse.
+//!
+//! ```
+//! # extern crate proc_macro;
+//! # extern crate syn;
+//! #
+//! use proc_macro::TokenStream;
+//! use syn::{braced, parse_macro_input, token, Field, Ident, Token};
+//! use syn::parse::{Parse, ParseStream, Result};
+//! use syn::punctuated::Punctuated;
+//!
+//! enum Item {
+//! Struct(ItemStruct),
+//! Enum(ItemEnum),
+//! }
+//!
+//! struct ItemStruct {
+//! struct_token: Token![struct],
+//! ident: Ident,
+//! brace_token: token::Brace,
+//! fields: Punctuated<Field, Token![,]>,
+//! }
+//! #
+//! # enum ItemEnum {}
+//!
+//! impl Parse for Item {
+//! fn parse(input: ParseStream) -> Result<Self> {
+//! let lookahead = input.lookahead1();
+//! if lookahead.peek(Token![struct]) {
+//! input.parse().map(Item::Struct)
+//! } else if lookahead.peek(Token![enum]) {
+//! input.parse().map(Item::Enum)
+//! } else {
+//! Err(lookahead.error())
+//! }
+//! }
+//! }
+//!
+//! impl Parse for ItemStruct {
+//! fn parse(input: ParseStream) -> Result<Self> {
+//! let content;
+//! Ok(ItemStruct {
+//! struct_token: input.parse()?,
+//! ident: input.parse()?,
+//! brace_token: braced!(content in input),
+//! fields: content.parse_terminated(Field::parse_named)?,
+//! })
+//! }
+//! }
+//! #
+//! # impl Parse for ItemEnum {
+//! # fn parse(input: ParseStream) -> Result<Self> {
+//! # unimplemented!()
+//! # }
+//! # }
+//!
+//! # const IGNORE: &str = stringify! {
+//! #[proc_macro]
+//! # };
+//! pub fn my_macro(tokens: TokenStream) -> TokenStream {
+//! let input = parse_macro_input!(tokens as Item);
+//!
+//! /* ... */
+//! # "".parse().unwrap()
+//! }
+//! #
+//! # fn main() {}
+//! ```
+//!
+//! # The `syn::parse*` functions
+//!
+//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve
+//! as an entry point for parsing syntax tree nodes that can be parsed in an
+//! obvious default way. These functions can return any syntax tree node that
+//! implements the [`Parse`] trait, which includes most types in Syn.
+//!
+//! [`syn::parse`]: ../fn.parse.html
+//! [`syn::parse2`]: ../fn.parse2.html
+//! [`syn::parse_str`]: ../fn.parse_str.html
+//! [`Parse`]: trait.Parse.html
+//!
+//! ```
+//! use syn::Type;
+//!
+//! # fn run_parser() -> Result<(), syn::parse::Error> {
+//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;
+//! # Ok(())
+//! # }
+//! #
+//! # fn main() {
+//! # run_parser().unwrap();
+//! # }
+//! ```
+//!
+//! The [`parse_quote!`] macro also uses this approach.
+//!
+//! [`parse_quote!`]: ../macro.parse_quote.html
+//!
+//! # The `Parser` trait
+//!
+//! Some types can be parsed in several ways depending on context. For example
+//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like
+//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]
+//! may or may not allow trailing punctuation, and parsing it the wrong way
+//! would either reject valid input or accept invalid input.
+//!
+//! [`Attribute`]: ../struct.Attribute.html
+//! [`Punctuated`]: ../punctuated/index.html
+//!
+//! The `Parse` trait is not implemented in these cases because there is no good
+//! behavior to consider the default.
+//!
+//! ```ignore
+//! // Can't parse `Punctuated` without knowing whether trailing punctuation
+//! // should be allowed in this context.
+//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;
+//! ```
+//!
+//! In these cases the types provide a choice of parser functions rather than a
+//! single `Parse` implementation, and those parser functions can be invoked
+//! through the [`Parser`] trait.
+//!
+//! [`Parser`]: trait.Parser.html
+//!
+//! ```
+//! # extern crate syn;
+//! #
+//! # extern crate proc_macro2;
+//! # use proc_macro2::TokenStream;
+//! #
+//! use syn::parse::Parser;
+//! use syn::punctuated::Punctuated;
+//! use syn::{Attribute, Expr, PathSegment, Token};
+//!
+//! # fn run_parsers() -> Result<(), syn::parse::Error> {
+//! # let tokens = TokenStream::new().into();
+//! // Parse a nonempty sequence of path segments separated by `::` punctuation
+//! // with no trailing punctuation.
+//! let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;
+//! let path = parser.parse(tokens)?;
+//!
+//! # let tokens = TokenStream::new().into();
+//! // Parse a possibly empty sequence of expressions terminated by commas with
+//! // an optional trailing punctuation.
+//! let parser = Punctuated::<Expr, Token![,]>::parse_terminated;
+//! let args = parser.parse(tokens)?;
+//!
+//! # let tokens = TokenStream::new().into();
+//! // Parse zero or more outer attributes but not inner attributes.
+//! let parser = Attribute::parse_outer;
+//! let attrs = parser.parse(tokens)?;
+//! #
+//! # Ok(())
+//! # }
+//! #
+//! # fn main() {}
+//! ```
+//!
+//! ---
+//!
+//! *This module is available if Syn is built with the `"parsing"` feature.*
+
+use std::cell::Cell;
+use std::fmt::Display;
+use std::marker::PhantomData;
+use std::mem;
+use std::ops::Deref;
+use std::rc::Rc;
+use std::str::FromStr;
+
+#[cfg(all(
+ not(all(target_arch = "wasm32", target_os = "unknown")),
+ feature = "proc-macro"
+))]
+use proc_macro;
+use proc_macro2::{self, Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
+
+use buffer::{Cursor, TokenBuffer};
+use error;
+use lookahead;
+use private;
+use punctuated::Punctuated;
+use token::Token;
+
+pub use error::{Error, Result};
+pub use lookahead::{Lookahead1, Peek};
+
+/// Parsing interface implemented by all types that can be parsed in a default
+/// way from a token stream.
+pub trait Parse: Sized {
+ fn parse(input: ParseStream) -> Result<Self>;
+}
+
+/// Input to a Syn parser function.
+///
+/// See the methods of this type under the documentation of [`ParseBuffer`]. For
+/// an overview of parsing in Syn, refer to the [module documentation].
+///
+/// [module documentation]: index.html
+pub type ParseStream<'a> = &'a ParseBuffer<'a>;
+
+/// Cursor position within a buffered token stream.
+///
+/// This type is more commonly used through the type alias [`ParseStream`] which
+/// is an alias for `&ParseBuffer`.
+///
+/// `ParseStream` is the input type for all parser functions in Syn. They have
+/// the signature `fn(ParseStream) -> Result<T>`.
+pub struct ParseBuffer<'a> {
+ scope: Span,
+ cell: Cell<Cursor<'static>>,
+ marker: PhantomData<Cursor<'a>>,
+ unexpected: Rc<Cell<Option<Span>>>,
+}
+
+impl<'a> Drop for ParseBuffer<'a> {
+ fn drop(&mut self) {
+ if !self.is_empty() && self.unexpected.get().is_none() {
+ self.unexpected.set(Some(self.cursor().span()));
+ }
+ }
+}
+
+/// Cursor state associated with speculative parsing.
+///
+/// This type is the input of the closure provided to [`ParseStream::step`].
+///
+/// [`ParseStream::step`]: struct.ParseBuffer.html#method.step
+///
+/// # Example
+///
+/// ```
+/// # extern crate proc_macro2;
+/// # extern crate syn;
+/// #
+/// use proc_macro2::TokenTree;
+/// use syn::parse::{ParseStream, Result};
+///
+/// // This function advances the stream past the next occurrence of `@`. If
+/// // no `@` is present in the stream, the stream position is unchanged and
+/// // an error is returned.
+/// fn skip_past_next_at(input: ParseStream) -> Result<()> {
+/// input.step(|cursor| {
+/// let mut rest = *cursor;
+/// while let Some((tt, next)) = cursor.token_tree() {
+/// match tt {
+/// TokenTree::Punct(ref punct) if punct.as_char() == '@' => {
+/// return Ok(((), next));
+/// }
+/// _ => rest = next,
+/// }
+/// }
+/// Err(cursor.error("no `@` was found after this point"))
+/// })
+/// }
+/// #
+/// # fn main() {}
+/// ```
+#[derive(Copy, Clone)]
+pub struct StepCursor<'c, 'a> {
+ scope: Span,
+ cursor: Cursor<'c>,
+ marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
+}
+
+impl<'c, 'a> Deref for StepCursor<'c, 'a> {
+ type Target = Cursor<'c>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.cursor
+ }
+}
+
+impl<'c, 'a> StepCursor<'c, 'a> {
+ /// Triggers an error at the current position of the parse stream.
+ ///
+ /// The `ParseStream::step` invocation will return this same error without
+ /// advancing the stream state.
+ pub fn error<T: Display>(self, message: T) -> Error {
+ error::new_at(self.scope, self.cursor, message)
+ }
+}
+
+impl private {
+ pub fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> {
+ let _ = proof;
+ unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) }
+ }
+}
+
+fn skip(input: ParseStream) -> bool {
+ input
+ .step(|cursor| {
+ if let Some((_lifetime, rest)) = cursor.lifetime() {
+ Ok((true, rest))
+ } else if let Some((_token, rest)) = cursor.token_tree() {
+ Ok((true, rest))
+ } else {
+ Ok((false, *cursor))
+ }
+ }).unwrap()
+}
+
+impl private {
+ pub fn new_parse_buffer(
+ scope: Span,
+ cursor: Cursor,
+ unexpected: Rc<Cell<Option<Span>>>,
+ ) -> ParseBuffer {
+ let extend = unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) };
+ ParseBuffer {
+ scope: scope,
+ cell: Cell::new(extend),
+ marker: PhantomData,
+ unexpected: unexpected,
+ }
+ }
+
+ pub fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Option<Span>>> {
+ buffer.unexpected.clone()
+ }
+}
+
+impl<'a> ParseBuffer<'a> {
+ /// Parses a syntax tree node of type `T`, advancing the position of our
+ /// parse stream past it.
+ pub fn parse<T: Parse>(&self) -> Result<T> {
+ T::parse(self)
+ }
+
+ /// Calls the given parser function to parse a syntax tree node of type `T`
+ /// from this stream.
+ ///
+ /// # Example
+ ///
+ /// The parser below invokes [`Attribute::parse_outer`] to parse a vector of
+ /// zero or more outer attributes.
+ ///
+ /// [`Attribute::parse_outer`]: ../struct.Attribute.html#method.parse_outer
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Attribute, Ident, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // Parses a unit struct with attributes.
+ /// //
+ /// // #[path = "s.tmpl"]
+ /// // struct S;
+ /// struct UnitStruct {
+ /// attrs: Vec<Attribute>,
+ /// struct_token: Token![struct],
+ /// name: Ident,
+ /// semi_token: Token![;],
+ /// }
+ ///
+ /// impl Parse for UnitStruct {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(UnitStruct {
+ /// attrs: input.call(Attribute::parse_outer)?,
+ /// struct_token: input.parse()?,
+ /// name: input.parse()?,
+ /// semi_token: input.parse()?,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn call<T>(&self, function: fn(ParseStream) -> Result<T>) -> Result<T> {
+ function(self)
+ }
+
+ /// Looks at the next token in the parse stream to determine whether it
+ /// matches the requested type of token.
+ ///
+ /// Does not advance the position of the parse stream.
+ ///
+ /// # Syntax
+ ///
+ /// Note that this method does not use turbofish syntax. Pass the peek type
+ /// inside of parentheses.
+ ///
+ /// - `input.peek(Token![struct])`
+ /// - `input.peek(Token![==])`
+ /// - `input.peek(Ident)`
+ /// - `input.peek(Lifetime)`
+ /// - `input.peek(token::Brace)`
+ ///
+ /// # Example
+ ///
+ /// In this example we finish parsing the list of supertraits when the next
+ /// token in the input is either `where` or an opening curly brace.
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{braced, token, Generics, Ident, Token, TypeParamBound};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ /// use syn::punctuated::Punctuated;
+ ///
+ /// // Parses a trait definition containing no associated items.
+ /// //
+ /// // trait Marker<'de, T>: A + B<'de> where Box<T>: Clone {}
+ /// struct MarkerTrait {
+ /// trait_token: Token![trait],
+ /// ident: Ident,
+ /// generics: Generics,
+ /// colon_token: Option<Token![:]>,
+ /// supertraits: Punctuated<TypeParamBound, Token![+]>,
+ /// brace_token: token::Brace,
+ /// }
+ ///
+ /// impl Parse for MarkerTrait {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let trait_token: Token![trait] = input.parse()?;
+ /// let ident: Ident = input.parse()?;
+ /// let mut generics: Generics = input.parse()?;
+ /// let colon_token: Option<Token![:]> = input.parse()?;
+ ///
+ /// let mut supertraits = Punctuated::new();
+ /// if colon_token.is_some() {
+ /// loop {
+ /// supertraits.push_value(input.parse()?);
+ /// if input.peek(Token![where]) || input.peek(token::Brace) {
+ /// break;
+ /// }
+ /// supertraits.push_punct(input.parse()?);
+ /// }
+ /// }
+ ///
+ /// generics.where_clause = input.parse()?;
+ /// let content;
+ /// let empty_brace_token = braced!(content in input);
+ ///
+ /// Ok(MarkerTrait {
+ /// trait_token: trait_token,
+ /// ident: ident,
+ /// generics: generics,
+ /// colon_token: colon_token,
+ /// supertraits: supertraits,
+ /// brace_token: empty_brace_token,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn peek<T: Peek>(&self, token: T) -> bool {
+ let _ = token;
+ T::Token::peek(self.cursor())
+ }
+
+ /// Looks at the second-next token in the parse stream.
+ ///
+ /// This is commonly useful as a way to implement contextual keywords.
+ ///
+ /// # Example
+ ///
+ /// This example needs to use `peek2` because the symbol `union` is not a
+ /// keyword in Rust. We can't use just `peek` and decide to parse a union if
+ /// the very next token is `union`, because someone is free to write a `mod
+ /// union` and a macro invocation that looks like `union::some_macro! { ...
+ /// }`. In other words `union` is a contextual keyword.
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Ident, ItemUnion, Macro, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // Parses either a union or a macro invocation.
+ /// enum UnionOrMacro {
+ /// // union MaybeUninit<T> { uninit: (), value: T }
+ /// Union(ItemUnion),
+ /// // lazy_static! { ... }
+ /// Macro(Macro),
+ /// }
+ ///
+ /// impl Parse for UnionOrMacro {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// if input.peek(Token![union]) && input.peek2(Ident) {
+ /// input.parse().map(UnionOrMacro::Union)
+ /// } else {
+ /// input.parse().map(UnionOrMacro::Macro)
+ /// }
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn peek2<T: Peek>(&self, token: T) -> bool {
+ let ahead = self.fork();
+ skip(&ahead) && ahead.peek(token)
+ }
+
+ /// Looks at the third-next token in the parse stream.
+ pub fn peek3<T: Peek>(&self, token: T) -> bool {
+ let ahead = self.fork();
+ skip(&ahead) && skip(&ahead) && ahead.peek(token)
+ }
+
+ /// Parses zero or more occurrences of `T` separated by punctuation of type
+ /// `P`, with optional trailing punctuation.
+ ///
+ /// Parsing continues until the end of this parse stream. The entire content
+ /// of this parse stream must consist of `T` and `P`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// # extern crate quote;
+ /// # extern crate syn;
+ /// #
+ /// # use quote::quote;
+ /// #
+ /// use syn::{parenthesized, token, Ident, Token, Type};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ /// use syn::punctuated::Punctuated;
+ ///
+ /// // Parse a simplified tuple struct syntax like:
+ /// //
+ /// // struct S(A, B);
+ /// struct TupleStruct {
+ /// struct_token: Token![struct],
+ /// ident: Ident,
+ /// paren_token: token::Paren,
+ /// fields: Punctuated<Type, Token![,]>,
+ /// semi_token: Token![;],
+ /// }
+ ///
+ /// impl Parse for TupleStruct {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let content;
+ /// Ok(TupleStruct {
+ /// struct_token: input.parse()?,
+ /// ident: input.parse()?,
+ /// paren_token: parenthesized!(content in input),
+ /// fields: content.parse_terminated(Type::parse)?,
+ /// semi_token: input.parse()?,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {
+ /// # let input = quote! {
+ /// # struct S(A, B);
+ /// # };
+ /// # syn::parse2::<TupleStruct>(input).unwrap();
+ /// # }
+ /// ```
+ pub fn parse_terminated<T, P: Parse>(
+ &self,
+ parser: fn(ParseStream) -> Result<T>,
+ ) -> Result<Punctuated<T, P>> {
+ Punctuated::parse_terminated_with(self, parser)
+ }
+
+ /// Returns whether there are tokens remaining in this stream.
+ ///
+ /// This method returns true at the end of the content of a set of
+ /// delimiters, as well as at the very end of the complete macro input.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// # extern crate syn;
+ /// #
+ /// use syn::{braced, token, Ident, Item, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // Parses a Rust `mod m { ... }` containing zero or more items.
+ /// struct Mod {
+ /// mod_token: Token![mod],
+ /// name: Ident,
+ /// brace_token: token::Brace,
+ /// items: Vec<Item>,
+ /// }
+ ///
+ /// impl Parse for Mod {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let content;
+ /// Ok(Mod {
+ /// mod_token: input.parse()?,
+ /// name: input.parse()?,
+ /// brace_token: braced!(content in input),
+ /// items: {
+ /// let mut items = Vec::new();
+ /// while !content.is_empty() {
+ /// items.push(content.parse()?);
+ /// }
+ /// items
+ /// },
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ pub fn is_empty(&self) -> bool {
+ self.cursor().eof()
+ }
+
+ /// Constructs a helper for peeking at the next token in this stream and
+ /// building an error message if it is not one of a set of expected tokens.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{ConstParam, Ident, Lifetime, LifetimeDef, Token, TypeParam};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // A generic parameter, a single one of the comma-separated elements inside
+ /// // angle brackets in:
+ /// //
+ /// // fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
+ /// //
+ /// // On invalid input, lookahead gives us a reasonable error message.
+ /// //
+ /// // error: expected one of: identifier, lifetime, `const`
+ /// // |
+ /// // 5 | fn f<!Sized>() {}
+ /// // | ^
+ /// enum GenericParam {
+ /// Type(TypeParam),
+ /// Lifetime(LifetimeDef),
+ /// Const(ConstParam),
+ /// }
+ ///
+ /// impl Parse for GenericParam {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let lookahead = input.lookahead1();
+ /// if lookahead.peek(Ident) {
+ /// input.parse().map(GenericParam::Type)
+ /// } else if lookahead.peek(Lifetime) {
+ /// input.parse().map(GenericParam::Lifetime)
+ /// } else if lookahead.peek(Token![const]) {
+ /// input.parse().map(GenericParam::Const)
+ /// } else {
+ /// Err(lookahead.error())
+ /// }
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn lookahead1(&self) -> Lookahead1<'a> {
+ lookahead::new(self.scope, self.cursor())
+ }
+
+ /// Forks a parse stream so that parsing tokens out of either the original
+ /// or the fork does not advance the position of the other.
+ ///
+ /// # Performance
+ ///
+ /// Forking a parse stream is a cheap fixed amount of work and does not
+ /// involve copying token buffers. Where you might hit performance problems
+ /// is if your macro ends up parsing a large amount of content more than
+ /// once.
+ ///
+ /// ```
+ /// # use syn::Expr;
+ /// # use syn::parse::{ParseStream, Result};
+ /// #
+ /// # fn bad(input: ParseStream) -> Result<Expr> {
+ /// // Do not do this.
+ /// if input.fork().parse::<Expr>().is_ok() {
+ /// return input.parse::<Expr>();
+ /// }
+ /// # unimplemented!()
+ /// # }
+ /// ```
+ ///
+ /// As a rule, avoid parsing an unbounded amount of tokens out of a forked
+ /// parse stream. Only use a fork when the amount of work performed against
+ /// the fork is small and bounded.
+ ///
+ /// For a lower level but occasionally more performant way to perform
+ /// speculative parsing, consider using [`ParseStream::step`] instead.
+ ///
+ /// [`ParseStream::step`]: #method.step
+ ///
+ /// # Example
+ ///
+ /// The parse implementation shown here parses possibly restricted `pub`
+ /// visibilities.
+ ///
+ /// - `pub`
+ /// - `pub(crate)`
+ /// - `pub(self)`
+ /// - `pub(super)`
+ /// - `pub(in some::path)`
+ ///
+ /// To handle the case of visibilities inside of tuple structs, the parser
+ /// needs to distinguish parentheses that specify visibility restrictions
+ /// from parentheses that form part of a tuple type.
+ ///
+ /// ```
+ /// # struct A;
+ /// # struct B;
+ /// # struct C;
+ /// #
+ /// struct S(pub(crate) A, pub (B, C));
+ /// ```
+ ///
+ /// In this example input the first tuple struct element of `S` has
+ /// `pub(crate)` visibility while the second tuple struct element has `pub`
+ /// visibility; the parentheses around `(B, C)` are part of the type rather
+ /// than part of a visibility restriction.
+ ///
+ /// The parser uses a forked parse stream to check the first token inside of
+ /// parentheses after the `pub` keyword. This is a small bounded amount of
+ /// work performed against the forked parse stream.
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{parenthesized, token, Ident, Path, Token};
+ /// use syn::ext::IdentExt;
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// struct PubVisibility {
+ /// pub_token: Token![pub],
+ /// restricted: Option<Restricted>,
+ /// }
+ ///
+ /// struct Restricted {
+ /// paren_token: token::Paren,
+ /// in_token: Option<Token![in]>,
+ /// path: Path,
+ /// }
+ ///
+ /// impl Parse for PubVisibility {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let pub_token: Token![pub] = input.parse()?;
+ ///
+ /// if input.peek(token::Paren) {
+ /// let ahead = input.fork();
+ /// let mut content;
+ /// parenthesized!(content in ahead);
+ ///
+ /// if content.peek(Token![crate])
+ /// || content.peek(Token![self])
+ /// || content.peek(Token![super])
+ /// {
+ /// return Ok(PubVisibility {
+ /// pub_token: pub_token,
+ /// restricted: Some(Restricted {
+ /// paren_token: parenthesized!(content in input),
+ /// in_token: None,
+ /// path: Path::from(content.call(Ident::parse_any)?),
+ /// }),
+ /// });
+ /// } else if content.peek(Token![in]) {
+ /// return Ok(PubVisibility {
+ /// pub_token: pub_token,
+ /// restricted: Some(Restricted {
+ /// paren_token: parenthesized!(content in input),
+ /// in_token: Some(content.parse()?),
+ /// path: content.call(Path::parse_mod_style)?,
+ /// }),
+ /// });
+ /// }
+ /// }
+ ///
+ /// Ok(PubVisibility {
+ /// pub_token: pub_token,
+ /// restricted: None,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn fork(&self) -> Self {
+ ParseBuffer {
+ scope: self.scope,
+ cell: self.cell.clone(),
+ marker: PhantomData,
+ // Not the parent's unexpected. Nothing cares whether the clone
+ // parses all the way.
+ unexpected: Rc::new(Cell::new(None)),
+ }
+ }
+
+ /// Triggers an error at the current position of the parse stream.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Expr, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // Some kind of loop: `while` or `for` or `loop`.
+ /// struct Loop {
+ /// expr: Expr,
+ /// }
+ ///
+ /// impl Parse for Loop {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// if input.peek(Token![while])
+ /// || input.peek(Token![for])
+ /// || input.peek(Token![loop])
+ /// {
+ /// Ok(Loop {
+ /// expr: input.parse()?,
+ /// })
+ /// } else {
+ /// Err(input.error("expected some kind of loop"))
+ /// }
+ /// }
+ /// }
+ /// ```
+ pub fn error<T: Display>(&self, message: T) -> Error {
+ error::new_at(self.scope, self.cursor(), message)
+ }
+
+ /// Speculatively parses tokens from this parse stream, advancing the
+ /// position of this stream only if parsing succeeds.
+ ///
+ /// This is a powerful low-level API used for defining the `Parse` impls of
+ /// the basic built-in token types. It is not something that will be used
+ /// widely outside of the Syn codebase.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate proc_macro2;
+ /// # extern crate syn;
+ /// #
+ /// use proc_macro2::TokenTree;
+ /// use syn::parse::{ParseStream, Result};
+ ///
+ /// // This function advances the stream past the next occurrence of `@`. If
+ /// // no `@` is present in the stream, the stream position is unchanged and
+ /// // an error is returned.
+ /// fn skip_past_next_at(input: ParseStream) -> Result<()> {
+ /// input.step(|cursor| {
+ /// let mut rest = *cursor;
+ /// while let Some((tt, next)) = cursor.token_tree() {
+ /// match tt {
+ /// TokenTree::Punct(ref punct) if punct.as_char() == '@' => {
+ /// return Ok(((), next));
+ /// }
+ /// _ => rest = next,
+ /// }
+ /// }
+ /// Err(cursor.error("no `@` was found after this point"))
+ /// })
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn step<F, R>(&self, function: F) -> Result<R>
+ where
+ F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
+ {
+ let (node, rest) = function(StepCursor {
+ scope: self.scope,
+ cursor: self.cell.get(),
+ marker: PhantomData,
+ })?;
+ self.cell.set(rest);
+ Ok(node)
+ }
+
+ /// Provides low-level access to the token representation underlying this
+ /// parse stream.
+ ///
+ /// Cursors are immutable so no operations you perform against the cursor
+ /// will affect the state of this parse stream.
+ pub fn cursor(&self) -> Cursor<'a> {
+ self.cell.get()
+ }
+
+ fn check_unexpected(&self) -> Result<()> {
+ match self.unexpected.get() {
+ Some(span) => Err(Error::new(span, "unexpected token")),
+ None => Ok(()),
+ }
+ }
+}
+
+impl<T: Parse> Parse for Box<T> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.parse().map(Box::new)
+ }
+}
+
+impl<T: Parse + Token> Parse for Option<T> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if T::peek(input.cursor()) {
+ Ok(Some(input.parse()?))
+ } else {
+ Ok(None)
+ }
+ }
+}
+
+impl Parse for TokenStream {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
+ }
+}
+
+impl Parse for TokenTree {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.token_tree() {
+ Some((tt, rest)) => Ok((tt, rest)),
+ None => Err(cursor.error("expected token tree")),
+ })
+ }
+}
+
+impl Parse for Group {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ for delim in &[Delimiter::Parenthesis, Delimiter::Brace, Delimiter::Bracket] {
+ if let Some((inside, span, rest)) = cursor.group(*delim) {
+ let mut group = Group::new(*delim, inside.token_stream());
+ group.set_span(span);
+ return Ok((group, rest));
+ }
+ }
+ Err(cursor.error("expected group token"))
+ })
+ }
+}
+
+impl Parse for Punct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.punct() {
+ Some((punct, rest)) => Ok((punct, rest)),
+ None => Err(cursor.error("expected punctuation token")),
+ })
+ }
+}
+
+impl Parse for Literal {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.literal() {
+ Some((literal, rest)) => Ok((literal, rest)),
+ None => Err(cursor.error("expected literal token")),
+ })
+ }
+}
+
+/// Parser that can parse Rust tokens into a particular syntax tree node.
+///
+/// Refer to the [module documentation] for details about parsing in Syn.
+///
+/// [module documentation]: index.html
+///
+/// *This trait is available if Syn is built with the `"parsing"` feature.*
+pub trait Parser: Sized {
+ type Output;
+
+ /// Parse a proc-macro2 token stream into the chosen syntax tree node.
+ fn parse2(self, tokens: TokenStream) -> Result<Self::Output>;
+
+ /// Parse tokens of source code into the chosen syntax tree node.
+ ///
+ /// *This method is available if Syn is built with both the `"parsing"` and
+ /// `"proc-macro"` features.*
+ #[cfg(all(
+ not(all(target_arch = "wasm32", target_os = "unknown")),
+ feature = "proc-macro"
+ ))]
+ fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output> {
+ self.parse2(proc_macro2::TokenStream::from(tokens))
+ }
+
+ /// Parse a string of Rust code into the chosen syntax tree node.
+ ///
+ /// # Hygiene
+ ///
+ /// Every span in the resulting syntax tree will be set to resolve at the
+ /// macro call site.
+ fn parse_str(self, s: &str) -> Result<Self::Output> {
+ self.parse2(proc_macro2::TokenStream::from_str(s)?)
+ }
+}
+
+fn tokens_to_parse_buffer(tokens: &TokenBuffer) -> ParseBuffer {
+ let scope = Span::call_site();
+ let cursor = tokens.begin();
+ let unexpected = Rc::new(Cell::new(None));
+ private::new_parse_buffer(scope, cursor, unexpected)
+}
+
+impl<F, T> Parser for F
+where
+ F: FnOnce(ParseStream) -> Result<T>,
+{
+ type Output = T;
+
+ fn parse2(self, tokens: TokenStream) -> Result<T> {
+ let buf = TokenBuffer::new2(tokens);
+ let state = tokens_to_parse_buffer(&buf);
+ let node = self(&state)?;
+ state.check_unexpected()?;
+ if state.is_empty() {
+ Ok(node)
+ } else {
+ Err(state.error("unexpected token"))
+ }
+ }
+}
diff --git a/src/parse_quote.rs b/src/parse_quote.rs
index ec8ef5a..0cb4565 100644
--- a/src/parse_quote.rs
+++ b/src/parse_quote.rs
@@ -1,21 +1,19 @@
/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
-/// [`quote!`]: https://docs.rs/quote/0.4/quote/index.html
+/// [`quote!`]: https://docs.rs/quote/0.6/quote/index.html
///
-/// The return type can be any syntax tree node that implements the [`Synom`]
+/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
-/// [`Synom`]: synom/trait.Synom.html
+/// [`Parse`]: parse/trait.Parse.html
///
/// ```
-/// #[macro_use]
-/// extern crate syn;
-///
-/// #[macro_use]
-/// extern crate quote;
-///
-/// use syn::Stmt;
+/// # extern crate syn;
+/// # extern crate quote;
+/// #
+/// use quote::quote;
+/// use syn::{parse_quote, Stmt};
///
/// fn main() {
/// let name = quote!(v);
@@ -39,14 +37,14 @@
/// parameter `T` in the input generics.
///
/// ```
-/// # #[macro_use]
+/// # extern crate quote;
/// # extern crate syn;
/// #
-/// # #[macro_use]
-/// # extern crate quote;
+/// # use quote::quote;
+/// # use syn::parse_quote;
/// #
-/// # use syn::{Generics, GenericParam};
-/// #
+/// use syn::{Generics, GenericParam};
+///
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
/// for param in &mut generics.params {
@@ -63,7 +61,7 @@
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
-/// though they do not implement the `Synom` trait.
+/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
/// or inner like `#![...]`
@@ -81,20 +79,15 @@
#[macro_export]
macro_rules! parse_quote {
($($tt:tt)*) => {
- $crate::parse_quote::parse($crate::parse_quote::From::from(quote!($($tt)*)))
+ $crate::parse_quote::parse($crate::export::From::from(quote!($($tt)*)))
};
}
////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Synom.
-use buffer::Cursor;
+use parse::{Parse, ParseStream, Parser, Result};
use proc_macro2::TokenStream;
-use synom::{PResult, Parser, Synom};
-
-// Not public API.
-#[doc(hidden)]
-pub use std::convert::From;
// Not public API.
#[doc(hidden)]
@@ -102,30 +95,19 @@
let parser = T::parse;
match parser.parse2(token_stream) {
Ok(t) => t,
- Err(err) => match T::description() {
- Some(s) => panic!("failed to parse {}: {}", s, err),
- None => panic!("{}", err),
- },
+ Err(err) => panic!("{}", err),
}
}
// Not public API.
#[doc(hidden)]
pub trait ParseQuote: Sized {
- fn parse(input: Cursor) -> PResult<Self>;
- fn description() -> Option<&'static str>;
+ fn parse(input: ParseStream) -> Result<Self>;
}
-impl<T> ParseQuote for T
-where
- T: Synom,
-{
- fn parse(input: Cursor) -> PResult<Self> {
- <T as Synom>::parse(input)
- }
-
- fn description() -> Option<&'static str> {
- <T as Synom>::description()
+impl<T: Parse> ParseQuote for T {
+ fn parse(input: ParseStream) -> Result<Self> {
+ <T as Parse>::parse(input)
}
}
@@ -133,31 +115,22 @@
// Any other types that we want `parse_quote!` to be able to parse.
use punctuated::Punctuated;
-
#[cfg(any(feature = "full", feature = "derive"))]
-use Attribute;
-
-impl<T, P> ParseQuote for Punctuated<T, P>
-where
- T: Synom,
- P: Synom,
-{
- named!(parse -> Self, call!(Punctuated::parse_terminated));
-
- fn description() -> Option<&'static str> {
- Some("punctuated sequence")
- }
-}
+use {attr, Attribute};
#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
- named!(parse -> Self, alt!(
- call!(Attribute::parse_outer)
- |
- call!(Attribute::parse_inner)
- ));
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![#]) && input.peek2(Token![!]) {
+ attr::parsing::single_parse_inner(input)
+ } else {
+ attr::parsing::single_parse_outer(input)
+ }
+ }
+}
- fn description() -> Option<&'static str> {
- Some("attribute")
+impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_terminated(input)
}
}
diff --git a/src/parsers.rs b/src/parsers.rs
deleted file mode 100644
index 400c0ca..0000000
--- a/src/parsers.rs
+++ /dev/null
@@ -1,1428 +0,0 @@
-// Copyright 2018 Syn Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use buffer::Cursor;
-use parse_error;
-use synom::PResult;
-
-/// Define a parser function with the signature expected by syn parser
-/// combinators.
-///
-/// The function may be the `parse` function of the [`Synom`] trait, or it may
-/// be a free-standing function with an arbitrary name. When implementing the
-/// `Synom` trait, the function name is `parse` and the return type is `Self`.
-///
-/// [`Synom`]: synom/trait.Synom.html
-///
-/// - **Syntax:** `named!(NAME -> TYPE, PARSER)` or `named!(pub NAME -> TYPE, PARSER)`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Type;
-/// use syn::punctuated::Punctuated;
-/// use syn::synom::Synom;
-///
-/// /// Parses one or more Rust types separated by commas.
-/// ///
-/// /// Example: `String, Vec<T>, [u8; LEN + 1]`
-/// named!(pub comma_separated_types -> Punctuated<Type, Token![,]>,
-/// call!(Punctuated::parse_separated_nonempty)
-/// );
-///
-/// /// The same function as a `Synom` implementation.
-/// struct CommaSeparatedTypes {
-/// types: Punctuated<Type, Token![,]>,
-/// }
-///
-/// impl Synom for CommaSeparatedTypes {
-/// /// As the default behavior, we want there to be at least 1 type.
-/// named!(parse -> Self, do_parse!(
-/// types: call!(Punctuated::parse_separated_nonempty) >>
-/// (CommaSeparatedTypes { types })
-/// ));
-/// }
-///
-/// impl CommaSeparatedTypes {
-/// /// A separate parser that the user can invoke explicitly which allows
-/// /// for parsing 0 or more types, rather than the default 1 or more.
-/// named!(pub parse0 -> Self, do_parse!(
-/// types: call!(Punctuated::parse_separated) >>
-/// (CommaSeparatedTypes { types })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! named {
- ($name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
- fn $name(i: $crate::buffer::Cursor) -> $crate::synom::PResult<$o> {
- $submac!(i, $($args)*)
- }
- };
-
- (pub $name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => {
- pub fn $name(i: $crate::buffer::Cursor) -> $crate::synom::PResult<$o> {
- $submac!(i, $($args)*)
- }
- };
-
- // These two variants are for defining named parsers which have custom
- // arguments, and are called with `call!()`
- ($name:ident($($params:tt)*) -> $o:ty, $submac:ident!( $($args:tt)* )) => {
- fn $name(i: $crate::buffer::Cursor, $($params)*) -> $crate::synom::PResult<$o> {
- $submac!(i, $($args)*)
- }
- };
-
- (pub $name:ident($($params:tt)*) -> $o:ty, $submac:ident!( $($args:tt)* )) => {
- pub fn $name(i: $crate::buffer::Cursor, $($params)*) -> $crate::synom::PResult<$o> {
- $submac!(i, $($args)*)
- }
- };
-}
-
-#[cfg(synom_verbose_trace)]
-#[macro_export]
-macro_rules! call {
- ($i:expr, $fun:expr $(, $args:expr)*) => {{
- #[allow(unused_imports)]
- use $crate::synom::ext::*;
- let i = $i;
- eprintln!(concat!(" -> ", stringify!($fun), " @ {:?}"), i);
- let r = $fun(i $(, $args)*);
- match r {
- Ok((_, i)) => eprintln!(concat!("OK ", stringify!($fun), " @ {:?}"), i),
- Err(_) => eprintln!(concat!("ERR ", stringify!($fun), " @ {:?}"), i),
- }
- r
- }};
-}
-
-/// Invoke the given parser function with zero or more arguments.
-///
-/// - **Syntax:** `call!(FN, ARGS...)`
-///
-/// where the signature of the function is `fn(Cursor, ARGS...) -> PResult<T>`
-///
-/// - **Output:** `T`, the result of invoking the function `FN`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Type;
-/// use syn::punctuated::Punctuated;
-/// use syn::synom::Synom;
-///
-/// /// Parses one or more Rust types separated by commas.
-/// ///
-/// /// Example: `String, Vec<T>, [u8; LEN + 1]`
-/// struct CommaSeparatedTypes {
-/// types: Punctuated<Type, Token![,]>,
-/// }
-///
-/// impl Synom for CommaSeparatedTypes {
-/// named!(parse -> Self, do_parse!(
-/// types: call!(Punctuated::parse_separated_nonempty) >>
-/// (CommaSeparatedTypes { types })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[cfg(not(synom_verbose_trace))]
-#[macro_export]
-macro_rules! call {
- ($i:expr, $fun:expr $(, $args:expr)*) => {{
- #[allow(unused_imports)]
- use $crate::synom::ext::*;
- $fun($i $(, $args)*)
- }};
-}
-
-/// Transform the result of a parser by applying a function or closure.
-///
-/// - **Syntax:** `map!(THING, FN)`
-/// - **Output:** the return type of function FN applied to THING
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::{Expr, ExprIf};
-///
-/// /// Extracts the branch condition of an `if`-expression.
-/// fn get_cond(if_: ExprIf) -> Expr {
-/// *if_.cond
-/// }
-///
-/// /// Parses a full `if`-expression but returns the condition part only.
-/// ///
-/// /// Example: `if x > 0xFF { "big" } else { "small" }`
-/// /// The return would be the expression `x > 0xFF`.
-/// named!(if_condition -> Expr,
-/// map!(syn!(ExprIf), get_cond)
-/// );
-///
-/// /// Equivalent using a closure.
-/// named!(if_condition2 -> Expr,
-/// map!(syn!(ExprIf), |if_| *if_.cond)
-/// );
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! map {
- ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- ::std::result::Result::Ok((o, i)) =>
- ::std::result::Result::Ok(($crate::parsers::invoke($g, o), i)),
- }
- };
-
- ($i:expr, $f:expr, $g:expr) => {
- map!($i, call!($f), $g)
- };
-}
-
-// Somehow this helps with type inference in `map!` and `alt!`.
-//
-// Not public API.
-#[doc(hidden)]
-pub fn invoke<T, R, F: FnOnce(T) -> R>(f: F, t: T) -> R {
- f(t)
-}
-
-/// Invert the result of a parser by parsing successfully if the given parser
-/// fails to parse and vice versa.
-///
-/// Does not consume any of the input.
-///
-/// - **Syntax:** `not!(THING)`
-/// - **Output:** `()`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Expr;
-///
-/// /// Parses any expression that does not begin with a `-` minus sign.
-/// named!(not_negative_expr -> Expr, do_parse!(
-/// not!(punct!(-)) >>
-/// e: syn!(Expr) >>
-/// (e)
-/// ));
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! not {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Ok(_) => $crate::parse_error(),
- ::std::result::Result::Err(_) =>
- ::std::result::Result::Ok(((), $i)),
- }
- };
-}
-
-/// Execute a parser only if a condition is met, otherwise return None.
-///
-/// If you are familiar with nom, this is nom's `cond_with_error` parser.
-///
-/// - **Syntax:** `cond!(CONDITION, THING)`
-/// - **Output:** `Some(THING)` if the condition is true, else `None`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::{Ident, MacroDelimiter};
-/// use syn::token::{Paren, Bracket, Brace};
-/// use syn::synom::Synom;
-///
-/// /// Parses a macro call with empty input. If the macro is written with
-/// /// parentheses or brackets, a trailing semicolon is required.
-/// ///
-/// /// Example: `my_macro!{}` or `my_macro!();` or `my_macro![];`
-/// struct EmptyMacroCall {
-/// name: Ident,
-/// bang_token: Token![!],
-/// empty_body: MacroDelimiter,
-/// semi_token: Option<Token![;]>,
-/// }
-///
-/// fn requires_semi(delimiter: &MacroDelimiter) -> bool {
-/// match *delimiter {
-/// MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => true,
-/// MacroDelimiter::Brace(_) => false,
-/// }
-/// }
-///
-/// impl Synom for EmptyMacroCall {
-/// named!(parse -> Self, do_parse!(
-/// name: syn!(Ident) >>
-/// bang_token: punct!(!) >>
-/// empty_body: alt!(
-/// parens!(epsilon!()) => { |d| MacroDelimiter::Paren(d.0) }
-/// |
-/// brackets!(epsilon!()) => { |d| MacroDelimiter::Bracket(d.0) }
-/// |
-/// braces!(epsilon!()) => { |d| MacroDelimiter::Brace(d.0) }
-/// ) >>
-/// semi_token: cond!(requires_semi(&empty_body), punct!(;)) >>
-/// (EmptyMacroCall {
-/// name,
-/// bang_token,
-/// empty_body,
-/// semi_token,
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! cond {
- ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => {
- if $cond {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Ok((o, i)) =>
- ::std::result::Result::Ok((::std::option::Option::Some(o), i)),
- ::std::result::Result::Err(x) => ::std::result::Result::Err(x),
- }
- } else {
- ::std::result::Result::Ok((::std::option::Option::None, $i))
- }
- };
-
- ($i:expr, $cond:expr, $f:expr) => {
- cond!($i, $cond, call!($f))
- };
-}
-
-/// Execute a parser only if a condition is met, otherwise fail to parse.
-///
-/// This is typically used inside of [`option!`] or [`alt!`].
-///
-/// [`option!`]: macro.option.html
-/// [`alt!`]: macro.alt.html
-///
-/// - **Syntax:** `cond_reduce!(CONDITION, THING)`
-/// - **Output:** `THING`
-///
-/// The subparser may be omitted in which case it defaults to [`epsilon!`].
-///
-/// [`epsilon!`]: macro.epsilon.html
-///
-/// - **Syntax:** `cond_reduce!(CONDITION)`
-/// - **Output:** `()`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Type;
-/// use syn::token::Paren;
-/// use syn::punctuated::Punctuated;
-/// use syn::synom::Synom;
-///
-/// /// Parses a possibly variadic function signature.
-/// ///
-/// /// Example: `fn(A) or `fn(A, B, C, ...)` or `fn(...)`
-/// /// Rejected: `fn(A, B...)`
-/// struct VariadicFn {
-/// fn_token: Token![fn],
-/// paren_token: Paren,
-/// types: Punctuated<Type, Token![,]>,
-/// variadic: Option<Token![...]>,
-/// }
-///
-/// // Example of using `cond_reduce!` inside of `option!`.
-/// impl Synom for VariadicFn {
-/// named!(parse -> Self, do_parse!(
-/// fn_token: keyword!(fn) >>
-/// params: parens!(do_parse!(
-/// types: call!(Punctuated::parse_terminated) >>
-/// // Allow, but do not require, an ending `...` but only if the
-/// // preceding list of types is empty or ends with a trailing comma.
-/// variadic: option!(cond_reduce!(types.empty_or_trailing(), punct!(...))) >>
-/// (types, variadic)
-/// )) >>
-/// ({
-/// let (paren_token, (types, variadic)) = params;
-/// VariadicFn {
-/// fn_token,
-/// paren_token,
-/// types,
-/// variadic,
-/// }
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! cond_reduce {
- ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => {
- if $cond {
- $submac!($i, $($args)*)
- } else {
- $crate::parse_error()
- }
- };
-
- ($i:expr, $cond:expr) => {
- cond_reduce!($i, $cond, epsilon!())
- };
-
- ($i:expr, $cond:expr, $f:expr) => {
- cond_reduce!($i, $cond, call!($f))
- };
-}
-
-/// Parse zero or more values using the given parser.
-///
-/// - **Syntax:** `many0!(THING)`
-/// - **Output:** `Vec<THING>`
-///
-/// You may also be looking for:
-///
-/// - `call!(Punctuated::parse_separated)` - zero or more values with separator
-/// - `call!(Punctuated::parse_separated_nonempty)` - one or more values
-/// - `call!(Punctuated::parse_terminated)` - zero or more, allows trailing separator
-/// - `call!(Punctuated::parse_terminated_nonempty)` - one or more
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::{Ident, Item};
-/// use syn::token::Brace;
-/// use syn::synom::Synom;
-///
-/// /// Parses a module containing zero or more Rust items.
-/// ///
-/// /// Example: `mod m { type Result<T> = ::std::result::Result<T, MyError>; }`
-/// struct SimpleMod {
-/// mod_token: Token![mod],
-/// name: Ident,
-/// brace_token: Brace,
-/// items: Vec<Item>,
-/// }
-///
-/// impl Synom for SimpleMod {
-/// named!(parse -> Self, do_parse!(
-/// mod_token: keyword!(mod) >>
-/// name: syn!(Ident) >>
-/// body: braces!(many0!(syn!(Item))) >>
-/// (SimpleMod {
-/// mod_token,
-/// name,
-/// brace_token: body.0,
-/// items: body.1,
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! many0 {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {{
- let ret;
- let mut res = ::std::vec::Vec::new();
- let mut input = $i;
-
- loop {
- if input.eof() {
- ret = ::std::result::Result::Ok((res, input));
- break;
- }
-
- match $submac!(input, $($args)*) {
- ::std::result::Result::Err(_) => {
- ret = ::std::result::Result::Ok((res, input));
- break;
- }
- ::std::result::Result::Ok((o, i)) => {
- // loop trip must always consume (otherwise infinite loops)
- if i == input {
- ret = $crate::parse_error();
- break;
- }
-
- res.push(o);
- input = i;
- }
- }
- }
-
- ret
- }};
-
- ($i:expr, $f:expr) => {
- $crate::parsers::many0($i, $f)
- };
-}
-
-// Improve compile time by compiling this loop only once per type it is used
-// with.
-//
-// Not public API.
-#[doc(hidden)]
-pub fn many0<T>(mut input: Cursor, f: fn(Cursor) -> PResult<T>) -> PResult<Vec<T>> {
- let mut res = Vec::new();
-
- loop {
- if input.eof() {
- return Ok((res, input));
- }
-
- match f(input) {
- Err(_) => {
- return Ok((res, input));
- }
- Ok((o, i)) => {
- // loop trip must always consume (otherwise infinite loops)
- if i == input {
- return parse_error();
- }
-
- res.push(o);
- input = i;
- }
- }
- }
-}
-
-/// Pattern-match the result of a parser to select which other parser to run.
-///
-/// - **Syntax:** `switch!(TARGET, PAT1 => THEN1 | PAT2 => THEN2 | ...)`
-/// - **Output:** `T`, the return type of `THEN1` and `THEN2` and ...
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Ident;
-/// use syn::token::Brace;
-/// use syn::synom::Synom;
-///
-/// /// Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
-/// enum UnitType {
-/// Struct {
-/// struct_token: Token![struct],
-/// name: Ident,
-/// semi_token: Token![;],
-/// },
-/// Enum {
-/// enum_token: Token![enum],
-/// name: Ident,
-/// brace_token: Brace,
-/// variant: Ident,
-/// },
-/// }
-///
-/// enum StructOrEnum {
-/// Struct(Token![struct]),
-/// Enum(Token![enum]),
-/// }
-///
-/// impl Synom for StructOrEnum {
-/// named!(parse -> Self, alt!(
-/// keyword!(struct) => { StructOrEnum::Struct }
-/// |
-/// keyword!(enum) => { StructOrEnum::Enum }
-/// ));
-/// }
-///
-/// impl Synom for UnitType {
-/// named!(parse -> Self, do_parse!(
-/// which: syn!(StructOrEnum) >>
-/// name: syn!(Ident) >>
-/// item: switch!(value!(which),
-/// StructOrEnum::Struct(struct_token) => map!(
-/// punct!(;),
-/// |semi_token| UnitType::Struct {
-/// struct_token,
-/// name,
-/// semi_token,
-/// }
-/// )
-/// |
-/// StructOrEnum::Enum(enum_token) => map!(
-/// braces!(syn!(Ident)),
-/// |(brace_token, variant)| UnitType::Enum {
-/// enum_token,
-/// name,
-/// brace_token,
-/// variant,
-/// }
-/// )
-/// ) >>
-/// (item)
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! switch {
- ($i:expr, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) => ::std::result::Result::Err(err),
- ::std::result::Result::Ok((o, i)) => match o {
- $(
- $p => $subrule!(i, $($args2)*),
- )*
- }
- }
- };
-}
-
-/// Produce the given value without parsing anything.
-///
-/// This can be needed where you have an existing parsed value but a parser
-/// macro's syntax expects you to provide a submacro, such as in the first
-/// argument of [`switch!`] or one of the branches of [`alt!`].
-///
-/// [`switch!`]: macro.switch.html
-/// [`alt!`]: macro.alt.html
-///
-/// - **Syntax:** `value!(VALUE)`
-/// - **Output:** `VALUE`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Ident;
-/// use syn::token::Brace;
-/// use syn::synom::Synom;
-///
-/// /// Parse a unit struct or enum: either `struct S;` or `enum E { V }`.
-/// enum UnitType {
-/// Struct {
-/// struct_token: Token![struct],
-/// name: Ident,
-/// semi_token: Token![;],
-/// },
-/// Enum {
-/// enum_token: Token![enum],
-/// name: Ident,
-/// brace_token: Brace,
-/// variant: Ident,
-/// },
-/// }
-///
-/// enum StructOrEnum {
-/// Struct(Token![struct]),
-/// Enum(Token![enum]),
-/// }
-///
-/// impl Synom for StructOrEnum {
-/// named!(parse -> Self, alt!(
-/// keyword!(struct) => { StructOrEnum::Struct }
-/// |
-/// keyword!(enum) => { StructOrEnum::Enum }
-/// ));
-/// }
-///
-/// impl Synom for UnitType {
-/// named!(parse -> Self, do_parse!(
-/// which: syn!(StructOrEnum) >>
-/// name: syn!(Ident) >>
-/// item: switch!(value!(which),
-/// StructOrEnum::Struct(struct_token) => map!(
-/// punct!(;),
-/// |semi_token| UnitType::Struct {
-/// struct_token,
-/// name,
-/// semi_token,
-/// }
-/// )
-/// |
-/// StructOrEnum::Enum(enum_token) => map!(
-/// braces!(syn!(Ident)),
-/// |(brace_token, variant)| UnitType::Enum {
-/// enum_token,
-/// name,
-/// brace_token,
-/// variant,
-/// }
-/// )
-/// ) >>
-/// (item)
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! value {
- ($i:expr, $res:expr) => {
- ::std::result::Result::Ok(($res, $i))
- };
-}
-
-/// Unconditionally fail to parse anything.
-///
-/// This may be useful in rejecting some arms of a `switch!` parser.
-///
-/// - **Syntax:** `reject!()`
-/// - **Output:** never succeeds
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Item;
-///
-/// // Parse any item, except for a module.
-/// named!(almost_any_item -> Item,
-/// switch!(syn!(Item),
-/// Item::Mod(_) => reject!()
-/// |
-/// ok => value!(ok)
-/// )
-/// );
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! reject {
- ($i:expr,) => {{
- let _ = $i;
- $crate::parse_error()
- }};
-}
-
-/// Run a series of parsers and produce all of the results in a tuple.
-///
-/// - **Syntax:** `tuple!(A, B, C, ...)`
-/// - **Output:** `(A, B, C, ...)`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Type;
-///
-/// named!(two_types -> (Type, Type), tuple!(syn!(Type), syn!(Type)));
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! tuple {
- ($i:expr, $($rest:tt)+) => {
- tuple_parser!($i, (), $($rest)+)
- };
-}
-
-// Internal parser, do not use directly.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! tuple_parser {
- ($i:expr, ($($parsed:ident,)*), $e:ident) => {
- tuple_parser!($i, ($($parsed,)*), call!($e))
- };
-
- ($i:expr, ($($parsed:ident,)*), $e:ident, $($rest:tt)*) => {
- tuple_parser!($i, ($($parsed,)*), call!($e), $($rest)*)
- };
-
- ($i:expr, ($($parsed:ident,)*), $submac:ident!( $($args:tt)* )) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- ::std::result::Result::Ok((o, i)) =>
- ::std::result::Result::Ok((($($parsed,)* o,), i)),
- }
- };
-
- ($i:expr, ($($parsed:ident,)*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- ::std::result::Result::Ok((o, i)) =>
- tuple_parser!(i, ($($parsed,)* o,), $($rest)*),
- }
- };
-
- ($i:expr, ($($parsed:ident,)*),) => {
- ::std::result::Result::Ok((($($parsed,)*), $i))
- };
-}
-
-/// Run a series of parsers, returning the result of the first one which
-/// succeeds.
-///
-/// Optionally allows for the result to be transformed.
-///
-/// - **Syntax:** `alt!(THING1 | THING2 => { FUNC } | ...)`
-/// - **Output:** `T`, the return type of `THING1` and `FUNC(THING2)` and ...
-///
-/// # Example
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-/// extern crate proc_macro2;
-///
-/// use proc_macro2::{Ident, Span};
-///
-/// // Parse any identifier token, or the `!` token in which case the
-/// // identifier is treated as `"BANG"`.
-/// named!(ident_or_bang -> Ident, alt!(
-/// syn!(Ident)
-/// |
-/// punct!(!) => { |_| Ident::new("BANG", Span::call_site()) }
-/// ));
-/// #
-/// # fn main() {}
-/// ```
-///
-/// The `alt!` macro is most commonly seen when parsing a syntax tree enum such
-/// as the [`Item`] enum.
-///
-/// [`Item`]: enum.Item.html
-///
-/// ```
-/// # #[macro_use]
-/// # extern crate syn;
-/// #
-/// # use syn::synom::Synom;
-/// #
-/// # struct Item;
-/// #
-/// impl Synom for Item {
-/// named!(parse -> Self, alt!(
-/// # epsilon!() => { |_| unimplemented!() }
-/// # ));
-/// # }
-/// #
-/// # mod example {
-/// # use syn::*;
-/// #
-/// # named!(parse -> Item, alt!(
-/// syn!(ItemExternCrate) => { Item::ExternCrate }
-/// |
-/// syn!(ItemUse) => { Item::Use }
-/// |
-/// syn!(ItemStatic) => { Item::Static }
-/// |
-/// syn!(ItemConst) => { Item::Const }
-/// |
-/// /* ... */
-/// # syn!(ItemFn) => { Item::Fn }
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! alt {
- ($i:expr, $e:ident | $($rest:tt)*) => {
- alt!($i, call!($e) | $($rest)*)
- };
-
- ($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => {
- match $subrule!($i, $($args)*) {
- res @ ::std::result::Result::Ok(_) => res,
- _ => alt!($i, $($rest)*)
- }
- };
-
- ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => {
- match $subrule!($i, $($args)*) {
- ::std::result::Result::Ok((o, i)) =>
- ::std::result::Result::Ok(($crate::parsers::invoke($gen, o), i)),
- ::std::result::Result::Err(_) => alt!($i, $($rest)*),
- }
- };
-
- ($i:expr, $e:ident => { $gen:expr } | $($rest:tt)*) => {
- alt!($i, call!($e) => { $gen } | $($rest)*)
- };
-
- ($i:expr, $e:ident => { $gen:expr }) => {
- alt!($i, call!($e) => { $gen })
- };
-
- ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => {
- match $subrule!($i, $($args)*) {
- ::std::result::Result::Ok((o, i)) =>
- ::std::result::Result::Ok(($crate::parsers::invoke($gen, o), i)),
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- }
- };
-
- ($i:expr, $e:ident) => {
- alt!($i, call!($e))
- };
-
- ($i:expr, $subrule:ident!( $($args:tt)*)) => {
- $subrule!($i, $($args)*)
- };
-}
-
-/// Run a series of parsers, optionally naming each intermediate result,
-/// followed by a step to combine the intermediate results.
-///
-/// Produces the result of evaluating the final expression in parentheses with
-/// all of the previously named results bound.
-///
-/// - **Syntax:** `do_parse!(name: THING1 >> THING2 >> (RESULT))`
-/// - **Output:** `RESULT`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-/// extern crate proc_macro2;
-///
-/// use proc_macro2::Ident;
-/// use proc_macro2::TokenStream;
-/// use syn::token::Paren;
-/// use syn::synom::Synom;
-///
-/// /// Parse a macro invocation that uses `(` `)` parentheses.
-/// ///
-/// /// Example: `stringify!($args)`.
-/// struct Macro {
-/// name: Ident,
-/// bang_token: Token![!],
-/// paren_token: Paren,
-/// tts: TokenStream,
-/// }
-///
-/// impl Synom for Macro {
-/// named!(parse -> Self, do_parse!(
-/// name: syn!(Ident) >>
-/// bang_token: punct!(!) >>
-/// body: parens!(syn!(TokenStream)) >>
-/// (Macro {
-/// name,
-/// bang_token,
-/// paren_token: body.0,
-/// tts: body.1,
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! do_parse {
- ($i:expr, ( $($rest:expr),* )) => {
- ::std::result::Result::Ok((( $($rest),* ), $i))
- };
-
- ($i:expr, $e:ident >> $($rest:tt)*) => {
- do_parse!($i, call!($e) >> $($rest)*)
- };
-
- ($i:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- ::std::result::Result::Ok((_, i)) =>
- do_parse!(i, $($rest)*),
- }
- };
-
- ($i:expr, $field:ident : $e:ident >> $($rest:tt)*) => {
- do_parse!($i, $field: call!($e) >> $($rest)*)
- };
-
- ($i:expr, $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- ::std::result::Result::Ok((o, i)) => {
- let $field = o;
- do_parse!(i, $($rest)*)
- },
- }
- };
-
- ($i:expr, mut $field:ident : $e:ident >> $($rest:tt)*) => {
- do_parse!($i, mut $field: call!($e) >> $($rest)*)
- };
-
- ($i:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- ::std::result::Result::Ok((o, i)) => {
- let mut $field = o;
- do_parse!(i, $($rest)*)
- },
- }
- };
-}
-
-/// Parse nothing and succeed only if the end of the enclosing block has been
-/// reached.
-///
-/// The enclosing block may be the full input if we are parsing at the top
-/// level, or the surrounding parenthesis/bracket/brace if we are parsing within
-/// those.
-///
-/// - **Syntax:** `input_end!()`
-/// - **Output:** `()`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Expr;
-/// use syn::synom::Synom;
-///
-/// /// Parses any Rust expression followed either by a semicolon or by the end
-/// /// of the input.
-/// ///
-/// /// For example `many0!(syn!(TerminatedExpr))` would successfully parse the
-/// /// following input into three expressions.
-/// ///
-/// /// 1 + 1; second.two(); third!()
-/// ///
-/// /// Similarly within a block, `braced!(many0!(syn!(TerminatedExpr)))` would
-/// /// successfully parse three expressions.
-/// ///
-/// /// { 1 + 1; second.two(); third!() }
-/// struct TerminatedExpr {
-/// expr: Expr,
-/// semi_token: Option<Token![;]>,
-/// }
-///
-/// impl Synom for TerminatedExpr {
-/// named!(parse -> Self, do_parse!(
-/// expr: syn!(Expr) >>
-/// semi_token: alt!(
-/// input_end!() => { |_| None }
-/// |
-/// punct!(;) => { Some }
-/// ) >>
-/// (TerminatedExpr {
-/// expr,
-/// semi_token,
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! input_end {
- ($i:expr,) => {
- $crate::parsers::input_end($i)
- };
-}
-
-// Not a public API
-#[doc(hidden)]
-pub fn input_end(input: Cursor) -> PResult<'static, ()> {
- if input.eof() {
- Ok(((), Cursor::empty()))
- } else {
- parse_error()
- }
-}
-
-/// Turn a failed parse into `None` and a successful parse into `Some`.
-///
-/// A failed parse consumes none of the input.
-///
-/// - **Syntax:** `option!(THING)`
-/// - **Output:** `Option<THING>`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::{Label, Block};
-/// use syn::synom::Synom;
-///
-/// /// Parses a Rust loop. Equivalent to syn::ExprLoop.
-/// ///
-/// /// Examples:
-/// /// loop { println!("y"); }
-/// /// 'x: loop { break 'x; }
-/// struct ExprLoop {
-/// label: Option<Label>,
-/// loop_token: Token![loop],
-/// body: Block,
-/// }
-///
-/// impl Synom for ExprLoop {
-/// named!(parse -> Self, do_parse!(
-/// // Loop may or may not have a label.
-/// label: option!(syn!(Label)) >>
-/// loop_token: keyword!(loop) >>
-/// body: syn!(Block) >>
-/// (ExprLoop {
-/// label,
-/// loop_token,
-/// body,
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! option {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Ok((o, i)) =>
- ::std::result::Result::Ok((Some(o), i)),
- ::std::result::Result::Err(_) =>
- ::std::result::Result::Ok((None, $i)),
- }
- };
-
- ($i:expr, $f:expr) => {
- option!($i, call!($f));
- };
-}
-
-/// Parses nothing and always succeeds.
-///
-/// This can be useful as a fallthrough case in [`alt!`], as shown below. Also
-/// useful for parsing empty delimiters using [`parens!`] or [`brackets!`] or
-/// [`braces!`] by parsing for example `braces!(epsilon!())` for an empty `{}`.
-///
-/// [`alt!`]: macro.alt.html
-/// [`parens!`]: macro.parens.html
-/// [`brackets!`]: macro.brackets.html
-/// [`braces!`]: macro.braces.html
-///
-/// - **Syntax:** `epsilon!()`
-/// - **Output:** `()`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::synom::Synom;
-///
-/// enum Mutability {
-/// Mutable(Token![mut]),
-/// Immutable,
-/// }
-///
-/// impl Synom for Mutability {
-/// named!(parse -> Self, alt!(
-/// keyword!(mut) => { Mutability::Mutable }
-/// |
-/// epsilon!() => { |_| Mutability::Immutable }
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! epsilon {
- ($i:expr,) => {
- ::std::result::Result::Ok(((), $i))
- };
-}
-
-/// Run a parser, binding the result to a name, and then evaluating an
-/// expression.
-///
-/// Discards the result of the expression and parser.
-///
-/// - **Syntax:** `tap!(NAME : THING => EXPR)`
-/// - **Output:** `()`
-#[doc(hidden)]
-#[macro_export]
-macro_rules! tap {
- ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => {
- match $submac!($i, $($args)*) {
- ::std::result::Result::Ok((o, i)) => {
- let $name = o;
- $e;
- ::std::result::Result::Ok(((), i))
- }
- ::std::result::Result::Err(err) =>
- ::std::result::Result::Err(err),
- }
- };
-
- ($i:expr, $name:ident : $f:expr => $e:expr) => {
- tap!($i, $name: call!($f) => $e);
- };
-}
-
-/// Parse any type that implements the `Synom` trait.
-///
-/// Any type implementing [`Synom`] can be used with this parser, whether the
-/// implementation is provided by Syn or is one that you write.
-///
-/// [`Synom`]: synom/trait.Synom.html
-///
-/// - **Syntax:** `syn!(TYPE)`
-/// - **Output:** `TYPE`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::{Ident, Item};
-/// use syn::token::Brace;
-/// use syn::synom::Synom;
-///
-/// /// Parses a module containing zero or more Rust items.
-/// ///
-/// /// Example: `mod m { type Result<T> = ::std::result::Result<T, MyError>; }`
-/// struct SimpleMod {
-/// mod_token: Token![mod],
-/// name: Ident,
-/// brace_token: Brace,
-/// items: Vec<Item>,
-/// }
-///
-/// impl Synom for SimpleMod {
-/// named!(parse -> Self, do_parse!(
-/// mod_token: keyword!(mod) >>
-/// name: syn!(Ident) >>
-/// body: braces!(many0!(syn!(Item))) >>
-/// (SimpleMod {
-/// mod_token,
-/// name,
-/// brace_token: body.0,
-/// items: body.1,
-/// })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! syn {
- ($i:expr, $t:ty) => {
- <$t as $crate::synom::Synom>::parse($i)
- };
-}
-
-/// Parse the given word as a keyword.
-///
-/// For words that are keywords in the Rust language, it is better to use the
-/// [`keyword!`] parser which returns a unique type for each keyword.
-///
-/// [`keyword!`]: macro.keyword.html
-///
-/// - **Syntax:** `custom_keyword!(KEYWORD)`
-/// - **Output:** `Ident`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Ident;
-/// use syn::synom::Synom;
-///
-/// struct Flag {
-/// name: Ident,
-/// }
-///
-/// // Parses the custom keyword `flag` followed by any name for a flag.
-/// //
-/// // Example: `flag Verbose`
-/// impl Synom for Flag {
-/// named!(parse -> Flag, do_parse!(
-/// custom_keyword!(flag) >>
-/// name: syn!(Ident) >>
-/// (Flag { name })
-/// ));
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! custom_keyword {
- ($i:expr, $keyword:ident) => {
- match <$crate::Ident as $crate::synom::Synom>::parse($i) {
- ::std::result::Result::Err(err) => ::std::result::Result::Err(err),
- ::std::result::Result::Ok((token, i)) => {
- if token == stringify!($keyword) {
- ::std::result::Result::Ok((token, i))
- } else {
- $crate::parse_error()
- }
- }
- }
- };
-}
-
-/// Parse inside of `(` `)` parentheses.
-///
-/// This macro parses a set of balanced parentheses and invokes a sub-parser on
-/// the content inside. The sub-parser is required to consume all tokens within
-/// the parentheses in order for this parser to return successfully.
-///
-/// - **Syntax:** `parens!(CONTENT)`
-/// - **Output:** `(token::Paren, CONTENT)`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Expr;
-/// use syn::token::Paren;
-///
-/// /// Parses an expression inside of parentheses.
-/// ///
-/// /// Example: `(1 + 1)`
-/// named!(expr_paren -> (Paren, Expr), parens!(syn!(Expr)));
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! parens {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {
- $crate::token::Paren::parse($i, |i| $submac!(i, $($args)*))
- };
-
- ($i:expr, $f:expr) => {
- parens!($i, call!($f));
- };
-}
-
-/// Parse inside of `[` `]` square brackets.
-///
-/// This macro parses a set of balanced brackets and invokes a sub-parser on the
-/// content inside. The sub-parser is required to consume all tokens within the
-/// brackets in order for this parser to return successfully.
-///
-/// - **Syntax:** `brackets!(CONTENT)`
-/// - **Output:** `(token::Bracket, CONTENT)`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Expr;
-/// use syn::token::Bracket;
-///
-/// /// Parses an expression inside of brackets.
-/// ///
-/// /// Example: `[1 + 1]`
-/// named!(expr_paren -> (Bracket, Expr), brackets!(syn!(Expr)));
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! brackets {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {
- $crate::token::Bracket::parse($i, |i| $submac!(i, $($args)*))
- };
-
- ($i:expr, $f:expr) => {
- brackets!($i, call!($f));
- };
-}
-
-/// Parse inside of `{` `}` curly braces.
-///
-/// This macro parses a set of balanced braces and invokes a sub-parser on the
-/// content inside. The sub-parser is required to consume all tokens within the
-/// braces in order for this parser to return successfully.
-///
-/// - **Syntax:** `braces!(CONTENT)`
-/// - **Output:** `(token::Brace, CONTENT)`
-///
-/// ```rust
-/// #[macro_use]
-/// extern crate syn;
-///
-/// use syn::Expr;
-/// use syn::token::Brace;
-///
-/// /// Parses an expression inside of braces.
-/// ///
-/// /// Example: `{1 + 1}`
-/// named!(expr_paren -> (Brace, Expr), braces!(syn!(Expr)));
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[macro_export]
-macro_rules! braces {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {
- $crate::token::Brace::parse($i, |i| $submac!(i, $($args)*))
- };
-
- ($i:expr, $f:expr) => {
- braces!($i, call!($f));
- };
-}
-
-// Not public API.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! grouped {
- ($i:expr, $submac:ident!( $($args:tt)* )) => {
- $crate::token::Group::parse($i, |i| $submac!(i, $($args)*))
- };
-
- ($i:expr, $f:expr) => {
- grouped!($i, call!($f));
- };
-}
diff --git a/src/path.rs b/src/path.rs
index a848944..443bac6 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -20,44 +20,6 @@
}
}
-impl Path {
- pub fn global(&self) -> bool {
- self.leading_colon.is_some()
- }
-}
-
-/// A helper for printing a self-type qualified path as tokens.
-///
-/// ```rust
-/// extern crate syn;
-/// extern crate quote;
-/// extern crate proc_macro2;
-///
-/// use syn::{QSelf, Path, PathTokens};
-/// use proc_macro2::TokenStream;
-/// use quote::ToTokens;
-///
-/// struct MyNode {
-/// qself: Option<QSelf>,
-/// path: Path,
-/// }
-///
-/// impl ToTokens for MyNode {
-/// fn to_tokens(&self, tokens: &mut TokenStream) {
-/// PathTokens(&self.qself, &self.path).to_tokens(tokens);
-/// }
-/// }
-/// #
-/// # fn main() {}
-/// ```
-///
-/// *This type is available if Syn is built with the `"derive"` or `"full"`
-/// feature and the `"printing"` feature.*
-#[cfg(feature = "printing")]
-#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
-#[cfg_attr(feature = "clone-impls", derive(Clone))]
-pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
-
impl<T> From<T> for Path
where
T: Into<PathSegment>,
@@ -227,202 +189,280 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use synom::Synom;
-
- impl Synom for Path {
- named!(parse -> Self, do_parse!(
- colon: option!(punct!(::)) >>
- segments: call!(Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty) >>
- cond_reduce!(segments.first().map_or(true, |seg| seg.value().ident != "dyn")) >>
- (Path {
- leading_colon: colon,
- segments: segments,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("path")
- }
- }
-
- #[cfg(not(feature = "full"))]
- impl Synom for GenericArgument {
- named!(parse -> Self, alt!(
- call!(ty_no_eq_after) => { GenericArgument::Type }
- |
- syn!(Lifetime) => { GenericArgument::Lifetime }
- |
- syn!(Binding) => { GenericArgument::Binding }
- ));
- }
#[cfg(feature = "full")]
- impl Synom for GenericArgument {
- named!(parse -> Self, alt!(
- call!(ty_no_eq_after) => { GenericArgument::Type }
- |
- syn!(Lifetime) => { GenericArgument::Lifetime }
- |
- syn!(Binding) => { GenericArgument::Binding }
- |
- syn!(ExprLit) => { |l| GenericArgument::Const(Expr::Lit(l)) }
- |
- syn!(ExprBlock) => { |b| GenericArgument::Const(Expr::Block(b)) }
- ));
+ use expr;
+ use ext::IdentExt;
+ use parse::{Parse, ParseStream, Result};
- fn description() -> Option<&'static str> {
- Some("generic argument")
+ impl Parse for Path {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_helper(input, false)
}
}
- impl Synom for AngleBracketedGenericArguments {
- named!(parse -> Self, do_parse!(
- colon2: option!(punct!(::)) >>
- lt: punct!(<) >>
- args: call!(Punctuated::parse_terminated) >>
- gt: punct!(>) >>
- (AngleBracketedGenericArguments {
- colon2_token: colon2,
- lt_token: lt,
- args: args,
- gt_token: gt,
+ impl Parse for GenericArgument {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) && !input.peek2(Token![+]) {
+ return Ok(GenericArgument::Lifetime(input.parse()?));
+ }
+
+ if input.peek(Ident) && input.peek2(Token![=]) {
+ return Ok(GenericArgument::Binding(input.parse()?));
+ }
+
+ #[cfg(feature = "full")]
+ {
+ if input.peek(Lit) {
+ let lit = input.call(expr::parsing::expr_lit)?;
+ return Ok(GenericArgument::Const(Expr::Lit(lit)));
+ }
+
+ if input.peek(token::Brace) {
+ let block = input.call(expr::parsing::expr_block)?;
+ return Ok(GenericArgument::Const(Expr::Block(block)));
+ }
+ }
+
+ input.parse().map(GenericArgument::Type)
+ }
+ }
+
+ impl Parse for AngleBracketedGenericArguments {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(AngleBracketedGenericArguments {
+ colon2_token: input.parse()?,
+ lt_token: input.parse()?,
+ args: {
+ let mut args = Punctuated::new();
+ loop {
+ if input.peek(Token![>]) {
+ break;
+ }
+ let value = input.parse()?;
+ args.push_value(value);
+ if input.peek(Token![>]) {
+ break;
+ }
+ let punct = input.parse()?;
+ args.push_punct(punct);
+ }
+ args
+ },
+ gt_token: input.parse()?,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("angle bracketed generic arguments")
}
}
- impl Synom for ParenthesizedGenericArguments {
- named!(parse -> Self, do_parse!(
- data: parens!(Punctuated::parse_terminated) >>
- output: call!(ReturnType::without_plus) >>
- (ParenthesizedGenericArguments {
- paren_token: data.0,
- inputs: data.1,
- output: output,
+ impl Parse for ParenthesizedGenericArguments {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(ParenthesizedGenericArguments {
+ paren_token: parenthesized!(content in input),
+ inputs: content.parse_terminated(Type::parse)?,
+ output: input.call(ReturnType::without_plus)?,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("parenthesized generic arguments: `Foo(A, B, ..) -> T`")
}
}
- impl Synom for PathSegment {
- named!(parse -> Self, alt!(
- do_parse!(
- ident: syn!(Ident) >>
- arguments: syn!(AngleBracketedGenericArguments) >>
- (PathSegment {
+ impl Parse for PathSegment {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_helper(input, false)
+ }
+ }
+
+ impl PathSegment {
+ fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
+ if input.peek(Token![super])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![crate])
+ || input.peek(Token![extern])
+ {
+ let ident = input.call(Ident::parse_any)?;
+ return Ok(PathSegment::from(ident));
+ }
+
+ let ident = input.parse()?;
+ if !expr_style && input.peek(Token![<]) && !input.peek(Token![<=])
+ || input.peek(Token![::]) && input.peek3(Token![<])
+ {
+ Ok(PathSegment {
ident: ident,
- arguments: PathArguments::AngleBracketed(arguments),
+ arguments: PathArguments::AngleBracketed(input.parse()?),
})
- )
- |
- mod_style_path_segment
- ));
-
- fn description() -> Option<&'static str> {
- Some("path segment")
+ } else {
+ Ok(PathSegment::from(ident))
+ }
}
}
- impl Synom for Binding {
- named!(parse -> Self, do_parse!(
- id: syn!(Ident) >>
- eq: punct!(=) >>
- ty: syn!(Type) >>
- (Binding {
- ident: id,
- eq_token: eq,
- ty: ty,
+ impl Parse for Binding {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Binding {
+ ident: input.parse()?,
+ eq_token: input.parse()?,
+ ty: input.parse()?,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("associated type binding")
}
}
impl Path {
- named!(pub parse_mod_style -> Self, do_parse!(
- colon: option!(punct!(::)) >>
- segments: call!(Punctuated::parse_separated_nonempty_with,
- mod_style_path_segment) >>
- (Path {
- leading_colon: colon,
- segments: segments,
+ /// Parse a `Path` containing no path arguments on any of its segments.
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # extern crate syn;
+ /// #
+ /// use syn::{Path, Token};
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// // A simplified single `use` statement like:
+ /// //
+ /// // use std::collections::HashMap;
+ /// //
+ /// // Note that generic parameters are not allowed in a `use` statement
+ /// // so the following must not be accepted.
+ /// //
+ /// // use a::<b>::c;
+ /// struct SingleUse {
+ /// use_token: Token![use],
+ /// path: Path,
+ /// }
+ ///
+ /// impl Parse for SingleUse {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(SingleUse {
+ /// use_token: input.parse()?,
+ /// path: input.call(Path::parse_mod_style)?,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ pub fn parse_mod_style(input: ParseStream) -> Result<Self> {
+ Ok(Path {
+ leading_colon: input.parse()?,
+ segments: {
+ let mut segments = Punctuated::new();
+ loop {
+ if !input.peek(Ident)
+ && !input.peek(Token![super])
+ && !input.peek(Token![self])
+ && !input.peek(Token![Self])
+ && !input.peek(Token![crate])
+ && !input.peek(Token![extern])
+ {
+ break;
+ }
+ let ident = Ident::parse_any(input)?;
+ segments.push_value(PathSegment::from(ident));
+ if !input.peek(Token![::]) {
+ break;
+ }
+ let punct = input.parse()?;
+ segments.push_punct(punct);
+ }
+ if segments.is_empty() {
+ return Err(input.error("expected path"));
+ } else if segments.trailing_punct() {
+ return Err(input.error("expected path segment"));
+ }
+ segments
+ },
})
- ));
+ }
+
+ fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
+ if input.peek(Token![dyn]) {
+ return Err(input.error("expected path"));
+ }
+
+ Ok(Path {
+ leading_colon: input.parse()?,
+ segments: {
+ let mut segments = Punctuated::new();
+ let value = PathSegment::parse_helper(input, expr_style)?;
+ segments.push_value(value);
+ while input.peek(Token![::]) {
+ let punct: Token![::] = input.parse()?;
+ segments.push_punct(punct);
+ let value = PathSegment::parse_helper(input, expr_style)?;
+ segments.push_value(value);
+ }
+ segments
+ },
+ })
+ }
}
- named!(pub mod_style_path_segment -> PathSegment, alt!(
- syn!(Ident) => { Into::into }
- |
- keyword!(super) => { Into::into }
- |
- keyword!(self) => { Into::into }
- |
- keyword!(Self) => { Into::into }
- |
- keyword!(crate) => { Into::into }
- |
- keyword!(extern) => { Into::into }
- ));
-
- named!(pub qpath -> (Option<QSelf>, Path), alt!(
- map!(syn!(Path), |p| (None, p))
- |
- do_parse!(
- lt: punct!(<) >>
- this: syn!(Type) >>
- path: option!(tuple!(keyword!(as), syn!(Path))) >>
- gt: punct!(>) >>
- colon2: punct!(::) >>
- rest: call!(Punctuated::parse_separated_nonempty) >>
- ({
- let (pos, as_, path) = match path {
- Some((as_, mut path)) => {
- let pos = path.segments.len();
- path.segments.push_punct(colon2);
- path.segments.extend(rest.into_pairs());
- (pos, Some(as_), path)
- }
- None => {
- (0, None, Path {
- leading_colon: Some(colon2),
- segments: rest,
- })
- }
- };
- (Some(QSelf {
- lt_token: lt,
- ty: Box::new(this),
- position: pos,
- as_token: as_,
- gt_token: gt,
- }), path)
- })
- )
- |
- map!(keyword!(self), |s| (None, s.into()))
- ));
-
- named!(pub ty_no_eq_after -> Type, do_parse!(
- ty: syn!(Type) >>
- not!(punct!(=)) >>
- (ty)
- ));
+ pub fn qpath(input: ParseStream, expr_style: bool) -> Result<(Option<QSelf>, Path)> {
+ if input.peek(Token![<]) {
+ let lt_token: Token![<] = input.parse()?;
+ let this: Type = input.parse()?;
+ let path = if input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let path: Path = input.parse()?;
+ Some((as_token, path))
+ } else {
+ None
+ };
+ let gt_token: Token![>] = input.parse()?;
+ let colon2_token: Token![::] = input.parse()?;
+ let mut rest = Punctuated::new();
+ loop {
+ let path = PathSegment::parse_helper(input, expr_style)?;
+ rest.push_value(path);
+ if !input.peek(Token![::]) {
+ break;
+ }
+ let punct: Token![::] = input.parse()?;
+ rest.push_punct(punct);
+ }
+ let (position, as_token, path) = match path {
+ Some((as_token, mut path)) => {
+ let pos = path.segments.len();
+ path.segments.push_punct(colon2_token);
+ path.segments.extend(rest.into_pairs());
+ (pos, Some(as_token), path)
+ }
+ None => {
+ let path = Path {
+ leading_colon: Some(colon2_token),
+ segments: rest,
+ };
+ (0, None, path)
+ }
+ };
+ let qself = QSelf {
+ lt_token: lt_token,
+ ty: Box::new(this),
+ position: position,
+ as_token: as_token,
+ gt_token: gt_token,
+ };
+ Ok((Some(qself), path))
+ } else {
+ let path = Path::parse_helper(input, expr_style)?;
+ Ok((None, path))
+ }
+ }
}
#[cfg(feature = "printing")]
mod printing {
use super::*;
+
use proc_macro2::TokenStream;
use quote::ToTokens;
+ use print::TokensOrDefault;
+
impl ToTokens for Path {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.leading_colon.to_tokens(tokens);
@@ -537,25 +577,27 @@
}
}
- impl<'a> ToTokens for PathTokens<'a> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- let qself = match *self.0 {
+ impl private {
+ pub fn print_path(tokens: &mut TokenStream, qself: &Option<QSelf>, path: &Path) {
+ let qself = match *qself {
Some(ref qself) => qself,
- None => return self.1.to_tokens(tokens),
+ None => {
+ path.to_tokens(tokens);
+ return;
+ }
};
qself.lt_token.to_tokens(tokens);
qself.ty.to_tokens(tokens);
- // XXX: Gross.
- let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
- self.1.segments.len() - 1
+ let pos = if qself.position > 0 && qself.position >= path.segments.len() {
+ path.segments.len() - 1
} else {
qself.position
};
- let mut segments = self.1.segments.pairs();
+ let mut segments = path.segments.pairs();
if pos > 0 {
TokensOrDefault(&qself.as_token).to_tokens(tokens);
- self.1.leading_colon.to_tokens(tokens);
+ path.leading_colon.to_tokens(tokens);
for (i, segment) in segments.by_ref().take(pos).enumerate() {
if i + 1 == pos {
segment.value().to_tokens(tokens);
@@ -567,7 +609,7 @@
}
} else {
qself.gt_token.to_tokens(tokens);
- self.1.leading_colon.to_tokens(tokens);
+ path.leading_colon.to_tokens(tokens);
}
for segment in segments {
segment.to_tokens(tokens);
diff --git a/src/print.rs b/src/print.rs
new file mode 100644
index 0000000..90570a0
--- /dev/null
+++ b/src/print.rs
@@ -0,0 +1,16 @@
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+
+pub struct TokensOrDefault<'a, T: 'a>(pub &'a Option<T>);
+
+impl<'a, T> ToTokens for TokensOrDefault<'a, T>
+where
+ T: ToTokens + Default,
+{
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match *self.0 {
+ Some(ref t) => t.to_tokens(tokens),
+ None => T::default().to_tokens(tokens),
+ }
+ }
+}
diff --git a/src/punctuated.rs b/src/punctuated.rs
index b4a0b3f..7bb7368 100644
--- a/src/punctuated.rs
+++ b/src/punctuated.rs
@@ -38,11 +38,11 @@
use std::vec;
#[cfg(feature = "parsing")]
-use buffer::Cursor;
+use parse::{Parse, ParseStream, Result};
+#[cfg(any(feature = "full", feature = "derive"))]
+use private;
#[cfg(feature = "parsing")]
-use parse_error;
-#[cfg(feature = "parsing")]
-use synom::{PResult, Synom};
+use token::Token;
/// A punctuated sequence of syntax tree nodes of type `T` separated by
/// punctuation of type `P`.
@@ -208,18 +208,16 @@
pub fn empty_or_trailing(&self) -> bool {
self.last.is_none()
}
-}
-impl<T, P> Punctuated<T, P>
-where
- P: Default,
-{
/// Appends a syntax tree node onto the end of this punctuated sequence.
///
/// If there is not a trailing punctuation in this sequence when this method
/// is called, the default value of punctuation type `P` is inserted before
/// the given value of type `T`.
- pub fn push(&mut self, value: T) {
+ pub fn push(&mut self, value: T)
+ where
+ P: Default,
+ {
if !self.empty_or_trailing() {
self.push_punct(Default::default());
}
@@ -232,7 +230,10 @@
///
/// Panics if `index` is greater than the number of elements previously in
/// this punctuated sequence.
- pub fn insert(&mut self, index: usize, value: T) {
+ pub fn insert(&mut self, index: usize, value: T)
+ where
+ P: Default,
+ {
assert!(index <= self.len());
if index == self.len() {
@@ -241,6 +242,113 @@
self.inner.insert(index, (value, Default::default()));
}
}
+
+ /// Parses zero or more occurrences of `T` separated by punctuation of type
+ /// `P`, with optional trailing punctuation.
+ ///
+ /// Parsing continues until the end of this parse stream. The entire content
+ /// of this parse stream must consist of `T` and `P`.
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ #[cfg(feature = "parsing")]
+ pub fn parse_terminated(input: ParseStream) -> Result<Self>
+ where
+ T: Parse,
+ P: Parse,
+ {
+ Self::parse_terminated_with(input, T::parse)
+ }
+
+ /// Parses zero or more occurrences of `T` using the given parse function,
+ /// separated by punctuation of type `P`, with optional trailing
+ /// punctuation.
+ ///
+ /// Like [`parse_terminated`], the entire content of this stream is expected
+ /// to be parsed.
+ ///
+ /// [`parse_terminated`]: #method.parse_terminated
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ #[cfg(feature = "parsing")]
+ pub fn parse_terminated_with(
+ input: ParseStream,
+ parser: fn(ParseStream) -> Result<T>,
+ ) -> Result<Self>
+ where
+ P: Parse,
+ {
+ let mut punctuated = Punctuated::new();
+
+ loop {
+ if input.is_empty() {
+ break;
+ }
+ let value = parser(input)?;
+ punctuated.push_value(value);
+ if input.is_empty() {
+ break;
+ }
+ let punct = input.parse()?;
+ punctuated.push_punct(punct);
+ }
+
+ Ok(punctuated)
+ }
+
+ /// Parses one or more occurrences of `T` separated by punctuation of type
+ /// `P`, not accepting trailing punctuation.
+ ///
+ /// Parsing continues as long as punctuation `P` is present at the head of
+ /// the stream. This method returns upon parsing a `T` and observing that it
+ /// is not followed by a `P`, even if there are remaining tokens in the
+ /// stream.
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ #[cfg(feature = "parsing")]
+ pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
+ where
+ T: Parse,
+ P: Token + Parse,
+ {
+ Self::parse_separated_nonempty_with(input, T::parse)
+ }
+
+ /// Parses one or more occurrences of `T` using the given parse function,
+ /// separated by punctuation of type `P`, not accepting trailing
+ /// punctuation.
+ ///
+ /// Like [`parse_separated_nonempty`], may complete early without parsing
+ /// the entire content of this stream.
+ ///
+ /// [`parse_separated_nonempty`]: #method.parse_separated_nonempty
+ ///
+ /// *This function is available if Syn is built with the `"parsing"`
+ /// feature.*
+ #[cfg(feature = "parsing")]
+ pub fn parse_separated_nonempty_with(
+ input: ParseStream,
+ parser: fn(ParseStream) -> Result<T>,
+ ) -> Result<Self>
+ where
+ P: Token + Parse,
+ {
+ let mut punctuated = Punctuated::new();
+
+ loop {
+ let value = parser(input)?;
+ punctuated.push_value(value);
+ if !P::peek(input.cursor()) {
+ break;
+ }
+ let punct = input.parse()?;
+ punctuated.push_punct(punct);
+ }
+
+ Ok(punctuated)
+ }
}
#[cfg(feature = "extra-traits")]
@@ -466,10 +574,8 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
-impl<'a, T> Iter<'a, T> {
- // Not public API.
- #[doc(hidden)]
- pub fn private_empty() -> Self {
+impl private {
+ pub fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
Iter {
inner: Box::new(iter::empty()),
}
@@ -522,10 +628,8 @@
}
#[cfg(any(feature = "full", feature = "derive"))]
-impl<'a, T> IterMut<'a, T> {
- // Not public API.
- #[doc(hidden)]
- pub fn private_empty() -> Self {
+impl private {
+ pub fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
IterMut {
inner: Box::new(iter::empty()),
}
@@ -653,126 +757,6 @@
}
}
-#[cfg(feature = "parsing")]
-impl<T, P> Punctuated<T, P>
-where
- T: Synom,
- P: Synom,
-{
- /// Parse **zero or more** syntax tree nodes with punctuation in between and
- /// **no trailing** punctuation.
- pub fn parse_separated(input: Cursor) -> PResult<Self> {
- Self::parse_separated_with(input, T::parse)
- }
-
- /// Parse **one or more** syntax tree nodes with punctuation in bewteen and
- /// **no trailing** punctuation.
- /// allowing trailing punctuation.
- pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self> {
- Self::parse_separated_nonempty_with(input, T::parse)
- }
-
- /// Parse **zero or more** syntax tree nodes with punctuation in between and
- /// **optional trailing** punctuation.
- pub fn parse_terminated(input: Cursor) -> PResult<Self> {
- Self::parse_terminated_with(input, T::parse)
- }
-
- /// Parse **one or more** syntax tree nodes with punctuation in between and
- /// **optional trailing** punctuation.
- pub fn parse_terminated_nonempty(input: Cursor) -> PResult<Self> {
- Self::parse_terminated_nonempty_with(input, T::parse)
- }
-}
-
-#[cfg(feature = "parsing")]
-impl<T, P> Punctuated<T, P>
-where
- P: Synom,
-{
- /// Parse **zero or more** syntax tree nodes using the given parser with
- /// punctuation in between and **no trailing** punctuation.
- pub fn parse_separated_with(input: Cursor, parse: fn(Cursor) -> PResult<T>) -> PResult<Self> {
- Self::parse(input, parse, false)
- }
-
- /// Parse **one or more** syntax tree nodes using the given parser with
- /// punctuation in between and **no trailing** punctuation.
- pub fn parse_separated_nonempty_with(
- input: Cursor,
- parse: fn(Cursor) -> PResult<T>,
- ) -> PResult<Self> {
- match Self::parse(input, parse, false) {
- Ok((ref b, _)) if b.is_empty() => parse_error(),
- other => other,
- }
- }
-
- /// Parse **zero or more** syntax tree nodes using the given parser with
- /// punctuation in between and **optional trailing** punctuation.
- pub fn parse_terminated_with(input: Cursor, parse: fn(Cursor) -> PResult<T>) -> PResult<Self> {
- Self::parse(input, parse, true)
- }
-
- /// Parse **one or more** syntax tree nodes using the given parser with
- /// punctuation in between and **optional trailing** punctuation.
- pub fn parse_terminated_nonempty_with(
- input: Cursor,
- parse: fn(Cursor) -> PResult<T>,
- ) -> PResult<Self> {
- match Self::parse(input, parse, true) {
- Ok((ref b, _)) if b.is_empty() => parse_error(),
- other => other,
- }
- }
-
- fn parse(
- mut input: Cursor,
- parse: fn(Cursor) -> PResult<T>,
- terminated: bool,
- ) -> PResult<Self> {
- let mut res = Punctuated::new();
-
- // get the first element
- match parse(input) {
- Err(_) => Ok((res, input)),
- Ok((o, i)) => {
- if i == input {
- return parse_error();
- }
- input = i;
- res.push_value(o);
-
- // get the separator first
- while let Ok((s, i2)) = P::parse(input) {
- if i2 == input {
- break;
- }
-
- // get the element next
- if let Ok((o3, i3)) = parse(i2) {
- if i3 == i2 {
- break;
- }
- res.push_punct(s);
- res.push_value(o3);
- input = i3;
- } else {
- break;
- }
- }
- if terminated {
- if let Ok((sep, after)) = P::parse(input) {
- res.push_punct(sep);
- input = after;
- }
- }
- Ok((res, input))
- }
- }
- }
-}
-
#[cfg(feature = "printing")]
mod printing {
use super::*;
diff --git a/src/span.rs b/src/span.rs
new file mode 100644
index 0000000..27a7fe8
--- /dev/null
+++ b/src/span.rs
@@ -0,0 +1,67 @@
+use proc_macro2::Span;
+
+pub trait IntoSpans<S> {
+ fn into_spans(self) -> S;
+}
+
+impl IntoSpans<[Span; 1]> for Span {
+ fn into_spans(self) -> [Span; 1] {
+ [self]
+ }
+}
+
+impl IntoSpans<[Span; 2]> for Span {
+ fn into_spans(self) -> [Span; 2] {
+ [self, self]
+ }
+}
+
+impl IntoSpans<[Span; 3]> for Span {
+ fn into_spans(self) -> [Span; 3] {
+ [self, self, self]
+ }
+}
+
+impl IntoSpans<[Span; 1]> for [Span; 1] {
+ fn into_spans(self) -> [Span; 1] {
+ self
+ }
+}
+
+impl IntoSpans<[Span; 2]> for [Span; 2] {
+ fn into_spans(self) -> [Span; 2] {
+ self
+ }
+}
+
+impl IntoSpans<[Span; 3]> for [Span; 3] {
+ fn into_spans(self) -> [Span; 3] {
+ self
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub trait FromSpans: Sized {
+ fn from_spans(spans: &[Span]) -> Self;
+}
+
+#[cfg(feature = "parsing")]
+impl FromSpans for [Span; 1] {
+ fn from_spans(spans: &[Span]) -> Self {
+ [spans[0]]
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl FromSpans for [Span; 2] {
+ fn from_spans(spans: &[Span]) -> Self {
+ [spans[0], spans[1]]
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl FromSpans for [Span; 3] {
+ fn from_spans(spans: &[Span]) -> Self {
+ [spans[0], spans[1], spans[2]]
+ }
+}
diff --git a/src/spanned.rs b/src/spanned.rs
index 9372dce..6dd50cb 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -29,17 +29,16 @@
//! static assertion that `Sync` is implemented for that type.
//!
//! ```
-//! #[macro_use]
-//! extern crate quote;
-//!
-//! extern crate syn;
-//! extern crate proc_macro;
-//! extern crate proc_macro2;
-//!
-//! use syn::Type;
-//! use syn::spanned::Spanned;
+//! # extern crate proc_macro;
+//! # extern crate proc_macro2;
+//! # extern crate quote;
+//! # extern crate syn;
+//! #
//! use proc_macro::TokenStream;
//! use proc_macro2::Span;
+//! use quote::quote_spanned;
+//! use syn::Type;
+//! use syn::spanned::Spanned;
//!
//! # const IGNORE_TOKENS: &str = stringify! {
//! #[proc_macro_derive(MyMacro)]
@@ -85,9 +84,10 @@
/// tree node.
///
/// This trait is automatically implemented for all types that implement
-/// [`ToTokens`] from the `quote` crate.
+/// [`ToTokens`] from the `quote` crate. It is sealed and cannot be implemented
+/// outside of the Syn crate other than by implementing `ToTokens`.
///
-/// [`ToTokens`]: https://docs.rs/quote/0.4/quote/trait.ToTokens.html
+/// [`ToTokens`]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html
///
/// See the [module documentation] for an example.
///
@@ -95,14 +95,20 @@
///
/// *This trait is available if Syn is built with both the `"parsing"` and
/// `"printing"` features.*
-pub trait Spanned {
+pub trait Spanned: private::Sealed {
/// Returns a `Span` covering the complete contents of this syntax tree
/// node, or [`Span::call_site()`] if this node is empty.
///
- /// [`Span::call_site()`]: https://docs.rs/proc-macro2/0.2/proc_macro2/struct.Span.html#method.call_site
+ /// [`Span::call_site()`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html#method.call_site
fn span(&self) -> Span;
}
+mod private {
+ use quote::ToTokens;
+ pub trait Sealed {}
+ impl<T: ToTokens> Sealed for T {}
+}
+
impl<T> Spanned for T
where
T: ToTokens,
diff --git a/src/synom.rs b/src/synom.rs
index f3454eb..e69de29 100644
--- a/src/synom.rs
+++ b/src/synom.rs
@@ -1,419 +0,0 @@
-// Copyright 2018 Syn Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Parsing interface for parsing a token stream into a syntax tree node.
-//!
-//! Parsing in Syn is built on parser functions that take in a [`Cursor`] and
-//! produce a [`PResult<T>`] where `T` is some syntax tree node. `Cursor` is a
-//! cheaply copyable cursor over a range of tokens in a token stream, and
-//! `PResult` is a result that packages together a parsed syntax tree node `T`
-//! with a stream of remaining unparsed tokens after `T` represented as another
-//! `Cursor`, or a [`ParseError`] if parsing failed.
-//!
-//! [`Cursor`]: ../buffer/index.html
-//! [`PResult<T>`]: type.PResult.html
-//! [`ParseError`]: struct.ParseError.html
-//!
-//! This `Cursor`- and `PResult`-based interface is convenient for parser
-//! combinators and parser implementations, but not necessarily when you just
-//! have some tokens that you want to parse. For that we expose the following
-//! two entry points.
-//!
-//! ## The `syn::parse*` functions
-//!
-//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve
-//! as an entry point for parsing syntax tree nodes that can be parsed in an
-//! obvious default way. These functions can return any syntax tree node that
-//! implements the [`Synom`] trait, which includes most types in Syn.
-//!
-//! [`syn::parse`]: ../fn.parse.html
-//! [`syn::parse2`]: ../fn.parse2.html
-//! [`syn::parse_str`]: ../fn.parse_str.html
-//! [`Synom`]: trait.Synom.html
-//!
-//! ```
-//! use syn::Type;
-//!
-//! # fn run_parser() -> Result<(), syn::synom::ParseError> {
-//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;
-//! # Ok(())
-//! # }
-//! #
-//! # fn main() {
-//! # run_parser().unwrap();
-//! # }
-//! ```
-//!
-//! The [`parse_quote!`] macro also uses this approach.
-//!
-//! [`parse_quote!`]: ../macro.parse_quote.html
-//!
-//! ## The `Parser` trait
-//!
-//! Some types can be parsed in several ways depending on context. For example
-//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like
-//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]
-//! may or may not allow trailing punctuation, and parsing it the wrong way
-//! would either reject valid input or accept invalid input.
-//!
-//! [`Attribute`]: ../struct.Attribute.html
-//! [`Punctuated`]: ../punctuated/index.html
-//!
-//! The `Synom` trait is not implemented in these cases because there is no good
-//! behavior to consider the default.
-//!
-//! ```ignore
-//! // Can't parse `Punctuated` without knowing whether trailing punctuation
-//! // should be allowed in this context.
-//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;
-//! ```
-//!
-//! In these cases the types provide a choice of parser functions rather than a
-//! single `Synom` implementation, and those parser functions can be invoked
-//! through the [`Parser`] trait.
-//!
-//! [`Parser`]: trait.Parser.html
-//!
-//! ```
-//! # #[macro_use]
-//! # extern crate syn;
-//! #
-//! # extern crate proc_macro2;
-//! # use proc_macro2::TokenStream;
-//! #
-//! use syn::synom::Parser;
-//! use syn::punctuated::Punctuated;
-//! use syn::{PathSegment, Expr, Attribute};
-//!
-//! # fn run_parsers() -> Result<(), syn::synom::ParseError> {
-//! # let tokens = TokenStream::new().into();
-//! // Parse a nonempty sequence of path segments separated by `::` punctuation
-//! // with no trailing punctuation.
-//! let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;
-//! let path = parser.parse(tokens)?;
-//!
-//! # let tokens = TokenStream::new().into();
-//! // Parse a possibly empty sequence of expressions terminated by commas with
-//! // an optional trailing punctuation.
-//! let parser = Punctuated::<Expr, Token![,]>::parse_terminated;
-//! let args = parser.parse(tokens)?;
-//!
-//! # let tokens = TokenStream::new().into();
-//! // Parse zero or more outer attributes but not inner attributes.
-//! named!(outer_attrs -> Vec<Attribute>, many0!(Attribute::parse_outer));
-//! let attrs = outer_attrs.parse(tokens)?;
-//! #
-//! # Ok(())
-//! # }
-//! #
-//! # fn main() {}
-//! ```
-//!
-//! # Implementing a parser function
-//!
-//! Parser functions are usually implemented using the [`nom`]-style parser
-//! combinator macros provided by Syn, but may also be implemented without
-//! macros be using the low-level [`Cursor`] API directly.
-//!
-//! [`nom`]: https://github.com/Geal/nom
-//!
-//! The following parser combinator macros are available and a `Synom` parsing
-//! example is provided for each one.
-//!
-//! - [`alt!`](../macro.alt.html)
-//! - [`braces!`](../macro.braces.html)
-//! - [`brackets!`](../macro.brackets.html)
-//! - [`call!`](../macro.call.html)
-//! - [`cond!`](../macro.cond.html)
-//! - [`cond_reduce!`](../macro.cond_reduce.html)
-//! - [`custom_keyword!`](../macro.custom_keyword.html)
-//! - [`do_parse!`](../macro.do_parse.html)
-//! - [`epsilon!`](../macro.epsilon.html)
-//! - [`input_end!`](../macro.input_end.html)
-//! - [`keyword!`](../macro.keyword.html)
-//! - [`many0!`](../macro.many0.html)
-//! - [`map!`](../macro.map.html)
-//! - [`not!`](../macro.not.html)
-//! - [`option!`](../macro.option.html)
-//! - [`parens!`](../macro.parens.html)
-//! - [`punct!`](../macro.punct.html)
-//! - [`reject!`](../macro.reject.html)
-//! - [`switch!`](../macro.switch.html)
-//! - [`syn!`](../macro.syn.html)
-//! - [`tuple!`](../macro.tuple.html)
-//! - [`value!`](../macro.value.html)
-//!
-//! *This module is available if Syn is built with the `"parsing"` feature.*
-
-#[cfg(all(
- not(all(target_arch = "wasm32", target_os = "unknown")),
- feature = "proc-macro"
-))]
-use proc_macro;
-use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, TokenStream, TokenTree};
-
-use error::parse_error;
-pub use error::{PResult, ParseError};
-
-use buffer::{Cursor, TokenBuffer};
-
-/// Parsing interface implemented by all types that can be parsed in a default
-/// way from a token stream.
-///
-/// Refer to the [module documentation] for details about parsing in Syn.
-///
-/// [module documentation]: index.html
-///
-/// *This trait is available if Syn is built with the `"parsing"` feature.*
-pub trait Synom: Sized {
- fn parse(input: Cursor) -> PResult<Self>;
-
- /// A short name of the type being parsed.
- ///
- /// The description should only be used for a simple name. It should not
- /// contain newlines or sentence-ending punctuation, to facilitate embedding in
- /// larger user-facing strings. Syn will use this description when building
- /// error messages about parse failures.
- ///
- /// # Examples
- ///
- /// ```
- /// # use syn::buffer::Cursor;
- /// # use syn::synom::{Synom, PResult};
- /// #
- /// struct ExprMacro {
- /// // ...
- /// }
- ///
- /// impl Synom for ExprMacro {
- /// # fn parse(input: Cursor) -> PResult<Self> { unimplemented!() }
- /// // fn parse(...) -> ... { ... }
- ///
- /// fn description() -> Option<&'static str> {
- /// // Will result in messages like
- /// //
- /// // "failed to parse macro invocation expression: $reason"
- /// Some("macro invocation expression")
- /// }
- /// }
- /// ```
- fn description() -> Option<&'static str> {
- None
- }
-}
-
-impl Synom for TokenStream {
- fn parse(input: Cursor) -> PResult<Self> {
- Ok((input.token_stream(), Cursor::empty()))
- }
-
- fn description() -> Option<&'static str> {
- Some("arbitrary token stream")
- }
-}
-
-impl Synom for TokenTree {
- fn parse(input: Cursor) -> PResult<Self> {
- match input.token_tree() {
- Some((tt, rest)) => Ok((tt, rest)),
- None => parse_error(),
- }
- }
-
- fn description() -> Option<&'static str> {
- Some("token tree")
- }
-}
-
-impl Synom for Group {
- fn parse(input: Cursor) -> PResult<Self> {
- for delim in &[Delimiter::Parenthesis, Delimiter::Brace, Delimiter::Bracket] {
- if let Some((inside, span, rest)) = input.group(*delim) {
- let mut group = Group::new(*delim, inside.token_stream());
- group.set_span(span);
- return Ok((group, rest));
- }
- }
- parse_error()
- }
-
- fn description() -> Option<&'static str> {
- Some("group token")
- }
-}
-
-impl Synom for Ident {
- fn parse(input: Cursor) -> PResult<Self> {
- let (ident, rest) = match input.ident() {
- Some(ident) => ident,
- _ => return parse_error(),
- };
- match &ident.to_string()[..] {
- "_"
- // Based on https://doc.rust-lang.org/grammar.html#keywords
- // and https://github.com/rust-lang/rfcs/blob/master/text/2421-unreservations-2018.md
- | "abstract" | "as" | "become" | "box" | "break" | "const"
- | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
- | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
- | "mod" | "move" | "mut" | "override" | "priv" | "proc" | "pub"
- | "ref" | "return" | "Self" | "self" | "static" | "struct"
- | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
- | "virtual" | "where" | "while" | "yield" => return parse_error(),
- _ => {}
- }
-
- Ok((ident, rest))
- }
-
- fn description() -> Option<&'static str> {
- Some("identifier")
- }
-}
-
-impl Synom for Punct {
- fn parse(input: Cursor) -> PResult<Self> {
- match input.punct() {
- Some((punct, rest)) => Ok((punct, rest)),
- None => parse_error(),
- }
- }
-
- fn description() -> Option<&'static str> {
- Some("punctuation token")
- }
-}
-
-impl Synom for Literal {
- fn parse(input: Cursor) -> PResult<Self> {
- match input.literal() {
- Some((literal, rest)) => Ok((literal, rest)),
- None => parse_error(),
- }
- }
-
- fn description() -> Option<&'static str> {
- Some("literal token")
- }
-}
-
-/// Parser that can parse Rust tokens into a particular syntax tree node.
-///
-/// Refer to the [module documentation] for details about parsing in Syn.
-///
-/// [module documentation]: index.html
-///
-/// *This trait is available if Syn is built with the `"parsing"` feature.*
-pub trait Parser: Sized {
- type Output;
-
- /// Parse a proc-macro2 token stream into the chosen syntax tree node.
- fn parse2(self, tokens: TokenStream) -> Result<Self::Output, ParseError>;
-
- /// Parse tokens of source code into the chosen syntax tree node.
- ///
- /// *This method is available if Syn is built with both the `"parsing"` and
- /// `"proc-macro"` features.*
- #[cfg(all(
- not(all(target_arch = "wasm32", target_os = "unknown")),
- feature = "proc-macro"
- ))]
- fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output, ParseError> {
- self.parse2(tokens.into())
- }
-
- /// Parse a string of Rust code into the chosen syntax tree node.
- ///
- /// # Hygiene
- ///
- /// Every span in the resulting syntax tree will be set to resolve at the
- /// macro call site.
- fn parse_str(self, s: &str) -> Result<Self::Output, ParseError> {
- match s.parse() {
- Ok(tts) => self.parse2(tts),
- Err(_) => Err(ParseError::new("error while lexing input string")),
- }
- }
-}
-
-impl<F, T> Parser for F
-where
- F: FnOnce(Cursor) -> PResult<T>,
-{
- type Output = T;
-
- fn parse2(self, tokens: TokenStream) -> Result<T, ParseError> {
- let buf = TokenBuffer::new2(tokens);
- let (t, rest) = self(buf.begin())?;
- if rest.eof() {
- Ok(t)
- } else if rest == buf.begin() {
- // parsed nothing
- Err(ParseError::new("failed to parse anything"))
- } else {
- Err(ParseError::new("failed to parse all tokens"))
- }
- }
-}
-
-/// Extension traits that are made available within the `call!` parser.
-///
-/// *This module is available if Syn is built with the `"parsing"` feature.*
-pub mod ext {
- use super::*;
- use proc_macro2::Ident;
-
- /// Additional parsing methods for `Ident`.
- ///
- /// This trait is sealed and cannot be implemented for types outside of Syn.
- ///
- /// *This trait is available if Syn is built with the `"parsing"` feature.*
- pub trait IdentExt: Sized + private::Sealed {
- /// Parses any identifier including keywords.
- ///
- /// This is useful when parsing a DSL which allows Rust keywords as
- /// identifiers.
- ///
- /// ```rust
- /// #[macro_use]
- /// extern crate syn;
- ///
- /// use syn::Ident;
- ///
- /// // Parses input that looks like `name = NAME` where `NAME` can be
- /// // any identifier.
- /// //
- /// // Examples:
- /// //
- /// // name = anything
- /// // name = impl
- /// named!(parse_dsl -> Ident, do_parse!(
- /// custom_keyword!(name) >>
- /// punct!(=) >>
- /// name: call!(Ident::parse_any) >>
- /// (name)
- /// ));
- /// #
- /// # fn main() {}
- /// ```
- fn parse_any(input: Cursor) -> PResult<Self>;
- }
-
- impl IdentExt for Ident {
- fn parse_any(input: Cursor) -> PResult<Self> {
- input.ident().map_or_else(parse_error, Ok)
- }
- }
-
- mod private {
- use proc_macro2::Ident;
-
- pub trait Sealed {}
-
- impl Sealed for Ident {}
- }
-}
diff --git a/src/token.rs b/src/token.rs
index 0fe8c4d..a95bdc2 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -21,10 +21,9 @@
//! [`ItemStatic`]: ../struct.ItemStatic.html
//!
//! ```
-//! # #[macro_use]
//! # extern crate syn;
//! #
-//! # use syn::{Attribute, Visibility, Ident, Type, Expr};
+//! # use syn::{Attribute, Expr, Ident, Token, Type, Visibility};
//! #
//! pub struct ItemStatic {
//! pub attrs: Vec<Attribute>,
@@ -44,471 +43,544 @@
//!
//! # Parsing
//!
-//! These tokens can be parsed using the [`Synom`] trait and the parser
-//! combinator macros [`punct!`], [`keyword!`], [`parens!`], [`braces!`], and
-//! [`brackets!`].
+//! Keywords and punctuation can be parsed through the [`ParseStream::parse`]
+//! method. Delimiter tokens are parsed using the [`parenthesized!`],
+//! [`bracketed!`] and [`braced!`] macros.
//!
-//! [`Synom`]: ../synom/trait.Synom.html
-//! [`punct!`]: ../macro.punct.html
-//! [`keyword!`]: ../macro.keyword.html
-//! [`parens!`]: ../macro.parens.html
-//! [`braces!`]: ../macro.braces.html
-//! [`brackets!`]: ../macro.brackets.html
+//! [`ParseStream::parse`]: ../parse/struct.ParseBuffer.html#method.parse
+//! [`parenthesized!`]: ../macro.parenthesized.html
+//! [`bracketed!`]: ../macro.bracketed.html
+//! [`braced!`]: ../macro.braced.html
//!
//! ```
-//! #[macro_use]
-//! extern crate syn;
-//!
-//! use syn::synom::Synom;
-//! use syn::{Attribute, Visibility, Ident, Type, Expr};
+//! # extern crate syn;
//! #
-//! # struct ItemStatic;
-//! # use syn::ItemStatic as SynItemStatic;
+//! use syn::Attribute;
+//! use syn::parse::{Parse, ParseStream, Result};
+//! #
+//! # enum ItemStatic {}
//!
//! // Parse the ItemStatic struct shown above.
-//! impl Synom for ItemStatic {
-//! named!(parse -> Self, do_parse!(
-//! # (ItemStatic)
-//! # ));
-//! # }
-//! #
-//! # mod example {
-//! # use super::*;
-//! # use super::SynItemStatic as ItemStatic;
-//! #
-//! # named!(parse -> ItemStatic, do_parse!(
-//! attrs: many0!(Attribute::parse_outer) >>
-//! vis: syn!(Visibility) >>
-//! static_token: keyword!(static) >>
-//! mutability: option!(keyword!(mut)) >>
-//! ident: syn!(Ident) >>
-//! colon_token: punct!(:) >>
-//! ty: syn!(Type) >>
-//! eq_token: punct!(=) >>
-//! expr: syn!(Expr) >>
-//! semi_token: punct!(;) >>
-//! (ItemStatic {
-//! attrs, vis, static_token, mutability, ident, colon_token,
-//! ty: Box::new(ty), eq_token, expr: Box::new(expr), semi_token,
+//! impl Parse for ItemStatic {
+//! fn parse(input: ParseStream) -> Result<Self> {
+//! # use syn::ItemStatic;
+//! # fn parse(input: ParseStream) -> Result<ItemStatic> {
+//! Ok(ItemStatic {
+//! attrs: input.call(Attribute::parse_outer)?,
+//! vis: input.parse()?,
+//! static_token: input.parse()?,
+//! mutability: input.parse()?,
+//! ident: input.parse()?,
+//! colon_token: input.parse()?,
+//! ty: input.parse()?,
+//! eq_token: input.parse()?,
+//! expr: input.parse()?,
+//! semi_token: input.parse()?,
//! })
-//! ));
+//! # }
+//! # unimplemented!()
+//! }
//! }
//! #
//! # fn main() {}
//! ```
+use std;
+#[cfg(feature = "parsing")]
+use std::cell::Cell;
+#[cfg(feature = "extra-traits")]
+use std::cmp;
+#[cfg(feature = "extra-traits")]
+use std::fmt::{self, Debug};
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+#[cfg(feature = "parsing")]
+use std::rc::Rc;
+
+#[cfg(feature = "parsing")]
+use proc_macro2::Delimiter;
+#[cfg(feature = "printing")]
+use proc_macro2::TokenStream;
use proc_macro2::{Ident, Span};
+#[cfg(feature = "printing")]
+use quote::{ToTokens, TokenStreamExt};
-macro_rules! tokens {
- (
- punct: {
- $($punct:tt pub struct $punct_name:ident/$len:tt #[$punct_doc:meta])*
- }
- delimiter: {
- $($delimiter:tt pub struct $delimiter_name:ident #[$delimiter_doc:meta])*
- }
- keyword: {
- $($keyword:tt pub struct $keyword_name:ident #[$keyword_doc:meta])*
- }
- ) => (
- $(token_punct_def! { #[$punct_doc] 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 })*
- )
+#[cfg(feature = "parsing")]
+use buffer::Cursor;
+#[cfg(feature = "parsing")]
+use error::Result;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg(feature = "parsing")]
+use lifetime::Lifetime;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg(feature = "parsing")]
+use lit::{Lit, LitBool, LitByte, LitByteStr, LitChar, LitFloat, LitInt, LitStr};
+#[cfg(feature = "parsing")]
+use lookahead;
+#[cfg(feature = "parsing")]
+use parse::{Parse, ParseStream};
+use span::IntoSpans;
+
+/// Marker trait for types that represent single tokens.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+#[cfg(feature = "parsing")]
+pub trait Token: private::Sealed {
+ // Not public API.
+ #[doc(hidden)]
+ fn peek(cursor: Cursor) -> bool;
+
+ // Not public API.
+ #[doc(hidden)]
+ fn display() -> &'static str;
}
-macro_rules! token_punct_def {
- (#[$doc:meta]pub struct $name:ident / $len:tt) => {
- #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
- #[$doc]
- ///
- /// Don't try to remember the name of this type -- use the [`Token!`]
- /// macro instead.
- ///
- /// [`Token!`]: index.html
- pub struct $name(pub [Span; $len]);
-
- impl $name {
- pub fn new(span: Span) -> Self {
- $name([span; $len])
- }
- }
-
- impl ::std::default::Default for $name {
- fn default() -> Self {
- $name([Span::call_site(); $len])
- }
- }
-
- #[cfg(feature = "extra-traits")]
- impl ::std::fmt::Debug for $name {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- f.write_str(stringify!($name))
- }
- }
-
- #[cfg(feature = "extra-traits")]
- impl ::std::cmp::Eq for $name {}
-
- #[cfg(feature = "extra-traits")]
- impl ::std::cmp::PartialEq for $name {
- fn eq(&self, _other: &$name) -> bool {
- true
- }
- }
-
- #[cfg(feature = "extra-traits")]
- impl ::std::hash::Hash for $name {
- fn hash<H>(&self, _state: &mut H)
- where
- H: ::std::hash::Hasher,
- {
- }
- }
-
- impl From<Span> for $name {
- fn from(span: Span) -> Self {
- $name([span; $len])
- }
- }
- };
+#[cfg(feature = "parsing")]
+mod private {
+ pub trait Sealed {}
}
-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 ::proc_macro2::TokenStream) {
- printing::punct($s, &self.0, tokens);
+#[cfg(feature = "parsing")]
+fn peek_impl(cursor: Cursor, peek: fn(ParseStream) -> bool) -> bool {
+ let scope = Span::call_site();
+ let unexpected = Rc::new(Cell::new(None));
+ let buffer = ::private::new_parse_buffer(scope, cursor, unexpected);
+ peek(&buffer)
+}
+
+macro_rules! impl_token {
+ ($name:ident $display:expr) => {
+ #[cfg(feature = "parsing")]
+ impl Token for $name {
+ fn peek(cursor: Cursor) -> bool {
+ fn peek(input: ParseStream) -> bool {
+ <$name as Parse>::parse(input).is_ok()
+ }
+ peek_impl(cursor, peek)
+ }
+
+ fn display() -> &'static str {
+ $display
}
}
#[cfg(feature = "parsing")]
- impl ::Synom for $name {
- fn parse(tokens: $crate::buffer::Cursor) -> $crate::synom::PResult<$name> {
- parsing::punct($s, tokens, $name)
- }
-
- fn description() -> Option<&'static str> {
- Some(concat!("`", $s, "`"))
- }
- }
+ impl private::Sealed for $name {}
};
}
-macro_rules! token_keyword {
- (#[$doc:meta] $s:tt pub struct $name:ident) => {
- #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
- #[$doc]
- ///
- /// Don't try to remember the name of this type -- use the [`Token!`]
- /// macro instead.
- ///
- /// [`Token!`]: index.html
- pub struct $name(pub Span);
+impl_token!(Ident "identifier");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(Lifetime "lifetime");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(Lit "literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitStr "string literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitByteStr "byte string literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitByte "byte literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitChar "character literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitInt "integer literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitFloat "floating point literal");
+#[cfg(any(feature = "full", feature = "derive"))]
+impl_token!(LitBool "boolean literal");
- impl ::std::default::Default for $name {
- fn default() -> Self {
- $name(Span::call_site())
- }
- }
-
- #[cfg(feature = "extra-traits")]
- impl ::std::fmt::Debug for $name {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- f.write_str(stringify!($name))
- }
- }
-
- #[cfg(feature = "extra-traits")]
- impl ::std::cmp::Eq for $name {}
-
- #[cfg(feature = "extra-traits")]
- impl ::std::cmp::PartialEq for $name {
- fn eq(&self, _other: &$name) -> bool {
- true
- }
- }
-
- #[cfg(feature = "extra-traits")]
- impl ::std::hash::Hash for $name {
- fn hash<H>(&self, _state: &mut H)
- where
- H: ::std::hash::Hasher,
- {
- }
- }
-
- #[cfg(feature = "printing")]
- impl ::quote::ToTokens for $name {
- fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
- printing::keyword($s, &self.0, tokens);
- }
- }
-
- #[cfg(feature = "parsing")]
- impl ::Synom for $name {
- fn parse(tokens: $crate::buffer::Cursor) -> $crate::synom::PResult<$name> {
- parsing::keyword($s, tokens, $name)
+macro_rules! define_keywords {
+ ($($token:tt pub struct $name:ident #[$doc:meta])*) => {
+ $(
+ #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
+ #[$doc]
+ ///
+ /// Don't try to remember the name of this type -- use the [`Token!`]
+ /// macro instead.
+ ///
+ /// [`Token!`]: index.html
+ pub struct $name {
+ pub span: Span,
}
- fn description() -> Option<&'static str> {
- Some(concat!("`", $s, "`"))
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $name<S: IntoSpans<[Span; 1]>>(span: S) -> $name {
+ $name {
+ span: span.into_spans()[0],
+ }
}
- }
- impl From<Span> for $name {
- fn from(span: Span) -> Self {
- $name(span)
+ impl_token!($name concat!("`", $token, "`"));
+
+ impl std::default::Default for $name {
+ fn default() -> Self {
+ $name {
+ span: Span::call_site(),
+ }
+ }
}
- }
- };
-}
-macro_rules! token_delimiter {
- (#[$doc:meta] $s:tt pub struct $name:ident) => {
- #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
- #[$doc]
- pub struct $name(pub Span);
-
- impl ::std::default::Default for $name {
- fn default() -> Self {
- $name(Span::call_site())
+ #[cfg(feature = "extra-traits")]
+ impl Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
}
- }
- #[cfg(feature = "extra-traits")]
- impl ::std::fmt::Debug for $name {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- f.write_str(stringify!($name))
+ #[cfg(feature = "extra-traits")]
+ impl cmp::Eq for $name {}
+
+ #[cfg(feature = "extra-traits")]
+ impl PartialEq for $name {
+ fn eq(&self, _other: &$name) -> bool {
+ true
+ }
}
- }
- #[cfg(feature = "extra-traits")]
- impl ::std::cmp::Eq for $name {}
-
- #[cfg(feature = "extra-traits")]
- impl ::std::cmp::PartialEq for $name {
- fn eq(&self, _other: &$name) -> bool {
- true
+ #[cfg(feature = "extra-traits")]
+ impl Hash for $name {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
}
- }
- #[cfg(feature = "extra-traits")]
- impl ::std::hash::Hash for $name {
- fn hash<H>(&self, _state: &mut H)
- where
- H: ::std::hash::Hasher,
- {
- }
- }
-
- impl $name {
#[cfg(feature = "printing")]
- pub fn surround<F>(&self, tokens: &mut ::proc_macro2::TokenStream, f: F)
- where
- F: FnOnce(&mut ::proc_macro2::TokenStream),
- {
- printing::delim($s, &self.0, tokens, f);
+ impl ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ printing::keyword($token, &self.span, tokens);
+ }
}
#[cfg(feature = "parsing")]
- pub fn parse<F, R>(
- tokens: $crate::buffer::Cursor,
- f: F,
- ) -> $crate::synom::PResult<($name, R)>
- where
- F: FnOnce($crate::buffer::Cursor) -> $crate::synom::PResult<R>,
- {
- parsing::delim($s, tokens, $name, f)
+ impl Parse for $name {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok($name {
+ span: parsing::keyword(input, $token)?,
+ })
+ }
}
- }
-
- impl From<Span> for $name {
- fn from(span: Span) -> Self {
- $name(span)
- }
- }
+ )*
};
}
-token_punct_def! {
- /// `_`
- pub struct Underscore/1
+macro_rules! define_punctuation_structs {
+ ($($token:tt pub struct $name:ident/$len:tt #[$doc:meta])*) => {
+ $(
+ #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
+ #[$doc]
+ ///
+ /// Don't try to remember the name of this type -- use the [`Token!`]
+ /// macro instead.
+ ///
+ /// [`Token!`]: index.html
+ pub struct $name {
+ pub spans: [Span; $len],
+ }
+
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $name<S: IntoSpans<[Span; $len]>>(spans: S) -> $name {
+ $name {
+ spans: spans.into_spans(),
+ }
+ }
+
+ impl_token!($name concat!("`", $token, "`"));
+
+ impl std::default::Default for $name {
+ fn default() -> Self {
+ $name {
+ spans: [Span::call_site(); $len],
+ }
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ impl Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ impl cmp::Eq for $name {}
+
+ #[cfg(feature = "extra-traits")]
+ impl PartialEq for $name {
+ fn eq(&self, _other: &$name) -> bool {
+ true
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ impl Hash for $name {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+ }
+ )*
+ };
+}
+
+macro_rules! define_punctuation {
+ ($($token:tt pub struct $name:ident/$len:tt #[$doc:meta])*) => {
+ $(
+ define_punctuation_structs! {
+ $token pub struct $name/$len #[$doc]
+ }
+
+ #[cfg(feature = "printing")]
+ impl ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ printing::punct($token, &self.spans, tokens);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl Parse for $name {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok($name {
+ spans: parsing::punct(input, $token)?,
+ })
+ }
+ }
+ )*
+ };
+}
+
+macro_rules! define_delimiters {
+ ($($token:tt pub struct $name:ident #[$doc:meta])*) => {
+ $(
+ #[cfg_attr(feature = "clone-impls", derive(Copy, Clone))]
+ #[$doc]
+ pub struct $name {
+ pub span: Span,
+ }
+
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $name<S: IntoSpans<[Span; 1]>>(span: S) -> $name {
+ $name {
+ span: span.into_spans()[0],
+ }
+ }
+
+ impl std::default::Default for $name {
+ fn default() -> Self {
+ $name {
+ span: Span::call_site(),
+ }
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ impl Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ impl cmp::Eq for $name {}
+
+ #[cfg(feature = "extra-traits")]
+ impl PartialEq for $name {
+ fn eq(&self, _other: &$name) -> bool {
+ true
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ impl Hash for $name {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+ }
+
+ impl $name {
+ #[cfg(feature = "printing")]
+ pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
+ where
+ F: FnOnce(&mut TokenStream),
+ {
+ printing::delim($token, &self.span, tokens, f);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl private::Sealed for $name {}
+ )*
+ };
+}
+
+define_punctuation_structs! {
+ "_" pub struct Underscore/1 /// `_`
}
#[cfg(feature = "printing")]
-impl ::quote::ToTokens for Underscore {
- fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
- use quote::TokenStreamExt;
- tokens.append(::proc_macro2::Ident::new("_", self.0[0]));
+impl ToTokens for Underscore {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Ident::new("_", self.spans[0]));
}
}
#[cfg(feature = "parsing")]
-impl ::Synom for Underscore {
- fn parse(input: ::buffer::Cursor) -> ::synom::PResult<Underscore> {
- match input.ident() {
- Some((ident, rest)) => {
+impl Parse for Underscore {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((ident, rest)) = cursor.ident() {
if ident == "_" {
- Ok((Underscore([ident.span()]), rest))
- } else {
- ::parse_error()
+ return Ok((Underscore(ident.span()), rest));
}
}
- None => parsing::punct("_", input, Underscore),
- }
- }
-
- fn description() -> Option<&'static str> {
- Some("`_`")
- }
-}
-
-token_punct_def! {
- /// `'`
- pub struct Apostrophe/1
-}
-
-// Implement Clone anyway because it is required for cloning Lifetime.
-#[cfg(not(feature = "clone-impls"))]
-impl Clone for Apostrophe {
- fn clone(&self) -> Self {
- Apostrophe(self.0)
- }
-}
-
-#[cfg(feature = "printing")]
-impl ::quote::ToTokens for Apostrophe {
- fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
- use quote::TokenStreamExt;
- let mut token = ::proc_macro2::Punct::new('\'', ::proc_macro2::Spacing::Joint);
- token.set_span(self.0[0]);
- tokens.append(token);
+ if let Some((punct, rest)) = cursor.punct() {
+ if punct.as_char() == '_' {
+ return Ok((Underscore(punct.span()), rest));
+ }
+ }
+ Err(cursor.error("expected `_`"))
+ })
}
}
#[cfg(feature = "parsing")]
-impl ::Synom for Apostrophe {
- fn parse(input: ::buffer::Cursor) -> ::synom::PResult<Apostrophe> {
- match input.punct() {
- Some((op, rest)) => {
- if op.as_char() == '\'' && op.spacing() == ::proc_macro2::Spacing::Joint {
- Ok((Apostrophe([op.span()]), rest))
- } else {
- ::parse_error()
- }
- }
- None => ::parse_error(),
- }
+impl Token for Paren {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::Parenthesis)
}
- fn description() -> Option<&'static str> {
- Some("`'`")
+ fn display() -> &'static str {
+ "parentheses"
}
}
-tokens! {
- punct: {
- "+" pub struct Add/1 /// `+`
- "+=" pub struct AddEq/2 /// `+=`
- "&" pub struct And/1 /// `&`
- "&&" pub struct AndAnd/2 /// `&&`
- "&=" pub struct AndEq/2 /// `&=`
- "@" pub struct At/1 /// `@`
- "!" pub struct Bang/1 /// `!`
- "^" pub struct Caret/1 /// `^`
- "^=" pub struct CaretEq/2 /// `^=`
- ":" pub struct Colon/1 /// `:`
- "::" pub struct Colon2/2 /// `::`
- "," pub struct Comma/1 /// `,`
- "/" pub struct Div/1 /// `/`
- "/=" pub struct DivEq/2 /// `/=`
- "$" pub struct Dollar/1 /// `$`
- "." pub struct Dot/1 /// `.`
- ".." pub struct Dot2/2 /// `..`
- "..." pub struct Dot3/3 /// `...`
- "..=" pub struct DotDotEq/3 /// `..=`
- "=" pub struct Eq/1 /// `=`
- "==" pub struct EqEq/2 /// `==`
- ">=" pub struct Ge/2 /// `>=`
- ">" pub struct Gt/1 /// `>`
- "<=" pub struct Le/2 /// `<=`
- "<" pub struct Lt/1 /// `<`
- "*=" pub struct MulEq/2 /// `*=`
- "!=" pub struct Ne/2 /// `!=`
- "|" pub struct Or/1 /// `|`
- "|=" pub struct OrEq/2 /// `|=`
- "||" pub struct OrOr/2 /// `||`
- "#" pub struct Pound/1 /// `#`
- "?" pub struct Question/1 /// `?`
- "->" pub struct RArrow/2 /// `->`
- "<-" pub struct LArrow/2 /// `<-`
- "%" pub struct Rem/1 /// `%`
- "%=" pub struct RemEq/2 /// `%=`
- "=>" pub struct FatArrow/2 /// `=>`
- ";" pub struct Semi/1 /// `;`
- "<<" pub struct Shl/2 /// `<<`
- "<<=" pub struct ShlEq/3 /// `<<=`
- ">>" pub struct Shr/2 /// `>>`
- ">>=" pub struct ShrEq/3 /// `>>=`
- "*" pub struct Star/1 /// `*`
- "-" pub struct Sub/1 /// `-`
- "-=" pub struct SubEq/2 /// `-=`
+#[cfg(feature = "parsing")]
+impl Token for Brace {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::Brace)
}
- delimiter: {
- "{" pub struct Brace /// `{...}`
- "[" pub struct Bracket /// `[...]`
- "(" pub struct Paren /// `(...)`
- " " pub struct Group /// None-delimited group
+
+ fn display() -> &'static str {
+ "curly braces"
}
- keyword: {
- "as" pub struct As /// `as`
- "async" pub struct Async /// `async`
- "auto" pub struct Auto /// `auto`
- "box" pub struct Box /// `box`
- "break" pub struct Break /// `break`
- "Self" pub struct CapSelf /// `Self`
- "catch" pub struct Catch /// `catch`
- "const" pub struct Const /// `const`
- "continue" pub struct Continue /// `continue`
- "crate" pub struct Crate /// `crate`
- "default" pub struct Default /// `default`
- "do" pub struct Do /// `do`
- "dyn" pub struct Dyn /// `dyn`
- "else" pub struct Else /// `else`
- "enum" pub struct Enum /// `enum`
- "extern" pub struct Extern /// `extern`
- "fn" pub struct Fn /// `fn`
- "for" pub struct For /// `for`
- "if" pub struct If /// `if`
- "impl" pub struct Impl /// `impl`
- "in" pub struct In /// `in`
- "let" pub struct Let /// `let`
- "loop" pub struct Loop /// `loop`
- "macro" pub struct Macro /// `macro`
- "match" pub struct Match /// `match`
- "mod" pub struct Mod /// `mod`
- "move" pub struct Move /// `move`
- "mut" pub struct Mut /// `mut`
- "pub" pub struct Pub /// `pub`
- "ref" pub struct Ref /// `ref`
- "return" pub struct Return /// `return`
- "self" pub struct Self_ /// `self`
- "static" pub struct Static /// `static`
- "struct" pub struct Struct /// `struct`
- "super" pub struct Super /// `super`
- "trait" pub struct Trait /// `trait`
- "try" pub struct Try /// `try`
- "type" pub struct Type /// `type`
- "union" pub struct Union /// `union`
- "unsafe" pub struct Unsafe /// `unsafe`
- "use" pub struct Use /// `use`
- "where" pub struct Where /// `where`
- "while" pub struct While /// `while`
- "yield" pub struct Yield /// `yield`
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Bracket {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::Bracket)
}
+
+ fn display() -> &'static str {
+ "square brackets"
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Group {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::None)
+ }
+
+ fn display() -> &'static str {
+ "invisible group"
+ }
+}
+
+define_keywords! {
+ "as" pub struct As /// `as`
+ "async" pub struct Async /// `async`
+ "auto" pub struct Auto /// `auto`
+ "box" pub struct Box /// `box`
+ "break" pub struct Break /// `break`
+ "Self" pub struct CapSelf /// `Self`
+ "const" pub struct Const /// `const`
+ "continue" pub struct Continue /// `continue`
+ "crate" pub struct Crate /// `crate`
+ "default" pub struct Default /// `default`
+ "dyn" pub struct Dyn /// `dyn`
+ "else" pub struct Else /// `else`
+ "enum" pub struct Enum /// `enum`
+ "existential" pub struct Existential /// `existential`
+ "extern" pub struct Extern /// `extern`
+ "fn" pub struct Fn /// `fn`
+ "for" pub struct For /// `for`
+ "if" pub struct If /// `if`
+ "impl" pub struct Impl /// `impl`
+ "in" pub struct In /// `in`
+ "let" pub struct Let /// `let`
+ "loop" pub struct Loop /// `loop`
+ "macro" pub struct Macro /// `macro`
+ "match" pub struct Match /// `match`
+ "mod" pub struct Mod /// `mod`
+ "move" pub struct Move /// `move`
+ "mut" pub struct Mut /// `mut`
+ "pub" pub struct Pub /// `pub`
+ "ref" pub struct Ref /// `ref`
+ "return" pub struct Return /// `return`
+ "self" pub struct Self_ /// `self`
+ "static" pub struct Static /// `static`
+ "struct" pub struct Struct /// `struct`
+ "super" pub struct Super /// `super`
+ "trait" pub struct Trait /// `trait`
+ "try" pub struct Try /// `try`
+ "type" pub struct Type /// `type`
+ "union" pub struct Union /// `union`
+ "unsafe" pub struct Unsafe /// `unsafe`
+ "use" pub struct Use /// `use`
+ "where" pub struct Where /// `where`
+ "while" pub struct While /// `while`
+ "yield" pub struct Yield /// `yield`
+}
+
+define_punctuation! {
+ "+" pub struct Add/1 /// `+`
+ "+=" pub struct AddEq/2 /// `+=`
+ "&" pub struct And/1 /// `&`
+ "&&" pub struct AndAnd/2 /// `&&`
+ "&=" pub struct AndEq/2 /// `&=`
+ "@" pub struct At/1 /// `@`
+ "!" pub struct Bang/1 /// `!`
+ "^" pub struct Caret/1 /// `^`
+ "^=" pub struct CaretEq/2 /// `^=`
+ ":" pub struct Colon/1 /// `:`
+ "::" pub struct Colon2/2 /// `::`
+ "," pub struct Comma/1 /// `,`
+ "/" pub struct Div/1 /// `/`
+ "/=" pub struct DivEq/2 /// `/=`
+ "$" pub struct Dollar/1 /// `$`
+ "." pub struct Dot/1 /// `.`
+ ".." pub struct Dot2/2 /// `..`
+ "..." pub struct Dot3/3 /// `...`
+ "..=" pub struct DotDotEq/3 /// `..=`
+ "=" pub struct Eq/1 /// `=`
+ "==" pub struct EqEq/2 /// `==`
+ ">=" pub struct Ge/2 /// `>=`
+ ">" pub struct Gt/1 /// `>`
+ "<=" pub struct Le/2 /// `<=`
+ "<" pub struct Lt/1 /// `<`
+ "*=" pub struct MulEq/2 /// `*=`
+ "!=" pub struct Ne/2 /// `!=`
+ "|" pub struct Or/1 /// `|`
+ "|=" pub struct OrEq/2 /// `|=`
+ "||" pub struct OrOr/2 /// `||`
+ "#" pub struct Pound/1 /// `#`
+ "?" pub struct Question/1 /// `?`
+ "->" pub struct RArrow/2 /// `->`
+ "<-" pub struct LArrow/2 /// `<-`
+ "%" pub struct Rem/1 /// `%`
+ "%=" pub struct RemEq/2 /// `%=`
+ "=>" pub struct FatArrow/2 /// `=>`
+ ";" pub struct Semi/1 /// `;`
+ "<<" pub struct Shl/2 /// `<<`
+ "<<=" pub struct ShlEq/3 /// `<<=`
+ ">>" pub struct Shr/2 /// `>>`
+ ">>=" pub struct ShrEq/3 /// `>>=`
+ "*" pub struct Star/1 /// `*`
+ "-" pub struct Sub/1 /// `-`
+ "-=" pub struct SubEq/2 /// `-=`
+}
+
+define_delimiters! {
+ "{" pub struct Brace /// `{...}`
+ "[" pub struct Bracket /// `[...]`
+ "(" pub struct Paren /// `(...)`
+ " " pub struct Group /// None-delimited group
}
/// A type-macro that expands to the name of the Rust type representation of a
@@ -522,217 +594,101 @@
#[macro_export]
#[cfg_attr(rustfmt, rustfmt_skip)]
macro_rules! Token {
- (+) => { $crate::token::Add };
- (+=) => { $crate::token::AddEq };
- (&) => { $crate::token::And };
- (&&) => { $crate::token::AndAnd };
- (&=) => { $crate::token::AndEq };
- (@) => { $crate::token::At };
- (!) => { $crate::token::Bang };
- (^) => { $crate::token::Caret };
- (^=) => { $crate::token::CaretEq };
- (:) => { $crate::token::Colon };
- (::) => { $crate::token::Colon2 };
- (,) => { $crate::token::Comma };
- (/) => { $crate::token::Div };
- (/=) => { $crate::token::DivEq };
- (.) => { $crate::token::Dot };
- (..) => { $crate::token::Dot2 };
- (...) => { $crate::token::Dot3 };
- (..=) => { $crate::token::DotDotEq };
- (=) => { $crate::token::Eq };
- (==) => { $crate::token::EqEq };
- (>=) => { $crate::token::Ge };
- (>) => { $crate::token::Gt };
- (<=) => { $crate::token::Le };
- (<) => { $crate::token::Lt };
- (*=) => { $crate::token::MulEq };
- (!=) => { $crate::token::Ne };
- (|) => { $crate::token::Or };
- (|=) => { $crate::token::OrEq };
- (||) => { $crate::token::OrOr };
- (#) => { $crate::token::Pound };
- (?) => { $crate::token::Question };
- (->) => { $crate::token::RArrow };
- (<-) => { $crate::token::LArrow };
- (%) => { $crate::token::Rem };
- (%=) => { $crate::token::RemEq };
- (=>) => { $crate::token::FatArrow };
- (;) => { $crate::token::Semi };
- (<<) => { $crate::token::Shl };
- (<<=) => { $crate::token::ShlEq };
- (>>) => { $crate::token::Shr };
- (>>=) => { $crate::token::ShrEq };
- (*) => { $crate::token::Star };
- (-) => { $crate::token::Sub };
- (-=) => { $crate::token::SubEq };
- (_) => { $crate::token::Underscore };
- (as) => { $crate::token::As };
- (async) => { $crate::token::Async };
- (auto) => { $crate::token::Auto };
- (box) => { $crate::token::Box };
- (break) => { $crate::token::Break };
- (Self) => { $crate::token::CapSelf };
- (catch) => { $crate::token::Catch };
- (const) => { $crate::token::Const };
- (continue) => { $crate::token::Continue };
- (crate) => { $crate::token::Crate };
- (default) => { $crate::token::Default };
- (do) => { $crate::token::Do };
- (dyn) => { $crate::token::Dyn };
- (else) => { $crate::token::Else };
- (enum) => { $crate::token::Enum };
- (extern) => { $crate::token::Extern };
- (fn) => { $crate::token::Fn };
- (for) => { $crate::token::For };
- (if) => { $crate::token::If };
- (impl) => { $crate::token::Impl };
- (in) => { $crate::token::In };
- (let) => { $crate::token::Let };
- (loop) => { $crate::token::Loop };
- (macro) => { $crate::token::Macro };
- (match) => { $crate::token::Match };
- (mod) => { $crate::token::Mod };
- (move) => { $crate::token::Move };
- (mut) => { $crate::token::Mut };
- (pub) => { $crate::token::Pub };
- (ref) => { $crate::token::Ref };
- (return) => { $crate::token::Return };
- (self) => { $crate::token::Self_ };
- (static) => { $crate::token::Static };
- (struct) => { $crate::token::Struct };
- (super) => { $crate::token::Super };
- (trait) => { $crate::token::Trait };
- (try) => { $crate::token::Try };
- (type) => { $crate::token::Type };
- (union) => { $crate::token::Union };
- (unsafe) => { $crate::token::Unsafe };
- (use) => { $crate::token::Use };
- (where) => { $crate::token::Where };
- (while) => { $crate::token::While };
- (yield) => { $crate::token::Yield };
-}
-
-/// Parse a single Rust punctuation token.
-///
-/// See the [token module] documentation for details and examples.
-///
-/// [token module]: token/index.html
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[cfg(feature = "parsing")]
-#[macro_export]
-#[cfg_attr(rustfmt, rustfmt_skip)]
-macro_rules! punct {
- ($i:expr, +) => { call!($i, <$crate::token::Add as $crate::synom::Synom>::parse) };
- ($i:expr, +=) => { call!($i, <$crate::token::AddEq as $crate::synom::Synom>::parse) };
- ($i:expr, &) => { call!($i, <$crate::token::And as $crate::synom::Synom>::parse) };
- ($i:expr, &&) => { call!($i, <$crate::token::AndAnd as $crate::synom::Synom>::parse) };
- ($i:expr, &=) => { call!($i, <$crate::token::AndEq as $crate::synom::Synom>::parse) };
- ($i:expr, @) => { call!($i, <$crate::token::At as $crate::synom::Synom>::parse) };
- ($i:expr, !) => { call!($i, <$crate::token::Bang as $crate::synom::Synom>::parse) };
- ($i:expr, ^) => { call!($i, <$crate::token::Caret as $crate::synom::Synom>::parse) };
- ($i:expr, ^=) => { call!($i, <$crate::token::CaretEq as $crate::synom::Synom>::parse) };
- ($i:expr, :) => { call!($i, <$crate::token::Colon as $crate::synom::Synom>::parse) };
- ($i:expr, ::) => { call!($i, <$crate::token::Colon2 as $crate::synom::Synom>::parse) };
- ($i:expr, ,) => { call!($i, <$crate::token::Comma as $crate::synom::Synom>::parse) };
- ($i:expr, /) => { call!($i, <$crate::token::Div as $crate::synom::Synom>::parse) };
- ($i:expr, /=) => { call!($i, <$crate::token::DivEq as $crate::synom::Synom>::parse) };
- ($i:expr, .) => { call!($i, <$crate::token::Dot as $crate::synom::Synom>::parse) };
- ($i:expr, ..) => { call!($i, <$crate::token::Dot2 as $crate::synom::Synom>::parse) };
- ($i:expr, ...) => { call!($i, <$crate::token::Dot3 as $crate::synom::Synom>::parse) };
- ($i:expr, ..=) => { call!($i, <$crate::token::DotDotEq as $crate::synom::Synom>::parse) };
- ($i:expr, =) => { call!($i, <$crate::token::Eq as $crate::synom::Synom>::parse) };
- ($i:expr, ==) => { call!($i, <$crate::token::EqEq as $crate::synom::Synom>::parse) };
- ($i:expr, >=) => { call!($i, <$crate::token::Ge as $crate::synom::Synom>::parse) };
- ($i:expr, >) => { call!($i, <$crate::token::Gt as $crate::synom::Synom>::parse) };
- ($i:expr, <=) => { call!($i, <$crate::token::Le as $crate::synom::Synom>::parse) };
- ($i:expr, <) => { call!($i, <$crate::token::Lt as $crate::synom::Synom>::parse) };
- ($i:expr, *=) => { call!($i, <$crate::token::MulEq as $crate::synom::Synom>::parse) };
- ($i:expr, !=) => { call!($i, <$crate::token::Ne as $crate::synom::Synom>::parse) };
- ($i:expr, |) => { call!($i, <$crate::token::Or as $crate::synom::Synom>::parse) };
- ($i:expr, |=) => { call!($i, <$crate::token::OrEq as $crate::synom::Synom>::parse) };
- ($i:expr, ||) => { call!($i, <$crate::token::OrOr as $crate::synom::Synom>::parse) };
- ($i:expr, #) => { call!($i, <$crate::token::Pound as $crate::synom::Synom>::parse) };
- ($i:expr, ?) => { call!($i, <$crate::token::Question as $crate::synom::Synom>::parse) };
- ($i:expr, ->) => { call!($i, <$crate::token::RArrow as $crate::synom::Synom>::parse) };
- ($i:expr, <-) => { call!($i, <$crate::token::LArrow as $crate::synom::Synom>::parse) };
- ($i:expr, %) => { call!($i, <$crate::token::Rem as $crate::synom::Synom>::parse) };
- ($i:expr, %=) => { call!($i, <$crate::token::RemEq as $crate::synom::Synom>::parse) };
- ($i:expr, =>) => { call!($i, <$crate::token::FatArrow as $crate::synom::Synom>::parse) };
- ($i:expr, ;) => { call!($i, <$crate::token::Semi as $crate::synom::Synom>::parse) };
- ($i:expr, <<) => { call!($i, <$crate::token::Shl as $crate::synom::Synom>::parse) };
- ($i:expr, <<=) => { call!($i, <$crate::token::ShlEq as $crate::synom::Synom>::parse) };
- ($i:expr, >>) => { call!($i, <$crate::token::Shr as $crate::synom::Synom>::parse) };
- ($i:expr, >>=) => { call!($i, <$crate::token::ShrEq as $crate::synom::Synom>::parse) };
- ($i:expr, *) => { call!($i, <$crate::token::Star as $crate::synom::Synom>::parse) };
- ($i:expr, -) => { call!($i, <$crate::token::Sub as $crate::synom::Synom>::parse) };
- ($i:expr, -=) => { call!($i, <$crate::token::SubEq as $crate::synom::Synom>::parse) };
- ($i:expr, _) => { call!($i, <$crate::token::Underscore as $crate::synom::Synom>::parse) };
-}
-
-/// Parse a single Rust keyword token.
-///
-/// See the [token module] documentation for details and examples.
-///
-/// [token module]: token/index.html
-///
-/// *This macro is available if Syn is built with the `"parsing"` feature.*
-#[cfg(feature = "parsing")]
-#[macro_export]
-#[cfg_attr(rustfmt, rustfmt_skip)]
-macro_rules! keyword {
- ($i:expr, as) => { call!($i, <$crate::token::As as $crate::synom::Synom>::parse) };
- ($i:expr, async) => { call!($i, <$crate::token::Async as $crate::synom::Synom>::parse) };
- ($i:expr, auto) => { call!($i, <$crate::token::Auto as $crate::synom::Synom>::parse) };
- ($i:expr, box) => { call!($i, <$crate::token::Box as $crate::synom::Synom>::parse) };
- ($i:expr, break) => { call!($i, <$crate::token::Break as $crate::synom::Synom>::parse) };
- ($i:expr, Self) => { call!($i, <$crate::token::CapSelf as $crate::synom::Synom>::parse) };
- ($i:expr, catch) => { call!($i, <$crate::token::Catch as $crate::synom::Synom>::parse) };
- ($i:expr, const) => { call!($i, <$crate::token::Const as $crate::synom::Synom>::parse) };
- ($i:expr, continue) => { call!($i, <$crate::token::Continue as $crate::synom::Synom>::parse) };
- ($i:expr, crate) => { call!($i, <$crate::token::Crate as $crate::synom::Synom>::parse) };
- ($i:expr, default) => { call!($i, <$crate::token::Default as $crate::synom::Synom>::parse) };
- ($i:expr, do) => { call!($i, <$crate::token::Do as $crate::synom::Synom>::parse) };
- ($i:expr, dyn) => { call!($i, <$crate::token::Dyn as $crate::synom::Synom>::parse) };
- ($i:expr, else) => { call!($i, <$crate::token::Else as $crate::synom::Synom>::parse) };
- ($i:expr, enum) => { call!($i, <$crate::token::Enum as $crate::synom::Synom>::parse) };
- ($i:expr, extern) => { call!($i, <$crate::token::Extern as $crate::synom::Synom>::parse) };
- ($i:expr, fn) => { call!($i, <$crate::token::Fn as $crate::synom::Synom>::parse) };
- ($i:expr, for) => { call!($i, <$crate::token::For as $crate::synom::Synom>::parse) };
- ($i:expr, if) => { call!($i, <$crate::token::If as $crate::synom::Synom>::parse) };
- ($i:expr, impl) => { call!($i, <$crate::token::Impl as $crate::synom::Synom>::parse) };
- ($i:expr, in) => { call!($i, <$crate::token::In as $crate::synom::Synom>::parse) };
- ($i:expr, let) => { call!($i, <$crate::token::Let as $crate::synom::Synom>::parse) };
- ($i:expr, loop) => { call!($i, <$crate::token::Loop as $crate::synom::Synom>::parse) };
- ($i:expr, macro) => { call!($i, <$crate::token::Macro as $crate::synom::Synom>::parse) };
- ($i:expr, match) => { call!($i, <$crate::token::Match as $crate::synom::Synom>::parse) };
- ($i:expr, mod) => { call!($i, <$crate::token::Mod as $crate::synom::Synom>::parse) };
- ($i:expr, move) => { call!($i, <$crate::token::Move as $crate::synom::Synom>::parse) };
- ($i:expr, mut) => { call!($i, <$crate::token::Mut as $crate::synom::Synom>::parse) };
- ($i:expr, pub) => { call!($i, <$crate::token::Pub as $crate::synom::Synom>::parse) };
- ($i:expr, ref) => { call!($i, <$crate::token::Ref as $crate::synom::Synom>::parse) };
- ($i:expr, return) => { call!($i, <$crate::token::Return as $crate::synom::Synom>::parse) };
- ($i:expr, self) => { call!($i, <$crate::token::Self_ as $crate::synom::Synom>::parse) };
- ($i:expr, static) => { call!($i, <$crate::token::Static as $crate::synom::Synom>::parse) };
- ($i:expr, struct) => { call!($i, <$crate::token::Struct as $crate::synom::Synom>::parse) };
- ($i:expr, super) => { call!($i, <$crate::token::Super as $crate::synom::Synom>::parse) };
- ($i:expr, trait) => { call!($i, <$crate::token::Trait as $crate::synom::Synom>::parse) };
- ($i:expr, try) => { call!($i, <$crate::token::Try as $crate::synom::Synom>::parse) };
- ($i:expr, type) => { call!($i, <$crate::token::Type as $crate::synom::Synom>::parse) };
- ($i:expr, union) => { call!($i, <$crate::token::Union as $crate::synom::Synom>::parse) };
- ($i:expr, unsafe) => { call!($i, <$crate::token::Unsafe as $crate::synom::Synom>::parse) };
- ($i:expr, use) => { call!($i, <$crate::token::Use as $crate::synom::Synom>::parse) };
- ($i:expr, where) => { call!($i, <$crate::token::Where as $crate::synom::Synom>::parse) };
- ($i:expr, while) => { call!($i, <$crate::token::While as $crate::synom::Synom>::parse) };
- ($i:expr, yield) => { call!($i, <$crate::token::Yield as $crate::synom::Synom>::parse) };
+ (as) => { $crate::token::As };
+ (async) => { $crate::token::Async };
+ (auto) => { $crate::token::Auto };
+ (box) => { $crate::token::Box };
+ (break) => { $crate::token::Break };
+ (Self) => { $crate::token::CapSelf };
+ (const) => { $crate::token::Const };
+ (continue) => { $crate::token::Continue };
+ (crate) => { $crate::token::Crate };
+ (default) => { $crate::token::Default };
+ (dyn) => { $crate::token::Dyn };
+ (else) => { $crate::token::Else };
+ (enum) => { $crate::token::Enum };
+ (existential) => { $crate::token::Existential };
+ (extern) => { $crate::token::Extern };
+ (fn) => { $crate::token::Fn };
+ (for) => { $crate::token::For };
+ (if) => { $crate::token::If };
+ (impl) => { $crate::token::Impl };
+ (in) => { $crate::token::In };
+ (let) => { $crate::token::Let };
+ (loop) => { $crate::token::Loop };
+ (macro) => { $crate::token::Macro };
+ (match) => { $crate::token::Match };
+ (mod) => { $crate::token::Mod };
+ (move) => { $crate::token::Move };
+ (mut) => { $crate::token::Mut };
+ (pub) => { $crate::token::Pub };
+ (ref) => { $crate::token::Ref };
+ (return) => { $crate::token::Return };
+ (self) => { $crate::token::Self_ };
+ (static) => { $crate::token::Static };
+ (struct) => { $crate::token::Struct };
+ (super) => { $crate::token::Super };
+ (trait) => { $crate::token::Trait };
+ (try) => { $crate::token::Try };
+ (type) => { $crate::token::Type };
+ (union) => { $crate::token::Union };
+ (unsafe) => { $crate::token::Unsafe };
+ (use) => { $crate::token::Use };
+ (where) => { $crate::token::Where };
+ (while) => { $crate::token::While };
+ (yield) => { $crate::token::Yield };
+ (+) => { $crate::token::Add };
+ (+=) => { $crate::token::AddEq };
+ (&) => { $crate::token::And };
+ (&&) => { $crate::token::AndAnd };
+ (&=) => { $crate::token::AndEq };
+ (@) => { $crate::token::At };
+ (!) => { $crate::token::Bang };
+ (^) => { $crate::token::Caret };
+ (^=) => { $crate::token::CaretEq };
+ (:) => { $crate::token::Colon };
+ (::) => { $crate::token::Colon2 };
+ (,) => { $crate::token::Comma };
+ (/) => { $crate::token::Div };
+ (/=) => { $crate::token::DivEq };
+ (.) => { $crate::token::Dot };
+ (..) => { $crate::token::Dot2 };
+ (...) => { $crate::token::Dot3 };
+ (..=) => { $crate::token::DotDotEq };
+ (=) => { $crate::token::Eq };
+ (==) => { $crate::token::EqEq };
+ (>=) => { $crate::token::Ge };
+ (>) => { $crate::token::Gt };
+ (<=) => { $crate::token::Le };
+ (<) => { $crate::token::Lt };
+ (*=) => { $crate::token::MulEq };
+ (!=) => { $crate::token::Ne };
+ (|) => { $crate::token::Or };
+ (|=) => { $crate::token::OrEq };
+ (||) => { $crate::token::OrOr };
+ (#) => { $crate::token::Pound };
+ (?) => { $crate::token::Question };
+ (->) => { $crate::token::RArrow };
+ (<-) => { $crate::token::LArrow };
+ (%) => { $crate::token::Rem };
+ (%=) => { $crate::token::RemEq };
+ (=>) => { $crate::token::FatArrow };
+ (;) => { $crate::token::Semi };
+ (<<) => { $crate::token::Shl };
+ (<<=) => { $crate::token::ShlEq };
+ (>>) => { $crate::token::Shr };
+ (>>=) => { $crate::token::ShrEq };
+ (*) => { $crate::token::Star };
+ (-) => { $crate::token::Sub };
+ (-=) => { $crate::token::SubEq };
+ (_) => { $crate::token::Underscore };
}
macro_rules! ident_from_token {
($token:ident) => {
impl From<Token![$token]> for Ident {
fn from(token: Token![$token]) -> Ident {
- Ident::new(stringify!($token), token.0)
+ Ident::new(stringify!($token), token.span)
}
}
};
@@ -746,102 +702,53 @@
#[cfg(feature = "parsing")]
mod parsing {
- use proc_macro2::{Delimiter, Spacing, Span};
+ use proc_macro2::{Spacing, Span};
- use buffer::Cursor;
- use parse_error;
- use synom::PResult;
+ use error::{Error, Result};
+ use parse::ParseStream;
+ use span::FromSpans;
- pub trait FromSpans: Sized {
- fn from_spans(spans: &[Span]) -> Self;
+ pub fn keyword(input: ParseStream, token: &str) -> Result<Span> {
+ input.step(|cursor| {
+ if let Some((ident, rest)) = cursor.ident() {
+ if ident == token {
+ return Ok((ident.span(), rest));
+ }
+ }
+ Err(cursor.error(format!("expected `{}`", token)))
+ })
}
- impl FromSpans for [Span; 1] {
- fn from_spans(spans: &[Span]) -> Self {
- [spans[0]]
- }
+ pub fn punct<S: FromSpans>(input: ParseStream, token: &str) -> Result<S> {
+ let mut spans = [input.cursor().span(); 3];
+ punct_helper(input, token, &mut spans)?;
+ Ok(S::from_spans(&spans))
}
- impl FromSpans for [Span; 2] {
- fn from_spans(spans: &[Span]) -> Self {
- [spans[0], spans[1]]
- }
- }
+ fn punct_helper(input: ParseStream, token: &str, spans: &mut [Span; 3]) -> Result<()> {
+ input.step(|cursor| {
+ let mut cursor = *cursor;
+ assert!(token.len() <= spans.len());
- impl FromSpans for [Span; 3] {
- fn from_spans(spans: &[Span]) -> Self {
- [spans[0], spans[1], spans[2]]
- }
- }
-
- pub fn punct<'a, T, R>(s: &str, mut tokens: Cursor<'a>, new: fn(T) -> R) -> PResult<'a, R>
- where
- T: FromSpans,
- {
- let mut spans = [Span::call_site(); 3];
- assert!(s.len() <= spans.len());
- let chars = s.chars();
-
- for (i, (ch, slot)) in chars.zip(&mut spans).enumerate() {
- match tokens.punct() {
- Some((op, rest)) => {
- if op.as_char() == ch {
- if i != s.len() - 1 {
- match op.spacing() {
- Spacing::Joint => {}
- _ => return parse_error(),
- }
+ for (i, ch) in token.chars().enumerate() {
+ match cursor.punct() {
+ Some((punct, rest)) => {
+ spans[i] = punct.span();
+ if punct.as_char() != ch {
+ break;
+ } else if i == token.len() - 1 {
+ return Ok(((), rest));
+ } else if punct.spacing() != Spacing::Joint {
+ break;
}
- *slot = op.span();
- tokens = rest;
- } else {
- return parse_error();
+ cursor = rest;
}
+ None => break,
}
- _ => return parse_error(),
}
- }
- Ok((new(T::from_spans(&spans)), tokens))
- }
- pub fn keyword<'a, T>(keyword: &str, tokens: Cursor<'a>, new: fn(Span) -> T) -> PResult<'a, T> {
- if let Some((ident, rest)) = tokens.ident() {
- if ident == keyword {
- return Ok((new(ident.span()), rest));
- }
- }
- parse_error()
- }
-
- pub fn delim<'a, F, R, T>(
- delim: &str,
- tokens: Cursor<'a>,
- new: fn(Span) -> T,
- f: F,
- ) -> PResult<'a, (T, R)>
- where
- F: FnOnce(Cursor) -> PResult<R>,
- {
- // NOTE: We should support none-delimited sequences here.
- let delim = match delim {
- "(" => Delimiter::Parenthesis,
- "{" => Delimiter::Brace,
- "[" => Delimiter::Bracket,
- " " => Delimiter::None,
- _ => panic!("unknown delimiter: {}", delim),
- };
-
- if let Some((inside, span, rest)) = tokens.group(delim) {
- match f(inside) {
- Ok((ret, remaining)) => {
- if remaining.eof() {
- return Ok(((new(span), ret), rest));
- }
- }
- Err(err) => return Err(err),
- }
- }
- parse_error()
+ Err(Error::new(spans[0], format!("expected `{}`", token)))
+ })
}
}
diff --git a/src/tt.rs b/src/tt.rs
index bde82dc..e4f703e 100644
--- a/src/tt.rs
+++ b/src/tt.rs
@@ -6,61 +6,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#[cfg(feature = "parsing")]
-use buffer::Cursor;
-#[cfg(feature = "parsing")]
-use synom::PResult;
-#[cfg(feature = "parsing")]
-use token::{Brace, Bracket, Paren};
-#[cfg(feature = "parsing")]
-use {parse_error, MacroDelimiter};
-
-#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
-#[cfg(any(feature = "parsing", feature = "extra-traits"))]
use proc_macro2::{Delimiter, TokenStream, TokenTree};
-#[cfg(feature = "parsing")]
-pub fn delimited(input: Cursor) -> PResult<(MacroDelimiter, TokenStream)> {
- if let Some((TokenTree::Group(g), rest)) = input.token_tree() {
- let span = g.span();
- let delimiter = match g.delimiter() {
- Delimiter::Parenthesis => MacroDelimiter::Paren(Paren(span)),
- Delimiter::Brace => MacroDelimiter::Brace(Brace(span)),
- Delimiter::Bracket => MacroDelimiter::Bracket(Bracket(span)),
- Delimiter::None => return parse_error(),
- };
-
- return Ok(((delimiter, g.stream().clone()), rest));
- }
- parse_error()
-}
-
-#[cfg(all(feature = "full", feature = "parsing"))]
-pub fn braced(input: Cursor) -> PResult<(Brace, TokenStream)> {
- if let Some((TokenTree::Group(g), rest)) = input.token_tree() {
- if g.delimiter() == Delimiter::Brace {
- return Ok(((Brace(g.span()), g.stream().clone()), rest));
- }
- }
- parse_error()
-}
-
-#[cfg(all(feature = "full", feature = "parsing"))]
-pub fn parenthesized(input: Cursor) -> PResult<(Paren, TokenStream)> {
- if let Some((TokenTree::Group(g), rest)) = input.token_tree() {
- if g.delimiter() == Delimiter::Parenthesis {
- return Ok(((Paren(g.span()), g.stream().clone()), rest));
- }
- }
- parse_error()
-}
-
-#[cfg(feature = "extra-traits")]
pub struct TokenTreeHelper<'a>(pub &'a TokenTree);
-#[cfg(feature = "extra-traits")]
impl<'a> PartialEq for TokenTreeHelper<'a> {
fn eq(&self, other: &Self) -> bool {
use proc_macro2::Spacing;
@@ -104,7 +55,6 @@
}
}
-#[cfg(feature = "extra-traits")]
impl<'a> Hash for TokenTreeHelper<'a> {
fn hash<H: Hasher>(&self, h: &mut H) {
use proc_macro2::Spacing;
@@ -138,10 +88,8 @@
}
}
-#[cfg(feature = "extra-traits")]
pub struct TokenStreamHelper<'a>(pub &'a TokenStream);
-#[cfg(feature = "extra-traits")]
impl<'a> PartialEq for TokenStreamHelper<'a> {
fn eq(&self, other: &Self) -> bool {
let left = self.0.clone().into_iter().collect::<Vec<_>>();
@@ -158,7 +106,6 @@
}
}
-#[cfg(feature = "extra-traits")]
impl<'a> Hash for TokenStreamHelper<'a> {
fn hash<H: Hasher>(&self, state: &mut H) {
let tts = self.0.clone().into_iter().collect::<Vec<_>>();
diff --git a/src/ty.rs b/src/ty.rs
index 1ee46d0..29f2311 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -73,10 +73,10 @@
/// *This type is available if Syn is built with the `"derive"` or
/// `"full"` feature.*
pub BareFn(TypeBareFn {
+ pub lifetimes: Option<BoundLifetimes>,
pub unsafety: Option<Token![unsafe]>,
pub abi: Option<Abi>,
pub fn_token: Token![fn],
- pub lifetimes: Option<BoundLifetimes>,
pub paren_token: token::Paren,
pub inputs: Punctuated<BareFnArg, Token![,]>,
pub variadic: Option<Token![...]>,
@@ -249,14 +249,13 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use path::parsing::qpath;
- use synom::Synom;
- impl Synom for Type {
- named!(parse -> Self, call!(ambig_ty, true));
+ use parse::{Parse, ParseStream, Result};
+ use path;
- fn description() -> Option<&'static str> {
- Some("type")
+ impl Parse for Type {
+ fn parse(input: ParseStream) -> Result<Self> {
+ ambig_ty(input, true)
}
}
@@ -266,250 +265,351 @@
/// contain a `+` character.
///
/// This parser does not allow a `+`, while the default parser does.
- named!(pub without_plus -> Self, call!(ambig_ty, false));
- }
-
- named!(ambig_ty(allow_plus: bool) -> Type, alt!(
- syn!(TypeGroup) => { Type::Group }
- |
- // must be before TypeTuple
- call!(TypeParen::parse, allow_plus) => { Type::Paren }
- |
- // must be before TypePath
- syn!(TypeMacro) => { Type::Macro }
- |
- // must be before TypePath
- syn!(TypeBareFn) => { Type::BareFn }
- |
- // must be before TypeTraitObject
- call!(TypePath::parse, allow_plus) => { Type::Path }
- |
- // Don't try parsing more than one trait bound if we aren't allowing it.
- // must be before TypeTuple
- call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
- |
- syn!(TypeSlice) => { Type::Slice }
- |
- syn!(TypeArray) => { Type::Array }
- |
- syn!(TypePtr) => { Type::Ptr }
- |
- syn!(TypeReference) => { Type::Reference }
- |
- syn!(TypeNever) => { Type::Never }
- |
- syn!(TypeTuple) => { Type::Tuple }
- |
- syn!(TypeImplTrait) => { Type::ImplTrait }
- |
- syn!(TypeInfer) => { Type::Infer }
- ));
-
- impl Synom for TypeSlice {
- named!(parse -> Self, map!(
- brackets!(syn!(Type)),
- |(b, ty)| TypeSlice {
- elem: Box::new(ty),
- bracket_token: b,
- }
- ));
-
- fn description() -> Option<&'static str> {
- Some("slice type")
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ ambig_ty(input, false)
}
}
- impl Synom for TypeArray {
- named!(parse -> Self, map!(
- brackets!(do_parse!(
- elem: syn!(Type) >>
- semi: punct!(;) >>
- len: syn!(Expr) >>
- (elem, semi, len)
- )),
- |(brackets, (elem, semi, len))| {
- TypeArray {
+ fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
+ if input.peek(token::Group) {
+ return input.parse().map(Type::Group);
+ }
+
+ let mut lifetimes = None::<BoundLifetimes>;
+ let mut lookahead = input.lookahead1();
+ if lookahead.peek(Token![for]) {
+ lifetimes = input.parse()?;
+ lookahead = input.lookahead1();
+ if !lookahead.peek(Ident)
+ && !lookahead.peek(Token![fn])
+ && !lookahead.peek(Token![unsafe])
+ && !lookahead.peek(Token![extern])
+ && !lookahead.peek(Token![super])
+ && !lookahead.peek(Token![self])
+ && !lookahead.peek(Token![Self])
+ && !lookahead.peek(Token![crate])
+ {
+ return Err(lookahead.error());
+ }
+ }
+
+ if lookahead.peek(token::Paren) {
+ let content;
+ let paren_token = parenthesized!(content in input);
+ if content.is_empty() {
+ return Ok(Type::Tuple(TypeTuple {
+ paren_token: paren_token,
+ elems: Punctuated::new(),
+ }));
+ }
+ if content.peek(Lifetime) {
+ return Ok(Type::Paren(TypeParen {
+ paren_token: paren_token,
+ elem: Box::new(Type::TraitObject(content.parse()?)),
+ }));
+ }
+ let first: Type = content.parse()?;
+ if content.peek(Token![,]) {
+ Ok(Type::Tuple(TypeTuple {
+ paren_token: paren_token,
+ elems: {
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ elems.push_punct(content.parse()?);
+ let rest: Punctuated<Type, Token![,]> =
+ content.parse_terminated(Parse::parse)?;
+ elems.extend(rest);
+ elems
+ },
+ }))
+ } else {
+ Ok(Type::Paren(TypeParen {
+ paren_token: paren_token,
+ elem: Box::new(first),
+ }))
+ }
+ } else if lookahead.peek(Token![fn])
+ || lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
+ {
+ let mut bare_fn: TypeBareFn = input.parse()?;
+ bare_fn.lifetimes = lifetimes;
+ Ok(Type::BareFn(bare_fn))
+ } else if lookahead.peek(Ident)
+ || input.peek(Token![super])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![crate])
+ || input.peek(Token![extern])
+ || lookahead.peek(Token![::])
+ || lookahead.peek(Token![<])
+ {
+ if input.peek(Token![dyn]) {
+ let mut trait_object: TypeTraitObject = input.parse()?;
+ if lifetimes.is_some() {
+ match *trait_object.bounds.iter_mut().next().unwrap() {
+ TypeParamBound::Trait(ref mut trait_bound) => {
+ trait_bound.lifetimes = lifetimes;
+ }
+ TypeParamBound::Lifetime(_) => unreachable!(),
+ }
+ }
+ return Ok(Type::TraitObject(trait_object));
+ }
+
+ let ty: TypePath = input.parse()?;
+ if ty.qself.is_some() {
+ return Ok(Type::Path(ty));
+ }
+
+ if input.peek(Token![!]) && !input.peek(Token![!=]) {
+ let mut contains_arguments = false;
+ for segment in &ty.path.segments {
+ match segment.arguments {
+ PathArguments::None => {}
+ PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
+ contains_arguments = true;
+ }
+ }
+ }
+
+ if !contains_arguments {
+ let bang_token: Token![!] = input.parse()?;
+ let (delimiter, tts) = mac::parse_delimiter(input)?;
+ return Ok(Type::Macro(TypeMacro {
+ mac: Macro {
+ path: ty.path,
+ bang_token: bang_token,
+ delimiter: delimiter,
+ tts: tts,
+ },
+ }));
+ }
+ }
+
+ if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
+ let mut bounds = Punctuated::new();
+ bounds.push_value(TypeParamBound::Trait(TraitBound {
+ paren_token: None,
+ modifier: TraitBoundModifier::None,
+ lifetimes: lifetimes,
+ path: ty.path,
+ }));
+ if allow_plus {
+ while input.peek(Token![+]) {
+ bounds.push_punct(input.parse()?);
+ bounds.push_value(input.parse()?);
+ }
+ }
+ return Ok(Type::TraitObject(TypeTraitObject {
+ dyn_token: None,
+ bounds: bounds,
+ }));
+ }
+
+ Ok(Type::Path(ty))
+ } else if lookahead.peek(token::Bracket) {
+ let content;
+ let bracket_token = bracketed!(content in input);
+ let elem: Type = content.parse()?;
+ if content.peek(Token![;]) {
+ Ok(Type::Array(TypeArray {
+ bracket_token: bracket_token,
elem: Box::new(elem),
- len: len,
- bracket_token: brackets,
- semi_token: semi,
- }
+ semi_token: content.parse()?,
+ len: content.parse()?,
+ }))
+ } else {
+ Ok(Type::Slice(TypeSlice {
+ bracket_token: bracket_token,
+ elem: Box::new(elem),
+ }))
}
- ));
-
- fn description() -> Option<&'static str> {
- Some("array type")
+ } else if lookahead.peek(Token![*]) {
+ input.parse().map(Type::Ptr)
+ } else if lookahead.peek(Token![&]) {
+ input.parse().map(Type::Reference)
+ } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
+ input.parse().map(Type::Never)
+ } else if lookahead.peek(Token![impl ]) {
+ input.parse().map(Type::ImplTrait)
+ } else if lookahead.peek(Token![_]) {
+ input.parse().map(Type::Infer)
+ } else if lookahead.peek(Lifetime) {
+ input.parse().map(Type::TraitObject)
+ } else {
+ Err(lookahead.error())
}
}
- impl Synom for TypePtr {
- named!(parse -> Self, do_parse!(
- star: punct!(*) >>
- mutability: alt!(
- keyword!(const) => { |c| (None, Some(c)) }
- |
- keyword!(mut) => { |m| (Some(m), None) }
- ) >>
- target: call!(Type::without_plus) >>
- (TypePtr {
- const_token: mutability.1,
- star_token: star,
- mutability: mutability.0,
- elem: Box::new(target),
+ impl Parse for TypeSlice {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(TypeSlice {
+ bracket_token: bracketed!(content in input),
+ elem: content.parse()?,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("raw pointer type")
}
}
- impl Synom for TypeReference {
- named!(parse -> Self, do_parse!(
- amp: punct!(&) >>
- life: option!(syn!(Lifetime)) >>
- mutability: option!(keyword!(mut)) >>
- // & binds tighter than +, so we don't allow + here.
- target: call!(Type::without_plus) >>
- (TypeReference {
- lifetime: life,
+ impl Parse for TypeArray {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(TypeArray {
+ bracket_token: bracketed!(content in input),
+ elem: content.parse()?,
+ semi_token: content.parse()?,
+ len: content.parse()?,
+ })
+ }
+ }
+
+ impl Parse for TypePtr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let star_token: Token![*] = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let (const_token, mutability) = if lookahead.peek(Token![const]) {
+ (Some(input.parse()?), None)
+ } else if lookahead.peek(Token![mut]) {
+ (None, Some(input.parse()?))
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok(TypePtr {
+ star_token: star_token,
+ const_token: const_token,
mutability: mutability,
- elem: Box::new(target),
- and_token: amp,
+ elem: Box::new(input.call(Type::without_plus)?),
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("reference type")
}
}
- impl Synom for TypeBareFn {
- named!(parse -> Self, do_parse!(
- lifetimes: option!(syn!(BoundLifetimes)) >>
- unsafety: option!(keyword!(unsafe)) >>
- abi: option!(syn!(Abi)) >>
- fn_: keyword!(fn) >>
- parens: parens!(do_parse!(
- inputs: call!(Punctuated::parse_terminated) >>
- variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >>
- (inputs, variadic)
- )) >>
- output: call!(ReturnType::without_plus) >>
- (TypeBareFn {
- unsafety: unsafety,
- abi: abi,
- lifetimes: lifetimes,
- output: output,
- variadic: (parens.1).1,
- fn_token: fn_,
- paren_token: parens.0,
- inputs: (parens.1).0,
+ impl Parse for TypeReference {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeReference {
+ and_token: input.parse()?,
+ lifetime: input.parse()?,
+ mutability: input.parse()?,
+ // & binds tighter than +, so we don't allow + here.
+ elem: Box::new(input.call(Type::without_plus)?),
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("`fn` type")
}
}
- impl Synom for TypeNever {
- named!(parse -> Self, map!(
- punct!(!),
- |b| TypeNever { bang_token: b }
- ));
-
- fn description() -> Option<&'static str> {
- Some("never type: `!`")
- }
- }
-
- impl Synom for TypeInfer {
- named!(parse -> Self, map!(
- punct!(_),
- |u| TypeInfer { underscore_token: u }
- ));
-
- fn description() -> Option<&'static str> {
- Some("inferred type: `_`")
- }
- }
-
- impl Synom for TypeTuple {
- named!(parse -> Self, do_parse!(
- data: parens!(Punctuated::parse_terminated) >>
- (TypeTuple {
- paren_token: data.0,
- elems: data.1,
+ impl Parse for TypeBareFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let args;
+ let allow_variadic;
+ Ok(TypeBareFn {
+ lifetimes: input.parse()?,
+ unsafety: input.parse()?,
+ abi: input.parse()?,
+ fn_token: input.parse()?,
+ paren_token: parenthesized!(args in input),
+ inputs: {
+ let mut inputs = Punctuated::new();
+ while !args.is_empty() && !args.peek(Token![...]) {
+ inputs.push_value(args.parse()?);
+ if args.is_empty() {
+ break;
+ }
+ inputs.push_punct(args.parse()?);
+ }
+ allow_variadic = inputs.empty_or_trailing();
+ inputs
+ },
+ variadic: {
+ if allow_variadic && args.peek(Token![...]) {
+ Some(args.parse()?)
+ } else {
+ None
+ }
+ },
+ output: input.call(ReturnType::without_plus)?,
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("tuple type")
}
}
- impl Synom for TypeMacro {
- named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac }));
-
- fn description() -> Option<&'static str> {
- Some("macro invocation")
- }
- }
-
- impl Synom for TypePath {
- named!(parse -> Self, call!(Self::parse, false));
-
- fn description() -> Option<&'static str> {
- Some("type path")
- }
- }
-
- impl TypePath {
- named!(parse(allow_plus: bool) -> Self, do_parse!(
- qpath: qpath >>
- parenthesized: option!(cond_reduce!(
- qpath.1.segments.last().unwrap().value().arguments.is_empty(),
- syn!(ParenthesizedGenericArguments)
- )) >>
- cond!(allow_plus, not!(punct!(+))) >>
- ({
- let (qself, mut path) = qpath;
- if let Some(parenthesized) = parenthesized {
- let parenthesized = PathArguments::Parenthesized(parenthesized);
- path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
- }
- TypePath { qself: qself, path: path }
+ impl Parse for TypeNever {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeNever {
+ bang_token: input.parse()?,
})
- ));
+ }
+ }
+
+ impl Parse for TypeInfer {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeInfer {
+ underscore_token: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for TypeTuple {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(TypeTuple {
+ paren_token: parenthesized!(content in input),
+ elems: content.parse_terminated(Type::parse)?,
+ })
+ }
+ }
+
+ impl Parse for TypeMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeMacro {
+ mac: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for TypePath {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let (qself, mut path) = path::parsing::qpath(input, false)?;
+
+ if path.segments.last().unwrap().value().arguments.is_empty()
+ && input.peek(token::Paren)
+ {
+ let args: ParenthesizedGenericArguments = input.parse()?;
+ let parenthesized = PathArguments::Parenthesized(args);
+ path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
+ }
+
+ Ok(TypePath {
+ qself: qself,
+ path: path,
+ })
+ }
}
impl ReturnType {
- named!(pub without_plus -> Self, call!(Self::parse, false));
- named!(parse(allow_plus: bool) -> Self, alt!(
- do_parse!(
- arrow: punct!(->) >>
- ty: call!(ambig_ty, allow_plus) >>
- (ReturnType::Type(arrow, Box::new(ty)))
- )
- |
- epsilon!() => { |_| ReturnType::Default }
- ));
- }
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ Self::parse(input, false)
+ }
- impl Synom for ReturnType {
- named!(parse -> Self, call!(Self::parse, true));
-
- fn description() -> Option<&'static str> {
- Some("return type")
+ pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ if input.peek(Token![->]) {
+ let arrow = input.parse()?;
+ let ty = ambig_ty(input, allow_plus)?;
+ Ok(ReturnType::Type(arrow, Box::new(ty)))
+ } else {
+ Ok(ReturnType::Default)
+ }
}
}
- impl Synom for TypeTraitObject {
- named!(parse -> Self, call!(Self::parse, true));
+ impl Parse for ReturnType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse(input, true)
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("trait object type")
+ impl Parse for TypeTraitObject {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse(input, true)
}
}
@@ -523,123 +623,133 @@
}
impl TypeTraitObject {
- named!(pub without_plus -> Self, call!(Self::parse, false));
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ Self::parse(input, false)
+ }
// Only allow multiple trait references if allow_plus is true.
- named!(parse(allow_plus: bool) -> Self, do_parse!(
- dyn_token: option!(keyword!(dyn)) >>
- bounds: alt!(
- cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty)
- |
- syn!(TypeParamBound) => {|x| {
+ pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ Ok(TypeTraitObject {
+ dyn_token: input.parse()?,
+ bounds: {
let mut bounds = Punctuated::new();
- bounds.push_value(x);
+ if allow_plus {
+ loop {
+ bounds.push_value(input.parse()?);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ bounds.push_punct(input.parse()?);
+ }
+ } else {
+ bounds.push_value(input.parse()?);
+ }
+ // Just lifetimes like `'a + 'b` is not a TraitObject.
+ if !at_least_one_type(&bounds) {
+ return Err(input.error("expected at least one type"));
+ }
bounds
- }}
- ) >>
- // Just lifetimes like `'a + 'b` is not a TraitObject.
- cond_reduce!(at_least_one_type(&bounds)) >>
- (TypeTraitObject {
- dyn_token: dyn_token,
- bounds: bounds,
+ },
})
- ));
- }
-
- impl Synom for TypeImplTrait {
- named!(parse -> Self, do_parse!(
- impl_: keyword!(impl) >>
- // NOTE: rust-lang/rust#34511 includes discussion about whether or
- // not + should be allowed in ImplTrait directly without ().
- elem: call!(Punctuated::parse_terminated_nonempty) >>
- (TypeImplTrait {
- impl_token: impl_,
- bounds: elem,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("`impl Trait` type")
}
}
- impl Synom for TypeGroup {
- named!(parse -> Self, do_parse!(
- data: grouped!(syn!(Type)) >>
- (TypeGroup {
- group_token: data.0,
- elem: Box::new(data.1),
+ impl Parse for TypeImplTrait {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeImplTrait {
+ impl_token: input.parse()?,
+ // NOTE: rust-lang/rust#34511 includes discussion about whether
+ // or not + should be allowed in ImplTrait directly without ().
+ bounds: {
+ let mut bounds = Punctuated::new();
+ loop {
+ bounds.push_value(input.parse()?);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ bounds.push_punct(input.parse()?);
+ }
+ bounds
+ },
})
- ));
-
- fn description() -> Option<&'static str> {
- Some("type surrounded by invisible delimiters")
}
}
- impl Synom for TypeParen {
- named!(parse -> Self, call!(Self::parse, false));
+ impl Parse for TypeGroup {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let group = private::parse_group(input)?;
+ Ok(TypeGroup {
+ group_token: group.token,
+ elem: group.content.parse()?,
+ })
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("parenthesized type")
+ impl Parse for TypeParen {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse(input, false)
}
}
impl TypeParen {
- named!(parse(allow_plus: bool) -> Self, do_parse!(
- data: parens!(syn!(Type)) >>
- cond!(allow_plus, not!(punct!(+))) >>
- (TypeParen {
- paren_token: data.0,
- elem: Box::new(data.1),
+ fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ let content;
+ Ok(TypeParen {
+ paren_token: parenthesized!(content in input),
+ elem: Box::new(ambig_ty(&content, allow_plus)?),
})
- ));
- }
-
- impl Synom for BareFnArg {
- named!(parse -> Self, do_parse!(
- name: option!(do_parse!(
- name: syn!(BareFnArgName) >>
- not!(punct!(::)) >>
- colon: punct!(:) >>
- (name, colon)
- )) >>
- ty: syn!(Type) >>
- (BareFnArg {
- name: name,
- ty: ty,
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("function type argument")
}
}
- impl Synom for BareFnArgName {
- named!(parse -> Self, alt!(
- map!(syn!(Ident), BareFnArgName::Named)
- |
- map!(punct!(_), BareFnArgName::Wild)
- ));
-
- fn description() -> Option<&'static str> {
- Some("function argument name")
+ impl Parse for BareFnArg {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(BareFnArg {
+ name: {
+ if (input.peek(Ident) || input.peek(Token![_]))
+ && !input.peek2(Token![::])
+ && input.peek2(Token![:])
+ {
+ let name: BareFnArgName = input.parse()?;
+ let colon: Token![:] = input.parse()?;
+ Some((name, colon))
+ } else {
+ None
+ }
+ },
+ ty: input.parse()?,
+ })
}
}
- impl Synom for Abi {
- named!(parse -> Self, do_parse!(
- extern_: keyword!(extern) >>
- name: option!(syn!(LitStr)) >>
- (Abi {
- extern_token: extern_,
- name: name,
- })
- ));
+ impl Parse for BareFnArgName {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Ident) {
+ input.parse().map(BareFnArgName::Named)
+ } else if lookahead.peek(Token![_]) {
+ input.parse().map(BareFnArgName::Wild)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
- fn description() -> Option<&'static str> {
- Some("`extern` ABI qualifier")
+ impl Parse for Abi {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Abi {
+ extern_token: input.parse()?,
+ name: input.parse()?,
+ })
+ }
+ }
+
+ impl Parse for Option<Abi> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![extern]) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
}
}
}
@@ -647,9 +757,12 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
+
use proc_macro2::TokenStream;
use quote::ToTokens;
+ use print::TokensOrDefault;
+
impl ToTokens for TypeSlice {
fn to_tokens(&self, tokens: &mut TokenStream) {
self.bracket_token.surround(tokens, |tokens| {
@@ -700,8 +813,8 @@
self.inputs.to_tokens(tokens);
if let Some(ref variadic) = self.variadic {
if !self.inputs.empty_or_trailing() {
- let span = variadic.0[0];
- <Token![,]>::new(span).to_tokens(tokens);
+ let span = variadic.spans[0];
+ Token.to_tokens(tokens);
}
variadic.to_tokens(tokens);
}
@@ -726,7 +839,7 @@
impl ToTokens for TypePath {
fn to_tokens(&self, tokens: &mut TokenStream) {
- PathTokens(&self.qself, &self.path).to_tokens(tokens);
+ private::print_path(tokens, &self.qself, &self.path);
}
}
diff --git a/src/verbatim.rs b/src/verbatim.rs
deleted file mode 100644
index 8ab0603..0000000
--- a/src/verbatim.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use std::ops::Range;
-
-use buffer::Cursor;
-use proc_macro2::TokenStream;
-use synom::PResult;
-
-pub fn grab_cursor(cursor: Cursor) -> PResult<Cursor> {
- Ok((cursor, cursor))
-}
-
-pub fn token_range(range: Range<Cursor>) -> TokenStream {
- let mut tts = Vec::new();
- let mut cursor = range.start;
- while cursor != range.end {
- let (tt, next) = cursor.token_tree().expect("malformed token range");
- tts.push(tt);
- cursor = next;
- }
- tts.into_iter().collect()
-}
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
index e09544b..108019a 100644
--- a/tests/common/mod.rs
+++ b/tests/common/mod.rs
@@ -20,20 +20,6 @@
pub mod eq;
pub mod parse;
-pub fn check_min_stack() {
- let min_stack_value = match env::var("RUST_MIN_STACK") {
- Ok(s) => s,
- Err(_) => {
- env::set_var("RUST_MIN_STACK", 16000000.to_string());
- return;
- }
- };
- let min_stack_value: usize = min_stack_value
- .parse()
- .expect("RUST_MIN_STACK env var should be set since some tests require it.");
- assert!(min_stack_value >= 16_000_000);
-}
-
/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
pub fn abort_after() -> usize {
match env::var("ABORT_AFTER_FAILURE") {
diff --git a/tests/common/parse.rs b/tests/common/parse.rs
index 0f410e6..a0cc40c 100644
--- a/tests/common/parse.rs
+++ b/tests/common/parse.rs
@@ -20,9 +20,6 @@
use std::panic;
-use self::syn::buffer::TokenBuffer;
-use self::syn::synom::Synom;
-
pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
match panic::catch_unwind(|| {
hygiene::set_default_edition(Edition::Edition2018);
@@ -59,20 +56,3 @@
}
}
}
-
-pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
- let buf = TokenBuffer::new2(tokens);
- let result = T::parse(buf.begin());
- match result {
- Ok((t, rest)) => {
- if rest.eof() {
- t
- } else if rest == buf.begin() {
- panic!("failed to parse anything")
- } else {
- panic!("failed to parse all tokens")
- }
- }
- Err(err) => panic!("failed to parse: {}", err),
- }
-}
diff --git a/tests/test_asyncness.rs b/tests/test_asyncness.rs
new file mode 100644
index 0000000..b73537b
--- /dev/null
+++ b/tests/test_asyncness.rs
@@ -0,0 +1,71 @@
+// Copyright 2018 Syn Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg(all(feature = "extra-traits", feature = "full"))]
+
+extern crate proc_macro2;
+extern crate syn;
+
+use proc_macro2::Span;
+use syn::punctuated::Punctuated;
+use syn::{Block, Expr, ExprBlock, ExprClosure, FnDecl, Ident, ItemFn, ReturnType, Visibility};
+
+#[test]
+fn test_async_fn() {
+ let raw = "async fn process() {}";
+
+ let expected = ItemFn {
+ attrs: vec![],
+ vis: Visibility::Inherited,
+ constness: None,
+ unsafety: None,
+ asyncness: Some(Default::default()),
+ abi: None,
+ ident: Ident::new("process", Span::call_site()),
+ decl: Box::new(FnDecl {
+ fn_token: Default::default(),
+ generics: Default::default(),
+ paren_token: Default::default(),
+ inputs: Punctuated::new(),
+ variadic: None,
+ output: ReturnType::Default,
+ }),
+ block: Box::new(Block {
+ brace_token: Default::default(),
+ stmts: vec![],
+ }),
+ };
+
+ assert_eq!(expected, syn::parse_str(raw).unwrap());
+}
+
+#[test]
+fn test_async_closure() {
+ let raw = "async || {}";
+
+ let expected = Expr::Closure(ExprClosure {
+ attrs: vec![],
+ movability: None,
+ asyncness: Some(Default::default()),
+ capture: None,
+ or1_token: Default::default(),
+ inputs: Punctuated::new(),
+ or2_token: Default::default(),
+ output: ReturnType::Default,
+ body: Box::new(Expr::Block(ExprBlock {
+ attrs: vec![],
+ label: None,
+ block: Block {
+ brace_token: Default::default(),
+ stmts: vec![],
+ },
+ })),
+ });
+
+ assert_eq!(expected, syn::parse_str(raw).unwrap());
+}
diff --git a/tests/test_derive_input.rs b/tests/test_derive_input.rs
index 5ca2c72..045e506 100644
--- a/tests/test_derive_input.rs
+++ b/tests/test_derive_input.rs
@@ -84,7 +84,6 @@
Parenthesis,
vec![word("Debug"), op(','), word("Clone")],
)]),
- is_sugared_doc: false,
}],
generics: Generics::default(),
data: Data::Struct(DataStruct {
@@ -254,7 +253,6 @@
" See the std::result module documentation for details.",
)),
]),
- is_sugared_doc: false,
},
Attribute {
bracket_token: Default::default(),
@@ -262,7 +260,6 @@
style: AttrStyle::Outer,
path: ident("must_use").into(),
tts: TokenStream::new(),
- is_sugared_doc: false,
},
],
generics: Generics {
@@ -447,7 +444,6 @@
],
),
]),
- is_sugared_doc: false,
}],
generics: Generics::default(),
data: Data::Struct(DataStruct {
@@ -483,7 +479,6 @@
segments: punctuated![PathSegment::from(ident("inert"))],
},
tts: TokenStream::from_iter(vec![op('<'), word("T"), op('>')]),
- is_sugared_doc: false,
}],
generics: Generics::default(),
data: Data::Struct(DataStruct {
@@ -522,7 +517,6 @@
],
},
tts: TokenStream::new(),
- is_sugared_doc: false,
}],
generics: Generics::default(),
data: Data::Struct(DataStruct {
diff --git a/tests/test_expr.rs b/tests/test_expr.rs
deleted file mode 100644
index 4b5bf8c..0000000
--- a/tests/test_expr.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2018 Syn Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(feature = "extra-traits")]
-
-extern crate proc_macro2;
-extern crate syn;
-use proc_macro2::*;
-use syn::*;
-
-macro_rules! assert_let {
- ($p:pat = $e:expr) => {
- assert_let!($p = $e; {})
- };
-
- ($p:pat = $e:expr; $body:block) => {
- if let $p = $e
- $body
- else {
- panic!("Expected to match {} but got {:?}", stringify!($p), $e)
- }
- };
-}
-
-#[test]
-#[cfg(feature = "full")]
-fn test_catch_expr() {
- // Taken from tests/rust/src/test/run-pass/catch-expr.rs
- let raw = r#"
- struct catch {}
-
- pub fn main() {
- let catch_result = do catch {
- let x = 5;
- x
- };
- assert_eq!(catch_result, 5);
-
- let mut catch = true;
- while catch { catch = false; }
- assert_eq!(catch, false);
-
- catch = if catch { false } else { true };
- assert_eq!(catch, true);
-
- match catch {
- _ => {}
- };
-
- let catch_err = do catch {
- Err(22)?;
- Ok(1)
- };
- assert_eq!(catch_err, Err(22));
-
- let catch_okay: Result<i32, i32> = do catch {
- if false { Err(25)?; }
- Ok::<(), i32>(())?;
- Ok(28)
- };
- assert_eq!(catch_okay, Ok(28));
-
- let catch_from_loop: Result<i32, i32> = do catch {
- for i in 0..10 {
- if i < 5 { Ok::<i32, i32>(i)?; } else { Err(i)?; }
- }
- Ok(22)
- };
- assert_eq!(catch_from_loop, Err(5));
-
- let cfg_init;
- let _res: Result<(), ()> = do catch {
- cfg_init = 5;
- Ok(())
- };
- assert_eq!(cfg_init, 5);
-
- let cfg_init_2;
- let _res: Result<(), ()> = do catch {
- cfg_init_2 = 6;
- Err(())?;
- Ok(())
- };
- assert_eq!(cfg_init_2, 6);
-
- let my_string = "test".to_string();
- let res: Result<&str, ()> = do catch {
- Ok(&my_string)
- };
- assert_eq!(res, Ok("test"));
- }
- "#;
-
- let actual: File = syn::parse_str(raw).unwrap();
-
- assert_let!(Item::Struct(ItemStruct { ref ident, .. }) = actual.items[0]; {
- assert_eq!(ident, "catch");
- });
-
- assert_let!(Item::Fn(ItemFn { ref block, .. }) = actual.items[1]; {
- assert_let!(Stmt::Local(ref local) = block.stmts[0]; {
- assert_let!(Local { init: Some((_, ref init_expr)), .. } = *local; {
- assert_let!(Expr::Catch(..) = **init_expr);
- });
- });
-
- assert_let!(Stmt::Local(ref local) = block.stmts[2]; {
- assert_let!(Pat::Ident(PatIdent { by_ref: None, mutability: Some(_), ref ident, .. }) = local.pats.iter().next().unwrap(); {
- assert_eq!(ident, "catch");
- });
- });
-
- assert_let!(Stmt::Expr(ref expr) = block.stmts[3]; {
- assert_let!(Expr::While(ExprWhile { ref cond, .. }) = *expr; {
- assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
- let name = Ident::new("catch", Span::call_site());
- assert_eq!(*path, name.into());
- });
- });
- });
-
- assert_let!(Stmt::Semi(ref expr, _) = block.stmts[5]; {
- assert_let!(Expr::Assign(ExprAssign { ref left, ref right, .. }) = *expr; {
- assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **left; {
- let name = Ident::new("catch", Span::call_site());
- assert_eq!(*path, name.into());
- });
-
- assert_let!(Expr::If(ExprIf { ref cond, .. }) = **right; {
- assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **cond; {
- let name = Ident::new("catch", Span::call_site());
- assert_eq!(*path, name.into());
- });
- });
- });
- });
-
- assert_let!(Stmt::Semi(ref expr, _) = block.stmts[7]; {
- assert_let!(Expr::Match(ExprMatch { ref expr, .. }) = *expr; {
- assert_let!(Expr::Path(ExprPath { qself: None, ref path, .. }) = **expr; {
- let name = Ident::new("catch", Span::call_site());
- assert_eq!(*path, name.into());
- });
- });
- });
- });
-}
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index fe33fbd..d3b33ed 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -54,7 +54,6 @@
style: AttrStyle::Outer,
path: ident("may_dangle").into(),
tts: TokenStream::new(),
- is_sugared_doc: false,
}],
ident: ident("T"),
bounds: punctuated![TypeParamBound::Lifetime(Lifetime::new(
@@ -113,18 +112,12 @@
fn test_ty_param_bound() {
let tokens = quote!('a);
let expected = TypeParamBound::Lifetime(Lifetime::new("'a", Span::call_site()));
- assert_eq!(
- expected,
- common::parse::syn::<TypeParamBound>(tokens.into())
- );
+ assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
let tokens = quote!('_);
println!("{:?}", tokens);
let expected = TypeParamBound::Lifetime(Lifetime::new("'_", Span::call_site()));
- assert_eq!(
- expected,
- common::parse::syn::<TypeParamBound>(tokens.into())
- );
+ assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
let tokens = quote!(Debug);
let expected = TypeParamBound::Trait(TraitBound {
@@ -133,10 +126,7 @@
lifetimes: None,
path: ident("Debug").into(),
});
- assert_eq!(
- expected,
- common::parse::syn::<TypeParamBound>(tokens.into())
- );
+ assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
let tokens = quote!(?Sized);
let expected = TypeParamBound::Trait(TraitBound {
@@ -145,10 +135,7 @@
lifetimes: None,
path: ident("Sized").into(),
});
- assert_eq!(
- expected,
- common::parse::syn::<TypeParamBound>(tokens.into())
- );
+ assert_eq!(expected, syn::parse2::<TypeParamBound>(tokens).unwrap());
}
#[test]
@@ -161,7 +148,7 @@
{
}
};
- let fun = common::parse::syn::<ItemFn>(sig.into());
+ let fun = syn::parse2::<ItemFn>(sig).unwrap();
let where_clause = fun.decl.generics.where_clause.as_ref().unwrap();
assert_eq!(where_clause.predicates.len(), 1);
let predicate = match where_clause.predicates[0] {
diff --git a/tests/test_grouping.rs b/tests/test_grouping.rs
index 96ab164..78211ec 100644
--- a/tests/test_grouping.rs
+++ b/tests/test_grouping.rs
@@ -56,7 +56,7 @@
assert_eq!(raw.to_string(), "1i32 + 2i32 + 3i32 * 4i32");
assert_eq!(
- common::parse::syn::<Expr>(raw),
+ syn::parse2::<syn::Expr>(raw).unwrap(),
expr(ExprBinary {
attrs: Vec::new(),
left: Box::new(lit(Literal::i32_suffixed(1))),
@@ -79,45 +79,3 @@
})
);
}
-
-#[test]
-fn test_invalid_grouping() {
- let raw: TokenStream = vec![
- TokenTree::Literal(Literal::i32_suffixed(1)),
- TokenTree::Punct(Punct::new('+', Spacing::Alone)),
- TokenTree::Group(proc_macro2::Group::new(
- Delimiter::None,
- vec![
- TokenTree::Literal(Literal::i32_suffixed(2)),
- TokenTree::Punct(Punct::new('+', Spacing::Alone)),
- ].into_iter()
- .collect(),
- )),
- TokenTree::Literal(Literal::i32_suffixed(3)),
- TokenTree::Punct(Punct::new('*', Spacing::Alone)),
- TokenTree::Literal(Literal::i32_suffixed(4)),
- ].into_iter()
- .collect();
-
- assert_eq!(raw.to_string(), "1i32 + 2i32 + 3i32 * 4i32");
-
- assert_eq!(
- common::parse::syn::<Expr>(raw),
- expr(ExprBinary {
- attrs: Vec::new(),
- left: Box::new(expr(ExprBinary {
- attrs: Vec::new(),
- left: Box::new(lit(Literal::i32_suffixed(1))),
- op: BinOp::Add(<Token![+]>::default()),
- right: Box::new(lit(Literal::i32_suffixed(2))),
- })),
- op: BinOp::Add(<Token![+]>::default()),
- right: Box::new(expr(ExprBinary {
- attrs: Vec::new(),
- left: Box::new(lit(Literal::i32_suffixed(3))),
- op: BinOp::Mul(<Token![*]>::default()),
- right: Box::new(lit(Literal::i32_suffixed(4))),
- })),
- })
- );
-}
diff --git a/tests/test_ident.rs b/tests/test_ident.rs
index 73187d3..498e8be 100644
--- a/tests/test_ident.rs
+++ b/tests/test_ident.rs
@@ -11,9 +11,9 @@
use proc_macro2::{Ident, Span, TokenStream};
use std::str::FromStr;
-use syn::synom::ParseError;
+use syn::parse::Error;
-fn parse(s: &str) -> Result<Ident, ParseError> {
+fn parse(s: &str) -> Result<Ident, Error> {
syn::parse2(TokenStream::from_str(s).unwrap())
}
diff --git a/tests/test_meta_item.rs b/tests/test_meta_item.rs
index a45e36e..623e5da 100644
--- a/tests/test_meta_item.rs
+++ b/tests/test_meta_item.rs
@@ -11,8 +11,8 @@
extern crate proc_macro2;
extern crate syn;
-use proc_macro2::{Ident, Literal, Span, TokenStream};
-use syn::buffer::TokenBuffer;
+use proc_macro2::{Ident, Literal, Span};
+use syn::parse::Parser;
use syn::*;
#[macro_use]
@@ -168,14 +168,8 @@
}
fn run_test<T: Into<Meta>>(input: &str, expected: T) {
- let tokens = input.parse::<TokenStream>().unwrap();
- let buf = TokenBuffer::new2(tokens);
- let attr = match Attribute::parse_outer(buf.begin()) {
- Ok((e, rest)) => {
- assert!(rest.eof());
- e
- }
- Err(err) => panic!(err),
- };
+ let attrs = Attribute::parse_outer.parse_str(input).unwrap();
+ assert_eq!(attrs.len(), 1);
+ let attr = attrs.into_iter().next().unwrap();
assert_eq!(expected.into(), attr.interpret_meta().unwrap());
}
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
index b272d49..4d10090 100644
--- a/tests/test_precedence.rs
+++ b/tests/test_precedence.rs
@@ -92,7 +92,6 @@
/// Test expressions from rustc, like in `test_round_trip`.
#[test]
fn test_rustc_precedence() {
- common::check_min_stack();
common::clone_rust();
let abort_after = common::abort_after();
if abort_after == 0 {
@@ -228,18 +227,6 @@
impl Folder for BracketsFolder {
fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
e.map(|e| match e.node {
- ExprKind::Block(_, label) if label.is_some() => Expr {
- id: ast::DUMMY_NODE_ID,
- node: ExprKind::Paren(P(e)),
- span: DUMMY_SP,
- attrs: ThinVec::new(),
- },
- ExprKind::TryBlock(_) => Expr {
- id: ast::DUMMY_NODE_ID,
- node: ExprKind::Paren(P(e)),
- span: DUMMY_SP,
- attrs: ThinVec::new(),
- },
ExprKind::If(..) | ExprKind::Block(..) | ExprKind::IfLet(..) => {
fold::noop_fold_expr(e, self)
}
diff --git a/tests/test_round_trip.rs b/tests/test_round_trip.rs
index 87c1a04..954c34d 100644
--- a/tests/test_round_trip.rs
+++ b/tests/test_round_trip.rs
@@ -42,7 +42,6 @@
#[test]
fn test_round_trip() {
- common::check_min_stack();
common::clone_rust();
let abort_after = common::abort_after();
if abort_after == 0 {
diff --git a/tests/test_token_trees.rs b/tests/test_token_trees.rs
index c385727..02d8f48 100644
--- a/tests/test_token_trees.rs
+++ b/tests/test_token_trees.rs
@@ -82,7 +82,6 @@
bracket_token: Default::default(),
path: Ident::new("test", Span::call_site()).into(),
tts,
- is_sugared_doc: false,
}
}