blob: b55f2f099ac82e1f3a3236e6b83ab6ebe98c2112 [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use delimited::Delimited;
David Tolnayb79ee962016-09-04 09:39:20 -07002use super::*;
3
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_enum_of_structs! {
5 /// The different kinds of types recognized by the compiler
David Tolnayfd6bf5c2017-11-12 09:41:14 -08006 pub enum Type {
Alex Crichton62a0a592017-05-22 13:58:53 -07007 /// A variable-length array (`[T]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -08008 pub Slice(TypeSlice {
9 pub ty: Box<Type>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070010 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070011 }),
12 /// A fixed length array (`[T; n]`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080013 pub Array(TypeArray {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070014 pub bracket_token: tokens::Bracket,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080015 pub ty: Box<Type>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080016 pub semi_token: Token![;],
Michael Layzelld7ee9102017-06-07 10:02:19 -040017 pub amt: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -070018 }),
19 /// A raw pointer (`*const T` or `*mut T`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080020 pub Ptr(TypePtr {
David Tolnayf8db7ba2017-11-11 22:52:16 -080021 pub star_token: Token![*],
22 pub const_token: Option<Token![const]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080023 pub ty: Box<MutType>,
Alex Crichton62a0a592017-05-22 13:58:53 -070024 }),
25 /// A reference (`&'a T` or `&'a mut T`)
David Tolnay0a89b4d2017-11-13 00:55:45 -080026 pub Reference(TypeReference {
David Tolnayf8db7ba2017-11-11 22:52:16 -080027 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub lifetime: Option<Lifetime>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080029 pub ty: Box<MutType>,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
31 /// A bare function (e.g. `fn(usize) -> bool`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080032 pub BareFn(TypeBareFn {
33 pub ty: Box<BareFnType>,
Alex Crichton62a0a592017-05-22 13:58:53 -070034 }),
35 /// The never type (`!`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080036 pub Never(TypeNever {
David Tolnayf8db7ba2017-11-11 22:52:16 -080037 pub bang_token: Token![!],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070038 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// A tuple (`(A, B, C, D, ...)`)
David Tolnayfd6bf5c2017-11-12 09:41:14 -080040 pub Tup(TypeTup {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 pub paren_token: tokens::Paren,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080042 pub tys: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080043 pub lone_comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070044 }),
45 /// A path (`module::module::...::Type`), optionally
46 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
47 ///
Nika Layzellc08227a2017-12-04 16:30:17 -050048 /// Type arguments are stored in the Path itself
David Tolnayfd6bf5c2017-11-12 09:41:14 -080049 pub Path(TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -070050 pub qself: Option<QSelf>,
51 pub path: Path,
52 }),
53 /// A trait object type `Bound1 + Bound2 + Bound3`
54 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080055 pub TraitObject(TypeTraitObject {
David Tolnaye45b59f2017-12-25 18:44:49 -050056 pub dyn_token: Option<Token![dyn]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080057 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070058 }),
59 /// An `impl Bound1 + Bound2 + Bound3` type
60 /// where `Bound` is a trait or a lifetime.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080061 pub ImplTrait(TypeImplTrait {
David Tolnayf8db7ba2017-11-11 22:52:16 -080062 pub impl_token: Token![impl],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080063 pub bounds: Delimited<TypeParamBound, Token![+]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070064 }),
65 /// No-op; kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080066 pub Paren(TypeParen {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070067 pub paren_token: tokens::Paren,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080068 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070069 }),
Michael Layzell93c36282017-06-04 20:43:14 -040070 /// No-op: kept solely so that we can pretty-print faithfully
David Tolnayfd6bf5c2017-11-12 09:41:14 -080071 pub Group(TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -040072 pub group_token: tokens::Group,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080073 pub ty: Box<Type>,
Michael Layzell93c36282017-06-04 20:43:14 -040074 }),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080075 /// TypeKind::Infer means the type should be inferred instead of it having been
Alex Crichton62a0a592017-05-22 13:58:53 -070076 /// specified. This can appear anywhere in a type.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080077 pub Infer(TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -080078 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070079 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070080 /// A macro in the type position.
David Tolnaydecf28d2017-11-11 11:56:45 -080081 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -070082 }
83}
84
85ast_struct! {
David Tolnayfd6bf5c2017-11-12 09:41:14 -080086 pub struct MutType {
87 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070088 pub mutability: Mutability,
89 }
90}
91
92ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -070093 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -070094 pub enum Mutability {
David Tolnayf8db7ba2017-11-11 22:52:16 -080095 Mutable(Token![mut]),
Alex Crichton62a0a592017-05-22 13:58:53 -070096 Immutable,
97 }
98}
99
100ast_struct! {
101 /// A "Path" is essentially Rust's notion of a name.
David Tolnayb79ee962016-09-04 09:39:20 -0700102 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700103 /// It's represented as a sequence of identifiers,
104 /// along with a bunch of supporting information.
105 ///
106 /// E.g. `std::cmp::PartialEq`
107 pub struct Path {
108 /// A `::foo` path, is relative to the crate root rather than current
109 /// module (like paths in an import).
David Tolnayf8db7ba2017-11-11 22:52:16 -0800110 pub leading_colon: Option<Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700111 /// The segments in the path: the things separated by `::`.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800112 pub segments: Delimited<PathSegment, Token![::]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 }
David Tolnayb79ee962016-09-04 09:39:20 -0700114}
115
David Tolnay570695e2017-06-03 16:15:13 -0700116impl Path {
117 pub fn global(&self) -> bool {
118 self.leading_colon.is_some()
119 }
120}
121
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700122#[cfg(feature = "printing")]
Nika Layzell6b38b132017-10-24 23:09:39 -0400123#[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
124#[cfg_attr(feature = "clone-impls", derive(Clone))]
125pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700126
David Tolnaydaaf7742016-10-03 11:11:43 -0700127impl<T> From<T> for Path
128 where T: Into<PathSegment>
129{
David Tolnay84aa0752016-10-02 23:01:13 -0700130 fn from(segment: T) -> Self {
131 Path {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700132 leading_colon: None,
133 segments: vec![(segment.into(), None)].into(),
David Tolnay84aa0752016-10-02 23:01:13 -0700134 }
135 }
136}
137
Alex Crichton62a0a592017-05-22 13:58:53 -0700138ast_struct! {
139 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
140 ///
141 /// E.g. `std`, `String` or `Box<T>`
142 pub struct PathSegment {
143 /// The identifier portion of this path segment.
144 pub ident: Ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500145 /// Type/lifetime arguments attached to this path. They come in
Alex Crichton62a0a592017-05-22 13:58:53 -0700146 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
147 /// this is more than just simple syntactic sugar; the use of
148 /// parens affects the region binding rules, so we preserve the
149 /// distinction.
Nika Layzellc08227a2017-12-04 16:30:17 -0500150 pub arguments: PathArguments,
Alex Crichton62a0a592017-05-22 13:58:53 -0700151 }
David Tolnayb79ee962016-09-04 09:39:20 -0700152}
153
David Tolnaydaaf7742016-10-03 11:11:43 -0700154impl<T> From<T> for PathSegment
155 where T: Into<Ident>
156{
David Tolnay84aa0752016-10-02 23:01:13 -0700157 fn from(ident: T) -> Self {
David Tolnayb79ee962016-09-04 09:39:20 -0700158 PathSegment {
David Tolnay84aa0752016-10-02 23:01:13 -0700159 ident: ident.into(),
Nika Layzellc08227a2017-12-04 16:30:17 -0500160 arguments: PathArguments::None,
David Tolnayb79ee962016-09-04 09:39:20 -0700161 }
162 }
163}
164
Alex Crichton62a0a592017-05-22 13:58:53 -0700165ast_enum! {
Nika Layzellc08227a2017-12-04 16:30:17 -0500166 /// Arguments of a path segment.
Alex Crichton62a0a592017-05-22 13:58:53 -0700167 ///
168 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
Nika Layzellc08227a2017-12-04 16:30:17 -0500169 pub enum PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700170 None,
Alex Crichton62a0a592017-05-22 13:58:53 -0700171 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500172 AngleBracketed(AngleBracketedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700173 /// The `(A, B)` and `C` in `Foo(A, B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500174 Parenthesized(ParenthesizedGenericArguments),
Alex Crichton62a0a592017-05-22 13:58:53 -0700175 }
David Tolnayb79ee962016-09-04 09:39:20 -0700176}
177
Nika Layzellc08227a2017-12-04 16:30:17 -0500178impl Default for PathArguments {
David Tolnay570695e2017-06-03 16:15:13 -0700179 fn default() -> Self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500180 PathArguments::None
David Tolnayb79ee962016-09-04 09:39:20 -0700181 }
David Tolnay570695e2017-06-03 16:15:13 -0700182}
David Tolnay5332d4b2016-10-30 14:25:22 -0700183
Nika Layzellc08227a2017-12-04 16:30:17 -0500184impl PathArguments {
David Tolnay5332d4b2016-10-30 14:25:22 -0700185 pub fn is_empty(&self) -> bool {
186 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -0500187 PathArguments::None => true,
188 PathArguments::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
189 PathArguments::Parenthesized(_) => false,
David Tolnay5332d4b2016-10-30 14:25:22 -0700190 }
191 }
David Tolnayb79ee962016-09-04 09:39:20 -0700192}
193
Nika Layzell357885a2017-12-04 15:47:07 -0500194ast_enum! {
195 /// A individual generic argument, like `'a`, `T`, or `Item=T`.
Nika Layzellc08227a2017-12-04 16:30:17 -0500196 pub enum GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500197 /// The lifetime parameters for this path segment.
198 Lifetime(Lifetime),
199 /// The type parameters for this path segment, if present.
200 Type(Type),
201 /// Bindings (equality constraints) on associated types, if present.
202 ///
203 /// E.g., `Foo<A=Bar>`.
204 TypeBinding(TypeBinding),
Nika Layzellc680e612017-12-04 19:07:20 -0500205 /// Const expression. Must be inside of a block.
206 ///
207 /// NOTE: Identity expressions are represented as Type arguments, as
208 /// they are indistinguishable syntactically.
Nika Layzellce37f332017-12-05 12:01:22 -0500209 Const(Expr),
Nika Layzell357885a2017-12-04 15:47:07 -0500210 }
211}
212
Alex Crichton62a0a592017-05-22 13:58:53 -0700213ast_struct! {
214 /// A path like `Foo<'a, T>`
Nika Layzellc08227a2017-12-04 16:30:17 -0500215 pub struct AngleBracketedGenericArguments {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800216 pub turbofish: Option<Token![::]>,
217 pub lt_token: Token![<],
Nika Layzellc08227a2017-12-04 16:30:17 -0500218 pub args: Delimited<GenericArgument, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800219 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700220 }
221}
222
223ast_struct! {
224 /// Bind a type to an associated type: `A=Foo`.
225 pub struct TypeBinding {
226 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800227 pub eq_token: Token![=],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800228 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 }
230}
231
232
233ast_struct! {
234 /// A path like `Foo(A,B) -> C`
Nika Layzellc08227a2017-12-04 16:30:17 -0500235 pub struct ParenthesizedGenericArguments {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700236 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700237 /// `(A, B)`
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800238 pub inputs: Delimited<Type, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700239 /// `C`
David Tolnayf93b90d2017-11-11 19:21:26 -0800240 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700241 }
242}
243
244ast_struct! {
245 pub struct PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700246 /// The `for<'a>` in `for<'a> Foo<&'a T>`
247 pub bound_lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
249 pub trait_ref: Path,
250 }
251}
252
253ast_struct! {
254 /// The explicit Self type in a "qualified path". The actual
255 /// path, including the trait and the associated item, is stored
256 /// separately. `position` represents the index of the associated
257 /// item qualified with this Self type.
David Tolnayb79ee962016-09-04 09:39:20 -0700258 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700259 /// ```rust,ignore
260 /// <Vec<T> as a::b::Trait>::AssociatedItem
261 /// ^~~~~ ~~~~~~~~~~~~~~^
262 /// ty position = 3
David Tolnayb79ee962016-09-04 09:39:20 -0700263 ///
Alex Crichton62a0a592017-05-22 13:58:53 -0700264 /// <Vec<T>>::AssociatedItem
265 /// ^~~~~ ^
266 /// ty position = 0
267 /// ```
268 pub struct QSelf {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800269 pub lt_token: Token![<],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800270 pub ty: Box<Type>,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400271 pub position: usize,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800272 pub as_token: Option<Token![as]>,
273 pub gt_token: Token![>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700274 }
275}
276
277ast_struct! {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800278 pub struct BareFnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700279 pub lifetimes: Option<BoundLifetimes>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700280 pub unsafety: Unsafety,
281 pub abi: Option<Abi>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800282 pub fn_token: Token![fn],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700283 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800284 pub inputs: Delimited<BareFnArg, Token![,]>,
285 pub variadic: Option<Token![...]>,
David Tolnayf93b90d2017-11-11 19:21:26 -0800286 pub output: ReturnType,
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 }
288}
289
290ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700291 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 pub enum Unsafety {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800293 Unsafe(Token![unsafe]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 Normal,
295 }
296}
297
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700298ast_struct! {
299 pub struct Abi {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800300 pub extern_token: Token![extern],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700301 pub kind: AbiKind,
302 }
303}
304
Alex Crichton62a0a592017-05-22 13:58:53 -0700305ast_enum! {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700306 pub enum AbiKind {
307 Named(Lit),
308 Default,
Alex Crichton62a0a592017-05-22 13:58:53 -0700309 }
310}
311
312ast_struct! {
313 /// An argument in a function type.
314 ///
315 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
316 pub struct BareFnArg {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800317 pub name: Option<(BareFnArgName, Token![:])>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800318 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 }
320}
321
Alex Crichton23a15f62017-08-28 12:34:23 -0700322ast_enum! {
323 /// Names of arguments in the `BareFnArg` structure
324 pub enum BareFnArgName {
325 /// Argument with the provided name
326 Named(Ident),
327 /// Argument matched with `_`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800328 Wild(Token![_]),
Alex Crichton23a15f62017-08-28 12:34:23 -0700329 }
330}
Alex Crichton62a0a592017-05-22 13:58:53 -0700331
332ast_enum! {
David Tolnayf93b90d2017-11-11 19:21:26 -0800333 pub enum ReturnType {
Alex Crichton62a0a592017-05-22 13:58:53 -0700334 /// Return type is not specified.
335 ///
336 /// Functions default to `()` and
337 /// closures default to inference. Span points to where return
338 /// type would be inserted.
339 Default,
340 /// Everything else
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800341 Type(Type, Token![->]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700342 }
David Tolnayb79ee962016-09-04 09:39:20 -0700343}
344
David Tolnay86eca752016-09-04 11:26:41 -0700345#[cfg(feature = "parsing")]
David Tolnay9d8f1972016-09-04 11:58:48 -0700346pub mod parsing {
347 use super::*;
Michael Layzell92639a52017-06-01 00:07:44 -0400348 use synom::Synom;
David Tolnayda4049b2016-09-04 10:59:23 -0700349
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800350 impl Synom for Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400351 named!(parse -> Self, call!(ambig_ty, true));
David Tolnayb79ee962016-09-04 09:39:20 -0700352
Alex Crichton954046c2017-05-30 21:49:42 -0700353 fn description() -> Option<&'static str> {
354 Some("type")
355 }
356 }
David Tolnay0047c712016-12-21 21:59:25 -0500357
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800358 impl Type {
Michael Layzell9bf2b002017-06-04 18:49:53 -0400359 /// In some positions, types may not contain the `+` character, to
360 /// disambiguate them. For example in the expression `1 as T`, T may not
361 /// contain a `+` character.
362 ///
363 /// This parser does not allow a `+`, while the default parser does.
Michael Layzell6a5a1642017-06-04 19:35:15 -0400364 named!(pub without_plus -> Self, call!(ambig_ty, false));
Michael Layzell9bf2b002017-06-04 18:49:53 -0400365 }
366
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800367 named!(ambig_ty(allow_plus: bool) -> Type, alt!(
368 syn!(TypeGroup) => { Type::Group }
Michael Layzell93c36282017-06-04 20:43:14 -0400369 |
Michael Layzell9bf2b002017-06-04 18:49:53 -0400370 // must be before mac
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800371 syn!(TypeParen) => { Type::Paren }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400372 |
373 // must be before path
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800374 syn!(Macro) => { Type::Macro }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400375 |
376 // must be before ty_poly_trait_ref
377 call!(ty_path, allow_plus)
378 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800379 syn!(TypeSlice) => { Type::Slice }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400380 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800381 syn!(TypeArray) => { Type::Array }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400382 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800383 syn!(TypePtr) => { Type::Ptr }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400384 |
David Tolnay0a89b4d2017-11-13 00:55:45 -0800385 syn!(TypeReference) => { Type::Reference }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400386 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800387 syn!(TypeBareFn) => { Type::BareFn }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400388 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800389 syn!(TypeNever) => { Type::Never }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400390 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800391 syn!(TypeTup) => { Type::Tup }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400392 |
393 // Don't try parsing poly_trait_ref if we aren't allowing it
394 call!(ty_poly_trait_ref, allow_plus)
395 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800396 syn!(TypeImplTrait) => { Type::ImplTrait }
Alex Crichton23a15f62017-08-28 12:34:23 -0700397 |
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800398 syn!(TypeInfer) => { Type::Infer }
Michael Layzell9bf2b002017-06-04 18:49:53 -0400399 ));
400
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800401 impl Synom for TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400402 named!(parse -> Self, map!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800403 brackets!(syn!(Type)),
404 |(ty, b)| TypeSlice {
Michael Layzell92639a52017-06-01 00:07:44 -0400405 ty: Box::new(ty),
406 bracket_token: b,
Alex Crichton954046c2017-05-30 21:49:42 -0700407 }
Michael Layzell92639a52017-06-01 00:07:44 -0400408 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700409 }
David Tolnayb79ee962016-09-04 09:39:20 -0700410
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800411 impl Synom for TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400412 named!(parse -> Self, map!(
413 brackets!(do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800414 elem: syn!(Type) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800415 semi: punct!(;) >>
Michael Layzelld7ee9102017-06-07 10:02:19 -0400416 len: syn!(Expr) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700417 (elem, semi, len)
Michael Layzell92639a52017-06-01 00:07:44 -0400418 )),
419 |((elem, semi, len), brackets)| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800420 TypeArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400421 ty: Box::new(elem),
422 amt: len,
423 bracket_token: brackets,
424 semi_token: semi,
Alex Crichton954046c2017-05-30 21:49:42 -0700425 }
426 }
Michael Layzell92639a52017-06-01 00:07:44 -0400427 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700428 }
David Tolnayfa94b6f2016-10-05 23:26:11 -0700429
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800430 impl Synom for TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400431 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800432 star: punct!(*) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400433 mutability: alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800434 keyword!(const) => { |c| (Mutability::Immutable, Some(c)) }
Michael Layzell92639a52017-06-01 00:07:44 -0400435 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800436 keyword!(mut) => { |m| (Mutability::Mutable(m), None) }
Michael Layzell92639a52017-06-01 00:07:44 -0400437 ) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800438 target: call!(Type::without_plus) >>
439 (TypePtr {
Michael Layzell92639a52017-06-01 00:07:44 -0400440 const_token: mutability.1,
441 star_token: star,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800442 ty: Box::new(MutType {
Michael Layzell92639a52017-06-01 00:07:44 -0400443 ty: target,
444 mutability: mutability.0,
445 }),
446 })
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)) >>
454 mutability: syn!(Mutability) >>
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 Tolnayfd6bf5c2017-11-12 09:41:14 -0800459 ty: Box::new(MutType {
Michael Layzell92639a52017-06-01 00:07:44 -0400460 ty: target,
461 mutability: mutability,
462 }),
463 and_token: amp,
464 })
465 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700466 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700467
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800468 impl Synom for TypeBareFn {
Michael Layzell92639a52017-06-01 00:07:44 -0400469 named!(parse -> Self, do_parse!(
470 lifetimes: option!(syn!(BoundLifetimes)) >>
471 unsafety: syn!(Unsafety) >>
472 abi: option!(syn!(Abi)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800473 fn_: keyword!(fn) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400474 parens: parens!(do_parse!(
475 inputs: call!(Delimited::parse_terminated) >>
476 variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -0800477 punct!(...))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400478 (inputs, variadic)
479 )) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800480 output: syn!(ReturnType) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800481 (TypeBareFn {
482 ty: Box::new(BareFnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400483 unsafety: unsafety,
484 abi: abi,
485 lifetimes: lifetimes,
486 output: output,
487 variadic: (parens.0).1,
488 fn_token: fn_,
489 paren_token: parens.1,
490 inputs: (parens.0).0,
491 }),
492 })
493 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700494 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700495
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800496 impl Synom for TypeNever {
Michael Layzell92639a52017-06-01 00:07:44 -0400497 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800498 punct!(!),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800499 |b| TypeNever { bang_token: b }
Michael Layzell92639a52017-06-01 00:07:44 -0400500 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700501 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700502
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800503 impl Synom for TypeInfer {
Alex Crichton23a15f62017-08-28 12:34:23 -0700504 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800505 punct!(_),
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800506 |u| TypeInfer { underscore_token: u }
Alex Crichton23a15f62017-08-28 12:34:23 -0700507 ));
508 }
509
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800510 impl Synom for TypeTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400511 named!(parse -> Self, do_parse!(
512 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800513 (TypeTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400514 tys: data.0,
515 paren_token: data.1,
516 lone_comma: None, // TODO: does this just not parse?
517 })
518 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700519 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700520
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800521 named!(ty_path(allow_plus: bool) -> Type, do_parse!(
David Tolnay6414da72016-10-08 00:55:17 -0700522 qpath: qpath >>
David Tolnayf6c74402016-10-08 02:31:26 -0700523 parenthesized: cond!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500524 qpath.1.segments.get(qpath.1.segments.len() - 1).item().arguments.is_empty(),
525 option!(syn!(ParenthesizedGenericArguments))
David Tolnayf6c74402016-10-08 02:31:26 -0700526 ) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400527 // Only allow parsing additional bounds if allow_plus is true.
528 bounds: alt!(
529 cond_reduce!(
530 allow_plus,
Nika Layzellb49a9e52017-12-05 13:31:52 -0500531 option!(tuple!(punct!(+), call!(Delimited::<TypeParamBound, Token![+]>::parse_terminated)))
Michael Layzell9bf2b002017-06-04 18:49:53 -0400532 )
533 |
Nika Layzellb49a9e52017-12-05 13:31:52 -0500534 value!(None)
Michael Layzell9bf2b002017-06-04 18:49:53 -0400535 ) >>
David Tolnay6414da72016-10-08 00:55:17 -0700536 ({
David Tolnayf6c74402016-10-08 02:31:26 -0700537 let (qself, mut path) = qpath;
538 if let Some(Some(parenthesized)) = parenthesized {
Nika Layzellc08227a2017-12-04 16:30:17 -0500539 let parenthesized = PathArguments::Parenthesized(parenthesized);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700540 let len = path.segments.len();
Nika Layzellc08227a2017-12-04 16:30:17 -0500541 path.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
David Tolnayf6c74402016-10-08 02:31:26 -0700542 }
Nika Layzellb49a9e52017-12-05 13:31:52 -0500543 if let Some((plus, rest)) = bounds {
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800544 let path = TypeParamBound::Trait(
David Tolnay02c907f2017-01-23 00:06:37 -0800545 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700546 bound_lifetimes: None,
David Tolnay02c907f2017-01-23 00:06:37 -0800547 trait_ref: path,
548 },
549 TraitBoundModifier::None,
550 );
Nika Layzellb49a9e52017-12-05 13:31:52 -0500551
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700552 let mut new_bounds = Delimited::new();
Nika Layzellb49a9e52017-12-05 13:31:52 -0500553 new_bounds.push(delimited::Element::Delimited(path, plus));
554 new_bounds.extend(rest);
David Tolnaye45b59f2017-12-25 18:44:49 -0500555 TypeTraitObject { dyn_token: None, bounds: new_bounds }.into()
Nika Layzellb49a9e52017-12-05 13:31:52 -0500556 } else {
557 TypePath { qself: qself, path: path }.into()
David Tolnay6414da72016-10-08 00:55:17 -0700558 }
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) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700568 path: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800569 as_: keyword!(as) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700570 path: syn!(Path) >>
571 (as_, path)
David Tolnay9636c052016-10-02 17:11:17 -0700572 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800573 gt: punct!(>) >>
574 colon2: punct!(::) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700575 rest: call!(Delimited::parse_separated_nonempty) >>
David Tolnay9636c052016-10-02 17:11:17 -0700576 ({
Michael Layzell3936ceb2017-07-08 00:28:36 -0400577 let (pos, as_, path) = match path {
Alex Crichton954046c2017-05-30 21:49:42 -0700578 Some((as_, mut path)) => {
David Tolnay9636c052016-10-02 17:11:17 -0700579 let pos = path.segments.len();
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700580 if !path.segments.is_empty() && !path.segments.trailing_delim() {
Alex Crichton954046c2017-05-30 21:49:42 -0700581 path.segments.push_trailing(colon2);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700582 }
Alex Crichton954046c2017-05-30 21:49:42 -0700583 for item in rest {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700584 path.segments.push(item);
585 }
Michael Layzell3936ceb2017-07-08 00:28:36 -0400586 (pos, Some(as_), path)
David Tolnay9636c052016-10-02 17:11:17 -0700587 }
588 None => {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400589 (0, None, Path {
David Tolnay570695e2017-06-03 16:15:13 -0700590 leading_colon: Some(colon2),
David Tolnay9636c052016-10-02 17:11:17 -0700591 segments: rest,
David Tolnay570695e2017-06-03 16:15:13 -0700592 })
David Tolnay9636c052016-10-02 17:11:17 -0700593 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700594 };
595 (Some(QSelf {
David Tolnay570695e2017-06-03 16:15:13 -0700596 lt_token: lt,
597 ty: Box::new(this),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700598 position: pos,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400599 as_token: as_,
Alex Crichton954046c2017-05-30 21:49:42 -0700600 gt_token: gt,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700601 }), path)
David Tolnay9636c052016-10-02 17:11:17 -0700602 })
603 )
David Tolnay6cd2a232016-10-24 22:41:08 -0700604 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800605 map!(keyword!(self), |s| (None, s.into()))
David Tolnay9d8f1972016-09-04 11:58:48 -0700606 ));
David Tolnayb79ee962016-09-04 09:39:20 -0700607
Nika Layzellc08227a2017-12-04 16:30:17 -0500608 impl Synom for ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400609 named!(parse -> Self, do_parse!(
610 data: parens!(call!(Delimited::parse_terminated)) >>
David Tolnayf93b90d2017-11-11 19:21:26 -0800611 output: syn!(ReturnType) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500612 (ParenthesizedGenericArguments {
Michael Layzell92639a52017-06-01 00:07:44 -0400613 paren_token: data.1,
614 inputs: data.0,
615 output: output,
616 })
617 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700618 }
619
David Tolnayf93b90d2017-11-11 19:21:26 -0800620 impl Synom for ReturnType {
Michael Layzell92639a52017-06-01 00:07:44 -0400621 named!(parse -> Self, alt!(
622 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800623 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800624 ty: syn!(Type) >>
625 (ReturnType::Type(ty, arrow))
Michael Layzell92639a52017-06-01 00:07:44 -0400626 )
627 |
David Tolnayf93b90d2017-11-11 19:21:26 -0800628 epsilon!() => { |_| ReturnType::Default }
Michael Layzell92639a52017-06-01 00:07:44 -0400629 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700630 }
631
Michael Layzell9bf2b002017-06-04 18:49:53 -0400632 // Only allow multiple trait references if allow_plus is true.
David Tolnaye45b59f2017-12-25 18:44:49 -0500633 named!(ty_poly_trait_ref(allow_plus: bool) -> Type, do_parse!(
634 dyn_token: option!(keyword!(dyn)) >>
635 bounds: alt!(
636 cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty))
637 |
638 syn!(TypeParamBound) => { |x| vec![x].into() }
639 ) >>
640 (TypeTraitObject {
641 dyn_token: dyn_token,
642 bounds: bounds,
643 }.into())
David Tolnay6414da72016-10-08 00:55:17 -0700644 ));
645
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800646 impl Synom for TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400647 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800648 impl_: keyword!(impl) >>
Michael Layzell9bf2b002017-06-04 18:49:53 -0400649 // NOTE: rust-lang/rust#34511 includes discussion about whether or
650 // not + should be allowed in ImplTrait directly without ().
Nika Layzellb49a9e52017-12-05 13:31:52 -0500651 elem: call!(Delimited::parse_terminated_nonempty) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800652 (TypeImplTrait {
Michael Layzell92639a52017-06-01 00:07:44 -0400653 impl_token: impl_,
654 bounds: elem,
655 })
656 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700657 }
David Tolnayb79ee962016-09-04 09:39:20 -0700658
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800659 impl Synom for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400660 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800661 data: grouped!(syn!(Type)) >>
662 (TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400663 group_token: data.1,
664 ty: Box::new(data.0),
665 })
666 ));
667 }
668
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800669 impl Synom for TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400670 named!(parse -> Self, do_parse!(
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800671 data: parens!(syn!(Type)) >>
672 (TypeParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400673 paren_token: data.1,
674 ty: Box::new(data.0),
675 })
676 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700677 }
David Tolnayb79ee962016-09-04 09:39:20 -0700678
Alex Crichton954046c2017-05-30 21:49:42 -0700679 impl Synom for Mutability {
Michael Layzell92639a52017-06-01 00:07:44 -0400680 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800681 keyword!(mut) => { Mutability::Mutable }
Michael Layzell92639a52017-06-01 00:07:44 -0400682 |
683 epsilon!() => { |_| Mutability::Immutable }
684 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700685 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700686
Alex Crichton954046c2017-05-30 21:49:42 -0700687 impl Synom for Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400688 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800689 colon: option!(punct!(::)) >>
David Tolnaye45b59f2017-12-25 18:44:49 -0500690 segments: call!(Delimited::<PathSegment, Token![::]>::parse_separated_nonempty) >>
691 cond_reduce!(segments.first().map_or(true, |seg| seg.item().ident != "dyn"), epsilon!()) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400692 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700693 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400694 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400695 })
696 ));
Alex Crichton36e91bf2017-07-06 14:59:56 -0700697
698 fn description() -> Option<&'static str> {
699 Some("path")
700 }
Alex Crichton954046c2017-05-30 21:49:42 -0700701 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700702
Nika Layzellc680e612017-12-04 19:07:20 -0500703 #[cfg(not(feature = "full"))]
Nika Layzellc08227a2017-12-04 16:30:17 -0500704 impl Synom for GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -0500705 named!(parse -> Self, alt!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500706 call!(ty_no_eq_after) => { GenericArgument::Type }
Nika Layzell357885a2017-12-04 15:47:07 -0500707 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500708 syn!(Lifetime) => { GenericArgument::Lifetime }
Nika Layzell357885a2017-12-04 15:47:07 -0500709 |
Nika Layzellc08227a2017-12-04 16:30:17 -0500710 syn!(TypeBinding) => { GenericArgument::TypeBinding }
Nika Layzell357885a2017-12-04 15:47:07 -0500711 ));
712 }
713
Nika Layzellc680e612017-12-04 19:07:20 -0500714 #[cfg(feature = "full")]
715 impl Synom for GenericArgument {
716 named!(parse -> Self, alt!(
717 call!(ty_no_eq_after) => { GenericArgument::Type }
718 |
719 syn!(Lifetime) => { GenericArgument::Lifetime }
720 |
721 syn!(TypeBinding) => { GenericArgument::TypeBinding }
722 |
Nika Layzellce37f332017-12-05 12:01:22 -0500723 syn!(Lit) => { |l| GenericArgument::Const(ExprKind::Lit(l).into()) }
724 |
725 syn!(ExprBlock) => { |b| GenericArgument::Const(ExprKind::Block(b).into()) }
Nika Layzellc680e612017-12-04 19:07:20 -0500726 ));
727 }
728
Nika Layzellc08227a2017-12-04 16:30:17 -0500729 impl Synom for AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500730 named!(parse -> Self, do_parse!(
731 turbofish: option!(punct!(::)) >>
732 lt: punct!(<) >>
733 args: call!(Delimited::parse_terminated) >>
734 gt: punct!(>) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500735 (AngleBracketedGenericArguments {
Nika Layzell357885a2017-12-04 15:47:07 -0500736 turbofish: turbofish,
737 lt_token: lt,
738 args: args,
739 gt_token: gt,
740 })
741 ));
742 }
743
Alex Crichton954046c2017-05-30 21:49:42 -0700744 impl Synom for PathSegment {
Michael Layzell92639a52017-06-01 00:07:44 -0400745 named!(parse -> Self, alt!(
746 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -0700747 ident: syn!(Ident) >>
Nika Layzellc08227a2017-12-04 16:30:17 -0500748 arguments: syn!(AngleBracketedGenericArguments) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400749 (PathSegment {
David Tolnay570695e2017-06-03 16:15:13 -0700750 ident: ident,
Nika Layzellc08227a2017-12-04 16:30:17 -0500751 arguments: PathArguments::AngleBracketed(arguments),
Michael Layzell92639a52017-06-01 00:07:44 -0400752 })
753 )
754 |
755 mod_style_path_segment
756 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700757 }
David Tolnay570695e2017-06-03 16:15:13 -0700758
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800759 named!(ty_no_eq_after -> Type, terminated!(syn!(Type), not!(punct!(=))));
David Tolnay9d8f1972016-09-04 11:58:48 -0700760
Alex Crichton954046c2017-05-30 21:49:42 -0700761 impl Path {
Michael Layzell92639a52017-06-01 00:07:44 -0400762 named!(pub parse_mod_style -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800763 colon: option!(punct!(::)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400764 segments: call!(Delimited::parse_separated_nonempty_with,
765 mod_style_path_segment) >>
766 (Path {
David Tolnay570695e2017-06-03 16:15:13 -0700767 leading_colon: colon,
Michael Layzell92639a52017-06-01 00:07:44 -0400768 segments: segments,
Michael Layzell92639a52017-06-01 00:07:44 -0400769 })
770 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700771 }
Arnavionf2dada12017-04-20 23:55:20 -0700772
773 named!(mod_style_path_segment -> PathSegment, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700774 map!(syn!(Ident), Into::into)
Arnavionf2dada12017-04-20 23:55:20 -0700775 |
Alex Crichton954046c2017-05-30 21:49:42 -0700776 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800777 keyword!(super) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700778 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800779 keyword!(self) => { Into::into }
Arnavionf2dada12017-04-20 23:55:20 -0700780 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800781 keyword!(Self) => { Into::into }
Alex Crichton954046c2017-05-30 21:49:42 -0700782 )
Arnavionf2dada12017-04-20 23:55:20 -0700783 ));
784
Alex Crichton954046c2017-05-30 21:49:42 -0700785 impl Synom for TypeBinding {
Michael Layzell92639a52017-06-01 00:07:44 -0400786 named!(parse -> Self, do_parse!(
787 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800788 eq: punct!(=) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800789 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400790 (TypeBinding {
791 ident: id,
792 eq_token: eq,
793 ty: ty,
794 })
795 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700796 }
797
798 impl Synom for PolyTraitRef {
Michael Layzell92639a52017-06-01 00:07:44 -0400799 named!(parse -> Self, do_parse!(
800 bound_lifetimes: option!(syn!(BoundLifetimes)) >>
801 trait_ref: syn!(Path) >>
802 parenthesized: option!(cond_reduce!(
Nika Layzellc08227a2017-12-04 16:30:17 -0500803 trait_ref.segments.get(trait_ref.segments.len() - 1).item().arguments.is_empty(),
804 syn!(ParenthesizedGenericArguments)
Michael Layzell92639a52017-06-01 00:07:44 -0400805 )) >>
806 ({
807 let mut trait_ref = trait_ref;
808 if let Some(parenthesized) = parenthesized {
Nika Layzellc08227a2017-12-04 16:30:17 -0500809 let parenthesized = PathArguments::Parenthesized(parenthesized);
Michael Layzell92639a52017-06-01 00:07:44 -0400810 let len = trait_ref.segments.len();
Nika Layzellc08227a2017-12-04 16:30:17 -0500811 trait_ref.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
Michael Layzell92639a52017-06-01 00:07:44 -0400812 }
813 PolyTraitRef {
814 bound_lifetimes: bound_lifetimes,
815 trait_ref: trait_ref,
816 }
817 })
818 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700819 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700820
Alex Crichton954046c2017-05-30 21:49:42 -0700821 impl Synom for BareFnArg {
Michael Layzell92639a52017-06-01 00:07:44 -0400822 named!(parse -> Self, do_parse!(
823 name: option!(do_parse!(
Alex Crichton23a15f62017-08-28 12:34:23 -0700824 name: syn!(BareFnArgName) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800825 not!(punct!(::)) >>
826 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400827 (name, colon)
828 )) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800829 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400830 (BareFnArg {
831 name: name,
832 ty: ty,
833 })
834 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700835 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700836
Alex Crichton23a15f62017-08-28 12:34:23 -0700837 impl Synom for BareFnArgName {
838 named!(parse -> Self, alt!(
839 map!(syn!(Ident), BareFnArgName::Named)
840 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800841 map!(punct!(_), BareFnArgName::Wild)
Alex Crichton23a15f62017-08-28 12:34:23 -0700842 ));
843 }
844
Alex Crichton954046c2017-05-30 21:49:42 -0700845 impl Synom for Unsafety {
Michael Layzell92639a52017-06-01 00:07:44 -0400846 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800847 keyword!(unsafe) => { Unsafety::Unsafe }
Michael Layzell92639a52017-06-01 00:07:44 -0400848 |
849 epsilon!() => { |_| Unsafety::Normal }
850 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700851 }
David Tolnayb8d8ef52016-10-29 14:30:08 -0700852
Alex Crichton954046c2017-05-30 21:49:42 -0700853 impl Synom for Abi {
Michael Layzell92639a52017-06-01 00:07:44 -0400854 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800855 extern_: keyword!(extern) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400856 // TODO: this parses all literals, not just strings
857 name: option!(syn!(Lit)) >>
858 (Abi {
859 extern_token: extern_,
860 kind: match name {
861 Some(name) => AbiKind::Named(name),
862 None => AbiKind::Default,
863 },
864 })
865 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700866 }
David Tolnay9d8f1972016-09-04 11:58:48 -0700867}
David Tolnay87d0b442016-09-04 11:52:12 -0700868
869#[cfg(feature = "printing")]
870mod printing {
871 use super::*;
872 use quote::{Tokens, ToTokens};
873
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800874 impl ToTokens for TypeSlice {
David Tolnay87d0b442016-09-04 11:52:12 -0700875 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700876 self.bracket_token.surround(tokens, |tokens| {
877 self.ty.to_tokens(tokens);
878 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700879 }
880 }
881
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800882 impl ToTokens for TypeArray {
Alex Crichton62a0a592017-05-22 13:58:53 -0700883 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700884 self.bracket_token.surround(tokens, |tokens| {
885 self.ty.to_tokens(tokens);
886 self.semi_token.to_tokens(tokens);
887 self.amt.to_tokens(tokens);
888 });
Alex Crichton62a0a592017-05-22 13:58:53 -0700889 }
890 }
891
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800892 impl ToTokens for TypePtr {
Alex Crichton62a0a592017-05-22 13:58:53 -0700893 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700894 self.star_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400895 match self.ty.mutability {
896 Mutability::Mutable(ref tok) => tok.to_tokens(tokens),
897 Mutability::Immutable => {
Alex Crichton259ee532017-07-14 06:51:02 -0700898 TokensOrDefault(&self.const_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400899 }
900 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700901 self.ty.ty.to_tokens(tokens);
902 }
903 }
904
David Tolnay0a89b4d2017-11-13 00:55:45 -0800905 impl ToTokens for TypeReference {
Alex Crichton62a0a592017-05-22 13:58:53 -0700906 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700907 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700908 self.lifetime.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700909 self.ty.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700910 self.ty.ty.to_tokens(tokens);
911 }
912 }
913
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800914 impl ToTokens for TypeBareFn {
Alex Crichton62a0a592017-05-22 13:58:53 -0700915 fn to_tokens(&self, tokens: &mut Tokens) {
916 self.ty.to_tokens(tokens)
917 }
918 }
919
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800920 impl ToTokens for TypeNever {
Alex Crichton62a0a592017-05-22 13:58:53 -0700921 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700922 self.bang_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700923 }
924 }
925
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800926 impl ToTokens for TypeTup {
Alex Crichton62a0a592017-05-22 13:58:53 -0700927 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700928 self.paren_token.surround(tokens, |tokens| {
929 self.tys.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400930 // XXX: I don't think (,) is a thing.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700931 self.lone_comma.to_tokens(tokens);
932 })
Alex Crichton62a0a592017-05-22 13:58:53 -0700933 }
934 }
935
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800936 impl ToTokens for TypePath {
Alex Crichton62a0a592017-05-22 13:58:53 -0700937 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700938 PathTokens(&self.qself, &self.path).to_tokens(tokens);
939 }
940 }
941
942 impl<'a> ToTokens for PathTokens<'a> {
943 fn to_tokens(&self, tokens: &mut Tokens) {
944 let qself = match *self.0 {
Alex Crichton62a0a592017-05-22 13:58:53 -0700945 Some(ref qself) => qself,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700946 None => return self.1.to_tokens(tokens),
Alex Crichton62a0a592017-05-22 13:58:53 -0700947 };
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700948 qself.lt_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700949 qself.ty.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400950
951 // XXX: Gross.
952 let pos = if qself.position > 0 && qself.position >= self.1.segments.len() {
953 self.1.segments.len() - 1
954 } else {
955 qself.position
956 };
David Tolnay570695e2017-06-03 16:15:13 -0700957 let mut segments = self.1.segments.iter();
Michael Layzell3936ceb2017-07-08 00:28:36 -0400958 if pos > 0 {
Alex Crichton259ee532017-07-14 06:51:02 -0700959 TokensOrDefault(&qself.as_token).to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700960 self.1.leading_colon.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700961 for (i, segment) in (&mut segments).take(pos).enumerate() {
962 if i + 1 == pos {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700963 segment.item().to_tokens(tokens);
964 qself.gt_token.to_tokens(tokens);
965 segment.delimiter().to_tokens(tokens);
966 } else {
967 segment.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700968 }
Alex Crichton62a0a592017-05-22 13:58:53 -0700969 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700970 } else {
971 qself.gt_token.to_tokens(tokens);
David Tolnay570695e2017-06-03 16:15:13 -0700972 self.1.leading_colon.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700973 }
David Tolnay570695e2017-06-03 16:15:13 -0700974 for segment in segments {
Alex Crichton62a0a592017-05-22 13:58:53 -0700975 segment.to_tokens(tokens);
976 }
977 }
978 }
979
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800980 impl ToTokens for TypeTraitObject {
Alex Crichton62a0a592017-05-22 13:58:53 -0700981 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye45b59f2017-12-25 18:44:49 -0500982 self.dyn_token.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700983 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700984 }
985 }
986
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800987 impl ToTokens for TypeImplTrait {
Alex Crichton62a0a592017-05-22 13:58:53 -0700988 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700989 self.impl_token.to_tokens(tokens);
990 self.bounds.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -0700991 }
992 }
993
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800994 impl ToTokens for TypeGroup {
Michael Layzell93c36282017-06-04 20:43:14 -0400995 fn to_tokens(&self, tokens: &mut Tokens) {
996 self.group_token.surround(tokens, |tokens| {
997 self.ty.to_tokens(tokens);
998 });
999 }
1000 }
1001
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001002 impl ToTokens for TypeParen {
Alex Crichton62a0a592017-05-22 13:58:53 -07001003 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001004 self.paren_token.surround(tokens, |tokens| {
1005 self.ty.to_tokens(tokens);
1006 });
Alex Crichton62a0a592017-05-22 13:58:53 -07001007 }
1008 }
1009
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001010 impl ToTokens for TypeInfer {
Alex Crichton62a0a592017-05-22 13:58:53 -07001011 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001012 self.underscore_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001013 }
1014 }
1015
David Tolnay47a877c2016-10-01 16:50:55 -07001016 impl ToTokens for Mutability {
1017 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001018 if let Mutability::Mutable(ref t) = *self {
1019 t.to_tokens(tokens);
David Tolnay47a877c2016-10-01 16:50:55 -07001020 }
1021 }
1022 }
1023
David Tolnay87d0b442016-09-04 11:52:12 -07001024 impl ToTokens for Path {
1025 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001026 self.leading_colon.to_tokens(tokens);
1027 self.segments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001028 }
1029 }
1030
1031 impl ToTokens for PathSegment {
1032 fn to_tokens(&self, tokens: &mut Tokens) {
1033 self.ident.to_tokens(tokens);
Nika Layzellc08227a2017-12-04 16:30:17 -05001034 self.arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001035 }
1036 }
1037
Nika Layzellc08227a2017-12-04 16:30:17 -05001038 impl ToTokens for PathArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001039 fn to_tokens(&self, tokens: &mut Tokens) {
1040 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001041 PathArguments::None => {}
1042 PathArguments::AngleBracketed(ref arguments) => {
1043 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001044 }
Nika Layzellc08227a2017-12-04 16:30:17 -05001045 PathArguments::Parenthesized(ref arguments) => {
1046 arguments.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001047 }
1048 }
1049 }
1050 }
1051
Nika Layzellc08227a2017-12-04 16:30:17 -05001052 impl ToTokens for GenericArgument {
Nika Layzell357885a2017-12-04 15:47:07 -05001053 fn to_tokens(&self, tokens: &mut Tokens) {
1054 match *self {
Nika Layzellc08227a2017-12-04 16:30:17 -05001055 GenericArgument::Lifetime(ref lt) => lt.to_tokens(tokens),
1056 GenericArgument::Type(ref ty) => ty.to_tokens(tokens),
1057 GenericArgument::TypeBinding(ref tb) => tb.to_tokens(tokens),
Nika Layzellce37f332017-12-05 12:01:22 -05001058 GenericArgument::Const(ref e) => match e.node {
1059 ExprKind::Lit(_) => e.to_tokens(tokens),
1060
1061 // NOTE: We should probably support parsing blocks with only
1062 // expressions in them without the full feature for const
1063 // generics.
1064 #[cfg(feature = "full")]
1065 ExprKind::Block(_) => e.to_tokens(tokens),
1066
1067 // ERROR CORRECTION: Add braces to make sure that the
1068 // generated code is valid.
1069 _ => tokens::Brace::default().surround(tokens, |tokens| {
1070 e.to_tokens(tokens);
1071 }),
1072 }
Nika Layzell357885a2017-12-04 15:47:07 -05001073 }
1074 }
1075 }
1076
Nika Layzellc08227a2017-12-04 16:30:17 -05001077 impl ToTokens for AngleBracketedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001078 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay570695e2017-06-03 16:15:13 -07001079 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001080 self.lt_token.to_tokens(tokens);
Nika Layzell357885a2017-12-04 15:47:07 -05001081 self.args.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001082 self.gt_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001083 }
1084 }
1085
1086 impl ToTokens for TypeBinding {
1087 fn to_tokens(&self, tokens: &mut Tokens) {
1088 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001089 self.eq_token.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001090 self.ty.to_tokens(tokens);
1091 }
1092 }
1093
Nika Layzellc08227a2017-12-04 16:30:17 -05001094 impl ToTokens for ParenthesizedGenericArguments {
David Tolnay87d0b442016-09-04 11:52:12 -07001095 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001096 self.paren_token.surround(tokens, |tokens| {
1097 self.inputs.to_tokens(tokens);
1098 });
1099 self.output.to_tokens(tokens);
1100 }
1101 }
1102
David Tolnayf93b90d2017-11-11 19:21:26 -08001103 impl ToTokens for ReturnType {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001104 fn to_tokens(&self, tokens: &mut Tokens) {
1105 match *self {
David Tolnayf93b90d2017-11-11 19:21:26 -08001106 ReturnType::Default => {}
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001107 ReturnType::Type(ref ty, ref arrow) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001108 arrow.to_tokens(tokens);
1109 ty.to_tokens(tokens);
1110 }
David Tolnay87d0b442016-09-04 11:52:12 -07001111 }
1112 }
1113 }
1114
1115 impl ToTokens for PolyTraitRef {
1116 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001117 self.bound_lifetimes.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001118 self.trait_ref.to_tokens(tokens);
1119 }
1120 }
1121
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001122 impl ToTokens for BareFnType {
David Tolnay87d0b442016-09-04 11:52:12 -07001123 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001124 self.lifetimes.to_tokens(tokens);
David Tolnayb8d8ef52016-10-29 14:30:08 -07001125 self.unsafety.to_tokens(tokens);
1126 self.abi.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001127 self.fn_token.to_tokens(tokens);
1128 self.paren_token.surround(tokens, |tokens| {
1129 self.inputs.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001130 if self.variadic.is_some() && !self.inputs.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001131 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04001132 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001133 self.variadic.to_tokens(tokens);
1134 });
1135 self.output.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001136 }
1137 }
1138
David Tolnay62f374c2016-10-02 13:37:00 -07001139 impl ToTokens for BareFnArg {
David Tolnay42602292016-10-01 22:25:45 -07001140 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001141 if let Some((ref name, ref colon)) = self.name {
David Tolnay62f374c2016-10-02 13:37:00 -07001142 name.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001143 colon.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07001144 }
1145 self.ty.to_tokens(tokens);
David Tolnay87d0b442016-09-04 11:52:12 -07001146 }
1147 }
David Tolnayb8d8ef52016-10-29 14:30:08 -07001148
Alex Crichton23a15f62017-08-28 12:34:23 -07001149 impl ToTokens for BareFnArgName {
1150 fn to_tokens(&self, tokens: &mut Tokens) {
1151 match *self {
1152 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
1153 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
1154 }
1155 }
1156 }
1157
David Tolnayb8d8ef52016-10-29 14:30:08 -07001158 impl ToTokens for Unsafety {
1159 fn to_tokens(&self, tokens: &mut Tokens) {
1160 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001161 Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
David Tolnayb8d8ef52016-10-29 14:30:08 -07001162 Unsafety::Normal => {
1163 // nothing
1164 }
1165 }
1166 }
1167 }
1168
1169 impl ToTokens for Abi {
1170 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001171 self.extern_token.to_tokens(tokens);
1172 match self.kind {
1173 AbiKind::Named(ref named) => named.to_tokens(tokens),
1174 AbiKind::Default => {}
David Tolnayb8d8ef52016-10-29 14:30:08 -07001175 }
1176 }
1177 }
David Tolnay87d0b442016-09-04 11:52:12 -07001178}