Require Ident to contain a valid ident
diff --git a/src/expr.rs b/src/expr.rs
index fff9c52..f64bc31 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1253,11 +1253,11 @@
impl Synom for FieldValue {
named!(parse -> Self, alt!(
do_parse!(
- name: wordlike >>
+ ident: field_ident >>
colon: syn!(Colon) >>
value: syn!(Expr) >>
(FieldValue {
- ident: name,
+ ident: ident,
expr: value,
is_shorthand: false,
attrs: Vec::new(),
@@ -1413,6 +1413,7 @@
Mac {
path: what,
bang_token: bang,
+ ident: None,
tokens: vec![TokenTree(proc_macro2::TokenTree {
span: ((data.1).0).0,
kind: TokenKind::Sequence(Delimiter::Brace, data.0),
@@ -1582,7 +1583,7 @@
impl Synom for FieldPat {
named!(parse -> Self, alt!(
do_parse!(
- ident: wordlike >>
+ ident: field_ident >>
colon: syn!(Colon) >>
pat: syn!(Pat) >>
(FieldPat {
@@ -1628,14 +1629,14 @@
));
}
- named!(wordlike -> Ident, alt!(
+ named!(field_ident -> Ident, alt!(
syn!(Ident)
|
do_parse!(
lit: syn!(Lit) >>
({
- let s = lit.value.to_string();
- if s.parse::<u32>().is_ok() {
+ let s = lit.to_string();
+ if s.parse::<usize>().is_ok() {
Ident::new(s.into(), lit.span)
} else {
return parse_error();
diff --git a/src/ident.rs b/src/ident.rs
index afc8a3a..40dc1a8 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -4,11 +4,27 @@
use std::hash::{Hash, Hasher};
use proc_macro2::Symbol;
+use unicode_xid::UnicodeXID;
use Span;
use tokens;
-#[derive(Clone, Debug)]
+/// A word of Rust code, such as a keyword or variable name.
+///
+/// An identifier consists of at least one Unicode code point, the first of
+/// which has the XID_Start property and the rest of which have the XID_Continue
+/// property. An underscore may be used as the first character as long as it is
+/// not the only character.
+///
+/// - The empty string is not an identifier. Use `Option<Ident>`.
+/// - An underscore by itself is not an identifier. Use
+/// `syn::tokens::Underscore` instead.
+/// - A lifetime is not an identifier. Use `syn::Lifetime` instead.
+///
+/// An identifier constructed with `Ident::new` is permitted to be a Rust
+/// keyword, though parsing an identifier with `syn!(Ident)` rejects Rust
+/// keywords.
+#[derive(Copy, Clone, Debug)]
pub struct Ident {
pub sym: Symbol,
pub span: Span,
@@ -16,6 +32,42 @@
impl Ident {
pub fn new(sym: Symbol, span: Span) -> Self {
+ let s = sym.as_str();
+
+ if s.is_empty() {
+ panic!("ident is not allowed to be empty; use Option<Ident>");
+ }
+
+ if s.starts_with('\'') {
+ panic!("ident is not allowed to be a lifetime; use syn::Lifetime");
+ }
+
+ if s == "_" {
+ panic!("`_` is not a valid ident; use syn::tokens::Underscore");
+ }
+
+ fn xid_ok(s: &str) -> bool {
+ let mut chars = s.chars();
+ let first = chars.next().unwrap();
+ if !(UnicodeXID::is_xid_start(first) || first == '_') {
+ return false;
+ }
+ for ch in chars {
+ if !UnicodeXID::is_xid_continue(ch) {
+ return false;
+ }
+ }
+ true
+ }
+
+ fn integer_ok(s: &str) -> bool {
+ s.bytes().all(|digit| digit >= b'0' && digit <= b'9')
+ }
+
+ if !(xid_ok(s) || integer_ok(s)) {
+ panic!("{:?} is not a valid ident", s);
+ }
+
Ident {
sym: sym,
span: span,
@@ -59,12 +111,6 @@
}
}
-impl From<usize> for Ident {
- fn from(u: usize) -> Self {
- Ident::new(u.to_string()[..].into(), Span::default())
- }
-}
-
impl AsRef<str> for Ident {
fn as_ref(&self) -> &str {
self.sym.as_str()
diff --git a/src/item.rs b/src/item.rs
index a433512..fa8a754 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -2,12 +2,8 @@
use delimited::Delimited;
ast_struct! {
- /// An item
- ///
- /// The name might be a dummy name in case of anonymous items
+ /// Things that can appear directly inside of a module.
pub struct Item {
- pub ident: Ident,
- pub vis: Visibility,
pub attrs: Vec<Attribute>,
pub node: ItemKind,
}
@@ -15,20 +11,22 @@
ast_enum_of_structs! {
pub enum ItemKind {
- /// An`extern crate` item, with optional original crate name.
+ /// An `extern crate` item, with optional original crate name.
///
/// E.g. `extern crate foo` or `extern crate foo_bar as foo`
pub ExternCrate(ItemExternCrate {
+ pub vis: Visibility,
pub extern_token: tokens::Extern,
pub crate_token: tokens::Crate,
- pub as_token: Option<tokens::As>,
- pub original: Option<Ident>,
+ pub ident: Ident,
+ pub rename: Option<(tokens::As, Ident)>,
pub semi_token: tokens::Semi,
}),
/// A use declaration (`use` or `pub use`) item.
///
/// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
pub Use(ItemUse {
+ pub vis: Visibility,
pub use_token: tokens::Use,
pub path: Box<ViewPath>,
pub semi_token: tokens::Semi,
@@ -37,94 +35,111 @@
///
/// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
pub Static(ItemStatic {
+ pub vis: Visibility,
pub static_token: tokens::Static,
- pub colon_token: tokens::Colon,
- pub eq_token: tokens::Eq,
- pub semi_token: tokens::Semi,
- pub ty: Box<Ty>,
pub mutbl: Mutability,
+ pub ident: Ident,
+ pub colon_token: tokens::Colon,
+ pub ty: Box<Ty>,
+ pub eq_token: tokens::Eq,
pub expr: Box<Expr>,
+ pub semi_token: tokens::Semi,
}),
/// A constant item (`const` or `pub const`).
///
/// E.g. `const FOO: i32 = 42;`
pub Const(ItemConst {
+ pub vis: Visibility,
pub const_token: tokens::Const,
+ pub ident: Ident,
pub colon_token: tokens::Colon,
- pub eq_token: tokens::Eq,
- pub semi_token: tokens::Semi,
pub ty: Box<Ty>,
+ pub eq_token: tokens::Eq,
pub expr: Box<Expr>,
+ pub semi_token: tokens::Semi,
}),
/// A function declaration (`fn` or `pub fn`).
///
/// E.g. `fn foo(bar: usize) -> usize { .. }`
pub Fn(ItemFn {
- pub decl: Box<FnDecl>,
- pub unsafety: Unsafety,
+ pub vis: Visibility,
pub constness: Constness,
+ pub unsafety: Unsafety,
pub abi: Option<Abi>,
+ pub decl: Box<FnDecl>,
+ pub ident: Ident,
pub block: Box<Block>,
}),
/// A module declaration (`mod` or `pub mod`).
///
/// E.g. `mod foo;` or `mod foo { .. }`
pub Mod(ItemMod {
+ pub vis: Visibility,
pub mod_token: tokens::Mod,
- pub semi_token: Option<tokens::Semi>,
- pub items: Option<(Vec<Item>, tokens::Brace)>,
+ pub ident: Ident,
+ pub content: Option<(tokens::Brace, Vec<Item>)>,
+ pub semi: Option<tokens::Semi>,
}),
/// An external module (`extern` or `pub extern`).
///
/// E.g. `extern {}` or `extern "C" {}`
pub ForeignMod(ItemForeignMod {
- pub brace_token: tokens::Brace,
pub abi: Abi,
+ pub brace_token: tokens::Brace,
pub items: Vec<ForeignItem>,
}),
-
/// A type alias (`type` or `pub type`).
///
/// E.g. `type Foo = Bar<u8>;`
pub Ty(ItemTy {
+ pub vis: Visibility,
pub type_token: tokens::Type,
- pub eq_token: tokens::Eq,
- pub semi_token: tokens::Semi,
- pub ty: Box<Ty>,
+ pub ident: Ident,
pub generics: Generics,
+ pub eq_token: tokens::Eq,
+ pub ty: Box<Ty>,
+ pub semi_token: tokens::Semi,
}),
/// An enum definition (`enum` or `pub enum`).
///
/// E.g. `enum Foo<A, B> { C<A>, D<B> }`
pub Enum(ItemEnum {
+ pub vis: Visibility,
pub enum_token: tokens::Enum,
+ pub ident: Ident,
+ pub generics: Generics,
pub brace_token: tokens::Brace,
pub variants: Delimited<Variant, tokens::Comma>,
- pub generics: Generics,
}),
/// A struct definition (`struct` or `pub struct`).
///
/// E.g. `struct Foo<A> { x: A }`
pub Struct(ItemStruct {
+ pub vis: Visibility,
pub struct_token: tokens::Struct,
- pub data: VariantData,
+ pub ident: Ident,
pub generics: Generics,
+ pub data: VariantData,
pub semi_token: Option<tokens::Semi>,
}),
/// A union definition (`union` or `pub union`).
///
/// E.g. `union Foo<A, B> { x: A, y: B }`
pub Union(ItemUnion {
+ pub vis: Visibility,
pub union_token: tokens::Union,
- pub data: VariantData,
+ pub ident: Ident,
pub generics: Generics,
+ pub data: VariantData,
}),
/// A Trait declaration (`trait` or `pub trait`).
///
/// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
pub Trait(ItemTrait {
- pub trait_token: tokens::Trait,
+ pub vis: Visibility,
pub unsafety: Unsafety,
+ pub trait_token: tokens::Trait,
+ pub ident: Ident,
pub generics: Generics,
pub colon_token: Option<tokens::Colon>,
pub supertraits: Delimited<TyParamBound, tokens::Add>,
@@ -136,8 +151,8 @@
/// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
pub DefaultImpl(ItemDefaultImpl {
pub unsafety: Unsafety,
- pub path: Path,
pub impl_token: tokens::Impl,
+ pub path: Path,
pub for_token: tokens::For,
pub dot2_token: tokens::Dot2,
pub brace_token: tokens::Brace,
@@ -146,13 +161,13 @@
///
/// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
pub Impl(ItemImpl {
- pub impl_token: tokens::Impl,
pub unsafety: Unsafety,
- pub polarity: ImplPolarity,
+ pub impl_token: tokens::Impl,
pub generics: Generics,
- pub for_token: Option<tokens::For>,
- pub trait_: Option<Path>, // (optional) trait this impl implements
- pub self_ty: Box<Ty>, // self
+ /// Trait this impl implements.
+ pub trait_: Option<(ImplPolarity, Path, tokens::For)>,
+ /// The Self type of the impl.
+ pub self_ty: Box<Ty>,
pub brace_token: tokens::Brace,
pub items: Vec<ImplItem>,
}),
@@ -168,24 +183,26 @@
impl From<DeriveInput> for Item {
fn from(input: DeriveInput) -> Item {
Item {
- ident: input.ident,
- vis: input.vis,
attrs: input.attrs,
node: match input.body {
Body::Enum(data) => {
ItemEnum {
- variants: data.variants,
+ vis: input.vis,
+ enum_token: data.enum_token,
+ ident: input.ident,
generics: input.generics,
brace_token: data.brace_token,
- enum_token: data.enum_token,
+ variants: data.variants,
}.into()
}
Body::Struct(data) => {
ItemStruct {
- data: data.data,
- generics: input.generics,
- semi_token: data.semi_token,
+ vis: input.vis,
struct_token: data.struct_token,
+ ident: input.ident,
+ generics: input.generics,
+ data: data.data,
+ semi_token: data.semi_token,
}.into()
}
},
@@ -283,7 +300,6 @@
/// either required (meaning it doesn't have an implementation, just a
/// signature) or provided (meaning it has a default implementation).
pub struct TraitItem {
- pub ident: Ident,
pub attrs: Vec<Attribute>,
pub node: TraitItemKind,
}
@@ -293,10 +309,10 @@
pub enum TraitItemKind {
pub Const(TraitItemConst {
pub const_token: tokens::Const,
+ pub ident: Ident,
pub colon_token: tokens::Colon,
pub ty: Ty,
- pub default: Option<Expr>,
- pub eq_token: Option<tokens::Eq>,
+ pub default: Option<(tokens::Eq, Expr)>,
pub semi_token: tokens::Semi,
}),
pub Method(TraitItemMethod {
@@ -306,10 +322,10 @@
}),
pub Type(TraitItemType {
pub type_token: tokens::Type,
+ pub ident: Ident,
pub colon_token: Option<tokens::Colon>,
pub bounds: Delimited<TyParamBound, tokens::Add>,
- pub eq_token: Option<tokens::Eq>,
- pub default: Option<Ty>,
+ pub default: Option<(tokens::Eq, Ty)>,
pub semi_token: tokens::Semi,
}),
pub Macro(Mac),
@@ -330,9 +346,6 @@
ast_struct! {
pub struct ImplItem {
- pub ident: Ident,
- pub vis: Visibility,
- pub defaultness: Defaultness,
pub attrs: Vec<Attribute>,
pub node: ImplItemKind,
}
@@ -341,22 +354,30 @@
ast_enum_of_structs! {
pub enum ImplItemKind {
pub Const(ImplItemConst {
+ pub vis: Visibility,
+ pub defaultness: Defaultness,
pub const_token: tokens::Const,
+ pub ident: Ident,
pub colon_token: tokens::Colon,
- pub eq_token: tokens::Eq,
- pub semi_token: tokens::Semi,
pub ty: Ty,
+ pub eq_token: tokens::Eq,
pub expr: Expr,
+ pub semi_token: tokens::Semi,
}),
pub Method(ImplItemMethod {
+ pub vis: Visibility,
+ pub defaultness: Defaultness,
pub sig: MethodSig,
pub block: Block,
}),
pub Type(ImplItemType {
+ pub vis: Visibility,
+ pub defaultness: Defaultness,
pub type_token: tokens::Type,
+ pub ident: Ident,
pub eq_token: tokens::Eq,
- pub semi_token: tokens::Semi,
pub ty: Ty,
+ pub semi_token: tokens::Semi,
}),
pub Macro(Mac),
}
@@ -368,9 +389,10 @@
/// Represents a method's signature in a trait declaration,
/// or in an implementation.
pub struct MethodSig {
- pub unsafety: Unsafety,
pub constness: Constness,
+ pub unsafety: Unsafety,
pub abi: Option<Abi>,
+ pub ident: Ident,
pub decl: FnDecl,
}
}
@@ -462,16 +484,15 @@
attrs: many0!(call!(Attribute::parse_outer)) >>
what: syn!(Path) >>
bang: syn!(Bang) >>
- name: option!(syn!(Ident)) >>
+ ident: option!(syn!(Ident)) >>
body: call!(::TokenTree::parse_delimited) >>
cond!(!body.is_braced(), syn!(Semi)) >>
(Item {
- ident: name.unwrap_or_else(|| Ident::from("")),
- vis: VisInherited {}.into(),
attrs: attrs,
node: ItemKind::Mac(Mac {
- bang_token: bang,
path: what,
+ bang_token: bang,
+ ident: ident,
tokens: vec![body],
}),
})
@@ -482,26 +503,19 @@
vis: syn!(Visibility) >>
extern_: syn!(Extern) >>
crate_: syn!(tokens::Crate) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
rename: option!(tuple!(syn!(As), syn!(Ident))) >>
semi: syn!(Semi) >>
- ({
- let (name, original_name, as_) = match rename {
- Some((as_, rename)) => (rename, Some(id), Some(as_)),
- None => (id, None, None),
- };
- Item {
- ident: name,
+ (Item {
+ attrs: attrs,
+ node: ItemExternCrate {
vis: vis,
- attrs: attrs,
- node: ItemExternCrate {
- as_token: as_,
- original: original_name,
- extern_token: extern_,
- crate_token: crate_,
- semi_token: semi,
- }.into(),
- }
+ extern_token: extern_,
+ crate_token: crate_,
+ ident: ident,
+ rename: rename,
+ semi_token: semi,
+ }.into(),
})
));
@@ -512,12 +526,11 @@
what: syn!(ViewPath) >>
semi: syn!(Semi) >>
(Item {
- ident: "".into(),
- vis: vis,
attrs: attrs,
node: ItemUse {
- path: Box::new(what),
+ vis: vis,
use_token: use_,
+ path: Box::new(what),
semi_token: semi,
}.into(),
})
@@ -573,15 +586,14 @@
)
|
do_parse!(
- global: option!(syn!(Colon2)) >>
+ colon: option!(syn!(Colon2)) >>
items: braces!(call!(Delimited::parse_terminated)) >>
(PathList {
path: Path {
- global: global.is_some(),
- segments: Delimited::new(),
leading_colon: None,
+ segments: Delimited::new(),
},
- colon2_token: global.unwrap_or_default(),
+ colon2_token: colon.unwrap_or_default(),
brace_token: items.1,
items: items.0,
})
@@ -610,23 +622,23 @@
vis: syn!(Visibility) >>
static_: syn!(Static) >>
mutability: syn!(Mutability) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
colon: syn!(Colon) >>
ty: syn!(Ty) >>
eq: syn!(Eq) >>
value: syn!(Expr) >>
semi: syn!(Semi) >>
(Item {
- ident: id,
- vis: vis,
attrs: attrs,
node: ItemStatic {
- ty: Box::new(ty),
- mutbl: mutability,
- expr: Box::new(value),
+ vis: vis,
static_token: static_,
+ mutbl: mutability,
+ ident: ident,
colon_token: colon,
+ ty: Box::new(ty),
eq_token: eq,
+ expr: Box::new(value),
semi_token: semi,
}.into(),
})
@@ -636,22 +648,22 @@
attrs: many0!(call!(Attribute::parse_outer)) >>
vis: syn!(Visibility) >>
const_: syn!(Const) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
colon: syn!(Colon) >>
ty: syn!(Ty) >>
eq: syn!(Eq) >>
value: syn!(Expr) >>
semi: syn!(Semi) >>
(Item {
- ident: id,
- vis: vis,
attrs: attrs,
node: ItemConst {
- ty: Box::new(ty),
- expr: Box::new(value),
+ vis: vis,
const_token: const_,
+ ident: ident,
colon_token: colon,
+ ty: Box::new(ty),
eq_token: eq,
+ expr: Box::new(value),
semi_token: semi,
}.into(),
})
@@ -664,7 +676,7 @@
unsafety: syn!(Unsafety) >>
abi: option!(syn!(Abi)) >>
fn_: syn!(Fn_) >>
- name: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
inputs: parens!(Delimited::parse_terminated) >>
ret: syn!(FunctionRetTy) >>
@@ -674,14 +686,16 @@
call!(Block::parse_within)
)) >>
(Item {
- ident: name,
- vis: vis,
attrs: {
let mut attrs = outer_attrs;
attrs.extend((inner_attrs_stmts.0).0);
attrs
},
node: ItemFn {
+ vis: vis,
+ constness: constness,
+ unsafety: unsafety,
+ abi: abi,
decl: Box::new(FnDecl {
dot_tokens: None,
fn_token: fn_,
@@ -694,9 +708,7 @@
.. generics
},
}),
- unsafety: unsafety,
- constness: constness,
- abi: abi,
+ ident: ident,
block: Box::new(Block {
brace_token: inner_attrs_stmts.1,
stmts: (inner_attrs_stmts.0).1,
@@ -750,42 +762,38 @@
outer_attrs: many0!(call!(Attribute::parse_outer)) >>
vis: syn!(Visibility) >>
mod_: syn!(Mod) >>
- id: syn!(Ident) >>
- content: alt!(
- syn!(Semi) => { Ok }
+ ident: syn!(Ident) >>
+ content_semi: alt!(
+ syn!(Semi) => {|semi| (
+ Vec::new(),
+ None,
+ Some(semi),
+ )}
|
braces!(
tuple!(
many0!(call!(Attribute::parse_inner)),
many0!(syn!(Item))
)
- ) => { Err }
+ ) => {|((inner_attrs, items), brace)| (
+ inner_attrs,
+ Some((brace, items)),
+ None,
+ )}
) >>
- (match content {
- Err(((inner_attrs, items), braces)) => Item {
- ident: id,
- vis: vis,
- attrs: {
- let mut attrs = outer_attrs;
- attrs.extend(inner_attrs);
- attrs
- },
- node: ItemMod {
- mod_token: mod_,
- semi_token: None,
- items: Some((items, braces)),
- }.into(),
+ (Item {
+ attrs: {
+ let mut attrs = outer_attrs;
+ attrs.extend(content_semi.0);
+ attrs
},
- Ok(semi) => Item {
- ident: id,
+ node: ItemMod {
vis: vis,
- attrs: outer_attrs,
- node: ItemMod {
- items: None,
- mod_token: mod_,
- semi_token: Some(semi),
- }.into(),
- },
+ mod_token: mod_,
+ ident: ident,
+ content: content_semi.1,
+ semi: content_semi.2,
+ }.into(),
})
));
@@ -794,12 +802,10 @@
abi: syn!(Abi) >>
items: braces!(many0!(syn!(ForeignItem))) >>
(Item {
- ident: "".into(),
- vis: VisInherited {}.into(),
attrs: attrs,
node: ItemForeignMod {
- brace_token: items.1,
abi: abi,
+ brace_token: items.1,
items: items.0,
}.into(),
})
@@ -817,7 +823,7 @@
attrs: many0!(call!(Attribute::parse_outer)) >>
vis: syn!(Visibility) >>
fn_: syn!(Fn_) >>
- name: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
inputs: parens!(do_parse!(
args: call!(Delimited::parse_terminated) >>
@@ -832,7 +838,7 @@
let ((inputs, variadic), parens) = inputs;
let variadic = variadic.and_then(|v| v);
ForeignItem {
- ident: name,
+ ident: ident,
attrs: attrs,
semi_token: semi,
node: ForeignItemFn {
@@ -859,12 +865,12 @@
vis: syn!(Visibility) >>
static_: syn!(Static) >>
mutability: syn!(Mutability) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
colon: syn!(Colon) >>
ty: syn!(Ty) >>
semi: syn!(Semi) >>
(ForeignItem {
- ident: id,
+ ident: ident,
attrs: attrs,
semi_token: semi,
node: ForeignItemStatic {
@@ -881,76 +887,51 @@
attrs: many0!(call!(Attribute::parse_outer)) >>
vis: syn!(Visibility) >>
type_: syn!(Type) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
where_clause: syn!(WhereClause) >>
eq: syn!(Eq) >>
ty: syn!(Ty) >>
semi: syn!(Semi) >>
(Item {
- ident: id,
- vis: vis,
attrs: attrs,
node: ItemTy {
+ vis: vis,
type_token: type_,
- eq_token: eq,
- semi_token: semi,
- ty: Box::new(ty),
+ ident: ident,
generics: Generics {
where_clause: where_clause,
..generics
},
+ eq_token: eq,
+ ty: Box::new(ty),
+ semi_token: semi,
}.into(),
})
));
- named!(item_struct_or_enum -> Item, map!(
- syn!(DeriveInput),
- |def: DeriveInput| Item {
- ident: def.ident,
- vis: def.vis,
- attrs: def.attrs,
- node: match def.body {
- Body::Enum(data) => {
- ItemEnum {
- variants: data.variants,
- brace_token: data.brace_token,
- enum_token: data.enum_token,
- generics: def.generics,
- }.into()
- }
- Body::Struct(data) => {
- ItemStruct {
- data: data.data,
- struct_token: data.struct_token,
- semi_token: data.semi_token,
- generics: def.generics,
- }.into()
- }
- }
- }
- ));
+ named!(item_struct_or_enum -> Item, map!(syn!(DeriveInput), Into::into));
named!(item_union -> Item, do_parse!(
attrs: many0!(call!(Attribute::parse_outer)) >>
vis: syn!(Visibility) >>
union_: syn!(Union) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
where_clause: syn!(WhereClause) >>
fields: braces!(call!(Delimited::parse_terminated_with,
Field::parse_struct)) >>
(Item {
- ident: id,
- vis: vis,
attrs: attrs,
node: ItemUnion {
+ vis: vis,
union_token: union_,
- data: VariantData::Struct(fields.0, fields.1),
+ ident: ident,
generics: Generics {
where_clause: where_clause,
.. generics
},
+ data: VariantData::Struct(fields.0, fields.1),
}.into(),
})
));
@@ -960,7 +941,7 @@
vis: syn!(Visibility) >>
unsafety: syn!(Unsafety) >>
trait_: syn!(Trait) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
colon: option!(syn!(Colon)) >>
bounds: cond!(colon.is_some(),
@@ -969,19 +950,19 @@
where_clause: syn!(WhereClause) >>
body: braces!(many0!(syn!(TraitItem))) >>
(Item {
- ident: id,
- vis: vis,
attrs: attrs,
node: ItemTrait {
- trait_token: trait_,
- brace_token: body.1,
- colon_token: colon,
+ vis: vis,
unsafety: unsafety,
+ trait_token: trait_,
+ ident: ident,
generics: Generics {
where_clause: where_clause,
.. generics
},
+ colon_token: colon,
supertraits: bounds.unwrap_or_default(),
+ brace_token: body.1,
items: body.0,
}.into(),
})
@@ -996,13 +977,11 @@
dot2: syn!(Dot2) >>
braces: braces!(epsilon!()) >>
(Item {
- ident: "".into(),
- vis: VisInherited {}.into(),
attrs: attrs,
node: ItemDefaultImpl {
unsafety: unsafety,
- path: path,
impl_token: impl_,
+ path: path,
for_token: for_,
dot2_token: dot2,
brace_token: braces.1,
@@ -1025,20 +1004,19 @@
named!(trait_item_const -> TraitItem, do_parse!(
attrs: many0!(call!(Attribute::parse_outer)) >>
const_: syn!(Const) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
colon: syn!(Colon) >>
ty: syn!(Ty) >>
- value: option!(tuple!(syn!(Eq), syn!(Expr))) >>
+ default: option!(tuple!(syn!(Eq), syn!(Expr))) >>
semi: syn!(Semi) >>
(TraitItem {
- ident: id,
attrs: attrs,
node: TraitItemConst {
- ty: ty,
const_token: const_,
+ ident: ident,
colon_token: colon,
- eq_token: value.as_ref().map(|p| Eq((p.0).0)),
- default: value.map(|p| p.1),
+ ty: ty,
+ default: default,
semi_token: semi,
}.into(),
})
@@ -1050,7 +1028,7 @@
unsafety: syn!(Unsafety) >>
abi: option!(syn!(Abi)) >>
fn_: syn!(Fn_) >>
- name: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
inputs: parens!(call!(Delimited::parse_terminated)) >>
ret: syn!(FunctionRetTy) >>
@@ -1066,18 +1044,17 @@
None => (Vec::new(), None),
};
TraitItem {
- ident: name,
attrs: {
let mut attrs = outer_attrs;
attrs.extend(inner_attrs);
attrs
},
node: TraitItemMethod {
- semi_token: semi,
sig: MethodSig {
- unsafety: unsafety,
constness: constness,
+ unsafety: unsafety,
abi: abi,
+ ident: ident,
decl: FnDecl {
inputs: inputs.0,
output: ret,
@@ -1097,6 +1074,7 @@
brace_token: stmts.1,
}
}),
+ semi_token: semi,
}.into(),
}
})
@@ -1105,7 +1083,7 @@
named!(trait_item_type -> TraitItem, do_parse!(
attrs: many0!(call!(Attribute::parse_outer)) >>
type_: syn!(Type) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
colon: option!(syn!(Colon)) >>
bounds: cond!(colon.is_some(),
call!(Delimited::parse_separated_nonempty)
@@ -1113,15 +1091,14 @@
default: option!(tuple!(syn!(Eq), syn!(Ty))) >>
semi: syn!(Semi) >>
(TraitItem {
- ident: id,
attrs: attrs,
node: TraitItemType {
type_token: type_,
+ ident: ident,
colon_token: colon,
- eq_token: default.as_ref().map(|p| Eq((p.0).0)),
bounds: bounds.unwrap_or_default(),
+ default: default,
semi_token: semi,
- default: default.map(|p| p.1),
}.into(),
})
));
@@ -1131,7 +1108,6 @@
mac: syn!(Mac) >>
cond!(!mac.is_braced(), syn!(Semi)) >>
(TraitItem {
- ident: "".into(),
attrs: attrs,
node: TraitItemKind::Macro(mac),
})
@@ -1147,30 +1123,26 @@
polarity: syn!(ImplPolarity) >>
path: syn!(Path) >>
for_: syn!(For) >>
- (polarity, Some(path), Some(for_))
+ (Some((polarity, path, for_)))
)
|
- epsilon!() => { |_| (ImplPolarity::Positive, None, None) }
+ epsilon!() => { |_| None }
) >>
self_ty: syn!(Ty) >>
where_clause: syn!(WhereClause) >>
body: braces!(many0!(syn!(ImplItem))) >>
(Item {
- ident: "".into(),
- vis: VisInherited {}.into(),
attrs: attrs,
node: ItemImpl {
- impl_token: impl_,
- brace_token: body.1,
- for_token: polarity_path.2,
unsafety: unsafety,
- polarity: polarity_path.0,
+ impl_token: impl_,
generics: Generics {
where_clause: where_clause,
.. generics
},
- trait_: polarity_path.1,
+ trait_: polarity_path,
self_ty: Box::new(self_ty),
+ brace_token: body.1,
items: body.0,
}.into(),
})
@@ -1184,7 +1156,7 @@
|
impl_item_type
|
- impl_item_macro
+ impl_item_mac
));
}
@@ -1193,23 +1165,23 @@
vis: syn!(Visibility) >>
defaultness: syn!(Defaultness) >>
const_: syn!(Const) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
colon: syn!(Colon) >>
ty: syn!(Ty) >>
eq: syn!(Eq) >>
value: syn!(Expr) >>
semi: syn!(Semi) >>
(ImplItem {
- ident: id,
- vis: vis,
- defaultness: defaultness,
attrs: attrs,
node: ImplItemConst {
- ty: ty,
- expr: value,
+ vis: vis,
+ defaultness: defaultness,
const_token: const_,
+ ident: ident,
colon_token: colon,
+ ty: ty,
eq_token: eq,
+ expr: value,
semi_token: semi,
}.into(),
})
@@ -1223,7 +1195,7 @@
unsafety: syn!(Unsafety) >>
abi: option!(syn!(Abi)) >>
fn_: syn!(Fn_) >>
- name: syn!(Ident) >>
+ ident: syn!(Ident) >>
generics: syn!(Generics) >>
inputs: parens!(call!(Delimited::parse_terminated)) >>
ret: syn!(FunctionRetTy) >>
@@ -1233,19 +1205,19 @@
call!(Block::parse_within)
)) >>
(ImplItem {
- ident: name,
- vis: vis,
- defaultness: defaultness,
attrs: {
let mut attrs = outer_attrs;
attrs.extend((inner_attrs_stmts.0).0);
attrs
},
node: ImplItemMethod {
+ vis: vis,
+ defaultness: defaultness,
sig: MethodSig {
- unsafety: unsafety,
constness: constness,
+ unsafety: unsafety,
abi: abi,
+ ident: ident,
decl: FnDecl {
fn_token: fn_,
paren_token: inputs.1,
@@ -1272,32 +1244,29 @@
vis: syn!(Visibility) >>
defaultness: syn!(Defaultness) >>
type_: syn!(Type) >>
- id: syn!(Ident) >>
+ ident: syn!(Ident) >>
eq: syn!(Eq) >>
ty: syn!(Ty) >>
semi: syn!(Semi) >>
(ImplItem {
- ident: id,
- vis: vis,
- defaultness: defaultness,
attrs: attrs,
node: ImplItemType {
+ vis: vis,
+ defaultness: defaultness,
type_token: type_,
+ ident: ident,
eq_token: eq,
- semi_token: semi,
ty: ty,
+ semi_token: semi,
}.into(),
})
));
- named!(impl_item_macro -> ImplItem, do_parse!(
+ named!(impl_item_mac -> ImplItem, do_parse!(
attrs: many0!(call!(Attribute::parse_outer)) >>
mac: syn!(Mac) >>
cond!(!mac.is_braced(), syn!(Semi)) >>
(ImplItem {
- ident: "".into(),
- vis: VisInherited {}.into(),
- defaultness: Defaultness::Final,
attrs: attrs,
node: ImplItemKind::Macro(mac),
})
@@ -1340,25 +1309,27 @@
tokens.append_all(self.attrs.outer());
match self.node {
ItemKind::ExternCrate(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.extern_token.to_tokens(tokens);
item.crate_token.to_tokens(tokens);
- item.original.to_tokens(tokens);
- item.as_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
+ if let Some((as_token, ref rename)) = item.rename {
+ as_token.to_tokens(tokens);
+ rename.to_tokens(tokens);
+ }
item.semi_token.to_tokens(tokens);
}
ItemKind::Use(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.use_token.to_tokens(tokens);
item.path.to_tokens(tokens);
item.semi_token.to_tokens(tokens);
}
ItemKind::Static(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.static_token.to_tokens(tokens);
item.mutbl.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
item.eq_token.to_tokens(tokens);
@@ -1366,9 +1337,9 @@
item.semi_token.to_tokens(tokens);
}
ItemKind::Const(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.const_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
item.eq_token.to_tokens(tokens);
@@ -1376,39 +1347,38 @@
item.semi_token.to_tokens(tokens);
}
ItemKind::Fn(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.constness.to_tokens(tokens);
item.unsafety.to_tokens(tokens);
item.abi.to_tokens(tokens);
- NamedDecl(&item.decl, &self.ident).to_tokens(tokens);
+ NamedDecl(&item.decl, item.ident).to_tokens(tokens);
item.block.brace_token.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(&item.block.stmts);
});
}
ItemKind::Mod(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.mod_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- if let Some((ref items, ref brace)) = item.items {
+ item.ident.to_tokens(tokens);
+ if let Some((brace, ref items)) = item.content {
brace.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(items);
});
}
- item.semi_token.to_tokens(tokens);
+ item.semi.to_tokens(tokens);
}
ItemKind::ForeignMod(ref item) => {
- self.vis.to_tokens(tokens);
item.abi.to_tokens(tokens);
item.brace_token.surround(tokens, |tokens| {
tokens.append_all(&item.items);
});
}
ItemKind::Ty(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
item.eq_token.to_tokens(tokens);
@@ -1416,9 +1386,9 @@
item.semi_token.to_tokens(tokens);
}
ItemKind::Enum(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.enum_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
item.brace_token.surround(tokens, |tokens| {
@@ -1426,9 +1396,9 @@
});
}
ItemKind::Struct(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.struct_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
match item.data {
VariantData::Struct(..) => {
@@ -1446,18 +1416,18 @@
item.semi_token.to_tokens(tokens);
}
ItemKind::Union(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.union_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
item.data.to_tokens(tokens);
}
ItemKind::Trait(ref item) => {
- self.vis.to_tokens(tokens);
+ item.vis.to_tokens(tokens);
item.unsafety.to_tokens(tokens);
item.trait_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.colon_token.to_tokens(tokens);
item.supertraits.to_tokens(tokens);
@@ -1478,9 +1448,11 @@
item.unsafety.to_tokens(tokens);
item.impl_token.to_tokens(tokens);
item.generics.to_tokens(tokens);
- item.polarity.to_tokens(tokens);
- item.trait_.to_tokens(tokens);
- item.for_token.to_tokens(tokens);
+ if let Some((polarity, ref path, for_token)) = item.trait_ {
+ polarity.to_tokens(tokens);
+ path.to_tokens(tokens);
+ for_token.to_tokens(tokens);
+ }
item.self_ty.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
item.brace_token.surround(tokens, |tokens| {
@@ -1490,7 +1462,7 @@
ItemKind::Mac(ref mac) => {
mac.path.to_tokens(tokens);
mac.bang_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ mac.ident.to_tokens(tokens);
tokens.append_all(&mac.tokens);
if !mac.is_braced() {
tokens::Semi::default().to_tokens(tokens);
@@ -1540,15 +1512,17 @@
match self.node {
TraitItemKind::Const(ref item) => {
item.const_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- item.eq_token.to_tokens(tokens);
- item.default.to_tokens(tokens);
+ if let Some((eq_token, ref default)) = item.default {
+ eq_token.to_tokens(tokens);
+ default.to_tokens(tokens);
+ }
item.semi_token.to_tokens(tokens);
}
TraitItemKind::Method(ref item) => {
- NamedMethod(&item.sig, &self.ident).to_tokens(tokens);
+ item.sig.to_tokens(tokens);
match item.default {
Some(ref block) => {
block.brace_token.surround(tokens, |tokens| {
@@ -1563,11 +1537,13 @@
}
TraitItemKind::Type(ref item) => {
item.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.colon_token.to_tokens(tokens);
item.bounds.to_tokens(tokens);
- item.eq_token.to_tokens(tokens);
- item.default.to_tokens(tokens);
+ if let Some((eq_token, ref default)) = item.default {
+ eq_token.to_tokens(tokens);
+ default.to_tokens(tokens);
+ }
item.semi_token.to_tokens(tokens);
}
TraitItemKind::Macro(ref mac) => {
@@ -1583,12 +1559,12 @@
impl ToTokens for ImplItem {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
match self.node {
ImplItemKind::Const(ref item) => {
+ item.vis.to_tokens(tokens);
+ item.defaultness.to_tokens(tokens);
item.const_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
item.eq_token.to_tokens(tokens);
@@ -1596,15 +1572,19 @@
item.semi_token.to_tokens(tokens);
}
ImplItemKind::Method(ref item) => {
- NamedMethod(&item.sig, &self.ident).to_tokens(tokens);
+ item.vis.to_tokens(tokens);
+ item.defaultness.to_tokens(tokens);
+ item.sig.to_tokens(tokens);
item.block.brace_token.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(&item.block.stmts);
});
}
ImplItemKind::Type(ref item) => {
+ item.vis.to_tokens(tokens);
+ item.defaultness.to_tokens(tokens);
item.type_token.to_tokens(tokens);
- self.ident.to_tokens(tokens);
+ item.ident.to_tokens(tokens);
item.eq_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
item.semi_token.to_tokens(tokens);
@@ -1612,6 +1592,7 @@
ImplItemKind::Macro(ref mac) => {
mac.to_tokens(tokens);
if !mac.is_braced() {
+ // FIXME needs a span
tokens::Semi::default().to_tokens(tokens);
}
}
@@ -1625,7 +1606,7 @@
self.vis.to_tokens(tokens);
match self.node {
ForeignItemKind::Fn(ref item) => {
- NamedDecl(&item.decl, &self.ident).to_tokens(tokens)
+ NamedDecl(&item.decl, self.ident).to_tokens(tokens)
}
ForeignItemKind::Static(ref item) => {
item.static_token.to_tokens(tokens);
@@ -1639,18 +1620,16 @@
}
}
- struct NamedMethod<'a>(&'a MethodSig, &'a Ident);
-
- impl<'a> ToTokens for NamedMethod<'a> {
+ impl ToTokens for MethodSig {
fn to_tokens(&self, tokens: &mut Tokens) {
- self.0.constness.to_tokens(tokens);
- self.0.unsafety.to_tokens(tokens);
- self.0.abi.to_tokens(tokens);
- NamedDecl(&self.0.decl, self.1).to_tokens(tokens);
+ self.constness.to_tokens(tokens);
+ self.unsafety.to_tokens(tokens);
+ self.abi.to_tokens(tokens);
+ NamedDecl(&self.decl, self.ident).to_tokens(tokens);
}
}
- struct NamedDecl<'a>(&'a FnDecl, &'a Ident);
+ struct NamedDecl<'a>(&'a FnDecl, Ident);
impl<'a> ToTokens for NamedDecl<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
diff --git a/src/lib.rs b/src/lib.rs
index 0519ed1..8e63ac4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,7 @@
#![cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]
extern crate proc_macro2;
+extern crate unicode_xid;
#[cfg(feature = "printing")]
extern crate quote;
diff --git a/src/mac.rs b/src/mac.rs
index 3517ac8..ad8385e 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -9,12 +9,11 @@
/// Represents a macro invocation. The Path indicates which macro
/// is being invoked, and the vector of token-trees contains the source
/// of the macro invocation.
- ///
- /// NB: the additional ident for a `macro_rules`-style macro is actually
- /// stored in the enclosing item. Oog.
pub struct Mac {
pub path: Path,
pub bang_token: tokens::Bang,
+ /// The `example` in `macro_rules! example { ... }`.
+ pub ident: Option<Ident>,
pub tokens: Vec<TokenTree>,
}
}
@@ -147,6 +146,7 @@
(Mac {
path: what,
bang_token: bang,
+ ident: None,
tokens: vec![body],
})
));
diff --git a/src/ty.rs b/src/ty.rs
index 284ffb3..b48eed9 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -101,13 +101,18 @@
pub struct Path {
/// A `::foo` path, is relative to the crate root rather than current
/// module (like paths in an import).
- pub global: bool,
pub leading_colon: Option<tokens::Colon2>,
/// The segments in the path: the things separated by `::`.
pub segments: Delimited<PathSegment, tokens::Colon2>,
}
}
+impl Path {
+ pub fn global(&self) -> bool {
+ self.leading_colon.is_some()
+ }
+}
+
#[cfg(feature = "printing")]
ast_struct! {
pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
@@ -118,7 +123,6 @@
{
fn from(segment: T) -> Self {
Path {
- global: false,
leading_colon: None,
segments: vec![(segment.into(), None)].into(),
}
@@ -147,7 +151,7 @@
fn from(ident: T) -> Self {
PathSegment {
ident: ident.into(),
- parameters: PathParameters::none(),
+ parameters: PathParameters::None,
}
}
}
@@ -157,6 +161,7 @@
///
/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
pub enum PathParameters {
+ None,
/// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
AngleBracketed(AngleBracketedParameterData),
/// The `(A, B)` and `C` in `Foo(A, B) -> C`
@@ -164,13 +169,16 @@
}
}
-impl PathParameters {
- pub fn none() -> Self {
- PathParameters::AngleBracketed(AngleBracketedParameterData::default())
+impl Default for PathParameters {
+ fn default() -> Self {
+ PathParameters::None
}
+}
+impl PathParameters {
pub fn is_empty(&self) -> bool {
match *self {
+ PathParameters::None => true,
PathParameters::AngleBracketed(ref bracketed) => {
bracketed.lifetimes.is_empty() && bracketed.types.is_empty() &&
bracketed.bindings.is_empty()
@@ -182,11 +190,9 @@
ast_struct! {
/// A path like `Foo<'a, T>`
- #[derive(Default)]
pub struct AngleBracketedParameterData {
- pub lt_token: Option<tokens::Lt>,
- pub gt_token: Option<tokens::Gt>,
-
+ pub turbofish: Option<tokens::Colon2>,
+ pub lt_token: tokens::Lt,
/// The lifetime parameters for this path segment.
pub lifetimes: Delimited<Lifetime, tokens::Comma>,
/// The type parameters for this path segment, if present.
@@ -195,6 +201,7 @@
///
/// E.g., `Foo<A=Bar>`.
pub bindings: Delimited<TypeBinding, tokens::Comma>,
+ pub gt_token: tokens::Gt,
}
}
@@ -245,10 +252,9 @@
/// ```
pub struct QSelf {
pub lt_token: tokens::Lt,
- pub gt_token: tokens::Gt,
- pub as_token: Option<tokens::As>,
pub ty: Box<Ty>,
- pub position: usize,
+ pub position: Option<(tokens::As, usize)>,
+ pub gt_token: tokens::Gt,
}
}
@@ -513,7 +519,7 @@
|
do_parse!(
lt: syn!(Lt) >>
- this: map!(syn!(Ty), Box::new) >>
+ this: syn!(Ty) >>
path: option!(do_parse!(
as_: syn!(As) >>
path: syn!(Path) >>
@@ -523,7 +529,7 @@
colon2: syn!(Colon2) >>
rest: call!(Delimited::parse_separated_nonempty) >>
({
- let (pos, path, as_) = match path {
+ let (pos, path) = match path {
Some((as_, mut path)) => {
let pos = path.segments.len();
if !path.segments.is_empty() && !path.segments.trailing_delim() {
@@ -532,22 +538,20 @@
for item in rest {
path.segments.push(item);
}
- (pos, path, Some(as_))
+ (Some((as_, pos)), path)
}
None => {
- (0, Path {
- leading_colon: None,
- global: false,
+ (None, Path {
+ leading_colon: Some(colon2),
segments: rest,
- }, None)
+ })
}
};
(Some(QSelf {
- ty: this,
+ lt_token: lt,
+ ty: Box::new(this),
position: pos,
gt_token: gt,
- lt_token: lt,
- as_token: as_,
}), path)
})
)
@@ -615,12 +619,11 @@
impl Synom for Path {
named!(parse -> Self, do_parse!(
- global: option!(syn!(Colon2)) >>
+ colon: option!(syn!(Colon2)) >>
segments: call!(Delimited::parse_separated_nonempty) >>
(Path {
- global: global.is_some(),
+ leading_colon: colon,
segments: segments,
- leading_colon: global,
})
));
}
@@ -628,7 +631,8 @@
impl Synom for PathSegment {
named!(parse -> Self, alt!(
do_parse!(
- id: option!(syn!(Ident)) >>
+ ident: syn!(Ident) >>
+ turbofish: option!(syn!(Colon2)) >>
lt: syn!(Lt) >>
lifetimes: call!(Delimited::parse_terminated) >>
types: cond!(
@@ -645,14 +649,15 @@
) >>
gt: syn!(Gt) >>
(PathSegment {
- ident: id.unwrap_or_else(|| "".into()),
+ ident: ident,
parameters: PathParameters::AngleBracketed(
AngleBracketedParameterData {
- gt_token: Some(gt),
- lt_token: Some(lt),
+ turbofish: turbofish,
+ lt_token: lt,
lifetimes: lifetimes,
types: types.unwrap_or_default(),
bindings: bindings.unwrap_or_default(),
+ gt_token: gt,
}
),
})
@@ -661,17 +666,17 @@
mod_style_path_segment
));
}
+
named!(ty_no_eq_after -> Ty, terminated!(syn!(Ty), not!(syn!(Eq))));
impl Path {
named!(pub parse_mod_style -> Self, do_parse!(
- global: option!(syn!(Colon2)) >>
+ colon: option!(syn!(Colon2)) >>
segments: call!(Delimited::parse_separated_nonempty_with,
mod_style_path_segment) >>
(Path {
- global: global.is_some(),
+ leading_colon: colon,
segments: segments,
- leading_colon: global,
})
));
}
@@ -840,14 +845,12 @@
};
qself.lt_token.to_tokens(tokens);
qself.ty.to_tokens(tokens);
- if qself.position > 0 {
- qself.as_token.to_tokens(tokens);
+ let mut segments = self.1.segments.iter();
+ if let Some((as_token, pos)) = qself.position {
+ as_token.to_tokens(tokens);
self.1.leading_colon.to_tokens(tokens);
- for (i, segment) in self.1.segments
- .iter()
- .take(qself.position)
- .enumerate() {
- if i == qself.position - 1 {
+ for (i, segment) in (&mut segments).take(pos).enumerate() {
+ if i + 1 == pos {
segment.item().to_tokens(tokens);
qself.gt_token.to_tokens(tokens);
segment.delimiter().to_tokens(tokens);
@@ -857,8 +860,9 @@
}
} else {
qself.gt_token.to_tokens(tokens);
+ self.1.leading_colon.to_tokens(tokens);
}
- for segment in self.1.segments.iter().skip(qself.position) {
+ for segment in segments {
segment.to_tokens(tokens);
}
}
@@ -916,6 +920,7 @@
impl ToTokens for PathParameters {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
+ PathParameters::None => {}
PathParameters::AngleBracketed(ref parameters) => {
parameters.to_tokens(tokens);
}
@@ -928,6 +933,7 @@
impl ToTokens for AngleBracketedParameterData {
fn to_tokens(&self, tokens: &mut Tokens) {
+ self.turbofish.to_tokens(tokens);
self.lt_token.to_tokens(tokens);
self.lifetimes.to_tokens(tokens);
self.types.to_tokens(tokens);