blob: 56560944e08d8849ba1974254eb8991e91a02467 [file] [log] [blame]
David Tolnayf2cfd722017-12-31 18:02:51 -05001use punctuated::Punctuated;
David Tolnayb79ee962016-09-04 09:39:20 -07002use super::*;
David Tolnay2ae520a2017-12-29 11:19:50 -05003use proc_macro2::TokenStream;
4#[cfg(feature = "extra-traits")]
5use std::hash::{Hash, Hasher};
6#[cfg(feature = "extra-traits")]
David Tolnayc43b44e2017-12-30 23:55:54 -05007use tt::TokenStreamHelper;
David Tolnayb79ee962016-09-04 09:39:20 -07008
Alex Crichton62a0a592017-05-22 13:58:53 -07009ast_enum_of_structs! {
10 /// The different kinds of types recognized by the compiler
David Tolnayfd6bf5c2017-11-12 09:41:14 -080011 pub enum Type {
Alex Crichton62a0a592017-05-22 13:58:53 -070012 /// A variable-length array (`[T]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080013 pub Slice(TypeSlice {
David Tolnay32954ef2017-12-26 22:43:16 -050014 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050015 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070016 }),
17 /// A fixed length array (`[T; n]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080018 pub Array(TypeArray {
David Tolnay32954ef2017-12-26 22:43:16 -050019 pub bracket_token: token::Bracket,
David Tolnayeadbda32017-12-29 02:33:47 -050020 pub elem: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080021 pub semi_token: Token![;],
David Tolnayeadbda32017-12-29 02:33:47 -050022 pub len: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070023 }),
24 /// A raw pointer (`*const T` or `*mut T`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080025 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080026 pub star_token: Token![*],
27 pub const_token: Option<Token![const]>,
David Tolnay136aaa32017-12-29 02:37:36 -050028 pub mutability: Option<Token![mut]>,
29 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
31 /// A reference (`&'a T` or `&'a mut T`)
David Tolnay0a89b4d2017-11-13 00:55:45 -080032 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080033 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub lifetime: Option<Lifetime>,
David Tolnay136aaa32017-12-29 02:37:36 -050035 pub mutability: Option<Token![mut]>,
36 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070037 }),
38 /// A bare function (e.g. `fn(usize) -> bool`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080039 pub BareFn(TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -050040 pub unsafety: Option<Token![unsafe]>,
41 pub abi: Option<Abi>,
42 pub fn_token: Token![fn],
43 pub lifetimes: Option<BoundLifetimes>,
44 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050045 pub inputs: Punctuated<BareFnArg, Token![,]>,
David Tolnaybe7a9592017-12-29 02:39:53 -050046 pub variadic: Option<Token![...]>,
47 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -070048 }),
49 /// The never type (`!`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080050 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080051 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070052 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070053 /// A tuple (`(A, B, C, D, ...)`)
David Tolnay05362582017-12-26 01:33:57 -050054 pub Tuple(TypeTuple {
David Tolnay32954ef2017-12-26 22:43:16 -050055 pub paren_token: token::Paren,
David Tolnayf2cfd722017-12-31 18:02:51 -050056 pub elems: Punctuated<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070057 }),
58 /// A path (`module::module::...::Type`), optionally
59 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
60 ///
Nika Layzellc08227a2017-12-04 16:30:17 -050061 /// Type arguments are stored in the Path itself
David Tolnayfd6bf5c2017-11-12 09:41:14 -080062 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -070063 pub qself: Option<QSelf>,
64 pub path: Path,
65 }),
66 /// A trait object type `Bound1 + Bound2 + Bound3`
67 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080068 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -050069 pub dyn_token: Option<Token![dyn]>,
David Tolnayf2cfd722017-12-31 18:02:51 -050070 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070071 }),
72 /// An `impl Bound1 + Bound2 + Bound3` type
73 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080074 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -080075 pub impl_token: Token![impl],
David Tolnayf2cfd722017-12-31 18:02:51 -050076 pub bounds: Punctuated<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
78 /// No-op; kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080079 pub Paren(TypeParen {
David Tolnay32954ef2017-12-26 22:43:16 -050080 pub paren_token: token::Paren,
David Tolnayeadbda32017-12-29 02:33:47 -050081 pub elem: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070082 }),
Michael Layzell93c36282017-06-04 20:43:14 -040083 /// No-op: kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080084 pub Group(TypeGroup {
David Tolnay32954ef2017-12-26 22:43:16 -050085 pub group_token: token::Group,
David Tolnayeadbda32017-12-29 02:33:47 -050086 pub elem: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -040087 }),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080088 /// TypeKind::Infer means the type should be inferred instead of it having been
Alex Crichton62a0a592017-05-22 13:58:53 -070089 /// specified. This can appear anywhere in a type.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080090 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -080091 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070093 /// A macro in the type position.
David Tolnay323279a2017-12-29 11:26:32 -050094 pub Macro(TypeMacro {
95 pub mac: Macro,
96 }),
David Tolnay2ae520a2017-12-29 11:19:50 -050097 pub Verbatim(TypeVerbatim #manual_extra_traits {
98 pub tts: TokenStream,
99 }),
100 }
101}
102
103#[cfg(feature = "extra-traits")]
104impl Eq for TypeVerbatim {}
105
106#[cfg(feature = "extra-traits")]
107impl PartialEq for TypeVerbatim {
108 fn eq(&self, other: &Self) -> bool {
109 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
110 }
111}
112
113#[cfg(feature = "extra-traits")]
114impl Hash for TypeVerbatim {
115 fn hash<H>(&self, state: &mut H)
116 where
117 H: Hasher,
118 {
119 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 }
121}
122
123ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700124 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -0700125 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 /// It's represented as a sequence of identifiers,
127 /// along with a bunch of supporting information.
128 ///
129 /// E.g. `std::cmp::PartialEq`
130 pub struct Path {
131 /// A `::foo` path, is relative to the crate root rather than current
132 /// module (like paths in an import).
David Tolnayf8db7ba2017-11-11 22:52:16 -0800133 pub leading_colon: Option<Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 /// The segments in the path: the things separated by `::`.
David Tolnayf2cfd722017-12-31 18:02:51 -0500135 pub segments: Punctuated<PathSegment, Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 }
David Tolnayb79ee962016-09-04 09:39:20 -0700137}
138
David Tolnay570695e2017-06-03 16:15:13 -0700139impl Path {
140 pub fn global(&self) -> bool {
141 self.leading_colon.is_some()
142 }
143}
144
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700145#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -0400146#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
147#[cfg_attr(feature = "clone-impls", derive(Clone))]
148pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700149
David Tolnaydaaf7742016-10-03 11:11:43 -0700150impl<T> From<T> for Path
David Tolnay51382052017-12-27 13:46:21 -0500151where
152 T: Into<PathSegment>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700153{
David Tolnay84aa0752016-10-02 23:01:13 -0700154 fn from(segment: T) -> Self {
David Tolnay660fd1f2017-12-31 01:52:57 -0500155 let mut path = Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700156 leading_colon: None,
David Tolnayf2cfd722017-12-31 18:02:51 -0500157 segments: Punctuated::new(),
David Tolnay660fd1f2017-12-31 01:52:57 -0500158 };
David Tolnaya0834b42018-01-01 21:30:02 -0800159 path.segments.push_item(segment.into());
David Tolnay660fd1f2017-12-31 01:52:57 -0500160 path
David Tolnay84aa0752016-10-02 23:01:13 -0700161 }
162}
163
Alex Crichton62a0a592017-05-22 13:58:53 -0700164ast_struct! {
165 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
166 ///
167 /// E.g. `std`, `String` or `Box<T>`
168 pub struct PathSegment {
169 /// The identifier portion of this path segment.
170 pub ident: Ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500171 /// Type/lifetime arguments attached to this path. They come in
Alex Crichton62a0a592017-05-22 13:58:53 -0700172 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
173 /// this is more than just simple syntactic sugar; the use of
174 /// parens affects the region binding rules, so we preserve the
175 /// distinction.
Nika Layzellc08227a2017-12-04 16:30:17 -0500176 pub arguments: PathArguments,
Alex Crichton62a0a592017-05-22 13:58:53 -0700177 }
David Tolnayb79ee962016-09-04 09:39:20 -0700178}
179
David Tolnaydaaf7742016-10-03 11:11:43 -0700180impl<T> From<T> for PathSegment
David Tolnay51382052017-12-27 13:46:21 -0500181where
182 T: Into<Ident>,
David Tolnaydaaf7742016-10-03 11:11:43 -0700183{
David Tolnay84aa0752016-10-02 23:01:13 -0700184 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700185 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700186 ident: ident.into(),
Nika Layzellc08227a2017-12-04 16:30:17 -0500187 arguments: PathArguments::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700188 }
189 }
190}
191
Alex Crichton62a0a592017-05-22 13:58:53 -0700192ast_enum! {
Nika Layzellc08227a2017-12-04 16:30:17 -0500193 /// Arguments of a path segment.
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 ///
195 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
Nika Layzellc08227a2017-12-04 16:30:17 -0500196 pub enum PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700197 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500199 AngleBracketed(AngleBracketedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700200 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500201 Parenthesized(ParenthesizedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700202 }
David Tolnayb79ee962016-09-04 09:39:20 -0700203}
204
Nika Layzellc08227a2017-12-04 16:30:17 -0500205impl Default for PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700206 fn default() -> Self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500207 PathArguments::None
David Tolnayb79ee962016-09-04 09:39:20 -0700208 }
David Tolnay570695e2017-06-03 16:15:13 -0700209}
David Tolnay5332d4b2016-10-30 14:25:22 -0700210
Nika Layzellc08227a2017-12-04 16:30:17 -0500211impl PathArguments {
David Tolnay5332d4b2016-10-30 14:25:22 -0700212 pub fn is_empty(&self) -> bool {
213 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500214 PathArguments::None => true,
215 PathArguments::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
216 PathArguments::Parenthesized(_) => false,
David Tolnay5332d4b2016-10-30 14:25:22 -0700217 }
218 }
David Tolnayb79ee962016-09-04 09:39:20 -0700219}
220
Nika Layzell357885a2017-12-04 15:47:07 -0500221ast_enum! {
222 /// A individual generic argument, like `'a`, `T`, or `Item=T`.
Nika Layzellc08227a2017-12-04 16:30:17 -0500223 pub enum GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500224 /// The lifetime parameters for this path segment.
225 Lifetime(Lifetime),
226 /// The type parameters for this path segment, if present.
227 Type(Type),
228 /// Bindings (equality constraints) on associated types, if present.
229 ///
230 /// E.g., `Foo<A=Bar>`.
David Tolnay506e43a2017-12-29 11:34:36 -0500231 Binding(Binding),
Nika Layzellc680e612017-12-04 19:07:20 -0500232 /// Const expression. Must be inside of a block.
233 ///
234 /// NOTE: Identity expressions are represented as Type arguments, as
235 /// they are indistinguishable syntactically.
Nika Layzellce37f332017-12-05 12:01:22 -0500236 Const(Expr),
Nika Layzell357885a2017-12-04 15:47:07 -0500237 }
238}
239
Alex Crichton62a0a592017-05-22 13:58:53 -0700240ast_struct! {
241 /// A path like `Foo<'a, T>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500242 pub struct AngleBracketedGenericArguments {
David Tolnay2d4e08a2017-12-28 23:54:07 -0500243 pub colon2_token: Option<Token![::]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800244 pub lt_token: Token![<],
David Tolnayf2cfd722017-12-31 18:02:51 -0500245 pub args: Punctuated<GenericArgument, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800246 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700247 }
248}
249
250ast_struct! {
251 /// Bind a type to an associated type: `A=Foo`.
David Tolnay506e43a2017-12-29 11:34:36 -0500252 pub struct Binding {
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800254 pub eq_token: Token![=],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800255 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700256 }
257}
258
Alex Crichton62a0a592017-05-22 13:58:53 -0700259ast_struct! {
260 /// A path like `Foo(A,B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500261 pub struct ParenthesizedGenericArguments {
David Tolnay32954ef2017-12-26 22:43:16 -0500262 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700263 /// `(A, B)`
David Tolnayf2cfd722017-12-31 18:02:51 -0500264 pub inputs: Punctuated<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700265 /// `C`
David Tolnayf93b90d2017-11-11 19:21:26 -0800266 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700267 }
268}
269
270ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700271 /// The explicit Self type in a "qualified path". The actual
272 /// path, including the trait and the associated item, is stored
273 /// separately. `position` represents the index of the associated
274 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700275 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500276 /// ```text
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 /// <Vec<T> as a::b::Trait>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500278 /// ^~~~~~ ~~~~~~~~~~~~~~^
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700280 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 /// <Vec<T>>::AssociatedItem
David Tolnaybcf26022017-12-25 22:10:52 -0500282 /// ^~~~~~ ^
Alex Crichton62a0a592017-05-22 13:58:53 -0700283 /// ty position = 0
284 /// ```
285 pub struct QSelf {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800286 pub lt_token: Token![<],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800287 pub ty: Box<Type>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400288 pub position: usize,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800289 pub as_token: Option<Token![as]>,
290 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 }
292}
293
294ast_struct! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700295 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800296 pub extern_token: Token![extern],
David Tolnayd5125762017-12-29 02:42:17 -0500297 pub name: Option<Lit>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700298 }
299}
300
301ast_struct! {
302 /// An argument in a function type.
303 ///
304 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
305 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800306 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800307 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 }
309}
310
Alex Crichton23a15f62017-08-28 12:34:23 -0700311ast_enum! {
312 /// Names of arguments in the `BareFnArg` structure
313 pub enum BareFnArgName {
314 /// Argument with the provided name
315 Named(Ident),
316 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800317 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700318 }
319}
Alex Crichton62a0a592017-05-22 13:58:53 -0700320
321ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800322 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700323 /// Return type is not specified.
324 ///
325 /// Functions default to `()` and
326 /// closures default to inference. Span points to where return
327 /// type would be inserted.
328 Default,
329 /// Everything else
David Tolnay4a3f59a2017-12-28 21:21:12 -0500330 Type(Token![->], Box<Type>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700331 }
David Tolnayb79ee962016-09-04 09:39:20 -0700332}
333
David Tolnay86eca752016-09-04 11:26:41 -0700334#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700335pub mod parsing {
336 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400337 use synom::Synom;
David Tolnayda4049b2016-09-04 10:59:23 -0700338
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800339 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400340 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700341
Alex Crichton954046c2017-05-30 21:49:42 -0700342 fn description() -> Option<&'static str> {
343 Some("type")
344 }
345 }
David Tolnay0047c712016-12-21 21:59:25 -0500346
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800347 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400348 /// In some positions, types may not contain the `+` character, to
349 /// disambiguate them. For example in the expression `1 as T`, T may not
350 /// contain a `+` character.
351 ///
352 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400353 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400354 }
355
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800356 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
357 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400358 |
David Tolnay05362582017-12-26 01:33:57 -0500359 // must be before TypeTuple
David Tolnay0a169d42017-12-29 17:57:29 -0500360 call!(TypeParen::parse, allow_plus) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400361 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500362 // must be before TypePath
David Tolnay323279a2017-12-29 11:26:32 -0500363 syn!(TypeMacro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400364 |
David Tolnay7d38c7e2017-12-25 22:31:50 -0500365 // must be before TypeTraitObject
366 call!(TypePath::parse, allow_plus) => { Type::Path }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400367 |
David Tolnay0a169d42017-12-29 17:57:29 -0500368 // Don't try parsing more than one trait bound if we aren't allowing it.
369 // must be before TypeTuple
370 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
371 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800372 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400373 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800374 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400375 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800376 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400377 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800378 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400379 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800380 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400381 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800382 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400383 |
David Tolnay05362582017-12-26 01:33:57 -0500384 syn!(TypeTuple) => { Type::Tuple }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400385 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800386 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700387 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800388 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400389 ));
390
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800391 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400392 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800393 brackets!(syn!(Type)),
David Tolnay8875fca2017-12-31 13:52:37 -0500394 |(b, ty)| TypeSlice {
David Tolnayeadbda32017-12-29 02:33:47 -0500395 elem: Box::new(ty),
Michael Layzell92639a52017-06-01 00:07:44 -0400396 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700397 }
Michael Layzell92639a52017-06-01 00:07:44 -0400398 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800399
400 fn description() -> Option<&'static str> {
401 Some("slice type")
402 }
Alex Crichton954046c2017-05-30 21:49:42 -0700403 }
David Tolnayb79ee962016-09-04 09:39:20 -0700404
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800405 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400406 named!(parse -> Self, map!(
407 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800408 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800409 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400410 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700411 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400412 )),
David Tolnay8875fca2017-12-31 13:52:37 -0500413 |(brackets, (elem, semi, len))| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800414 TypeArray {
David Tolnayeadbda32017-12-29 02:33:47 -0500415 elem: Box::new(elem),
416 len: len,
Michael Layzell92639a52017-06-01 00:07:44 -0400417 bracket_token: brackets,
418 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700419 }
420 }
Michael Layzell92639a52017-06-01 00:07:44 -0400421 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800422
423 fn description() -> Option<&'static str> {
424 Some("array type")
425 }
Alex Crichton954046c2017-05-30 21:49:42 -0700426 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700427
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800428 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400429 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800430 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400431 mutability: alt!(
David Tolnay24237fb2017-12-29 02:15:26 -0500432 keyword!(const) => { |c| (None, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400433 |
David Tolnay24237fb2017-12-29 02:15:26 -0500434 keyword!(mut) => { |m| (Some(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400435 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800436 target: call!(Type::without_plus) >>
437 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400438 const_token: mutability.1,
439 star_token: star,
David Tolnay136aaa32017-12-29 02:37:36 -0500440 mutability: mutability.0,
441 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400442 })
443 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800444
445 fn description() -> Option<&'static str> {
446 Some("raw pointer type")
447 }
Alex Crichton954046c2017-05-30 21:49:42 -0700448 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700449
David Tolnay0a89b4d2017-11-13 00:55:45 -0800450 impl Synom for TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400451 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800452 amp: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400453 life: option!(syn!(Lifetime)) >>
David Tolnay24237fb2017-12-29 02:15:26 -0500454 mutability: option!(keyword!(mut)) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400455 // & binds tighter than +, so we don't allow + here.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800456 target: call!(Type::without_plus) >>
David Tolnay0a89b4d2017-11-13 00:55:45 -0800457 (TypeReference {
Michael Layzell92639a52017-06-01 00:07:44 -0400458 lifetime: life,
David Tolnay136aaa32017-12-29 02:37:36 -0500459 mutability: mutability,
460 elem: Box::new(target),
Michael Layzell92639a52017-06-01 00:07:44 -0400461 and_token: amp,
462 })
463 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800464
465 fn description() -> Option<&'static str> {
466 Some("reference type")
467 }
Alex Crichton954046c2017-05-30 21:49:42 -0700468 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700469
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800470 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400471 named!(parse -> Self, do_parse!(
472 lifetimes: option!(syn!(BoundLifetimes)) >>
David Tolnay9b258702017-12-29 02:24:41 -0500473 unsafety: option!(keyword!(unsafe)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400474 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800475 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400476 parens: parens!(do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500477 inputs: call!(Punctuated::parse_terminated) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500478 variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400479 (inputs, variadic)
480 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800481 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800482 (TypeBareFn {
David Tolnaybe7a9592017-12-29 02:39:53 -0500483 unsafety: unsafety,
484 abi: abi,
485 lifetimes: lifetimes,
486 output: output,
David Tolnay8875fca2017-12-31 13:52:37 -0500487 variadic: (parens.1).1,
David Tolnaybe7a9592017-12-29 02:39:53 -0500488 fn_token: fn_,
David Tolnay8875fca2017-12-31 13:52:37 -0500489 paren_token: parens.0,
490 inputs: (parens.1).0,
Michael Layzell92639a52017-06-01 00:07:44 -0400491 })
492 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800493
494 fn description() -> Option<&'static str> {
495 Some("`fn` type")
496 }
Alex Crichton954046c2017-05-30 21:49:42 -0700497 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700498
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800499 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400500 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800501 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800502 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400503 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800504
505 fn description() -> Option<&'static str> {
506 Some("never type: `!`")
507 }
Alex Crichton954046c2017-05-30 21:49:42 -0700508 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700509
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800510 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700511 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800512 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800513 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700514 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800515
516 fn description() -> Option<&'static str> {
517 Some("inferred type: `_`")
518 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700519 }
520
David Tolnay05362582017-12-26 01:33:57 -0500521 impl Synom for TypeTuple {
Michael Layzell92639a52017-06-01 00:07:44 -0400522 named!(parse -> Self, do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500523 data: parens!(Punctuated::parse_terminated) >>
David Tolnay05362582017-12-26 01:33:57 -0500524 (TypeTuple {
David Tolnay8875fca2017-12-31 13:52:37 -0500525 paren_token: data.0,
526 elems: data.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400527 })
528 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800529
530 fn description() -> Option<&'static str> {
531 Some("tuple type")
532 }
Alex Crichton954046c2017-05-30 21:49:42 -0700533 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700534
David Tolnay323279a2017-12-29 11:26:32 -0500535 impl Synom for TypeMacro {
536 named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac }));
537 }
538
David Tolnay0a169d42017-12-29 17:57:29 -0500539 impl Synom for TypePath {
540 named!(parse -> Self, call!(Self::parse, false));
541 }
542
David Tolnay7d38c7e2017-12-25 22:31:50 -0500543 impl TypePath {
544 named!(parse(allow_plus: bool) -> Self, do_parse!(
545 qpath: qpath >>
David Tolnay660fd1f2017-12-31 01:52:57 -0500546 parenthesized: option!(cond_reduce!(
David Tolnay7d38c7e2017-12-25 22:31:50 -0500547 qpath.1.segments.last().unwrap().item().arguments.is_empty(),
David Tolnay660fd1f2017-12-31 01:52:57 -0500548 syn!(ParenthesizedGenericArguments)
549 )) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500550 cond!(allow_plus, not!(punct!(+))) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500551 ({
552 let (qself, mut path) = qpath;
David Tolnay660fd1f2017-12-31 01:52:57 -0500553 if let Some(parenthesized) = parenthesized {
David Tolnay7d38c7e2017-12-25 22:31:50 -0500554 let parenthesized = PathArguments::Parenthesized(parenthesized);
555 path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
556 }
557 TypePath { qself: qself, path: path }
558 })
559 ));
560 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700561
David Tolnay9636c052016-10-02 17:11:17 -0700562 named!(pub qpath -> (Option<QSelf>, Path), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700563 map!(syn!(Path), |p| (None, p))
David Tolnay9636c052016-10-02 17:11:17 -0700564 |
565 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800566 lt: punct!(<) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800567 this: syn!(Type) >>
David Tolnay7d38c7e2017-12-25 22:31:50 -0500568 path: option!(tuple!(keyword!(as), syn!(Path))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800569 gt: punct!(>) >>
570 colon2: punct!(::) >>
David Tolnayf2cfd722017-12-31 18:02:51 -0500571 rest: call!(Punctuated::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700572 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400573 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700574 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700575 let pos = path.segments.len();
David Tolnaya0834b42018-01-01 21:30:02 -0800576 path.segments.push_punct(colon2);
David Tolnay6eff4da2018-01-01 20:27:45 -0800577 path.segments.extend(rest.into_elements());
Michael Layzell3936ceb2017-07-08 00:28:36 -0400578 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700579 }
580 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400581 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700582 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700583 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700584 })
David Tolnay9636c052016-10-02 17:11:17 -0700585 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700586 };
587 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700588 lt_token: lt,
589 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700590 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400591 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700592 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700593 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700594 })
595 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700596 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800597 map!(keyword!(self), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700598 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700599
Nika Layzellc08227a2017-12-04 16:30:17 -0500600 impl Synom for ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400601 named!(parse -> Self, do_parse!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500602 data: parens!(Punctuated::parse_terminated) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800603 output: syn!(ReturnType) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500604 (ParenthesizedGenericArguments {
David Tolnay8875fca2017-12-31 13:52:37 -0500605 paren_token: data.0,
606 inputs: data.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400607 output: output,
608 })
609 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800610
611 fn description() -> Option<&'static str> {
612 Some("parenthesized generic arguments: `Foo(A, B, ..) -> T`")
613 }
Alex Crichton954046c2017-05-30 21:49:42 -0700614 }
615
David Tolnayf93b90d2017-11-11 19:21:26 -0800616 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400617 named!(parse -> Self, alt!(
618 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800619 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800620 ty: syn!(Type) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -0500621 (ReturnType::Type(arrow, Box::new(ty)))
Michael Layzell92639a52017-06-01 00:07:44 -0400622 )
623 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800624 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400625 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800626
627 fn description() -> Option<&'static str> {
628 Some("return type")
629 }
Alex Crichton954046c2017-05-30 21:49:42 -0700630 }
631
David Tolnay0a169d42017-12-29 17:57:29 -0500632 impl Synom for TypeTraitObject {
633 named!(parse -> Self, call!(Self::parse, true));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800634
635 fn description() -> Option<&'static str> {
636 Some("trait object type")
637 }
David Tolnay0a169d42017-12-29 17:57:29 -0500638 }
639
David Tolnay7d38c7e2017-12-25 22:31:50 -0500640 impl TypeTraitObject {
David Tolnay0a169d42017-12-29 17:57:29 -0500641 named!(pub without_plus -> Self, call!(Self::parse, false));
642
David Tolnay7d38c7e2017-12-25 22:31:50 -0500643 // Only allow multiple trait references if allow_plus is true.
644 named!(parse(allow_plus: bool) -> Self, do_parse!(
645 dyn_token: option!(keyword!(dyn)) >>
646 bounds: alt!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500647 cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty)
David Tolnay7d38c7e2017-12-25 22:31:50 -0500648 |
David Tolnay660fd1f2017-12-31 01:52:57 -0500649 syn!(TypeParamBound) => {|x| {
David Tolnayf2cfd722017-12-31 18:02:51 -0500650 let mut bounds = Punctuated::new();
David Tolnaya0834b42018-01-01 21:30:02 -0800651 bounds.push_item(x);
David Tolnayf2cfd722017-12-31 18:02:51 -0500652 bounds
David Tolnay660fd1f2017-12-31 01:52:57 -0500653 }}
David Tolnay7d38c7e2017-12-25 22:31:50 -0500654 ) >>
655 (TypeTraitObject {
656 dyn_token: dyn_token,
657 bounds: bounds,
658 })
659 ));
660 }
David Tolnay6414da72016-10-08 00:55:17 -0700661
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800662 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400663 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800664 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400665 // NOTE: rust-lang/rust#34511 includes discussion about whether or
666 // not + should be allowed in ImplTrait directly without ().
David Tolnayf2cfd722017-12-31 18:02:51 -0500667 elem: call!(Punctuated::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800668 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400669 impl_token: impl_,
670 bounds: elem,
671 })
672 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800673
674 fn description() -> Option<&'static str> {
675 Some("`impl Trait` type")
676 }
Alex Crichton954046c2017-05-30 21:49:42 -0700677 }
David Tolnayb79ee962016-09-04 09:39:20 -0700678
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800679 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400680 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800681 data: grouped!(syn!(Type)) >>
682 (TypeGroup {
David Tolnay8875fca2017-12-31 13:52:37 -0500683 group_token: data.0,
684 elem: Box::new(data.1),
Michael Layzell93c36282017-06-04 20:43:14 -0400685 })
686 ));
687 }
688
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800689 impl Synom for TypeParen {
David Tolnay0a169d42017-12-29 17:57:29 -0500690 named!(parse -> Self, call!(Self::parse, false));
691 }
692
693 impl TypeParen {
694 named!(parse(allow_plus: bool) -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800695 data: parens!(syn!(Type)) >>
David Tolnaydc03aec2017-12-30 01:54:18 -0500696 cond!(allow_plus, not!(punct!(+))) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800697 (TypeParen {
David Tolnay8875fca2017-12-31 13:52:37 -0500698 paren_token: data.0,
699 elem: Box::new(data.1),
Michael Layzell92639a52017-06-01 00:07:44 -0400700 })
701 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700702 }
David Tolnayb79ee962016-09-04 09:39:20 -0700703
Alex Crichton954046c2017-05-30 21:49:42 -0700704 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400705 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800706 colon: option!(punct!(::)) >>
David Tolnayf2cfd722017-12-31 18:02:51 -0500707 segments: call!(Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty) >>
David Tolnaye45b59f2017-12-25 18:44:49 -0500708 cond_reduce!(segments.first().map_or(true, |seg| seg.item().ident != "dyn"), epsilon!()) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400709 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700710 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400711 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400712 })
713 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700714
715 fn description() -> Option<&'static str> {
716 Some("path")
717 }
Alex Crichton954046c2017-05-30 21:49:42 -0700718 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700719
Nika Layzellc680e612017-12-04 19:07:20 -0500720 #[cfg(not(feature = "full"))]
Nika Layzellc08227a2017-12-04 16:30:17 -0500721 impl Synom for GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500722 named!(parse -> Self, alt!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500723 call!(ty_no_eq_after) => { GenericArgument::Type }
Nika Layzell357885a2017-12-04 15:47:07 -0500724 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500725 syn!(Lifetime) => { GenericArgument::Lifetime }
Nika Layzell357885a2017-12-04 15:47:07 -0500726 |
David Tolnay506e43a2017-12-29 11:34:36 -0500727 syn!(Binding) => { GenericArgument::Binding }
Nika Layzell357885a2017-12-04 15:47:07 -0500728 ));
729 }
730
Nika Layzellc680e612017-12-04 19:07:20 -0500731 #[cfg(feature = "full")]
732 impl Synom for GenericArgument {
733 named!(parse -> Self, alt!(
734 call!(ty_no_eq_after) => { GenericArgument::Type }
735 |
736 syn!(Lifetime) => { GenericArgument::Lifetime }
737 |
David Tolnay506e43a2017-12-29 11:34:36 -0500738 syn!(Binding) => { GenericArgument::Binding }
Nika Layzellc680e612017-12-04 19:07:20 -0500739 |
David Tolnay3bc597f2017-12-31 02:31:11 -0500740 syn!(ExprLit) => { |l| GenericArgument::Const(Expr::Lit(l)) }
Nika Layzellce37f332017-12-05 12:01:22 -0500741 |
David Tolnay3bc597f2017-12-31 02:31:11 -0500742 syn!(ExprBlock) => { |b| GenericArgument::Const(Expr::Block(b)) }
Nika Layzellc680e612017-12-04 19:07:20 -0500743 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800744
745 fn description() -> Option<&'static str> {
746 Some("generic argument")
747 }
Nika Layzellc680e612017-12-04 19:07:20 -0500748 }
749
Nika Layzellc08227a2017-12-04 16:30:17 -0500750 impl Synom for AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500751 named!(parse -> Self, do_parse!(
David Tolnay2d4e08a2017-12-28 23:54:07 -0500752 colon2: option!(punct!(::)) >>
Nika Layzell357885a2017-12-04 15:47:07 -0500753 lt: punct!(<) >>
David Tolnayf2cfd722017-12-31 18:02:51 -0500754 args: call!(Punctuated::parse_terminated) >>
Nika Layzell357885a2017-12-04 15:47:07 -0500755 gt: punct!(>) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500756 (AngleBracketedGenericArguments {
David Tolnay2d4e08a2017-12-28 23:54:07 -0500757 colon2_token: colon2,
Nika Layzell357885a2017-12-04 15:47:07 -0500758 lt_token: lt,
759 args: args,
760 gt_token: gt,
761 })
762 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800763
764 fn description() -> Option<&'static str> {
765 Some("angle bracketed generic arguments")
766 }
Nika Layzell357885a2017-12-04 15:47:07 -0500767 }
768
Alex Crichton954046c2017-05-30 21:49:42 -0700769 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400770 named!(parse -> Self, alt!(
771 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700772 ident: syn!(Ident) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500773 arguments: syn!(AngleBracketedGenericArguments) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400774 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700775 ident: ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500776 arguments: PathArguments::AngleBracketed(arguments),
Michael Layzell92639a52017-06-01 00:07:44 -0400777 })
778 )
779 |
780 mod_style_path_segment
781 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800782
783 fn description() -> Option<&'static str> {
784 Some("path segment")
785 }
Alex Crichton954046c2017-05-30 21:49:42 -0700786 }
David Tolnay570695e2017-06-03 16:15:13 -0700787
David Tolnaydc03aec2017-12-30 01:54:18 -0500788 named!(pub ty_no_eq_after -> Type, do_parse!(
789 ty: syn!(Type) >>
790 not!(punct!(=)) >>
791 (ty)
792 ));
David Tolnay9d8f1972016-09-04 11:58:48 -0700793
Alex Crichton954046c2017-05-30 21:49:42 -0700794 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400795 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800796 colon: option!(punct!(::)) >>
David Tolnayf2cfd722017-12-31 18:02:51 -0500797 segments: call!(Punctuated::parse_separated_nonempty_with,
Michael Layzell92639a52017-06-01 00:07:44 -0400798 mod_style_path_segment) >>
799 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700800 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400801 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400802 })
803 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700804 }
Arnavionf2dada12017-04-20 23:55:20 -0700805
806 named!(mod_style_path_segment -> PathSegment, alt!(
David Tolnay5f332a92017-12-26 00:42:45 -0500807 syn!(Ident) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700808 |
David Tolnay5f332a92017-12-26 00:42:45 -0500809 keyword!(super) => { Into::into }
810 |
811 keyword!(self) => { Into::into }
812 |
813 keyword!(Self) => { Into::into }
814 |
815 keyword!(crate) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700816 ));
817
David Tolnay506e43a2017-12-29 11:34:36 -0500818 impl Synom for Binding {
Michael Layzell92639a52017-06-01 00:07:44 -0400819 named!(parse -> Self, do_parse!(
820 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800821 eq: punct!(=) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800822 ty: syn!(Type) >>
David Tolnay506e43a2017-12-29 11:34:36 -0500823 (Binding {
Michael Layzell92639a52017-06-01 00:07:44 -0400824 ident: id,
825 eq_token: eq,
826 ty: ty,
827 })
828 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800829
830 fn description() -> Option<&'static str> {
831 Some("associated type binding")
832 }
Alex Crichton954046c2017-05-30 21:49:42 -0700833 }
834
Alex Crichton954046c2017-05-30 21:49:42 -0700835 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400836 named!(parse -> Self, do_parse!(
837 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700838 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800839 not!(punct!(::)) >>
840 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400841 (name, colon)
842 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800843 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400844 (BareFnArg {
845 name: name,
846 ty: ty,
847 })
848 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800849
850 fn description() -> Option<&'static str> {
851 Some("function type argument")
852 }
Alex Crichton954046c2017-05-30 21:49:42 -0700853 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700854
Alex Crichton23a15f62017-08-28 12:34:23 -0700855 impl Synom for BareFnArgName {
856 named!(parse -> Self, alt!(
857 map!(syn!(Ident), BareFnArgName::Named)
858 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800859 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700860 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800861
862 fn description() -> Option<&'static str> {
863 Some("function argument name")
864 }
Alex Crichton23a15f62017-08-28 12:34:23 -0700865 }
866
Alex Crichton954046c2017-05-30 21:49:42 -0700867 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400868 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800869 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400870 // TODO: this parses all literals, not just strings
871 name: option!(syn!(Lit)) >>
872 (Abi {
873 extern_token: extern_,
David Tolnayd5125762017-12-29 02:42:17 -0500874 name: name,
Michael Layzell92639a52017-06-01 00:07:44 -0400875 })
876 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800877
878 fn description() -> Option<&'static str> {
879 Some("ABI qualifier")
880 }
Alex Crichton954046c2017-05-30 21:49:42 -0700881 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700882}
David Tolnay87d0b442016-09-04 11:52:12 -0700883
884#[cfg(feature = "printing")]
885mod printing {
886 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500887 use quote::{ToTokens, Tokens};
David Tolnay87d0b442016-09-04 11:52:12 -0700888
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800889 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700890 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700891 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500892 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700893 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700894 }
895 }
896
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800897 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700898 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700899 self.bracket_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500900 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700901 self.semi_token.to_tokens(tokens);
David Tolnayeadbda32017-12-29 02:33:47 -0500902 self.len.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700903 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700904 }
905 }
906
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800907 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700908 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700909 self.star_token.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500910 match self.mutability {
David Tolnay24237fb2017-12-29 02:15:26 -0500911 Some(ref tok) => tok.to_tokens(tokens),
912 None => {
Alex Crichton259ee532017-07-14 06:51:02 -0700913 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400914 }
915 }
David Tolnay136aaa32017-12-29 02:37:36 -0500916 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700917 }
918 }
919
David Tolnay0a89b4d2017-11-13 00:55:45 -0800920 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700921 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700922 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700923 self.lifetime.to_tokens(tokens);
David Tolnay136aaa32017-12-29 02:37:36 -0500924 self.mutability.to_tokens(tokens);
925 self.elem.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700926 }
927 }
928
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800929 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700930 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaybe7a9592017-12-29 02:39:53 -0500931 self.lifetimes.to_tokens(tokens);
932 self.unsafety.to_tokens(tokens);
933 self.abi.to_tokens(tokens);
934 self.fn_token.to_tokens(tokens);
935 self.paren_token.surround(tokens, |tokens| {
936 self.inputs.to_tokens(tokens);
937 if let Some(ref variadic) = self.variadic {
938 if !self.inputs.empty_or_trailing() {
939 let span = variadic.0[0];
940 <Token![,]>::new(span).to_tokens(tokens);
941 }
942 variadic.to_tokens(tokens);
943 }
944 });
945 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700946 }
947 }
948
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800949 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700950 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700951 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700952 }
953 }
954
David Tolnay05362582017-12-26 01:33:57 -0500955 impl ToTokens for TypeTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -0700956 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700957 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -0500958 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700959 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700960 }
961 }
962
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800963 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700964 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700965 PathTokens(&self.qself, &self.path).to_tokens(tokens);
966 }
967 }
968
969 impl<'a> ToTokens for PathTokens<'a> {
970 fn to_tokens(&self, tokens: &mut Tokens) {
971 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700972 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700973 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700974 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700975 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700976 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400977
978 // XXX: Gross.
979 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
980 self.1.segments.len() - 1
981 } else {
982 qself.position
983 };
David Tolnay6eff4da2018-01-01 20:27:45 -0800984 let mut segments = self.1.segments.elements();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400985 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700986 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700987 self.1.leading_colon.to_tokens(tokens);
David Tolnay6eff4da2018-01-01 20:27:45 -0800988 for (i, segment) in segments.by_ref().take(pos).enumerate() {
David Tolnay570695e2017-06-03 16:15:13 -0700989 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700990 segment.item().to_tokens(tokens);
991 qself.gt_token.to_tokens(tokens);
David Tolnayf2cfd722017-12-31 18:02:51 -0500992 segment.punct().to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700993 } else {
994 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700995 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700996 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700997 } else {
998 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700999 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001000 }
David Tolnay570695e2017-06-03 16:15:13 -07001001 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -07001002 segment.to_tokens(tokens);
1003 }
1004 }
1005 }
1006
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001007 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -07001008 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -05001009 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001010 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001011 }
1012 }
1013
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001014 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -07001015 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001016 self.impl_token.to_tokens(tokens);
1017 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001018 }
1019 }
1020
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001021 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -04001022 fn to_tokens(&self, tokens: &mut Tokens) {
1023 self.group_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -05001024 self.elem.to_tokens(tokens);
Michael Layzell93c36282017-06-04 20:43:14 -04001025 });
1026 }
1027 }
1028
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001029 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -07001030 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001031 self.paren_token.surround(tokens, |tokens| {
David Tolnayeadbda32017-12-29 02:33:47 -05001032 self.elem.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001033 });
Alex Crichton62a0a592017-05-22 13:58:53 -07001034 }
1035 }
1036
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001037 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -07001038 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001039 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001040 }
1041 }
1042
David Tolnay323279a2017-12-29 11:26:32 -05001043 impl ToTokens for TypeMacro {
1044 fn to_tokens(&self, tokens: &mut Tokens) {
1045 self.mac.to_tokens(tokens);
1046 }
1047 }
1048
David Tolnay2ae520a2017-12-29 11:19:50 -05001049 impl ToTokens for TypeVerbatim {
1050 fn to_tokens(&self, tokens: &mut Tokens) {
1051 self.tts.to_tokens(tokens);
1052 }
1053 }
1054
David Tolnay87d0b442016-09-04 11:52:12 -07001055 impl ToTokens for Path {
1056 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001057 self.leading_colon.to_tokens(tokens);
1058 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001059 }
1060 }
1061
1062 impl ToTokens for PathSegment {
1063 fn to_tokens(&self, tokens: &mut Tokens) {
1064 self.ident.to_tokens(tokens);
Nika Layzellc08227a2017-12-04 16:30:17 -05001065 self.arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001066 }
1067 }
1068
Nika Layzellc08227a2017-12-04 16:30:17 -05001069 impl ToTokens for PathArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001070 fn to_tokens(&self, tokens: &mut Tokens) {
1071 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001072 PathArguments::None => {}
1073 PathArguments::AngleBracketed(ref arguments) => {
1074 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001075 }
Nika Layzellc08227a2017-12-04 16:30:17 -05001076 PathArguments::Parenthesized(ref arguments) => {
1077 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001078 }
1079 }
1080 }
1081 }
1082
Nika Layzellc08227a2017-12-04 16:30:17 -05001083 impl ToTokens for GenericArgument {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001084 #[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
Nika Layzell357885a2017-12-04 15:47:07 -05001085 fn to_tokens(&self, tokens: &mut Tokens) {
1086 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001087 GenericArgument::Lifetime(ref lt) => lt.to_tokens(tokens),
1088 GenericArgument::Type(ref ty) => ty.to_tokens(tokens),
David Tolnay506e43a2017-12-29 11:34:36 -05001089 GenericArgument::Binding(ref tb) => tb.to_tokens(tokens),
David Tolnay8c91b882017-12-28 23:04:32 -05001090 GenericArgument::Const(ref e) => match *e {
1091 Expr::Lit(_) => e.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -05001092
1093 // NOTE: We should probably support parsing blocks with only
1094 // expressions in them without the full feature for const
1095 // generics.
1096 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001097 Expr::Block(_) => e.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -05001098
1099 // ERROR CORRECTION: Add braces to make sure that the
1100 // generated code is valid.
David Tolnay32954ef2017-12-26 22:43:16 -05001101 _ => token::Brace::default().surround(tokens, |tokens| {
Nika Layzellce37f332017-12-05 12:01:22 -05001102 e.to_tokens(tokens);
1103 }),
David Tolnay51382052017-12-27 13:46:21 -05001104 },
Nika Layzell357885a2017-12-04 15:47:07 -05001105 }
1106 }
1107 }
1108
Nika Layzellc08227a2017-12-04 16:30:17 -05001109 impl ToTokens for AngleBracketedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001110 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay2d4e08a2017-12-28 23:54:07 -05001111 self.colon2_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001112 self.lt_token.to_tokens(tokens);
Nika Layzell357885a2017-12-04 15:47:07 -05001113 self.args.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001114 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001115 }
1116 }
1117
David Tolnay506e43a2017-12-29 11:34:36 -05001118 impl ToTokens for Binding {
David Tolnay87d0b442016-09-04 11:52:12 -07001119 fn to_tokens(&self, tokens: &mut Tokens) {
1120 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001121 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001122 self.ty.to_tokens(tokens);
1123 }
1124 }
1125
Nika Layzellc08227a2017-12-04 16:30:17 -05001126 impl ToTokens for ParenthesizedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001127 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001128 self.paren_token.surround(tokens, |tokens| {
1129 self.inputs.to_tokens(tokens);
1130 });
1131 self.output.to_tokens(tokens);
1132 }
1133 }
1134
David Tolnayf93b90d2017-11-11 19:21:26 -08001135 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001136 fn to_tokens(&self, tokens: &mut Tokens) {
1137 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -08001138 ReturnType::Default => {}
David Tolnay4a3f59a2017-12-28 21:21:12 -05001139 ReturnType::Type(ref arrow, ref ty) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001140 arrow.to_tokens(tokens);
1141 ty.to_tokens(tokens);
1142 }
David Tolnay87d0b442016-09-04 11:52:12 -07001143 }
1144 }
1145 }
1146
David Tolnay62f374c2016-10-02 13:37:00 -07001147 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001148 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001149 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001150 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001151 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001152 }
1153 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001154 }
1155 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001156
Alex Crichton23a15f62017-08-28 12:34:23 -07001157 impl ToTokens for BareFnArgName {
1158 fn to_tokens(&self, tokens: &mut Tokens) {
1159 match *self {
1160 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1161 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1162 }
1163 }
1164 }
1165
David Tolnayb8d8ef52016-10-29 14:30:08 -07001166 impl ToTokens for Abi {
1167 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001168 self.extern_token.to_tokens(tokens);
David Tolnayd5125762017-12-29 02:42:17 -05001169 self.name.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001170 }
1171 }
David Tolnay87d0b442016-09-04 11:52:12 -07001172}