]> git.proxmox.com Git - cargo.git/blob - vendor/syn/src/expr.rs
New upstream version 0.31.1
[cargo.git] / vendor / syn / src / expr.rs
1 // Copyright 2018 Syn Developers
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 use super::*;
10 use proc_macro2::{Span, TokenStream};
11 use punctuated::Punctuated;
12 #[cfg(feature = "extra-traits")]
13 use std::hash::{Hash, Hasher};
14 #[cfg(all(feature = "parsing", feature = "full"))]
15 use std::mem;
16 #[cfg(feature = "extra-traits")]
17 use tt::TokenStreamHelper;
18
19 ast_enum_of_structs! {
20 /// A Rust expression.
21 ///
22 /// *This type is available if Syn is built with the `"derive"` or `"full"`
23 /// feature.*
24 ///
25 /// # Syntax tree enums
26 ///
27 /// This type is a syntax tree enum. In Syn this and other syntax tree enums
28 /// are designed to be traversed using the following rebinding idiom.
29 ///
30 /// ```
31 /// # use syn::Expr;
32 /// #
33 /// # fn example(expr: Expr) {
34 /// # const IGNORE: &str = stringify! {
35 /// let expr: Expr = /* ... */;
36 /// # };
37 /// match expr {
38 /// Expr::MethodCall(expr) => {
39 /// /* ... */
40 /// }
41 /// Expr::Cast(expr) => {
42 /// /* ... */
43 /// }
44 /// Expr::If(expr) => {
45 /// /* ... */
46 /// }
47 /// /* ... */
48 /// # _ => {}
49 /// }
50 /// # }
51 /// ```
52 ///
53 /// We begin with a variable `expr` of type `Expr` that has no fields
54 /// (because it is an enum), and by matching on it and rebinding a variable
55 /// with the same name `expr` we effectively imbue our variable with all of
56 /// the data fields provided by the variant that it turned out to be. So for
57 /// example above if we ended up in the `MethodCall` case then we get to use
58 /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get
59 /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`.
60 ///
61 /// The pattern is similar if the input expression is borrowed:
62 ///
63 /// ```
64 /// # use syn::Expr;
65 /// #
66 /// # fn example(expr: &Expr) {
67 /// match *expr {
68 /// Expr::MethodCall(ref expr) => {
69 /// # }
70 /// # _ => {}
71 /// # }
72 /// # }
73 /// ```
74 ///
75 /// This approach avoids repeating the variant names twice on every line.
76 ///
77 /// ```
78 /// # use syn::{Expr, ExprMethodCall};
79 /// #
80 /// # fn example(expr: Expr) {
81 /// # match expr {
82 /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { // repetitive
83 /// # }
84 /// # _ => {}
85 /// # }
86 /// # }
87 /// ```
88 ///
89 /// In general, the name to which a syntax tree enum variant is bound should
90 /// be a suitable name for the complete syntax tree enum type.
91 ///
92 /// ```
93 /// # use syn::{Expr, ExprField};
94 /// #
95 /// # fn example(discriminant: &ExprField) {
96 /// // Binding is called `base` which is the name I would use if I were
97 /// // assigning `*discriminant.base` without an `if let`.
98 /// if let Expr::Tuple(ref base) = *discriminant.base {
99 /// # }
100 /// # }
101 /// ```
102 ///
103 /// A sign that you may not be choosing the right variable names is if you
104 /// see names getting repeated in your code, like accessing
105 /// `receiver.receiver` or `pat.pat` or `cond.cond`.
106 pub enum Expr {
107 /// A box expression: `box f`.
108 ///
109 /// *This type is available if Syn is built with the `"full"` feature.*
110 pub Box(ExprBox #full {
111 pub attrs: Vec<Attribute>,
112 pub box_token: Token![box],
113 pub expr: Box<Expr>,
114 }),
115
116 /// A placement expression: `place <- value`.
117 ///
118 /// *This type is available if Syn is built with the `"full"` feature.*
119 pub InPlace(ExprInPlace #full {
120 pub attrs: Vec<Attribute>,
121 pub place: Box<Expr>,
122 pub arrow_token: Token![<-],
123 pub value: Box<Expr>,
124 }),
125
126 /// A slice literal expression: `[a, b, c, d]`.
127 ///
128 /// *This type is available if Syn is built with the `"full"` feature.*
129 pub Array(ExprArray #full {
130 pub attrs: Vec<Attribute>,
131 pub bracket_token: token::Bracket,
132 pub elems: Punctuated<Expr, Token![,]>,
133 }),
134
135 /// A function call expression: `invoke(a, b)`.
136 ///
137 /// *This type is available if Syn is built with the `"derive"` or
138 /// `"full"` feature.*
139 pub Call(ExprCall {
140 pub attrs: Vec<Attribute>,
141 pub func: Box<Expr>,
142 pub paren_token: token::Paren,
143 pub args: Punctuated<Expr, Token![,]>,
144 }),
145
146 /// A method call expression: `x.foo::<T>(a, b)`.
147 ///
148 /// *This type is available if Syn is built with the `"full"` feature.*
149 pub MethodCall(ExprMethodCall #full {
150 pub attrs: Vec<Attribute>,
151 pub receiver: Box<Expr>,
152 pub dot_token: Token![.],
153 pub method: Ident,
154 pub turbofish: Option<MethodTurbofish>,
155 pub paren_token: token::Paren,
156 pub args: Punctuated<Expr, Token![,]>,
157 }),
158
159 /// A tuple expression: `(a, b, c, d)`.
160 ///
161 /// *This type is available if Syn is built with the `"full"` feature.*
162 pub Tuple(ExprTuple #full {
163 pub attrs: Vec<Attribute>,
164 pub paren_token: token::Paren,
165 pub elems: Punctuated<Expr, Token![,]>,
166 }),
167
168 /// A binary operation: `a + b`, `a * b`.
169 ///
170 /// *This type is available if Syn is built with the `"derive"` or
171 /// `"full"` feature.*
172 pub Binary(ExprBinary {
173 pub attrs: Vec<Attribute>,
174 pub left: Box<Expr>,
175 pub op: BinOp,
176 pub right: Box<Expr>,
177 }),
178
179 /// A unary operation: `!x`, `*x`.
180 ///
181 /// *This type is available if Syn is built with the `"derive"` or
182 /// `"full"` feature.*
183 pub Unary(ExprUnary {
184 pub attrs: Vec<Attribute>,
185 pub op: UnOp,
186 pub expr: Box<Expr>,
187 }),
188
189 /// A literal in place of an expression: `1`, `"foo"`.
190 ///
191 /// *This type is available if Syn is built with the `"derive"` or
192 /// `"full"` feature.*
193 pub Lit(ExprLit {
194 pub attrs: Vec<Attribute>,
195 pub lit: Lit,
196 }),
197
198 /// A cast expression: `foo as f64`.
199 ///
200 /// *This type is available if Syn is built with the `"derive"` or
201 /// `"full"` feature.*
202 pub Cast(ExprCast {
203 pub attrs: Vec<Attribute>,
204 pub expr: Box<Expr>,
205 pub as_token: Token![as],
206 pub ty: Box<Type>,
207 }),
208
209 /// A type ascription expression: `foo: f64`.
210 ///
211 /// *This type is available if Syn is built with the `"full"` feature.*
212 pub Type(ExprType #full {
213 pub attrs: Vec<Attribute>,
214 pub expr: Box<Expr>,
215 pub colon_token: Token![:],
216 pub ty: Box<Type>,
217 }),
218
219 /// A `let` guard: `let Some(x) = opt`.
220 ///
221 /// *This type is available if Syn is built with the `"full"` feature.*
222 pub Let(ExprLet #full {
223 pub attrs: Vec<Attribute>,
224 pub let_token: Token![let],
225 pub pats: Punctuated<Pat, Token![|]>,
226 pub eq_token: Token![=],
227 pub expr: Box<Expr>,
228 }),
229
230 /// An `if` expression with an optional `else` block: `if expr { ... }
231 /// else { ... }`.
232 ///
233 /// The `else` branch expression may only be an `If` or `Block`
234 /// expression, not any of the other types of expression.
235 ///
236 /// *This type is available if Syn is built with the `"full"` feature.*
237 pub If(ExprIf #full {
238 pub attrs: Vec<Attribute>,
239 pub if_token: Token![if],
240 pub cond: Box<Expr>,
241 pub then_branch: Block,
242 pub else_branch: Option<(Token![else], Box<Expr>)>,
243 }),
244
245 /// A while loop: `while expr { ... }`.
246 ///
247 /// *This type is available if Syn is built with the `"full"` feature.*
248 pub While(ExprWhile #full {
249 pub attrs: Vec<Attribute>,
250 pub label: Option<Label>,
251 pub while_token: Token![while],
252 pub cond: Box<Expr>,
253 pub body: Block,
254 }),
255
256 /// A for loop: `for pat in expr { ... }`.
257 ///
258 /// *This type is available if Syn is built with the `"full"` feature.*
259 pub ForLoop(ExprForLoop #full {
260 pub attrs: Vec<Attribute>,
261 pub label: Option<Label>,
262 pub for_token: Token![for],
263 pub pat: Box<Pat>,
264 pub in_token: Token![in],
265 pub expr: Box<Expr>,
266 pub body: Block,
267 }),
268
269 /// Conditionless loop: `loop { ... }`.
270 ///
271 /// *This type is available if Syn is built with the `"full"` feature.*
272 pub Loop(ExprLoop #full {
273 pub attrs: Vec<Attribute>,
274 pub label: Option<Label>,
275 pub loop_token: Token![loop],
276 pub body: Block,
277 }),
278
279 /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
280 ///
281 /// *This type is available if Syn is built with the `"full"` feature.*
282 pub Match(ExprMatch #full {
283 pub attrs: Vec<Attribute>,
284 pub match_token: Token![match],
285 pub expr: Box<Expr>,
286 pub brace_token: token::Brace,
287 pub arms: Vec<Arm>,
288 }),
289
290 /// A closure expression: `|a, b| a + b`.
291 ///
292 /// *This type is available if Syn is built with the `"full"` feature.*
293 pub Closure(ExprClosure #full {
294 pub attrs: Vec<Attribute>,
295 pub asyncness: Option<Token![async]>,
296 pub movability: Option<Token![static]>,
297 pub capture: Option<Token![move]>,
298 pub or1_token: Token![|],
299 pub inputs: Punctuated<FnArg, Token![,]>,
300 pub or2_token: Token![|],
301 pub output: ReturnType,
302 pub body: Box<Expr>,
303 }),
304
305 /// An unsafe block: `unsafe { ... }`.
306 ///
307 /// *This type is available if Syn is built with the `"full"` feature.*
308 pub Unsafe(ExprUnsafe #full {
309 pub attrs: Vec<Attribute>,
310 pub unsafe_token: Token![unsafe],
311 pub block: Block,
312 }),
313
314 /// A blocked scope: `{ ... }`.
315 ///
316 /// *This type is available if Syn is built with the `"full"` feature.*
317 pub Block(ExprBlock #full {
318 pub attrs: Vec<Attribute>,
319 pub label: Option<Label>,
320 pub block: Block,
321 }),
322
323 /// An assignment expression: `a = compute()`.
324 ///
325 /// *This type is available if Syn is built with the `"full"` feature.*
326 pub Assign(ExprAssign #full {
327 pub attrs: Vec<Attribute>,
328 pub left: Box<Expr>,
329 pub eq_token: Token![=],
330 pub right: Box<Expr>,
331 }),
332
333 /// A compound assignment expression: `counter += 1`.
334 ///
335 /// *This type is available if Syn is built with the `"full"` feature.*
336 pub AssignOp(ExprAssignOp #full {
337 pub attrs: Vec<Attribute>,
338 pub left: Box<Expr>,
339 pub op: BinOp,
340 pub right: Box<Expr>,
341 }),
342
343 /// Access of a named struct field (`obj.k`) or unnamed tuple struct
344 /// field (`obj.0`).
345 ///
346 /// *This type is available if Syn is built with the `"full"` feature.*
347 pub Field(ExprField {
348 pub attrs: Vec<Attribute>,
349 pub base: Box<Expr>,
350 pub dot_token: Token![.],
351 pub member: Member,
352 }),
353
354 /// A square bracketed indexing expression: `vector[2]`.
355 ///
356 /// *This type is available if Syn is built with the `"derive"` or
357 /// `"full"` feature.*
358 pub Index(ExprIndex {
359 pub attrs: Vec<Attribute>,
360 pub expr: Box<Expr>,
361 pub bracket_token: token::Bracket,
362 pub index: Box<Expr>,
363 }),
364
365 /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
366 ///
367 /// *This type is available if Syn is built with the `"full"` feature.*
368 pub Range(ExprRange #full {
369 pub attrs: Vec<Attribute>,
370 pub from: Option<Box<Expr>>,
371 pub limits: RangeLimits,
372 pub to: Option<Box<Expr>>,
373 }),
374
375 /// A path like `std::mem::replace` possibly containing generic
376 /// parameters and a qualified self-type.
377 ///
378 /// A plain identifier like `x` is a path of length 1.
379 ///
380 /// *This type is available if Syn is built with the `"derive"` or
381 /// `"full"` feature.*
382 pub Path(ExprPath {
383 pub attrs: Vec<Attribute>,
384 pub qself: Option<QSelf>,
385 pub path: Path,
386 }),
387
388 /// A referencing operation: `&a` or `&mut a`.
389 ///
390 /// *This type is available if Syn is built with the `"full"` feature.*
391 pub Reference(ExprReference #full {
392 pub attrs: Vec<Attribute>,
393 pub and_token: Token![&],
394 pub mutability: Option<Token![mut]>,
395 pub expr: Box<Expr>,
396 }),
397
398 /// A `break`, with an optional label to break and an optional
399 /// expression.
400 ///
401 /// *This type is available if Syn is built with the `"full"` feature.*
402 pub Break(ExprBreak #full {
403 pub attrs: Vec<Attribute>,
404 pub break_token: Token![break],
405 pub label: Option<Lifetime>,
406 pub expr: Option<Box<Expr>>,
407 }),
408
409 /// A `continue`, with an optional label.
410 ///
411 /// *This type is available if Syn is built with the `"full"` feature.*
412 pub Continue(ExprContinue #full {
413 pub attrs: Vec<Attribute>,
414 pub continue_token: Token![continue],
415 pub label: Option<Lifetime>,
416 }),
417
418 /// A `return`, with an optional value to be returned.
419 ///
420 /// *This type is available if Syn is built with the `"full"` feature.*
421 pub Return(ExprReturn #full {
422 pub attrs: Vec<Attribute>,
423 pub return_token: Token![return],
424 pub expr: Option<Box<Expr>>,
425 }),
426
427 /// A macro invocation expression: `format!("{}", q)`.
428 ///
429 /// *This type is available if Syn is built with the `"full"` feature.*
430 pub Macro(ExprMacro #full {
431 pub attrs: Vec<Attribute>,
432 pub mac: Macro,
433 }),
434
435 /// A struct literal expression: `Point { x: 1, y: 1 }`.
436 ///
437 /// The `rest` provides the value of the remaining fields as in `S { a:
438 /// 1, b: 1, ..rest }`.
439 ///
440 /// *This type is available if Syn is built with the `"full"` feature.*
441 pub Struct(ExprStruct #full {
442 pub attrs: Vec<Attribute>,
443 pub path: Path,
444 pub brace_token: token::Brace,
445 pub fields: Punctuated<FieldValue, Token![,]>,
446 pub dot2_token: Option<Token![..]>,
447 pub rest: Option<Box<Expr>>,
448 }),
449
450 /// An array literal constructed from one repeated element: `[0u8; N]`.
451 ///
452 /// *This type is available if Syn is built with the `"full"` feature.*
453 pub Repeat(ExprRepeat #full {
454 pub attrs: Vec<Attribute>,
455 pub bracket_token: token::Bracket,
456 pub expr: Box<Expr>,
457 pub semi_token: Token![;],
458 pub len: Box<Expr>,
459 }),
460
461 /// A parenthesized expression: `(a + b)`.
462 ///
463 /// *This type is available if Syn is built with the `"full"` feature.*
464 pub Paren(ExprParen {
465 pub attrs: Vec<Attribute>,
466 pub paren_token: token::Paren,
467 pub expr: Box<Expr>,
468 }),
469
470 /// An expression contained within invisible delimiters.
471 ///
472 /// This variant is important for faithfully representing the precedence
473 /// of expressions and is related to `None`-delimited spans in a
474 /// `TokenStream`.
475 ///
476 /// *This type is available if Syn is built with the `"full"` feature.*
477 pub Group(ExprGroup #full {
478 pub attrs: Vec<Attribute>,
479 pub group_token: token::Group,
480 pub expr: Box<Expr>,
481 }),
482
483 /// A try-expression: `expr?`.
484 ///
485 /// *This type is available if Syn is built with the `"full"` feature.*
486 pub Try(ExprTry #full {
487 pub attrs: Vec<Attribute>,
488 pub expr: Box<Expr>,
489 pub question_token: Token![?],
490 }),
491
492 /// An async block: `async { ... }`.
493 ///
494 /// *This type is available if Syn is built with the `"full"` feature.*
495 pub Async(ExprAsync #full {
496 pub attrs: Vec<Attribute>,
497 pub async_token: Token![async],
498 pub capture: Option<Token![move]>,
499 pub block: Block,
500 }),
501
502 /// A try block: `try { ... }`.
503 ///
504 /// *This type is available if Syn is built with the `"full"` feature.*
505 pub TryBlock(ExprTryBlock #full {
506 pub attrs: Vec<Attribute>,
507 pub try_token: Token![try],
508 pub block: Block,
509 }),
510
511 /// A yield expression: `yield expr`.
512 ///
513 /// *This type is available if Syn is built with the `"full"` feature.*
514 pub Yield(ExprYield #full {
515 pub attrs: Vec<Attribute>,
516 pub yield_token: Token![yield],
517 pub expr: Option<Box<Expr>>,
518 }),
519
520 /// Tokens in expression position not interpreted by Syn.
521 ///
522 /// *This type is available if Syn is built with the `"derive"` or
523 /// `"full"` feature.*
524 pub Verbatim(ExprVerbatim #manual_extra_traits {
525 pub tts: TokenStream,
526 }),
527 }
528 }
529
530 #[cfg(feature = "extra-traits")]
531 impl Eq for ExprVerbatim {}
532
533 #[cfg(feature = "extra-traits")]
534 impl PartialEq for ExprVerbatim {
535 fn eq(&self, other: &Self) -> bool {
536 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
537 }
538 }
539
540 #[cfg(feature = "extra-traits")]
541 impl Hash for ExprVerbatim {
542 fn hash<H>(&self, state: &mut H)
543 where
544 H: Hasher,
545 {
546 TokenStreamHelper(&self.tts).hash(state);
547 }
548 }
549
550 impl Expr {
551 #[cfg(all(feature = "parsing", feature = "full"))]
552 fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
553 match *self {
554 Expr::Box(ExprBox { ref mut attrs, .. })
555 | Expr::InPlace(ExprInPlace { ref mut attrs, .. })
556 | Expr::Array(ExprArray { ref mut attrs, .. })
557 | Expr::Call(ExprCall { ref mut attrs, .. })
558 | Expr::MethodCall(ExprMethodCall { ref mut attrs, .. })
559 | Expr::Tuple(ExprTuple { ref mut attrs, .. })
560 | Expr::Binary(ExprBinary { ref mut attrs, .. })
561 | Expr::Unary(ExprUnary { ref mut attrs, .. })
562 | Expr::Lit(ExprLit { ref mut attrs, .. })
563 | Expr::Cast(ExprCast { ref mut attrs, .. })
564 | Expr::Type(ExprType { ref mut attrs, .. })
565 | Expr::Let(ExprLet { ref mut attrs, .. })
566 | Expr::If(ExprIf { ref mut attrs, .. })
567 | Expr::While(ExprWhile { ref mut attrs, .. })
568 | Expr::ForLoop(ExprForLoop { ref mut attrs, .. })
569 | Expr::Loop(ExprLoop { ref mut attrs, .. })
570 | Expr::Match(ExprMatch { ref mut attrs, .. })
571 | Expr::Closure(ExprClosure { ref mut attrs, .. })
572 | Expr::Unsafe(ExprUnsafe { ref mut attrs, .. })
573 | Expr::Block(ExprBlock { ref mut attrs, .. })
574 | Expr::Assign(ExprAssign { ref mut attrs, .. })
575 | Expr::AssignOp(ExprAssignOp { ref mut attrs, .. })
576 | Expr::Field(ExprField { ref mut attrs, .. })
577 | Expr::Index(ExprIndex { ref mut attrs, .. })
578 | Expr::Range(ExprRange { ref mut attrs, .. })
579 | Expr::Path(ExprPath { ref mut attrs, .. })
580 | Expr::Reference(ExprReference { ref mut attrs, .. })
581 | Expr::Break(ExprBreak { ref mut attrs, .. })
582 | Expr::Continue(ExprContinue { ref mut attrs, .. })
583 | Expr::Return(ExprReturn { ref mut attrs, .. })
584 | Expr::Macro(ExprMacro { ref mut attrs, .. })
585 | Expr::Struct(ExprStruct { ref mut attrs, .. })
586 | Expr::Repeat(ExprRepeat { ref mut attrs, .. })
587 | Expr::Paren(ExprParen { ref mut attrs, .. })
588 | Expr::Group(ExprGroup { ref mut attrs, .. })
589 | Expr::Try(ExprTry { ref mut attrs, .. })
590 | Expr::Async(ExprAsync { ref mut attrs, .. })
591 | Expr::TryBlock(ExprTryBlock { ref mut attrs, .. })
592 | Expr::Yield(ExprYield { ref mut attrs, .. }) => mem::replace(attrs, new),
593 Expr::Verbatim(_) => Vec::new(),
594 }
595 }
596 }
597
598 ast_enum! {
599 /// A struct or tuple struct field accessed in a struct literal or field
600 /// expression.
601 ///
602 /// *This type is available if Syn is built with the `"derive"` or `"full"`
603 /// feature.*
604 pub enum Member {
605 /// A named field like `self.x`.
606 Named(Ident),
607 /// An unnamed field like `self.0`.
608 Unnamed(Index),
609 }
610 }
611
612 ast_struct! {
613 /// The index of an unnamed tuple struct field.
614 ///
615 /// *This type is available if Syn is built with the `"derive"` or `"full"`
616 /// feature.*
617 pub struct Index #manual_extra_traits {
618 pub index: u32,
619 pub span: Span,
620 }
621 }
622
623 impl From<usize> for Index {
624 fn from(index: usize) -> Index {
625 assert!(index < u32::max_value() as usize);
626 Index {
627 index: index as u32,
628 span: Span::call_site(),
629 }
630 }
631 }
632
633 #[cfg(feature = "extra-traits")]
634 impl Eq for Index {}
635
636 #[cfg(feature = "extra-traits")]
637 impl PartialEq for Index {
638 fn eq(&self, other: &Self) -> bool {
639 self.index == other.index
640 }
641 }
642
643 #[cfg(feature = "extra-traits")]
644 impl Hash for Index {
645 fn hash<H: Hasher>(&self, state: &mut H) {
646 self.index.hash(state);
647 }
648 }
649
650 #[cfg(feature = "full")]
651 ast_struct! {
652 /// The `::<>` explicit type parameters passed to a method call:
653 /// `parse::<u64>()`.
654 ///
655 /// *This type is available if Syn is built with the `"full"` feature.*
656 pub struct MethodTurbofish {
657 pub colon2_token: Token![::],
658 pub lt_token: Token![<],
659 pub args: Punctuated<GenericMethodArgument, Token![,]>,
660 pub gt_token: Token![>],
661 }
662 }
663
664 #[cfg(feature = "full")]
665 ast_enum! {
666 /// An individual generic argument to a method, like `T`.
667 ///
668 /// *This type is available if Syn is built with the `"full"` feature.*
669 pub enum GenericMethodArgument {
670 /// A type argument.
671 Type(Type),
672 /// A const expression. Must be inside of a block.
673 ///
674 /// NOTE: Identity expressions are represented as Type arguments, as
675 /// they are indistinguishable syntactically.
676 Const(Expr),
677 }
678 }
679
680 #[cfg(feature = "full")]
681 ast_struct! {
682 /// A field-value pair in a struct literal.
683 ///
684 /// *This type is available if Syn is built with the `"full"` feature.*
685 pub struct FieldValue {
686 /// Attributes tagged on the field.
687 pub attrs: Vec<Attribute>,
688
689 /// Name or index of the field.
690 pub member: Member,
691
692 /// The colon in `Struct { x: x }`. If written in shorthand like
693 /// `Struct { x }`, there is no colon.
694 pub colon_token: Option<Token![:]>,
695
696 /// Value of the field.
697 pub expr: Expr,
698 }
699 }
700
701 #[cfg(feature = "full")]
702 ast_struct! {
703 /// A lifetime labeling a `for`, `while`, or `loop`.
704 ///
705 /// *This type is available if Syn is built with the `"full"` feature.*
706 pub struct Label {
707 pub name: Lifetime,
708 pub colon_token: Token![:],
709 }
710 }
711
712 #[cfg(feature = "full")]
713 ast_struct! {
714 /// A braced block containing Rust statements.
715 ///
716 /// *This type is available if Syn is built with the `"full"` feature.*
717 pub struct Block {
718 pub brace_token: token::Brace,
719 /// Statements in a block
720 pub stmts: Vec<Stmt>,
721 }
722 }
723
724 #[cfg(feature = "full")]
725 ast_enum! {
726 /// A statement, usually ending in a semicolon.
727 ///
728 /// *This type is available if Syn is built with the `"full"` feature.*
729 pub enum Stmt {
730 /// A local (let) binding.
731 Local(Local),
732
733 /// An item definition.
734 Item(Item),
735
736 /// Expr without trailing semicolon.
737 Expr(Expr),
738
739 /// Expression with trailing semicolon.
740 Semi(Expr, Token![;]),
741 }
742 }
743
744 #[cfg(feature = "full")]
745 ast_struct! {
746 /// A local `let` binding: `let x: u64 = s.parse()?`.
747 ///
748 /// *This type is available if Syn is built with the `"full"` feature.*
749 pub struct Local {
750 pub attrs: Vec<Attribute>,
751 pub let_token: Token![let],
752 pub pats: Punctuated<Pat, Token![|]>,
753 pub ty: Option<(Token![:], Box<Type>)>,
754 pub init: Option<(Token![=], Box<Expr>)>,
755 pub semi_token: Token![;],
756 }
757 }
758
759 #[cfg(feature = "full")]
760 ast_enum_of_structs! {
761 /// A pattern in a local binding, function signature, match expression, or
762 /// various other places.
763 ///
764 /// *This type is available if Syn is built with the `"full"` feature.*
765 ///
766 /// # Syntax tree enum
767 ///
768 /// This type is a [syntax tree enum].
769 ///
770 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
771 pub enum Pat {
772 /// A pattern that matches any value: `_`.
773 ///
774 /// *This type is available if Syn is built with the `"full"` feature.*
775 pub Wild(PatWild {
776 pub underscore_token: Token![_],
777 }),
778
779 /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
780 ///
781 /// *This type is available if Syn is built with the `"full"` feature.*
782 pub Ident(PatIdent {
783 pub by_ref: Option<Token![ref]>,
784 pub mutability: Option<Token![mut]>,
785 pub ident: Ident,
786 pub subpat: Option<(Token![@], Box<Pat>)>,
787 }),
788
789 /// A struct or struct variant pattern: `Variant { x, y, .. }`.
790 ///
791 /// *This type is available if Syn is built with the `"full"` feature.*
792 pub Struct(PatStruct {
793 pub path: Path,
794 pub brace_token: token::Brace,
795 pub fields: Punctuated<FieldPat, Token![,]>,
796 pub dot2_token: Option<Token![..]>,
797 }),
798
799 /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
800 ///
801 /// *This type is available if Syn is built with the `"full"` feature.*
802 pub TupleStruct(PatTupleStruct {
803 pub path: Path,
804 pub pat: PatTuple,
805 }),
806
807 /// A path pattern like `Color::Red`, optionally qualified with a
808 /// self-type.
809 ///
810 /// Unquailfied path patterns can legally refer to variants, structs,
811 /// constants or associated constants. Quailfied path patterns like
812 /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
813 /// associated constants.
814 ///
815 /// *This type is available if Syn is built with the `"full"` feature.*
816 pub Path(PatPath {
817 pub qself: Option<QSelf>,
818 pub path: Path,
819 }),
820
821 /// A tuple pattern: `(a, b)`.
822 ///
823 /// *This type is available if Syn is built with the `"full"` feature.*
824 pub Tuple(PatTuple {
825 pub paren_token: token::Paren,
826 pub front: Punctuated<Pat, Token![,]>,
827 pub dot2_token: Option<Token![..]>,
828 pub comma_token: Option<Token![,]>,
829 pub back: Punctuated<Pat, Token![,]>,
830 }),
831
832 /// A box pattern: `box v`.
833 ///
834 /// *This type is available if Syn is built with the `"full"` feature.*
835 pub Box(PatBox {
836 pub box_token: Token![box],
837 pub pat: Box<Pat>,
838 }),
839
840 /// A reference pattern: `&mut (first, second)`.
841 ///
842 /// *This type is available if Syn is built with the `"full"` feature.*
843 pub Ref(PatRef {
844 pub and_token: Token![&],
845 pub mutability: Option<Token![mut]>,
846 pub pat: Box<Pat>,
847 }),
848
849 /// A literal pattern: `0`.
850 ///
851 /// This holds an `Expr` rather than a `Lit` because negative numbers
852 /// are represented as an `Expr::Unary`.
853 ///
854 /// *This type is available if Syn is built with the `"full"` feature.*
855 pub Lit(PatLit {
856 pub expr: Box<Expr>,
857 }),
858
859 /// A range pattern: `1..=2`.
860 ///
861 /// *This type is available if Syn is built with the `"full"` feature.*
862 pub Range(PatRange {
863 pub lo: Box<Expr>,
864 pub limits: RangeLimits,
865 pub hi: Box<Expr>,
866 }),
867
868 /// A dynamically sized slice pattern: `[a, b, i.., y, z]`.
869 ///
870 /// *This type is available if Syn is built with the `"full"` feature.*
871 pub Slice(PatSlice {
872 pub bracket_token: token::Bracket,
873 pub front: Punctuated<Pat, Token![,]>,
874 pub middle: Option<Box<Pat>>,
875 pub dot2_token: Option<Token![..]>,
876 pub comma_token: Option<Token![,]>,
877 pub back: Punctuated<Pat, Token![,]>,
878 }),
879
880 /// A macro in expression position.
881 ///
882 /// *This type is available if Syn is built with the `"full"` feature.*
883 pub Macro(PatMacro {
884 pub mac: Macro,
885 }),
886
887 /// Tokens in pattern position not interpreted by Syn.
888 ///
889 /// *This type is available if Syn is built with the `"full"` feature.*
890 pub Verbatim(PatVerbatim #manual_extra_traits {
891 pub tts: TokenStream,
892 }),
893 }
894 }
895
896 #[cfg(all(feature = "full", feature = "extra-traits"))]
897 impl Eq for PatVerbatim {}
898
899 #[cfg(all(feature = "full", feature = "extra-traits"))]
900 impl PartialEq for PatVerbatim {
901 fn eq(&self, other: &Self) -> bool {
902 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
903 }
904 }
905
906 #[cfg(all(feature = "full", feature = "extra-traits"))]
907 impl Hash for PatVerbatim {
908 fn hash<H>(&self, state: &mut H)
909 where
910 H: Hasher,
911 {
912 TokenStreamHelper(&self.tts).hash(state);
913 }
914 }
915
916 #[cfg(feature = "full")]
917 ast_struct! {
918 /// One arm of a `match` expression: `0...10 => { return true; }`.
919 ///
920 /// As in:
921 ///
922 /// ```rust
923 /// # fn f() -> bool {
924 /// # let n = 0;
925 /// match n {
926 /// 0...10 => {
927 /// return true;
928 /// }
929 /// // ...
930 /// # _ => {}
931 /// }
932 /// # false
933 /// # }
934 /// ```
935 ///
936 /// *This type is available if Syn is built with the `"full"` feature.*
937 pub struct Arm {
938 pub attrs: Vec<Attribute>,
939 pub leading_vert: Option<Token![|]>,
940 pub pats: Punctuated<Pat, Token![|]>,
941 pub guard: Option<(Token![if], Box<Expr>)>,
942 pub fat_arrow_token: Token![=>],
943 pub body: Box<Expr>,
944 pub comma: Option<Token![,]>,
945 }
946 }
947
948 #[cfg(feature = "full")]
949 ast_enum! {
950 /// Limit types of a range, inclusive or exclusive.
951 ///
952 /// *This type is available if Syn is built with the `"full"` feature.*
953 #[cfg_attr(feature = "clone-impls", derive(Copy))]
954 pub enum RangeLimits {
955 /// Inclusive at the beginning, exclusive at the end.
956 HalfOpen(Token![..]),
957 /// Inclusive at the beginning and end.
958 Closed(Token![..=]),
959 }
960 }
961
962 #[cfg(feature = "full")]
963 ast_struct! {
964 /// A single field in a struct pattern.
965 ///
966 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
967 /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
968 ///
969 /// *This type is available if Syn is built with the `"full"` feature.*
970 pub struct FieldPat {
971 pub attrs: Vec<Attribute>,
972 pub member: Member,
973 pub colon_token: Option<Token![:]>,
974 pub pat: Box<Pat>,
975 }
976 }
977
978 #[cfg(any(feature = "parsing", feature = "printing"))]
979 #[cfg(feature = "full")]
980 fn requires_terminator(expr: &Expr) -> bool {
981 // see https://github.com/rust-lang/rust/blob/eb8f2586e/src/libsyntax/parse/classify.rs#L17-L37
982 match *expr {
983 Expr::Unsafe(..)
984 | Expr::Block(..)
985 | Expr::If(..)
986 | Expr::Match(..)
987 | Expr::While(..)
988 | Expr::Loop(..)
989 | Expr::ForLoop(..)
990 | Expr::Async(..)
991 | Expr::TryBlock(..) => false,
992 _ => true,
993 }
994 }
995
996 #[cfg(feature = "parsing")]
997 pub mod parsing {
998 use super::*;
999
1000 #[cfg(feature = "full")]
1001 use ext::IdentExt;
1002 use parse::{Parse, ParseStream, Result};
1003 use path;
1004
1005 // When we're parsing expressions which occur before blocks, like in an if
1006 // statement's condition, we cannot parse a struct literal.
1007 //
1008 // Struct literals are ambiguous in certain positions
1009 // https://github.com/rust-lang/rfcs/pull/92
1010 #[derive(Copy, Clone)]
1011 pub struct AllowStruct(bool);
1012
1013 #[derive(Copy, Clone, PartialEq, PartialOrd)]
1014 enum Precedence {
1015 Any,
1016 Assign,
1017 Placement,
1018 Range,
1019 Or,
1020 And,
1021 Compare,
1022 BitOr,
1023 BitXor,
1024 BitAnd,
1025 Shift,
1026 Arithmetic,
1027 Term,
1028 Cast,
1029 }
1030
1031 impl Precedence {
1032 fn of(op: &BinOp) -> Self {
1033 match *op {
1034 BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
1035 BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
1036 BinOp::And(_) => Precedence::And,
1037 BinOp::Or(_) => Precedence::Or,
1038 BinOp::BitXor(_) => Precedence::BitXor,
1039 BinOp::BitAnd(_) => Precedence::BitAnd,
1040 BinOp::BitOr(_) => Precedence::BitOr,
1041 BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
1042 BinOp::Eq(_)
1043 | BinOp::Lt(_)
1044 | BinOp::Le(_)
1045 | BinOp::Ne(_)
1046 | BinOp::Ge(_)
1047 | BinOp::Gt(_) => Precedence::Compare,
1048 BinOp::AddEq(_)
1049 | BinOp::SubEq(_)
1050 | BinOp::MulEq(_)
1051 | BinOp::DivEq(_)
1052 | BinOp::RemEq(_)
1053 | BinOp::BitXorEq(_)
1054 | BinOp::BitAndEq(_)
1055 | BinOp::BitOrEq(_)
1056 | BinOp::ShlEq(_)
1057 | BinOp::ShrEq(_) => Precedence::Assign,
1058 }
1059 }
1060 }
1061
1062 impl Parse for Expr {
1063 fn parse(input: ParseStream) -> Result<Self> {
1064 ambiguous_expr(input, AllowStruct(true))
1065 }
1066 }
1067
1068 #[cfg(feature = "full")]
1069 fn expr_no_struct(input: ParseStream) -> Result<Expr> {
1070 ambiguous_expr(input, AllowStruct(false))
1071 }
1072
1073 #[cfg(feature = "full")]
1074 fn parse_expr(
1075 input: ParseStream,
1076 mut lhs: Expr,
1077 allow_struct: AllowStruct,
1078 base: Precedence,
1079 ) -> Result<Expr> {
1080 loop {
1081 if input
1082 .fork()
1083 .parse::<BinOp>()
1084 .ok()
1085 .map_or(false, |op| Precedence::of(&op) >= base)
1086 {
1087 let op: BinOp = input.parse()?;
1088 let precedence = Precedence::of(&op);
1089 let mut rhs = unary_expr(input, allow_struct)?;
1090 loop {
1091 let next = peek_precedence(input);
1092 if next > precedence || next == precedence && precedence == Precedence::Assign {
1093 rhs = parse_expr(input, rhs, allow_struct, next)?;
1094 } else {
1095 break;
1096 }
1097 }
1098 lhs = if precedence == Precedence::Assign {
1099 Expr::AssignOp(ExprAssignOp {
1100 attrs: Vec::new(),
1101 left: Box::new(lhs),
1102 op: op,
1103 right: Box::new(rhs),
1104 })
1105 } else {
1106 Expr::Binary(ExprBinary {
1107 attrs: Vec::new(),
1108 left: Box::new(lhs),
1109 op: op,
1110 right: Box::new(rhs),
1111 })
1112 };
1113 } else if Precedence::Assign >= base
1114 && input.peek(Token![=])
1115 && !input.peek(Token![==])
1116 && !input.peek(Token![=>])
1117 {
1118 let eq_token: Token![=] = input.parse()?;
1119 let mut rhs = unary_expr(input, allow_struct)?;
1120 loop {
1121 let next = peek_precedence(input);
1122 if next >= Precedence::Assign {
1123 rhs = parse_expr(input, rhs, allow_struct, next)?;
1124 } else {
1125 break;
1126 }
1127 }
1128 lhs = Expr::Assign(ExprAssign {
1129 attrs: Vec::new(),
1130 left: Box::new(lhs),
1131 eq_token: eq_token,
1132 right: Box::new(rhs),
1133 });
1134 } else if Precedence::Placement >= base && input.peek(Token![<-]) {
1135 let arrow_token: Token![<-] = input.parse()?;
1136 let mut rhs = unary_expr(input, allow_struct)?;
1137 loop {
1138 let next = peek_precedence(input);
1139 if next > Precedence::Placement {
1140 rhs = parse_expr(input, rhs, allow_struct, next)?;
1141 } else {
1142 break;
1143 }
1144 }
1145 lhs = Expr::InPlace(ExprInPlace {
1146 attrs: Vec::new(),
1147 place: Box::new(lhs),
1148 arrow_token: arrow_token,
1149 value: Box::new(rhs),
1150 });
1151 } else if Precedence::Range >= base && input.peek(Token![..]) {
1152 let limits: RangeLimits = input.parse()?;
1153 let rhs = if input.is_empty()
1154 || input.peek(Token![,])
1155 || input.peek(Token![;])
1156 || !allow_struct.0 && input.peek(token::Brace)
1157 {
1158 None
1159 } else {
1160 let mut rhs = unary_expr(input, allow_struct)?;
1161 loop {
1162 let next = peek_precedence(input);
1163 if next > Precedence::Range {
1164 rhs = parse_expr(input, rhs, allow_struct, next)?;
1165 } else {
1166 break;
1167 }
1168 }
1169 Some(rhs)
1170 };
1171 lhs = Expr::Range(ExprRange {
1172 attrs: Vec::new(),
1173 from: Some(Box::new(lhs)),
1174 limits: limits,
1175 to: rhs.map(Box::new),
1176 });
1177 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1178 let as_token: Token![as] = input.parse()?;
1179 let ty = input.call(Type::without_plus)?;
1180 lhs = Expr::Cast(ExprCast {
1181 attrs: Vec::new(),
1182 expr: Box::new(lhs),
1183 as_token: as_token,
1184 ty: Box::new(ty),
1185 });
1186 } else if Precedence::Cast >= base && input.peek(Token![:]) && !input.peek(Token![::]) {
1187 let colon_token: Token![:] = input.parse()?;
1188 let ty = input.call(Type::without_plus)?;
1189 lhs = Expr::Type(ExprType {
1190 attrs: Vec::new(),
1191 expr: Box::new(lhs),
1192 colon_token: colon_token,
1193 ty: Box::new(ty),
1194 });
1195 } else {
1196 break;
1197 }
1198 }
1199 Ok(lhs)
1200 }
1201
1202 #[cfg(not(feature = "full"))]
1203 fn parse_expr(
1204 input: ParseStream,
1205 mut lhs: Expr,
1206 allow_struct: AllowStruct,
1207 base: Precedence,
1208 ) -> Result<Expr> {
1209 loop {
1210 if input
1211 .fork()
1212 .parse::<BinOp>()
1213 .ok()
1214 .map_or(false, |op| Precedence::of(&op) >= base)
1215 {
1216 let op: BinOp = input.parse()?;
1217 let precedence = Precedence::of(&op);
1218 let mut rhs = unary_expr(input, allow_struct)?;
1219 loop {
1220 let next = peek_precedence(input);
1221 if next > precedence || next == precedence && precedence == Precedence::Assign {
1222 rhs = parse_expr(input, rhs, allow_struct, next)?;
1223 } else {
1224 break;
1225 }
1226 }
1227 lhs = Expr::Binary(ExprBinary {
1228 attrs: Vec::new(),
1229 left: Box::new(lhs),
1230 op: op,
1231 right: Box::new(rhs),
1232 });
1233 } else if Precedence::Cast >= base && input.peek(Token![as]) {
1234 let as_token: Token![as] = input.parse()?;
1235 let ty = input.call(Type::without_plus)?;
1236 lhs = Expr::Cast(ExprCast {
1237 attrs: Vec::new(),
1238 expr: Box::new(lhs),
1239 as_token: as_token,
1240 ty: Box::new(ty),
1241 });
1242 } else {
1243 break;
1244 }
1245 }
1246 Ok(lhs)
1247 }
1248
1249 fn peek_precedence(input: ParseStream) -> Precedence {
1250 if let Ok(op) = input.fork().parse() {
1251 Precedence::of(&op)
1252 } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
1253 Precedence::Assign
1254 } else if input.peek(Token![<-]) {
1255 Precedence::Placement
1256 } else if input.peek(Token![..]) {
1257 Precedence::Range
1258 } else if input.peek(Token![as]) || input.peek(Token![:]) && !input.peek(Token![::]) {
1259 Precedence::Cast
1260 } else {
1261 Precedence::Any
1262 }
1263 }
1264
1265 // Parse an arbitrary expression.
1266 fn ambiguous_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1267 let lhs = unary_expr(input, allow_struct)?;
1268 parse_expr(input, lhs, allow_struct, Precedence::Any)
1269 }
1270
1271 // <UnOp> <trailer>
1272 // & <trailer>
1273 // &mut <trailer>
1274 // box <trailer>
1275 #[cfg(feature = "full")]
1276 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1277 let ahead = input.fork();
1278 ahead.call(Attribute::parse_outer)?;
1279 if ahead.peek(Token![&])
1280 || ahead.peek(Token![box])
1281 || ahead.peek(Token![*])
1282 || ahead.peek(Token![!])
1283 || ahead.peek(Token![-])
1284 {
1285 let attrs = input.call(Attribute::parse_outer)?;
1286 if input.peek(Token![&]) {
1287 Ok(Expr::Reference(ExprReference {
1288 attrs: attrs,
1289 and_token: input.parse()?,
1290 mutability: input.parse()?,
1291 expr: Box::new(unary_expr(input, allow_struct)?),
1292 }))
1293 } else if input.peek(Token![box]) {
1294 Ok(Expr::Box(ExprBox {
1295 attrs: attrs,
1296 box_token: input.parse()?,
1297 expr: Box::new(unary_expr(input, allow_struct)?),
1298 }))
1299 } else {
1300 Ok(Expr::Unary(ExprUnary {
1301 attrs: attrs,
1302 op: input.parse()?,
1303 expr: Box::new(unary_expr(input, allow_struct)?),
1304 }))
1305 }
1306 } else {
1307 trailer_expr(input, allow_struct)
1308 }
1309 }
1310
1311 #[cfg(not(feature = "full"))]
1312 fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1313 let ahead = input.fork();
1314 ahead.call(Attribute::parse_outer)?;
1315 if ahead.peek(Token![*]) || ahead.peek(Token![!]) || ahead.peek(Token![-]) {
1316 Ok(Expr::Unary(ExprUnary {
1317 attrs: input.call(Attribute::parse_outer)?,
1318 op: input.parse()?,
1319 expr: Box::new(unary_expr(input, allow_struct)?),
1320 }))
1321 } else {
1322 trailer_expr(input, allow_struct)
1323 }
1324 }
1325
1326 // <atom> (..<args>) ...
1327 // <atom> . <ident> (..<args>) ...
1328 // <atom> . <ident> ...
1329 // <atom> . <lit> ...
1330 // <atom> [ <expr> ] ...
1331 // <atom> ? ...
1332 #[cfg(feature = "full")]
1333 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1334 if input.peek(token::Group) {
1335 return input.call(expr_group).map(Expr::Group);
1336 }
1337
1338 let outer_attrs = input.call(Attribute::parse_outer)?;
1339
1340 let atom = atom_expr(input, allow_struct)?;
1341 let mut e = trailer_helper(input, atom)?;
1342
1343 let inner_attrs = e.replace_attrs(Vec::new());
1344 let attrs = private::attrs(outer_attrs, inner_attrs);
1345 e.replace_attrs(attrs);
1346 Ok(e)
1347 }
1348
1349 #[cfg(feature = "full")]
1350 fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
1351 loop {
1352 if input.peek(token::Paren) {
1353 let content;
1354 e = Expr::Call(ExprCall {
1355 attrs: Vec::new(),
1356 func: Box::new(e),
1357 paren_token: parenthesized!(content in input),
1358 args: content.parse_terminated(Expr::parse)?,
1359 });
1360 } else if input.peek(Token![.]) && !input.peek(Token![..]) {
1361 let dot_token: Token![.] = input.parse()?;
1362 let member: Member = input.parse()?;
1363 let turbofish = if member.is_named() && input.peek(Token![::]) {
1364 Some(MethodTurbofish {
1365 colon2_token: input.parse()?,
1366 lt_token: input.parse()?,
1367 args: {
1368 let mut args = Punctuated::new();
1369 loop {
1370 if input.peek(Token![>]) {
1371 break;
1372 }
1373 let value = input.call(generic_method_argument)?;
1374 args.push_value(value);
1375 if input.peek(Token![>]) {
1376 break;
1377 }
1378 let punct = input.parse()?;
1379 args.push_punct(punct);
1380 }
1381 args
1382 },
1383 gt_token: input.parse()?,
1384 })
1385 } else {
1386 None
1387 };
1388
1389 if turbofish.is_some() || input.peek(token::Paren) {
1390 if let Member::Named(method) = member {
1391 let content;
1392 e = Expr::MethodCall(ExprMethodCall {
1393 attrs: Vec::new(),
1394 receiver: Box::new(e),
1395 dot_token: dot_token,
1396 method: method,
1397 turbofish: turbofish,
1398 paren_token: parenthesized!(content in input),
1399 args: content.parse_terminated(Expr::parse)?,
1400 });
1401 continue;
1402 }
1403 }
1404
1405 e = Expr::Field(ExprField {
1406 attrs: Vec::new(),
1407 base: Box::new(e),
1408 dot_token: dot_token,
1409 member: member,
1410 });
1411 } else if input.peek(token::Bracket) {
1412 let content;
1413 e = Expr::Index(ExprIndex {
1414 attrs: Vec::new(),
1415 expr: Box::new(e),
1416 bracket_token: bracketed!(content in input),
1417 index: content.parse()?,
1418 });
1419 } else if input.peek(Token![?]) {
1420 e = Expr::Try(ExprTry {
1421 attrs: Vec::new(),
1422 expr: Box::new(e),
1423 question_token: input.parse()?,
1424 });
1425 } else {
1426 break;
1427 }
1428 }
1429 Ok(e)
1430 }
1431
1432 #[cfg(not(feature = "full"))]
1433 fn trailer_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1434 let mut e = atom_expr(input, allow_struct)?;
1435
1436 loop {
1437 if input.peek(token::Paren) {
1438 let content;
1439 e = Expr::Call(ExprCall {
1440 attrs: Vec::new(),
1441 func: Box::new(e),
1442 paren_token: parenthesized!(content in input),
1443 args: content.parse_terminated(Expr::parse)?,
1444 });
1445 } else if input.peek(Token![.]) {
1446 e = Expr::Field(ExprField {
1447 attrs: Vec::new(),
1448 base: Box::new(e),
1449 dot_token: input.parse()?,
1450 member: input.parse()?,
1451 });
1452 } else if input.peek(token::Bracket) {
1453 let content;
1454 e = Expr::Index(ExprIndex {
1455 attrs: Vec::new(),
1456 expr: Box::new(e),
1457 bracket_token: bracketed!(content in input),
1458 index: content.parse()?,
1459 });
1460 } else {
1461 break;
1462 }
1463 }
1464
1465 Ok(e)
1466 }
1467
1468 // Parse all atomic expressions which don't have to worry about precedence
1469 // interactions, as they are fully contained.
1470 #[cfg(feature = "full")]
1471 fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1472 if input.peek(token::Group) {
1473 input.call(expr_group).map(Expr::Group)
1474 } else if input.peek(Lit) {
1475 input.call(expr_lit).map(Expr::Lit)
1476 } else if input.peek(Token![async])
1477 && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
1478 {
1479 input.call(expr_async).map(Expr::Async)
1480 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1481 input.call(expr_try_block).map(Expr::TryBlock)
1482 } else if input.peek(Token![|])
1483 || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
1484 || input.peek(Token![static])
1485 || input.peek(Token![move])
1486 {
1487 expr_closure(input, allow_struct).map(Expr::Closure)
1488 } else if input.peek(Ident)
1489 || input.peek(Token![::])
1490 || input.peek(Token![<])
1491 || input.peek(Token![self])
1492 || input.peek(Token![Self])
1493 || input.peek(Token![super])
1494 || input.peek(Token![extern])
1495 || input.peek(Token![crate])
1496 {
1497 path_or_macro_or_struct(input, allow_struct)
1498 } else if input.peek(token::Paren) {
1499 paren_or_tuple(input)
1500 } else if input.peek(Token![break]) {
1501 expr_break(input, allow_struct).map(Expr::Break)
1502 } else if input.peek(Token![continue]) {
1503 input.call(expr_continue).map(Expr::Continue)
1504 } else if input.peek(Token![return]) {
1505 expr_ret(input, allow_struct).map(Expr::Return)
1506 } else if input.peek(token::Bracket) {
1507 array_or_repeat(input)
1508 } else if input.peek(Token![let]) {
1509 input.call(expr_let).map(Expr::Let)
1510 } else if input.peek(Token![if]) {
1511 input.call(expr_if).map(Expr::If)
1512 } else if input.peek(Token![while]) {
1513 input.call(expr_while).map(Expr::While)
1514 } else if input.peek(Token![for]) {
1515 input.call(expr_for_loop).map(Expr::ForLoop)
1516 } else if input.peek(Token![loop]) {
1517 input.call(expr_loop).map(Expr::Loop)
1518 } else if input.peek(Token![match]) {
1519 input.call(expr_match).map(Expr::Match)
1520 } else if input.peek(Token![yield]) {
1521 input.call(expr_yield).map(Expr::Yield)
1522 } else if input.peek(Token![unsafe]) {
1523 input.call(expr_unsafe).map(Expr::Unsafe)
1524 } else if input.peek(token::Brace) {
1525 input.call(expr_block).map(Expr::Block)
1526 } else if input.peek(Token![..]) {
1527 expr_range(input, allow_struct).map(Expr::Range)
1528 } else if input.peek(Lifetime) {
1529 let the_label: Label = input.parse()?;
1530 let mut expr = if input.peek(Token![while]) {
1531 Expr::While(input.call(expr_while)?)
1532 } else if input.peek(Token![for]) {
1533 Expr::ForLoop(input.call(expr_for_loop)?)
1534 } else if input.peek(Token![loop]) {
1535 Expr::Loop(input.call(expr_loop)?)
1536 } else if input.peek(token::Brace) {
1537 Expr::Block(input.call(expr_block)?)
1538 } else {
1539 return Err(input.error("expected loop or block expression"));
1540 };
1541 match expr {
1542 Expr::While(ExprWhile { ref mut label, .. })
1543 | Expr::ForLoop(ExprForLoop { ref mut label, .. })
1544 | Expr::Loop(ExprLoop { ref mut label, .. })
1545 | Expr::Block(ExprBlock { ref mut label, .. }) => *label = Some(the_label),
1546 _ => unreachable!(),
1547 }
1548 Ok(expr)
1549 } else {
1550 Err(input.error("expected expression"))
1551 }
1552 }
1553
1554 #[cfg(not(feature = "full"))]
1555 fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result<Expr> {
1556 if input.peek(Lit) {
1557 input.call(expr_lit).map(Expr::Lit)
1558 } else if input.peek(token::Paren) {
1559 input.call(expr_paren).map(Expr::Paren)
1560 } else if input.peek(Ident)
1561 || input.peek(Token![::])
1562 || input.peek(Token![<])
1563 || input.peek(Token![self])
1564 || input.peek(Token![Self])
1565 || input.peek(Token![super])
1566 || input.peek(Token![extern])
1567 || input.peek(Token![crate])
1568 {
1569 input.parse().map(Expr::Path)
1570 } else {
1571 Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
1572 }
1573 }
1574
1575 #[cfg(feature = "full")]
1576 fn path_or_macro_or_struct(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
1577 let expr: ExprPath = input.parse()?;
1578 if expr.qself.is_some() {
1579 return Ok(Expr::Path(expr));
1580 }
1581
1582 if input.peek(Token![!]) && !input.peek(Token![!=]) {
1583 let mut contains_arguments = false;
1584 for segment in &expr.path.segments {
1585 match segment.arguments {
1586 PathArguments::None => {}
1587 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
1588 contains_arguments = true;
1589 }
1590 }
1591 }
1592
1593 if !contains_arguments {
1594 let bang_token: Token![!] = input.parse()?;
1595 let (delimiter, tts) = mac::parse_delimiter(input)?;
1596 return Ok(Expr::Macro(ExprMacro {
1597 attrs: Vec::new(),
1598 mac: Macro {
1599 path: expr.path,
1600 bang_token: bang_token,
1601 delimiter: delimiter,
1602 tts: tts,
1603 },
1604 }));
1605 }
1606 }
1607
1608 if allow_struct.0 && input.peek(token::Brace) {
1609 let outer_attrs = Vec::new();
1610 expr_struct_helper(input, outer_attrs, expr.path).map(Expr::Struct)
1611 } else {
1612 Ok(Expr::Path(expr))
1613 }
1614 }
1615
1616 #[cfg(feature = "full")]
1617 fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
1618 let content;
1619 let paren_token = parenthesized!(content in input);
1620 let inner_attrs = content.call(Attribute::parse_inner)?;
1621 if content.is_empty() {
1622 return Ok(Expr::Tuple(ExprTuple {
1623 attrs: inner_attrs,
1624 paren_token: paren_token,
1625 elems: Punctuated::new(),
1626 }));
1627 }
1628
1629 let first: Expr = content.parse()?;
1630 if content.is_empty() {
1631 return Ok(Expr::Paren(ExprParen {
1632 attrs: inner_attrs,
1633 paren_token: paren_token,
1634 expr: Box::new(first),
1635 }));
1636 }
1637
1638 let mut elems = Punctuated::new();
1639 elems.push_value(first);
1640 while !content.is_empty() {
1641 let punct = content.parse()?;
1642 elems.push_punct(punct);
1643 if content.is_empty() {
1644 break;
1645 }
1646 let value = content.parse()?;
1647 elems.push_value(value);
1648 }
1649 Ok(Expr::Tuple(ExprTuple {
1650 attrs: inner_attrs,
1651 paren_token: paren_token,
1652 elems: elems,
1653 }))
1654 }
1655
1656 #[cfg(feature = "full")]
1657 fn array_or_repeat(input: ParseStream) -> Result<Expr> {
1658 let content;
1659 let bracket_token = bracketed!(content in input);
1660 let inner_attrs = content.call(Attribute::parse_inner)?;
1661 if content.is_empty() {
1662 return Ok(Expr::Array(ExprArray {
1663 attrs: inner_attrs,
1664 bracket_token: bracket_token,
1665 elems: Punctuated::new(),
1666 }));
1667 }
1668
1669 let first: Expr = content.parse()?;
1670 if content.is_empty() || content.peek(Token![,]) {
1671 let mut elems = Punctuated::new();
1672 elems.push_value(first);
1673 while !content.is_empty() {
1674 let punct = content.parse()?;
1675 elems.push_punct(punct);
1676 if content.is_empty() {
1677 break;
1678 }
1679 let value = content.parse()?;
1680 elems.push_value(value);
1681 }
1682 Ok(Expr::Array(ExprArray {
1683 attrs: inner_attrs,
1684 bracket_token: bracket_token,
1685 elems: elems,
1686 }))
1687 } else if content.peek(Token![;]) {
1688 let semi_token: Token![;] = content.parse()?;
1689 let len: Expr = content.parse()?;
1690 Ok(Expr::Repeat(ExprRepeat {
1691 attrs: inner_attrs,
1692 bracket_token: bracket_token,
1693 expr: Box::new(first),
1694 semi_token: semi_token,
1695 len: Box::new(len),
1696 }))
1697 } else {
1698 Err(content.error("expected `,` or `;`"))
1699 }
1700 }
1701
1702 #[cfg(feature = "full")]
1703 fn expr_early(input: ParseStream) -> Result<Expr> {
1704 let mut attrs = input.call(Attribute::parse_outer)?;
1705 let mut expr = if input.peek(Token![if]) {
1706 Expr::If(input.call(expr_if)?)
1707 } else if input.peek(Token![while]) {
1708 Expr::While(input.call(expr_while)?)
1709 } else if input.peek(Token![for]) {
1710 Expr::ForLoop(input.call(expr_for_loop)?)
1711 } else if input.peek(Token![loop]) {
1712 Expr::Loop(input.call(expr_loop)?)
1713 } else if input.peek(Token![match]) {
1714 Expr::Match(input.call(expr_match)?)
1715 } else if input.peek(Token![try]) && input.peek2(token::Brace) {
1716 Expr::TryBlock(input.call(expr_try_block)?)
1717 } else if input.peek(Token![unsafe]) {
1718 Expr::Unsafe(input.call(expr_unsafe)?)
1719 } else if input.peek(token::Brace) {
1720 Expr::Block(input.call(expr_block)?)
1721 } else {
1722 let allow_struct = AllowStruct(true);
1723 let mut expr = unary_expr(input, allow_struct)?;
1724
1725 attrs.extend(expr.replace_attrs(Vec::new()));
1726 expr.replace_attrs(attrs);
1727
1728 return parse_expr(input, expr, allow_struct, Precedence::Any);
1729 };
1730
1731 if input.peek(Token![.]) || input.peek(Token![?]) {
1732 expr = trailer_helper(input, expr)?;
1733
1734 attrs.extend(expr.replace_attrs(Vec::new()));
1735 expr.replace_attrs(attrs);
1736
1737 let allow_struct = AllowStruct(true);
1738 return parse_expr(input, expr, allow_struct, Precedence::Any);
1739 }
1740
1741 attrs.extend(expr.replace_attrs(Vec::new()));
1742 expr.replace_attrs(attrs);
1743 Ok(expr)
1744 }
1745
1746 pub fn expr_lit(input: ParseStream) -> Result<ExprLit> {
1747 Ok(ExprLit {
1748 attrs: Vec::new(),
1749 lit: input.parse()?,
1750 })
1751 }
1752
1753 #[cfg(feature = "full")]
1754 fn expr_group(input: ParseStream) -> Result<ExprGroup> {
1755 let group = private::parse_group(input)?;
1756 Ok(ExprGroup {
1757 attrs: Vec::new(),
1758 group_token: group.token,
1759 expr: group.content.parse()?,
1760 })
1761 }
1762
1763 #[cfg(not(feature = "full"))]
1764 fn expr_paren(input: ParseStream) -> Result<ExprParen> {
1765 let content;
1766 Ok(ExprParen {
1767 attrs: Vec::new(),
1768 paren_token: parenthesized!(content in input),
1769 expr: content.parse()?,
1770 })
1771 }
1772
1773 #[cfg(feature = "full")]
1774 fn generic_method_argument(input: ParseStream) -> Result<GenericMethodArgument> {
1775 // TODO parse const generics as well
1776 input.parse().map(GenericMethodArgument::Type)
1777 }
1778
1779 #[cfg(feature = "full")]
1780 fn expr_let(input: ParseStream) -> Result<ExprLet> {
1781 Ok(ExprLet {
1782 attrs: Vec::new(),
1783 let_token: input.parse()?,
1784 pats: {
1785 let mut pats = Punctuated::new();
1786 let value: Pat = input.parse()?;
1787 pats.push_value(value);
1788 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
1789 let punct = input.parse()?;
1790 pats.push_punct(punct);
1791 let value: Pat = input.parse()?;
1792 pats.push_value(value);
1793 }
1794 pats
1795 },
1796 eq_token: input.parse()?,
1797 expr: Box::new(input.call(expr_no_struct)?),
1798 })
1799 }
1800
1801 #[cfg(feature = "full")]
1802 fn expr_if(input: ParseStream) -> Result<ExprIf> {
1803 Ok(ExprIf {
1804 attrs: Vec::new(),
1805 if_token: input.parse()?,
1806 cond: Box::new(input.call(expr_no_struct)?),
1807 then_branch: input.parse()?,
1808 else_branch: {
1809 if input.peek(Token![else]) {
1810 Some(input.call(else_block)?)
1811 } else {
1812 None
1813 }
1814 },
1815 })
1816 }
1817
1818 #[cfg(feature = "full")]
1819 fn else_block(input: ParseStream) -> Result<(Token![else], Box<Expr>)> {
1820 let else_token: Token![else] = input.parse()?;
1821
1822 let lookahead = input.lookahead1();
1823 let else_branch = if input.peek(Token![if]) {
1824 input.call(expr_if).map(Expr::If)?
1825 } else if input.peek(token::Brace) {
1826 Expr::Block(ExprBlock {
1827 attrs: Vec::new(),
1828 label: None,
1829 block: input.parse()?,
1830 })
1831 } else {
1832 return Err(lookahead.error());
1833 };
1834
1835 Ok((else_token, Box::new(else_branch)))
1836 }
1837
1838 #[cfg(feature = "full")]
1839 fn expr_for_loop(input: ParseStream) -> Result<ExprForLoop> {
1840 let label: Option<Label> = input.parse()?;
1841 let for_token: Token![for] = input.parse()?;
1842 let pat: Pat = input.parse()?;
1843 let in_token: Token![in] = input.parse()?;
1844 let expr: Expr = input.call(expr_no_struct)?;
1845
1846 let content;
1847 let brace_token = braced!(content in input);
1848 let inner_attrs = content.call(Attribute::parse_inner)?;
1849 let stmts = content.call(Block::parse_within)?;
1850
1851 Ok(ExprForLoop {
1852 attrs: inner_attrs,
1853 label: label,
1854 for_token: for_token,
1855 pat: Box::new(pat),
1856 in_token: in_token,
1857 expr: Box::new(expr),
1858 body: Block {
1859 brace_token: brace_token,
1860 stmts: stmts,
1861 },
1862 })
1863 }
1864
1865 #[cfg(feature = "full")]
1866 fn expr_loop(input: ParseStream) -> Result<ExprLoop> {
1867 let label: Option<Label> = input.parse()?;
1868 let loop_token: Token![loop] = input.parse()?;
1869
1870 let content;
1871 let brace_token = braced!(content in input);
1872 let inner_attrs = content.call(Attribute::parse_inner)?;
1873 let stmts = content.call(Block::parse_within)?;
1874
1875 Ok(ExprLoop {
1876 attrs: inner_attrs,
1877 label: label,
1878 loop_token: loop_token,
1879 body: Block {
1880 brace_token: brace_token,
1881 stmts: stmts,
1882 },
1883 })
1884 }
1885
1886 #[cfg(feature = "full")]
1887 fn expr_match(input: ParseStream) -> Result<ExprMatch> {
1888 let match_token: Token![match] = input.parse()?;
1889 let expr = expr_no_struct(input)?;
1890
1891 let content;
1892 let brace_token = braced!(content in input);
1893 let inner_attrs = content.call(Attribute::parse_inner)?;
1894
1895 let mut arms = Vec::new();
1896 while !content.is_empty() {
1897 arms.push(content.call(Arm::parse)?);
1898 }
1899
1900 Ok(ExprMatch {
1901 attrs: inner_attrs,
1902 match_token: match_token,
1903 expr: Box::new(expr),
1904 brace_token: brace_token,
1905 arms: arms,
1906 })
1907 }
1908
1909 #[cfg(feature = "full")]
1910 fn expr_try_block(input: ParseStream) -> Result<ExprTryBlock> {
1911 Ok(ExprTryBlock {
1912 attrs: Vec::new(),
1913 try_token: input.parse()?,
1914 block: input.parse()?,
1915 })
1916 }
1917
1918 #[cfg(feature = "full")]
1919 fn expr_yield(input: ParseStream) -> Result<ExprYield> {
1920 Ok(ExprYield {
1921 attrs: Vec::new(),
1922 yield_token: input.parse()?,
1923 expr: {
1924 if !input.is_empty() && !input.peek(Token![,]) && !input.peek(Token![;]) {
1925 Some(input.parse()?)
1926 } else {
1927 None
1928 }
1929 },
1930 })
1931 }
1932
1933 #[cfg(feature = "full")]
1934 fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
1935 let asyncness: Option<Token![async]> = input.parse()?;
1936 let movability: Option<Token![static]> = if asyncness.is_none() {
1937 input.parse()?
1938 } else {
1939 None
1940 };
1941 let capture: Option<Token![move]> = input.parse()?;
1942 let or1_token: Token![|] = input.parse()?;
1943
1944 let mut inputs = Punctuated::new();
1945 loop {
1946 if input.peek(Token![|]) {
1947 break;
1948 }
1949 let value = fn_arg(input)?;
1950 inputs.push_value(value);
1951 if input.peek(Token![|]) {
1952 break;
1953 }
1954 let punct: Token![,] = input.parse()?;
1955 inputs.push_punct(punct);
1956 }
1957
1958 let or2_token: Token![|] = input.parse()?;
1959
1960 let (output, body) = if input.peek(Token![->]) {
1961 let arrow_token: Token![->] = input.parse()?;
1962 let ty: Type = input.parse()?;
1963 let body: Block = input.parse()?;
1964 let output = ReturnType::Type(arrow_token, Box::new(ty));
1965 let block = Expr::Block(ExprBlock {
1966 attrs: Vec::new(),
1967 label: None,
1968 block: body,
1969 });
1970 (output, block)
1971 } else {
1972 let body = ambiguous_expr(input, allow_struct)?;
1973 (ReturnType::Default, body)
1974 };
1975
1976 Ok(ExprClosure {
1977 attrs: Vec::new(),
1978 asyncness: asyncness,
1979 movability: movability,
1980 capture: capture,
1981 or1_token: or1_token,
1982 inputs: inputs,
1983 or2_token: or2_token,
1984 output: output,
1985 body: Box::new(body),
1986 })
1987 }
1988
1989 #[cfg(feature = "full")]
1990 fn expr_async(input: ParseStream) -> Result<ExprAsync> {
1991 Ok(ExprAsync {
1992 attrs: Vec::new(),
1993 async_token: input.parse()?,
1994 capture: input.parse()?,
1995 block: input.parse()?,
1996 })
1997 }
1998
1999 #[cfg(feature = "full")]
2000 fn fn_arg(input: ParseStream) -> Result<FnArg> {
2001 let pat: Pat = input.parse()?;
2002
2003 if input.peek(Token![:]) {
2004 Ok(FnArg::Captured(ArgCaptured {
2005 pat: pat,
2006 colon_token: input.parse()?,
2007 ty: input.parse()?,
2008 }))
2009 } else {
2010 Ok(FnArg::Inferred(pat))
2011 }
2012 }
2013
2014 #[cfg(feature = "full")]
2015 fn expr_while(input: ParseStream) -> Result<ExprWhile> {
2016 let label: Option<Label> = input.parse()?;
2017 let while_token: Token![while] = input.parse()?;
2018 let cond = expr_no_struct(input)?;
2019
2020 let content;
2021 let brace_token = braced!(content in input);
2022 let inner_attrs = content.call(Attribute::parse_inner)?;
2023 let stmts = content.call(Block::parse_within)?;
2024
2025 Ok(ExprWhile {
2026 attrs: inner_attrs,
2027 label: label,
2028 while_token: while_token,
2029 cond: Box::new(cond),
2030 body: Block {
2031 brace_token: brace_token,
2032 stmts: stmts,
2033 },
2034 })
2035 }
2036
2037 #[cfg(feature = "full")]
2038 impl Parse for Label {
2039 fn parse(input: ParseStream) -> Result<Self> {
2040 Ok(Label {
2041 name: input.parse()?,
2042 colon_token: input.parse()?,
2043 })
2044 }
2045 }
2046
2047 #[cfg(feature = "full")]
2048 impl Parse for Option<Label> {
2049 fn parse(input: ParseStream) -> Result<Self> {
2050 if input.peek(Lifetime) {
2051 input.parse().map(Some)
2052 } else {
2053 Ok(None)
2054 }
2055 }
2056 }
2057
2058 #[cfg(feature = "full")]
2059 fn expr_continue(input: ParseStream) -> Result<ExprContinue> {
2060 Ok(ExprContinue {
2061 attrs: Vec::new(),
2062 continue_token: input.parse()?,
2063 label: input.parse()?,
2064 })
2065 }
2066
2067 #[cfg(feature = "full")]
2068 fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
2069 Ok(ExprBreak {
2070 attrs: Vec::new(),
2071 break_token: input.parse()?,
2072 label: input.parse()?,
2073 expr: {
2074 if input.is_empty()
2075 || input.peek(Token![,])
2076 || input.peek(Token![;])
2077 || !allow_struct.0 && input.peek(token::Brace)
2078 {
2079 None
2080 } else {
2081 let expr = ambiguous_expr(input, allow_struct)?;
2082 Some(Box::new(expr))
2083 }
2084 },
2085 })
2086 }
2087
2088 #[cfg(feature = "full")]
2089 fn expr_ret(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprReturn> {
2090 Ok(ExprReturn {
2091 attrs: Vec::new(),
2092 return_token: input.parse()?,
2093 expr: {
2094 if input.is_empty() || input.peek(Token![,]) || input.peek(Token![;]) {
2095 None
2096 } else {
2097 // NOTE: return is greedy and eats blocks after it even when in a
2098 // position where structs are not allowed, such as in if statement
2099 // conditions. For example:
2100 //
2101 // if return { println!("A") } {} // Prints "A"
2102 let expr = ambiguous_expr(input, allow_struct)?;
2103 Some(Box::new(expr))
2104 }
2105 },
2106 })
2107 }
2108
2109 #[cfg(feature = "full")]
2110 impl Parse for FieldValue {
2111 fn parse(input: ParseStream) -> Result<Self> {
2112 let member: Member = input.parse()?;
2113 let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
2114 let colon_token: Token![:] = input.parse()?;
2115 let value: Expr = input.parse()?;
2116 (Some(colon_token), value)
2117 } else if let Member::Named(ref ident) = member {
2118 let value = Expr::Path(ExprPath {
2119 attrs: Vec::new(),
2120 qself: None,
2121 path: Path::from(ident.clone()),
2122 });
2123 (None, value)
2124 } else {
2125 unreachable!()
2126 };
2127
2128 Ok(FieldValue {
2129 attrs: Vec::new(),
2130 member: member,
2131 colon_token: colon_token,
2132 expr: value,
2133 })
2134 }
2135 }
2136
2137 #[cfg(feature = "full")]
2138 fn expr_struct_helper(
2139 input: ParseStream,
2140 outer_attrs: Vec<Attribute>,
2141 path: Path,
2142 ) -> Result<ExprStruct> {
2143 let content;
2144 let brace_token = braced!(content in input);
2145 let inner_attrs = content.call(Attribute::parse_inner)?;
2146
2147 let mut fields = Punctuated::new();
2148 loop {
2149 let attrs = content.call(Attribute::parse_outer)?;
2150 if content.fork().parse::<Member>().is_err() {
2151 if attrs.is_empty() {
2152 break;
2153 } else {
2154 return Err(content.error("expected struct field"));
2155 }
2156 }
2157
2158 fields.push(FieldValue {
2159 attrs: attrs,
2160 ..content.parse()?
2161 });
2162
2163 if !content.peek(Token![,]) {
2164 break;
2165 }
2166 let punct: Token![,] = content.parse()?;
2167 fields.push_punct(punct);
2168 }
2169
2170 let (dot2_token, rest) = if fields.empty_or_trailing() && content.peek(Token![..]) {
2171 let dot2_token: Token![..] = content.parse()?;
2172 let rest: Expr = content.parse()?;
2173 (Some(dot2_token), Some(Box::new(rest)))
2174 } else {
2175 (None, None)
2176 };
2177
2178 Ok(ExprStruct {
2179 attrs: private::attrs(outer_attrs, inner_attrs),
2180 brace_token: brace_token,
2181 path: path,
2182 fields: fields,
2183 dot2_token: dot2_token,
2184 rest: rest,
2185 })
2186 }
2187
2188 #[cfg(feature = "full")]
2189 fn expr_unsafe(input: ParseStream) -> Result<ExprUnsafe> {
2190 let unsafe_token: Token![unsafe] = input.parse()?;
2191
2192 let content;
2193 let brace_token = braced!(content in input);
2194 let inner_attrs = content.call(Attribute::parse_inner)?;
2195 let stmts = content.call(Block::parse_within)?;
2196
2197 Ok(ExprUnsafe {
2198 attrs: inner_attrs,
2199 unsafe_token: unsafe_token,
2200 block: Block {
2201 brace_token: brace_token,
2202 stmts: stmts,
2203 },
2204 })
2205 }
2206
2207 #[cfg(feature = "full")]
2208 pub fn expr_block(input: ParseStream) -> Result<ExprBlock> {
2209 let label: Option<Label> = input.parse()?;
2210
2211 let content;
2212 let brace_token = braced!(content in input);
2213 let inner_attrs = content.call(Attribute::parse_inner)?;
2214 let stmts = content.call(Block::parse_within)?;
2215
2216 Ok(ExprBlock {
2217 attrs: inner_attrs,
2218 label: label,
2219 block: Block {
2220 brace_token: brace_token,
2221 stmts: stmts,
2222 },
2223 })
2224 }
2225
2226 #[cfg(feature = "full")]
2227 fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
2228 Ok(ExprRange {
2229 attrs: Vec::new(),
2230 from: None,
2231 limits: input.parse()?,
2232 to: {
2233 if input.is_empty()
2234 || input.peek(Token![,])
2235 || input.peek(Token![;])
2236 || !allow_struct.0 && input.peek(token::Brace)
2237 {
2238 None
2239 } else {
2240 let to = ambiguous_expr(input, allow_struct)?;
2241 Some(Box::new(to))
2242 }
2243 },
2244 })
2245 }
2246
2247 #[cfg(feature = "full")]
2248 impl Parse for RangeLimits {
2249 fn parse(input: ParseStream) -> Result<Self> {
2250 let lookahead = input.lookahead1();
2251 if lookahead.peek(Token![..=]) {
2252 input.parse().map(RangeLimits::Closed)
2253 } else if lookahead.peek(Token![...]) {
2254 let dot3: Token![...] = input.parse()?;
2255 Ok(RangeLimits::Closed(Token![..=](dot3.spans)))
2256 } else if lookahead.peek(Token![..]) {
2257 input.parse().map(RangeLimits::HalfOpen)
2258 } else {
2259 Err(lookahead.error())
2260 }
2261 }
2262 }
2263
2264 impl Parse for ExprPath {
2265 fn parse(input: ParseStream) -> Result<Self> {
2266 #[cfg(not(feature = "full"))]
2267 let attrs = Vec::new();
2268 #[cfg(feature = "full")]
2269 let attrs = input.call(Attribute::parse_outer)?;
2270
2271 let (qself, path) = path::parsing::qpath(input, true)?;
2272
2273 Ok(ExprPath {
2274 attrs: attrs,
2275 qself: qself,
2276 path: path,
2277 })
2278 }
2279 }
2280
2281 #[cfg(feature = "full")]
2282 impl Parse for Block {
2283 fn parse(input: ParseStream) -> Result<Self> {
2284 let content;
2285 Ok(Block {
2286 brace_token: braced!(content in input),
2287 stmts: content.call(Block::parse_within)?,
2288 })
2289 }
2290 }
2291
2292 #[cfg(feature = "full")]
2293 impl Block {
2294 /// Parse the body of a block as zero or more statements, possibly
2295 /// including one trailing expression.
2296 ///
2297 /// *This function is available if Syn is built with the `"parsing"`
2298 /// feature.*
2299 ///
2300 /// # Example
2301 ///
2302 /// ```
2303 /// #[macro_use]
2304 /// extern crate syn;
2305 ///
2306 /// use syn::{token, Attribute, Block, Ident, Result, Stmt};
2307 /// use syn::parse::{Parse, ParseStream};
2308 ///
2309 /// // Parse a function with no generics or parameter list.
2310 /// //
2311 /// // fn playground {
2312 /// // let mut x = 1;
2313 /// // x += 1;
2314 /// // println!("{}", x);
2315 /// // }
2316 /// struct MiniFunction {
2317 /// attrs: Vec<Attribute>,
2318 /// fn_token: Token![fn],
2319 /// name: Ident,
2320 /// brace_token: token::Brace,
2321 /// stmts: Vec<Stmt>,
2322 /// }
2323 ///
2324 /// impl Parse for MiniFunction {
2325 /// fn parse(input: ParseStream) -> Result<Self> {
2326 /// let outer_attrs = input.call(Attribute::parse_outer)?;
2327 /// let fn_token: Token![fn] = input.parse()?;
2328 /// let name: Ident = input.parse()?;
2329 ///
2330 /// let content;
2331 /// let brace_token = braced!(content in input);
2332 /// let inner_attrs = content.call(Attribute::parse_inner)?;
2333 /// let stmts = content.call(Block::parse_within)?;
2334 ///
2335 /// Ok(MiniFunction {
2336 /// attrs: {
2337 /// let mut attrs = outer_attrs;
2338 /// attrs.extend(inner_attrs);
2339 /// attrs
2340 /// },
2341 /// fn_token: fn_token,
2342 /// name: name,
2343 /// brace_token: brace_token,
2344 /// stmts: stmts,
2345 /// })
2346 /// }
2347 /// }
2348 /// #
2349 /// # fn main() {}
2350 /// ```
2351 pub fn parse_within(input: ParseStream) -> Result<Vec<Stmt>> {
2352 let mut stmts = Vec::new();
2353 loop {
2354 while input.peek(Token![;]) {
2355 input.parse::<Token![;]>()?;
2356 }
2357 if input.is_empty() {
2358 break;
2359 }
2360 let s = parse_stmt(input, true)?;
2361 let requires_semicolon = if let Stmt::Expr(ref s) = s {
2362 requires_terminator(s)
2363 } else {
2364 false
2365 };
2366 stmts.push(s);
2367 if input.is_empty() {
2368 break;
2369 } else if requires_semicolon {
2370 return Err(input.error("unexpected token"));
2371 }
2372 }
2373 Ok(stmts)
2374 }
2375 }
2376
2377 #[cfg(feature = "full")]
2378 impl Parse for Stmt {
2379 fn parse(input: ParseStream) -> Result<Self> {
2380 parse_stmt(input, false)
2381 }
2382 }
2383
2384 #[cfg(feature = "full")]
2385 fn parse_stmt(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
2386 let ahead = input.fork();
2387 ahead.call(Attribute::parse_outer)?;
2388
2389 if {
2390 let ahead = ahead.fork();
2391 // Only parse braces here; paren and bracket will get parsed as
2392 // expression statements
2393 ahead.call(Path::parse_mod_style).is_ok()
2394 && ahead.parse::<Token![!]>().is_ok()
2395 && (ahead.peek(token::Brace) || ahead.peek(Ident))
2396 } {
2397 stmt_mac(input)
2398 } else if ahead.peek(Token![let]) {
2399 stmt_local(input).map(Stmt::Local)
2400 } else if ahead.peek(Token![pub])
2401 || ahead.peek(Token![crate]) && !ahead.peek2(Token![::])
2402 || ahead.peek(Token![extern]) && !ahead.peek2(Token![::])
2403 || ahead.peek(Token![use])
2404 || ahead.peek(Token![static]) && (ahead.peek2(Token![mut]) || ahead.peek2(Ident))
2405 || ahead.peek(Token![const])
2406 || ahead.peek(Token![unsafe]) && !ahead.peek2(token::Brace)
2407 || ahead.peek(Token![async]) && (ahead.peek2(Token![extern]) || ahead.peek2(Token![fn]))
2408 || ahead.peek(Token![fn])
2409 || ahead.peek(Token![mod])
2410 || ahead.peek(Token![type])
2411 || ahead.peek(Token![existential]) && ahead.peek2(Token![type])
2412 || ahead.peek(Token![struct])
2413 || ahead.peek(Token![enum])
2414 || ahead.peek(Token![union]) && ahead.peek2(Ident)
2415 || ahead.peek(Token![auto]) && ahead.peek2(Token![trait])
2416 || ahead.peek(Token![trait])
2417 || ahead.peek(Token![default])
2418 && (ahead.peek2(Token![unsafe]) || ahead.peek2(Token![impl ]))
2419 || ahead.peek(Token![impl ])
2420 || ahead.peek(Token![macro])
2421 {
2422 input.parse().map(Stmt::Item)
2423 } else {
2424 stmt_expr(input, allow_nosemi)
2425 }
2426 }
2427
2428 #[cfg(feature = "full")]
2429 fn stmt_mac(input: ParseStream) -> Result<Stmt> {
2430 let attrs = input.call(Attribute::parse_outer)?;
2431 let path = input.call(Path::parse_mod_style)?;
2432 let bang_token: Token![!] = input.parse()?;
2433 let ident: Option<Ident> = input.parse()?;
2434 let (delimiter, tts) = mac::parse_delimiter(input)?;
2435 let semi_token: Option<Token![;]> = input.parse()?;
2436
2437 Ok(Stmt::Item(Item::Macro(ItemMacro {
2438 attrs: attrs,
2439 ident: ident,
2440 mac: Macro {
2441 path: path,
2442 bang_token: bang_token,
2443 delimiter: delimiter,
2444 tts: tts,
2445 },
2446 semi_token: semi_token,
2447 })))
2448 }
2449
2450 #[cfg(feature = "full")]
2451 fn stmt_local(input: ParseStream) -> Result<Local> {
2452 Ok(Local {
2453 attrs: input.call(Attribute::parse_outer)?,
2454 let_token: input.parse()?,
2455 pats: {
2456 let mut pats = Punctuated::new();
2457 let value: Pat = input.parse()?;
2458 pats.push_value(value);
2459 while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
2460 let punct = input.parse()?;
2461 pats.push_punct(punct);
2462 let value: Pat = input.parse()?;
2463 pats.push_value(value);
2464 }
2465 pats
2466 },
2467 ty: {
2468 if input.peek(Token![:]) {
2469 let colon_token: Token![:] = input.parse()?;
2470 let ty: Type = input.parse()?;
2471 Some((colon_token, Box::new(ty)))
2472 } else {
2473 None
2474 }
2475 },
2476 init: {
2477 if input.peek(Token![=]) {
2478 let eq_token: Token![=] = input.parse()?;
2479 let init: Expr = input.parse()?;
2480 Some((eq_token, Box::new(init)))
2481 } else {
2482 None
2483 }
2484 },
2485 semi_token: input.parse()?,
2486 })
2487 }
2488
2489 #[cfg(feature = "full")]
2490 fn stmt_expr(input: ParseStream, allow_nosemi: bool) -> Result<Stmt> {
2491 let mut attrs = input.call(Attribute::parse_outer)?;
2492 let mut e = expr_early(input)?;
2493
2494 attrs.extend(e.replace_attrs(Vec::new()));
2495 e.replace_attrs(attrs);
2496
2497 if input.peek(Token![;]) {
2498 return Ok(Stmt::Semi(e, input.parse()?));
2499 }
2500
2501 if allow_nosemi || !requires_terminator(&e) {
2502 Ok(Stmt::Expr(e))
2503 } else {
2504 Err(input.error("expected semicolon"))
2505 }
2506 }
2507
2508 #[cfg(feature = "full")]
2509 impl Parse for Pat {
2510 fn parse(input: ParseStream) -> Result<Self> {
2511 let lookahead = input.lookahead1();
2512 if lookahead.peek(Token![_]) {
2513 input.call(pat_wild).map(Pat::Wild)
2514 } else if lookahead.peek(Token![box]) {
2515 input.call(pat_box).map(Pat::Box)
2516 } else if lookahead.peek(Token![-]) || lookahead.peek(Lit) {
2517 pat_lit_or_range(input)
2518 } else if input.peek(Ident)
2519 && ({
2520 input.peek2(Token![::])
2521 || input.peek2(Token![!])
2522 || input.peek2(token::Brace)
2523 || input.peek2(token::Paren)
2524 || input.peek2(Token![..])
2525 && !{
2526 let ahead = input.fork();
2527 ahead.parse::<Ident>()?;
2528 ahead.parse::<RangeLimits>()?;
2529 ahead.is_empty() || ahead.peek(Token![,])
2530 }
2531 })
2532 || input.peek(Token![self]) && input.peek2(Token![::])
2533 || input.peek(Token![::])
2534 || input.peek(Token![<])
2535 || input.peek(Token![Self])
2536 || input.peek(Token![super])
2537 || input.peek(Token![extern])
2538 || input.peek(Token![crate])
2539 {
2540 pat_path_or_macro_or_struct_or_range(input)
2541 } else if input.peek(Token![ref])
2542 || input.peek(Token![mut])
2543 || input.peek(Token![self])
2544 || input.peek(Ident)
2545 {
2546 input.call(pat_ident).map(Pat::Ident)
2547 } else if lookahead.peek(token::Paren) {
2548 input.call(pat_tuple).map(Pat::Tuple)
2549 } else if lookahead.peek(Token![&]) {
2550 input.call(pat_ref).map(Pat::Ref)
2551 } else if lookahead.peek(token::Bracket) {
2552 input.call(pat_slice).map(Pat::Slice)
2553 } else {
2554 Err(lookahead.error())
2555 }
2556 }
2557 }
2558
2559 #[cfg(feature = "full")]
2560 fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
2561 let (qself, path) = path::parsing::qpath(input, true)?;
2562
2563 if input.peek(Token![..]) {
2564 return pat_range(input, qself, path).map(Pat::Range);
2565 }
2566
2567 if qself.is_some() {
2568 return Ok(Pat::Path(PatPath {
2569 qself: qself,
2570 path: path,
2571 }));
2572 }
2573
2574 if input.peek(Token![!]) && !input.peek(Token![!=]) {
2575 let mut contains_arguments = false;
2576 for segment in &path.segments {
2577 match segment.arguments {
2578 PathArguments::None => {}
2579 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
2580 contains_arguments = true;
2581 }
2582 }
2583 }
2584
2585 if !contains_arguments {
2586 let bang_token: Token![!] = input.parse()?;
2587 let (delimiter, tts) = mac::parse_delimiter(input)?;
2588 return Ok(Pat::Macro(PatMacro {
2589 mac: Macro {
2590 path: path,
2591 bang_token: bang_token,
2592 delimiter: delimiter,
2593 tts: tts,
2594 },
2595 }));
2596 }
2597 }
2598
2599 if input.peek(token::Brace) {
2600 pat_struct(input, path).map(Pat::Struct)
2601 } else if input.peek(token::Paren) {
2602 pat_tuple_struct(input, path).map(Pat::TupleStruct)
2603 } else if input.peek(Token![..]) {
2604 pat_range(input, qself, path).map(Pat::Range)
2605 } else {
2606 Ok(Pat::Path(PatPath {
2607 qself: qself,
2608 path: path,
2609 }))
2610 }
2611 }
2612
2613 #[cfg(feature = "full")]
2614 fn pat_wild(input: ParseStream) -> Result<PatWild> {
2615 Ok(PatWild {
2616 underscore_token: input.parse()?,
2617 })
2618 }
2619
2620 #[cfg(feature = "full")]
2621 fn pat_box(input: ParseStream) -> Result<PatBox> {
2622 Ok(PatBox {
2623 box_token: input.parse()?,
2624 pat: input.parse()?,
2625 })
2626 }
2627
2628 #[cfg(feature = "full")]
2629 fn pat_ident(input: ParseStream) -> Result<PatIdent> {
2630 Ok(PatIdent {
2631 by_ref: input.parse()?,
2632 mutability: input.parse()?,
2633 ident: input.call(Ident::parse_any)?,
2634 subpat: {
2635 if input.peek(Token![@]) {
2636 let at_token: Token![@] = input.parse()?;
2637 let subpat: Pat = input.parse()?;
2638 Some((at_token, Box::new(subpat)))
2639 } else {
2640 None
2641 }
2642 },
2643 })
2644 }
2645
2646 #[cfg(feature = "full")]
2647 fn pat_tuple_struct(input: ParseStream, path: Path) -> Result<PatTupleStruct> {
2648 Ok(PatTupleStruct {
2649 path: path,
2650 pat: input.call(pat_tuple)?,
2651 })
2652 }
2653
2654 #[cfg(feature = "full")]
2655 fn pat_struct(input: ParseStream, path: Path) -> Result<PatStruct> {
2656 let content;
2657 let brace_token = braced!(content in input);
2658
2659 let mut fields = Punctuated::new();
2660 while !content.is_empty() && !content.peek(Token![..]) {
2661 let value = content.call(field_pat)?;
2662 fields.push_value(value);
2663 if !content.peek(Token![,]) {
2664 break;
2665 }
2666 let punct: Token![,] = content.parse()?;
2667 fields.push_punct(punct);
2668 }
2669
2670 let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) {
2671 Some(content.parse()?)
2672 } else {
2673 None
2674 };
2675
2676 Ok(PatStruct {
2677 path: path,
2678 brace_token: brace_token,
2679 fields: fields,
2680 dot2_token: dot2_token,
2681 })
2682 }
2683
2684 #[cfg(feature = "full")]
2685 fn field_pat(input: ParseStream) -> Result<FieldPat> {
2686 let boxed: Option<Token![box]> = input.parse()?;
2687 let by_ref: Option<Token![ref]> = input.parse()?;
2688 let mutability: Option<Token![mut]> = input.parse()?;
2689 let member: Member = input.parse()?;
2690
2691 if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
2692 || member.is_unnamed()
2693 {
2694 return Ok(FieldPat {
2695 attrs: Vec::new(),
2696 member: member,
2697 colon_token: input.parse()?,
2698 pat: input.parse()?,
2699 });
2700 }
2701
2702 let ident = match member {
2703 Member::Named(ident) => ident,
2704 Member::Unnamed(_) => unreachable!(),
2705 };
2706
2707 let mut pat = Pat::Ident(PatIdent {
2708 by_ref: by_ref,
2709 mutability: mutability,
2710 ident: ident.clone(),
2711 subpat: None,
2712 });
2713
2714 if let Some(boxed) = boxed {
2715 pat = Pat::Box(PatBox {
2716 pat: Box::new(pat),
2717 box_token: boxed,
2718 });
2719 }
2720
2721 Ok(FieldPat {
2722 member: Member::Named(ident),
2723 pat: Box::new(pat),
2724 attrs: Vec::new(),
2725 colon_token: None,
2726 })
2727 }
2728
2729 impl Parse for Member {
2730 fn parse(input: ParseStream) -> Result<Self> {
2731 if input.peek(Ident) {
2732 input.parse().map(Member::Named)
2733 } else if input.peek(LitInt) {
2734 input.parse().map(Member::Unnamed)
2735 } else {
2736 Err(input.error("expected identifier or integer"))
2737 }
2738 }
2739 }
2740
2741 #[cfg(feature = "full")]
2742 impl Parse for Arm {
2743 fn parse(input: ParseStream) -> Result<Arm> {
2744 let requires_comma;
2745 Ok(Arm {
2746 attrs: input.call(Attribute::parse_outer)?,
2747 leading_vert: input.parse()?,
2748 pats: {
2749 let mut pats = Punctuated::new();
2750 let value: Pat = input.parse()?;
2751 pats.push_value(value);
2752 loop {
2753 if !input.peek(Token![|]) {
2754 break;
2755 }
2756 let punct = input.parse()?;
2757 pats.push_punct(punct);
2758 let value: Pat = input.parse()?;
2759 pats.push_value(value);
2760 }
2761 pats
2762 },
2763 guard: {
2764 if input.peek(Token![if]) {
2765 let if_token: Token![if] = input.parse()?;
2766 let guard: Expr = input.parse()?;
2767 Some((if_token, Box::new(guard)))
2768 } else {
2769 None
2770 }
2771 },
2772 fat_arrow_token: input.parse()?,
2773 body: {
2774 let body = input.call(expr_early)?;
2775 requires_comma = requires_terminator(&body);
2776 Box::new(body)
2777 },
2778 comma: {
2779 if requires_comma && !input.is_empty() {
2780 Some(input.parse()?)
2781 } else {
2782 input.parse()?
2783 }
2784 },
2785 })
2786 }
2787 }
2788
2789 impl Parse for Index {
2790 fn parse(input: ParseStream) -> Result<Self> {
2791 let lit: LitInt = input.parse()?;
2792 if let IntSuffix::None = lit.suffix() {
2793 Ok(Index {
2794 index: lit.value() as u32,
2795 span: lit.span(),
2796 })
2797 } else {
2798 Err(Error::new(lit.span(), "expected unsuffixed integer"))
2799 }
2800 }
2801 }
2802
2803 #[cfg(feature = "full")]
2804 fn pat_range(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<PatRange> {
2805 Ok(PatRange {
2806 lo: Box::new(Expr::Path(ExprPath {
2807 attrs: Vec::new(),
2808 qself: qself,
2809 path: path,
2810 })),
2811 limits: input.parse()?,
2812 hi: input.call(pat_lit_expr)?,
2813 })
2814 }
2815
2816 #[cfg(feature = "full")]
2817 fn pat_tuple(input: ParseStream) -> Result<PatTuple> {
2818 let content;
2819 let paren_token = parenthesized!(content in input);
2820
2821 let mut front = Punctuated::new();
2822 let mut dot2_token = None::<Token![..]>;
2823 let mut comma_token = None::<Token![,]>;
2824 loop {
2825 if content.is_empty() {
2826 break;
2827 }
2828 if content.peek(Token![..]) {
2829 dot2_token = Some(content.parse()?);
2830 comma_token = content.parse()?;
2831 break;
2832 }
2833 let value: Pat = content.parse()?;
2834 front.push_value(value);
2835 if content.is_empty() {
2836 break;
2837 }
2838 let punct = content.parse()?;
2839 front.push_punct(punct);
2840 }
2841
2842 let mut back = Punctuated::new();
2843 while !content.is_empty() {
2844 let value: Pat = content.parse()?;
2845 back.push_value(value);
2846 if content.is_empty() {
2847 break;
2848 }
2849 let punct = content.parse()?;
2850 back.push_punct(punct);
2851 }
2852
2853 Ok(PatTuple {
2854 paren_token: paren_token,
2855 front: front,
2856 dot2_token: dot2_token,
2857 comma_token: comma_token,
2858 back: back,
2859 })
2860 }
2861
2862 #[cfg(feature = "full")]
2863 fn pat_ref(input: ParseStream) -> Result<PatRef> {
2864 Ok(PatRef {
2865 and_token: input.parse()?,
2866 mutability: input.parse()?,
2867 pat: input.parse()?,
2868 })
2869 }
2870
2871 #[cfg(feature = "full")]
2872 fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
2873 let lo = input.call(pat_lit_expr)?;
2874 if input.peek(Token![..]) {
2875 Ok(Pat::Range(PatRange {
2876 lo: lo,
2877 limits: input.parse()?,
2878 hi: input.call(pat_lit_expr)?,
2879 }))
2880 } else {
2881 Ok(Pat::Lit(PatLit { expr: lo }))
2882 }
2883 }
2884
2885 #[cfg(feature = "full")]
2886 fn pat_lit_expr(input: ParseStream) -> Result<Box<Expr>> {
2887 let neg: Option<Token![-]> = input.parse()?;
2888
2889 let lookahead = input.lookahead1();
2890 let expr = if lookahead.peek(Lit) {
2891 Expr::Lit(input.call(expr_lit)?)
2892 } else if lookahead.peek(Ident)
2893 || lookahead.peek(Token![::])
2894 || lookahead.peek(Token![<])
2895 || lookahead.peek(Token![self])
2896 || lookahead.peek(Token![Self])
2897 || lookahead.peek(Token![super])
2898 || lookahead.peek(Token![extern])
2899 || lookahead.peek(Token![crate])
2900 {
2901 Expr::Path(input.parse()?)
2902 } else {
2903 return Err(lookahead.error());
2904 };
2905
2906 Ok(Box::new(if let Some(neg) = neg {
2907 Expr::Unary(ExprUnary {
2908 attrs: Vec::new(),
2909 op: UnOp::Neg(neg),
2910 expr: Box::new(expr),
2911 })
2912 } else {
2913 expr
2914 }))
2915 }
2916
2917 #[cfg(feature = "full")]
2918 fn pat_slice(input: ParseStream) -> Result<PatSlice> {
2919 let content;
2920 let bracket_token = bracketed!(content in input);
2921
2922 let mut front = Punctuated::new();
2923 let mut middle = None;
2924 loop {
2925 if content.is_empty() || content.peek(Token![..]) {
2926 break;
2927 }
2928 let value: Pat = content.parse()?;
2929 if content.peek(Token![..]) {
2930 middle = Some(Box::new(value));
2931 break;
2932 }
2933 front.push_value(value);
2934 if content.is_empty() {
2935 break;
2936 }
2937 let punct = content.parse()?;
2938 front.push_punct(punct);
2939 }
2940
2941 let dot2_token: Option<Token![..]> = content.parse()?;
2942 let mut comma_token = None::<Token![,]>;
2943 let mut back = Punctuated::new();
2944 if dot2_token.is_some() {
2945 comma_token = content.parse()?;
2946 if comma_token.is_some() {
2947 loop {
2948 if content.is_empty() {
2949 break;
2950 }
2951 let value: Pat = content.parse()?;
2952 back.push_value(value);
2953 if content.is_empty() {
2954 break;
2955 }
2956 let punct = content.parse()?;
2957 back.push_punct(punct);
2958 }
2959 }
2960 }
2961
2962 Ok(PatSlice {
2963 bracket_token: bracket_token,
2964 front: front,
2965 middle: middle,
2966 dot2_token: dot2_token,
2967 comma_token: comma_token,
2968 back: back,
2969 })
2970 }
2971
2972 #[cfg(feature = "full")]
2973 impl Member {
2974 fn is_named(&self) -> bool {
2975 match *self {
2976 Member::Named(_) => true,
2977 Member::Unnamed(_) => false,
2978 }
2979 }
2980
2981 fn is_unnamed(&self) -> bool {
2982 match *self {
2983 Member::Named(_) => false,
2984 Member::Unnamed(_) => true,
2985 }
2986 }
2987 }
2988 }
2989
2990 #[cfg(feature = "printing")]
2991 mod printing {
2992 use super::*;
2993
2994 use proc_macro2::{Literal, TokenStream};
2995 use quote::{ToTokens, TokenStreamExt};
2996
2997 #[cfg(feature = "full")]
2998 use attr::FilterAttrs;
2999 #[cfg(feature = "full")]
3000 use print::TokensOrDefault;
3001
3002 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
3003 // before appending it to `TokenStream`.
3004 #[cfg(feature = "full")]
3005 fn wrap_bare_struct(tokens: &mut TokenStream, e: &Expr) {
3006 if let Expr::Struct(_) = *e {
3007 token::Paren::default().surround(tokens, |tokens| {
3008 e.to_tokens(tokens);
3009 });
3010 } else {
3011 e.to_tokens(tokens);
3012 }
3013 }
3014
3015 #[cfg(feature = "full")]
3016 fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3017 tokens.append_all(attrs.outer());
3018 }
3019
3020 #[cfg(feature = "full")]
3021 fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
3022 tokens.append_all(attrs.inner());
3023 }
3024
3025 #[cfg(not(feature = "full"))]
3026 fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3027
3028 #[cfg(not(feature = "full"))]
3029 fn inner_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
3030
3031 #[cfg(feature = "full")]
3032 impl ToTokens for ExprBox {
3033 fn to_tokens(&self, tokens: &mut TokenStream) {
3034 outer_attrs_to_tokens(&self.attrs, tokens);
3035 self.box_token.to_tokens(tokens);
3036 self.expr.to_tokens(tokens);
3037 }
3038 }
3039
3040 #[cfg(feature = "full")]
3041 impl ToTokens for ExprInPlace {
3042 fn to_tokens(&self, tokens: &mut TokenStream) {
3043 outer_attrs_to_tokens(&self.attrs, tokens);
3044 self.place.to_tokens(tokens);
3045 self.arrow_token.to_tokens(tokens);
3046 self.value.to_tokens(tokens);
3047 }
3048 }
3049
3050 #[cfg(feature = "full")]
3051 impl ToTokens for ExprArray {
3052 fn to_tokens(&self, tokens: &mut TokenStream) {
3053 outer_attrs_to_tokens(&self.attrs, tokens);
3054 self.bracket_token.surround(tokens, |tokens| {
3055 inner_attrs_to_tokens(&self.attrs, tokens);
3056 self.elems.to_tokens(tokens);
3057 })
3058 }
3059 }
3060
3061 impl ToTokens for ExprCall {
3062 fn to_tokens(&self, tokens: &mut TokenStream) {
3063 outer_attrs_to_tokens(&self.attrs, tokens);
3064 self.func.to_tokens(tokens);
3065 self.paren_token.surround(tokens, |tokens| {
3066 self.args.to_tokens(tokens);
3067 })
3068 }
3069 }
3070
3071 #[cfg(feature = "full")]
3072 impl ToTokens for ExprMethodCall {
3073 fn to_tokens(&self, tokens: &mut TokenStream) {
3074 outer_attrs_to_tokens(&self.attrs, tokens);
3075 self.receiver.to_tokens(tokens);
3076 self.dot_token.to_tokens(tokens);
3077 self.method.to_tokens(tokens);
3078 self.turbofish.to_tokens(tokens);
3079 self.paren_token.surround(tokens, |tokens| {
3080 self.args.to_tokens(tokens);
3081 });
3082 }
3083 }
3084
3085 #[cfg(feature = "full")]
3086 impl ToTokens for MethodTurbofish {
3087 fn to_tokens(&self, tokens: &mut TokenStream) {
3088 self.colon2_token.to_tokens(tokens);
3089 self.lt_token.to_tokens(tokens);
3090 self.args.to_tokens(tokens);
3091 self.gt_token.to_tokens(tokens);
3092 }
3093 }
3094
3095 #[cfg(feature = "full")]
3096 impl ToTokens for GenericMethodArgument {
3097 fn to_tokens(&self, tokens: &mut TokenStream) {
3098 match *self {
3099 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
3100 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
3101 }
3102 }
3103 }
3104
3105 #[cfg(feature = "full")]
3106 impl ToTokens for ExprTuple {
3107 fn to_tokens(&self, tokens: &mut TokenStream) {
3108 outer_attrs_to_tokens(&self.attrs, tokens);
3109 self.paren_token.surround(tokens, |tokens| {
3110 inner_attrs_to_tokens(&self.attrs, tokens);
3111 self.elems.to_tokens(tokens);
3112 // If we only have one argument, we need a trailing comma to
3113 // distinguish ExprTuple from ExprParen.
3114 if self.elems.len() == 1 && !self.elems.trailing_punct() {
3115 <Token![,]>::default().to_tokens(tokens);
3116 }
3117 })
3118 }
3119 }
3120
3121 impl ToTokens for ExprBinary {
3122 fn to_tokens(&self, tokens: &mut TokenStream) {
3123 outer_attrs_to_tokens(&self.attrs, tokens);
3124 self.left.to_tokens(tokens);
3125 self.op.to_tokens(tokens);
3126 self.right.to_tokens(tokens);
3127 }
3128 }
3129
3130 impl ToTokens for ExprUnary {
3131 fn to_tokens(&self, tokens: &mut TokenStream) {
3132 outer_attrs_to_tokens(&self.attrs, tokens);
3133 self.op.to_tokens(tokens);
3134 self.expr.to_tokens(tokens);
3135 }
3136 }
3137
3138 impl ToTokens for ExprLit {
3139 fn to_tokens(&self, tokens: &mut TokenStream) {
3140 outer_attrs_to_tokens(&self.attrs, tokens);
3141 self.lit.to_tokens(tokens);
3142 }
3143 }
3144
3145 impl ToTokens for ExprCast {
3146 fn to_tokens(&self, tokens: &mut TokenStream) {
3147 outer_attrs_to_tokens(&self.attrs, tokens);
3148 self.expr.to_tokens(tokens);
3149 self.as_token.to_tokens(tokens);
3150 self.ty.to_tokens(tokens);
3151 }
3152 }
3153
3154 #[cfg(feature = "full")]
3155 impl ToTokens for ExprType {
3156 fn to_tokens(&self, tokens: &mut TokenStream) {
3157 outer_attrs_to_tokens(&self.attrs, tokens);
3158 self.expr.to_tokens(tokens);
3159 self.colon_token.to_tokens(tokens);
3160 self.ty.to_tokens(tokens);
3161 }
3162 }
3163
3164 #[cfg(feature = "full")]
3165 fn maybe_wrap_else(tokens: &mut TokenStream, else_: &Option<(Token![else], Box<Expr>)>) {
3166 if let Some((ref else_token, ref else_)) = *else_ {
3167 else_token.to_tokens(tokens);
3168
3169 // If we are not one of the valid expressions to exist in an else
3170 // clause, wrap ourselves in a block.
3171 match **else_ {
3172 Expr::If(_) | Expr::Block(_) => {
3173 else_.to_tokens(tokens);
3174 }
3175 _ => {
3176 token::Brace::default().surround(tokens, |tokens| {
3177 else_.to_tokens(tokens);
3178 });
3179 }
3180 }
3181 }
3182 }
3183
3184 #[cfg(feature = "full")]
3185 impl ToTokens for ExprLet {
3186 fn to_tokens(&self, tokens: &mut TokenStream) {
3187 outer_attrs_to_tokens(&self.attrs, tokens);
3188 self.let_token.to_tokens(tokens);
3189 self.pats.to_tokens(tokens);
3190 self.eq_token.to_tokens(tokens);
3191 wrap_bare_struct(tokens, &self.expr);
3192 }
3193 }
3194
3195 #[cfg(feature = "full")]
3196 impl ToTokens for ExprIf {
3197 fn to_tokens(&self, tokens: &mut TokenStream) {
3198 outer_attrs_to_tokens(&self.attrs, tokens);
3199 self.if_token.to_tokens(tokens);
3200 wrap_bare_struct(tokens, &self.cond);
3201 self.then_branch.to_tokens(tokens);
3202 maybe_wrap_else(tokens, &self.else_branch);
3203 }
3204 }
3205
3206 #[cfg(feature = "full")]
3207 impl ToTokens for ExprWhile {
3208 fn to_tokens(&self, tokens: &mut TokenStream) {
3209 outer_attrs_to_tokens(&self.attrs, tokens);
3210 self.label.to_tokens(tokens);
3211 self.while_token.to_tokens(tokens);
3212 wrap_bare_struct(tokens, &self.cond);
3213 self.body.brace_token.surround(tokens, |tokens| {
3214 inner_attrs_to_tokens(&self.attrs, tokens);
3215 tokens.append_all(&self.body.stmts);
3216 });
3217 }
3218 }
3219
3220 #[cfg(feature = "full")]
3221 impl ToTokens for ExprForLoop {
3222 fn to_tokens(&self, tokens: &mut TokenStream) {
3223 outer_attrs_to_tokens(&self.attrs, tokens);
3224 self.label.to_tokens(tokens);
3225 self.for_token.to_tokens(tokens);
3226 self.pat.to_tokens(tokens);
3227 self.in_token.to_tokens(tokens);
3228 wrap_bare_struct(tokens, &self.expr);
3229 self.body.brace_token.surround(tokens, |tokens| {
3230 inner_attrs_to_tokens(&self.attrs, tokens);
3231 tokens.append_all(&self.body.stmts);
3232 });
3233 }
3234 }
3235
3236 #[cfg(feature = "full")]
3237 impl ToTokens for ExprLoop {
3238 fn to_tokens(&self, tokens: &mut TokenStream) {
3239 outer_attrs_to_tokens(&self.attrs, tokens);
3240 self.label.to_tokens(tokens);
3241 self.loop_token.to_tokens(tokens);
3242 self.body.brace_token.surround(tokens, |tokens| {
3243 inner_attrs_to_tokens(&self.attrs, tokens);
3244 tokens.append_all(&self.body.stmts);
3245 });
3246 }
3247 }
3248
3249 #[cfg(feature = "full")]
3250 impl ToTokens for ExprMatch {
3251 fn to_tokens(&self, tokens: &mut TokenStream) {
3252 outer_attrs_to_tokens(&self.attrs, tokens);
3253 self.match_token.to_tokens(tokens);
3254 wrap_bare_struct(tokens, &self.expr);
3255 self.brace_token.surround(tokens, |tokens| {
3256 inner_attrs_to_tokens(&self.attrs, tokens);
3257 for (i, arm) in self.arms.iter().enumerate() {
3258 arm.to_tokens(tokens);
3259 // Ensure that we have a comma after a non-block arm, except
3260 // for the last one.
3261 let is_last = i == self.arms.len() - 1;
3262 if !is_last && requires_terminator(&arm.body) && arm.comma.is_none() {
3263 <Token![,]>::default().to_tokens(tokens);
3264 }
3265 }
3266 });
3267 }
3268 }
3269
3270 #[cfg(feature = "full")]
3271 impl ToTokens for ExprAsync {
3272 fn to_tokens(&self, tokens: &mut TokenStream) {
3273 outer_attrs_to_tokens(&self.attrs, tokens);
3274 self.async_token.to_tokens(tokens);
3275 self.capture.to_tokens(tokens);
3276 self.block.to_tokens(tokens);
3277 }
3278 }
3279
3280 #[cfg(feature = "full")]
3281 impl ToTokens for ExprTryBlock {
3282 fn to_tokens(&self, tokens: &mut TokenStream) {
3283 outer_attrs_to_tokens(&self.attrs, tokens);
3284 self.try_token.to_tokens(tokens);
3285 self.block.to_tokens(tokens);
3286 }
3287 }
3288
3289 #[cfg(feature = "full")]
3290 impl ToTokens for ExprYield {
3291 fn to_tokens(&self, tokens: &mut TokenStream) {
3292 outer_attrs_to_tokens(&self.attrs, tokens);
3293 self.yield_token.to_tokens(tokens);
3294 self.expr.to_tokens(tokens);
3295 }
3296 }
3297
3298 #[cfg(feature = "full")]
3299 impl ToTokens for ExprClosure {
3300 fn to_tokens(&self, tokens: &mut TokenStream) {
3301 outer_attrs_to_tokens(&self.attrs, tokens);
3302 self.asyncness.to_tokens(tokens);
3303 self.movability.to_tokens(tokens);
3304 self.capture.to_tokens(tokens);
3305 self.or1_token.to_tokens(tokens);
3306 for input in self.inputs.pairs() {
3307 match **input.value() {
3308 FnArg::Captured(ArgCaptured {
3309 ref pat,
3310 ty: Type::Infer(_),
3311 ..
3312 }) => {
3313 pat.to_tokens(tokens);
3314 }
3315 _ => input.value().to_tokens(tokens),
3316 }
3317 input.punct().to_tokens(tokens);
3318 }
3319 self.or2_token.to_tokens(tokens);
3320 self.output.to_tokens(tokens);
3321 self.body.to_tokens(tokens);
3322 }
3323 }
3324
3325 #[cfg(feature = "full")]
3326 impl ToTokens for ExprUnsafe {
3327 fn to_tokens(&self, tokens: &mut TokenStream) {
3328 outer_attrs_to_tokens(&self.attrs, tokens);
3329 self.unsafe_token.to_tokens(tokens);
3330 self.block.brace_token.surround(tokens, |tokens| {
3331 inner_attrs_to_tokens(&self.attrs, tokens);
3332 tokens.append_all(&self.block.stmts);
3333 });
3334 }
3335 }
3336
3337 #[cfg(feature = "full")]
3338 impl ToTokens for ExprBlock {
3339 fn to_tokens(&self, tokens: &mut TokenStream) {
3340 outer_attrs_to_tokens(&self.attrs, tokens);
3341 self.label.to_tokens(tokens);
3342 self.block.brace_token.surround(tokens, |tokens| {
3343 inner_attrs_to_tokens(&self.attrs, tokens);
3344 tokens.append_all(&self.block.stmts);
3345 });
3346 }
3347 }
3348
3349 #[cfg(feature = "full")]
3350 impl ToTokens for ExprAssign {
3351 fn to_tokens(&self, tokens: &mut TokenStream) {
3352 outer_attrs_to_tokens(&self.attrs, tokens);
3353 self.left.to_tokens(tokens);
3354 self.eq_token.to_tokens(tokens);
3355 self.right.to_tokens(tokens);
3356 }
3357 }
3358
3359 #[cfg(feature = "full")]
3360 impl ToTokens for ExprAssignOp {
3361 fn to_tokens(&self, tokens: &mut TokenStream) {
3362 outer_attrs_to_tokens(&self.attrs, tokens);
3363 self.left.to_tokens(tokens);
3364 self.op.to_tokens(tokens);
3365 self.right.to_tokens(tokens);
3366 }
3367 }
3368
3369 impl ToTokens for ExprField {
3370 fn to_tokens(&self, tokens: &mut TokenStream) {
3371 outer_attrs_to_tokens(&self.attrs, tokens);
3372 self.base.to_tokens(tokens);
3373 self.dot_token.to_tokens(tokens);
3374 self.member.to_tokens(tokens);
3375 }
3376 }
3377
3378 impl ToTokens for Member {
3379 fn to_tokens(&self, tokens: &mut TokenStream) {
3380 match *self {
3381 Member::Named(ref ident) => ident.to_tokens(tokens),
3382 Member::Unnamed(ref index) => index.to_tokens(tokens),
3383 }
3384 }
3385 }
3386
3387 impl ToTokens for Index {
3388 fn to_tokens(&self, tokens: &mut TokenStream) {
3389 let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
3390 lit.set_span(self.span);
3391 tokens.append(lit);
3392 }
3393 }
3394
3395 impl ToTokens for ExprIndex {
3396 fn to_tokens(&self, tokens: &mut TokenStream) {
3397 outer_attrs_to_tokens(&self.attrs, tokens);
3398 self.expr.to_tokens(tokens);
3399 self.bracket_token.surround(tokens, |tokens| {
3400 self.index.to_tokens(tokens);
3401 });
3402 }
3403 }
3404
3405 #[cfg(feature = "full")]
3406 impl ToTokens for ExprRange {
3407 fn to_tokens(&self, tokens: &mut TokenStream) {
3408 outer_attrs_to_tokens(&self.attrs, tokens);
3409 self.from.to_tokens(tokens);
3410 match self.limits {
3411 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3412 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
3413 }
3414 self.to.to_tokens(tokens);
3415 }
3416 }
3417
3418 impl ToTokens for ExprPath {
3419 fn to_tokens(&self, tokens: &mut TokenStream) {
3420 outer_attrs_to_tokens(&self.attrs, tokens);
3421 private::print_path(tokens, &self.qself, &self.path);
3422 }
3423 }
3424
3425 #[cfg(feature = "full")]
3426 impl ToTokens for ExprReference {
3427 fn to_tokens(&self, tokens: &mut TokenStream) {
3428 outer_attrs_to_tokens(&self.attrs, tokens);
3429 self.and_token.to_tokens(tokens);
3430 self.mutability.to_tokens(tokens);
3431 self.expr.to_tokens(tokens);
3432 }
3433 }
3434
3435 #[cfg(feature = "full")]
3436 impl ToTokens for ExprBreak {
3437 fn to_tokens(&self, tokens: &mut TokenStream) {
3438 outer_attrs_to_tokens(&self.attrs, tokens);
3439 self.break_token.to_tokens(tokens);
3440 self.label.to_tokens(tokens);
3441 self.expr.to_tokens(tokens);
3442 }
3443 }
3444
3445 #[cfg(feature = "full")]
3446 impl ToTokens for ExprContinue {
3447 fn to_tokens(&self, tokens: &mut TokenStream) {
3448 outer_attrs_to_tokens(&self.attrs, tokens);
3449 self.continue_token.to_tokens(tokens);
3450 self.label.to_tokens(tokens);
3451 }
3452 }
3453
3454 #[cfg(feature = "full")]
3455 impl ToTokens for ExprReturn {
3456 fn to_tokens(&self, tokens: &mut TokenStream) {
3457 outer_attrs_to_tokens(&self.attrs, tokens);
3458 self.return_token.to_tokens(tokens);
3459 self.expr.to_tokens(tokens);
3460 }
3461 }
3462
3463 #[cfg(feature = "full")]
3464 impl ToTokens for ExprMacro {
3465 fn to_tokens(&self, tokens: &mut TokenStream) {
3466 outer_attrs_to_tokens(&self.attrs, tokens);
3467 self.mac.to_tokens(tokens);
3468 }
3469 }
3470
3471 #[cfg(feature = "full")]
3472 impl ToTokens for ExprStruct {
3473 fn to_tokens(&self, tokens: &mut TokenStream) {
3474 outer_attrs_to_tokens(&self.attrs, tokens);
3475 self.path.to_tokens(tokens);
3476 self.brace_token.surround(tokens, |tokens| {
3477 inner_attrs_to_tokens(&self.attrs, tokens);
3478 self.fields.to_tokens(tokens);
3479 if self.rest.is_some() {
3480 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3481 self.rest.to_tokens(tokens);
3482 }
3483 })
3484 }
3485 }
3486
3487 #[cfg(feature = "full")]
3488 impl ToTokens for ExprRepeat {
3489 fn to_tokens(&self, tokens: &mut TokenStream) {
3490 outer_attrs_to_tokens(&self.attrs, tokens);
3491 self.bracket_token.surround(tokens, |tokens| {
3492 inner_attrs_to_tokens(&self.attrs, tokens);
3493 self.expr.to_tokens(tokens);
3494 self.semi_token.to_tokens(tokens);
3495 self.len.to_tokens(tokens);
3496 })
3497 }
3498 }
3499
3500 #[cfg(feature = "full")]
3501 impl ToTokens for ExprGroup {
3502 fn to_tokens(&self, tokens: &mut TokenStream) {
3503 outer_attrs_to_tokens(&self.attrs, tokens);
3504 self.group_token.surround(tokens, |tokens| {
3505 self.expr.to_tokens(tokens);
3506 });
3507 }
3508 }
3509
3510 impl ToTokens for ExprParen {
3511 fn to_tokens(&self, tokens: &mut TokenStream) {
3512 outer_attrs_to_tokens(&self.attrs, tokens);
3513 self.paren_token.surround(tokens, |tokens| {
3514 inner_attrs_to_tokens(&self.attrs, tokens);
3515 self.expr.to_tokens(tokens);
3516 });
3517 }
3518 }
3519
3520 #[cfg(feature = "full")]
3521 impl ToTokens for ExprTry {
3522 fn to_tokens(&self, tokens: &mut TokenStream) {
3523 outer_attrs_to_tokens(&self.attrs, tokens);
3524 self.expr.to_tokens(tokens);
3525 self.question_token.to_tokens(tokens);
3526 }
3527 }
3528
3529 impl ToTokens for ExprVerbatim {
3530 fn to_tokens(&self, tokens: &mut TokenStream) {
3531 self.tts.to_tokens(tokens);
3532 }
3533 }
3534
3535 #[cfg(feature = "full")]
3536 impl ToTokens for Label {
3537 fn to_tokens(&self, tokens: &mut TokenStream) {
3538 self.name.to_tokens(tokens);
3539 self.colon_token.to_tokens(tokens);
3540 }
3541 }
3542
3543 #[cfg(feature = "full")]
3544 impl ToTokens for FieldValue {
3545 fn to_tokens(&self, tokens: &mut TokenStream) {
3546 outer_attrs_to_tokens(&self.attrs, tokens);
3547 self.member.to_tokens(tokens);
3548 if let Some(ref colon_token) = self.colon_token {
3549 colon_token.to_tokens(tokens);
3550 self.expr.to_tokens(tokens);
3551 }
3552 }
3553 }
3554
3555 #[cfg(feature = "full")]
3556 impl ToTokens for Arm {
3557 fn to_tokens(&self, tokens: &mut TokenStream) {
3558 tokens.append_all(&self.attrs);
3559 self.leading_vert.to_tokens(tokens);
3560 self.pats.to_tokens(tokens);
3561 if let Some((ref if_token, ref guard)) = self.guard {
3562 if_token.to_tokens(tokens);
3563 guard.to_tokens(tokens);
3564 }
3565 self.fat_arrow_token.to_tokens(tokens);
3566 self.body.to_tokens(tokens);
3567 self.comma.to_tokens(tokens);
3568 }
3569 }
3570
3571 #[cfg(feature = "full")]
3572 impl ToTokens for PatWild {
3573 fn to_tokens(&self, tokens: &mut TokenStream) {
3574 self.underscore_token.to_tokens(tokens);
3575 }
3576 }
3577
3578 #[cfg(feature = "full")]
3579 impl ToTokens for PatIdent {
3580 fn to_tokens(&self, tokens: &mut TokenStream) {
3581 self.by_ref.to_tokens(tokens);
3582 self.mutability.to_tokens(tokens);
3583 self.ident.to_tokens(tokens);
3584 if let Some((ref at_token, ref subpat)) = self.subpat {
3585 at_token.to_tokens(tokens);
3586 subpat.to_tokens(tokens);
3587 }
3588 }
3589 }
3590
3591 #[cfg(feature = "full")]
3592 impl ToTokens for PatStruct {
3593 fn to_tokens(&self, tokens: &mut TokenStream) {
3594 self.path.to_tokens(tokens);
3595 self.brace_token.surround(tokens, |tokens| {
3596 self.fields.to_tokens(tokens);
3597 // NOTE: We need a comma before the dot2 token if it is present.
3598 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
3599 <Token![,]>::default().to_tokens(tokens);
3600 }
3601 self.dot2_token.to_tokens(tokens);
3602 });
3603 }
3604 }
3605
3606 #[cfg(feature = "full")]
3607 impl ToTokens for PatTupleStruct {
3608 fn to_tokens(&self, tokens: &mut TokenStream) {
3609 self.path.to_tokens(tokens);
3610 self.pat.to_tokens(tokens);
3611 }
3612 }
3613
3614 #[cfg(feature = "full")]
3615 impl ToTokens for PatPath {
3616 fn to_tokens(&self, tokens: &mut TokenStream) {
3617 private::print_path(tokens, &self.qself, &self.path);
3618 }
3619 }
3620
3621 #[cfg(feature = "full")]
3622 impl ToTokens for PatTuple {
3623 fn to_tokens(&self, tokens: &mut TokenStream) {
3624 self.paren_token.surround(tokens, |tokens| {
3625 self.front.to_tokens(tokens);
3626 if let Some(ref dot2_token) = self.dot2_token {
3627 if !self.front.empty_or_trailing() {
3628 // Ensure there is a comma before the .. token.
3629 <Token![,]>::default().to_tokens(tokens);
3630 }
3631 dot2_token.to_tokens(tokens);
3632 self.comma_token.to_tokens(tokens);
3633 if self.comma_token.is_none() && !self.back.is_empty() {
3634 // Ensure there is a comma after the .. token.
3635 <Token![,]>::default().to_tokens(tokens);
3636 }
3637 }
3638 self.back.to_tokens(tokens);
3639 });
3640 }
3641 }
3642
3643 #[cfg(feature = "full")]
3644 impl ToTokens for PatBox {
3645 fn to_tokens(&self, tokens: &mut TokenStream) {
3646 self.box_token.to_tokens(tokens);
3647 self.pat.to_tokens(tokens);
3648 }
3649 }
3650
3651 #[cfg(feature = "full")]
3652 impl ToTokens for PatRef {
3653 fn to_tokens(&self, tokens: &mut TokenStream) {
3654 self.and_token.to_tokens(tokens);
3655 self.mutability.to_tokens(tokens);
3656 self.pat.to_tokens(tokens);
3657 }
3658 }
3659
3660 #[cfg(feature = "full")]
3661 impl ToTokens for PatLit {
3662 fn to_tokens(&self, tokens: &mut TokenStream) {
3663 self.expr.to_tokens(tokens);
3664 }
3665 }
3666
3667 #[cfg(feature = "full")]
3668 impl ToTokens for PatRange {
3669 fn to_tokens(&self, tokens: &mut TokenStream) {
3670 self.lo.to_tokens(tokens);
3671 match self.limits {
3672 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3673 RangeLimits::Closed(ref t) => Token![...](t.spans).to_tokens(tokens),
3674 }
3675 self.hi.to_tokens(tokens);
3676 }
3677 }
3678
3679 #[cfg(feature = "full")]
3680 impl ToTokens for PatSlice {
3681 fn to_tokens(&self, tokens: &mut TokenStream) {
3682 self.bracket_token.surround(tokens, |tokens| {
3683 self.front.to_tokens(tokens);
3684
3685 // If we need a comma before the middle or standalone .. token,
3686 // then make sure it's present.
3687 if !self.front.empty_or_trailing()
3688 && (self.middle.is_some() || self.dot2_token.is_some())
3689 {
3690 <Token![,]>::default().to_tokens(tokens);
3691 }
3692
3693 // If we have an identifier, we always need a .. token.
3694 if self.middle.is_some() {
3695 self.middle.to_tokens(tokens);
3696 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3697 } else if self.dot2_token.is_some() {
3698 self.dot2_token.to_tokens(tokens);
3699 }
3700
3701 // Make sure we have a comma before the back half.
3702 if !self.back.is_empty() {
3703 TokensOrDefault(&self.comma_token).to_tokens(tokens);
3704 self.back.to_tokens(tokens);
3705 } else {
3706 self.comma_token.to_tokens(tokens);
3707 }
3708 })
3709 }
3710 }
3711
3712 #[cfg(feature = "full")]
3713 impl ToTokens for PatMacro {
3714 fn to_tokens(&self, tokens: &mut TokenStream) {
3715 self.mac.to_tokens(tokens);
3716 }
3717 }
3718
3719 #[cfg(feature = "full")]
3720 impl ToTokens for PatVerbatim {
3721 fn to_tokens(&self, tokens: &mut TokenStream) {
3722 self.tts.to_tokens(tokens);
3723 }
3724 }
3725
3726 #[cfg(feature = "full")]
3727 impl ToTokens for FieldPat {
3728 fn to_tokens(&self, tokens: &mut TokenStream) {
3729 if let Some(ref colon_token) = self.colon_token {
3730 self.member.to_tokens(tokens);
3731 colon_token.to_tokens(tokens);
3732 }
3733 self.pat.to_tokens(tokens);
3734 }
3735 }
3736
3737 #[cfg(feature = "full")]
3738 impl ToTokens for Block {
3739 fn to_tokens(&self, tokens: &mut TokenStream) {
3740 self.brace_token.surround(tokens, |tokens| {
3741 tokens.append_all(&self.stmts);
3742 });
3743 }
3744 }
3745
3746 #[cfg(feature = "full")]
3747 impl ToTokens for Stmt {
3748 fn to_tokens(&self, tokens: &mut TokenStream) {
3749 match *self {
3750 Stmt::Local(ref local) => local.to_tokens(tokens),
3751 Stmt::Item(ref item) => item.to_tokens(tokens),
3752 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
3753 Stmt::Semi(ref expr, ref semi) => {
3754 expr.to_tokens(tokens);
3755 semi.to_tokens(tokens);
3756 }
3757 }
3758 }
3759 }
3760
3761 #[cfg(feature = "full")]
3762 impl ToTokens for Local {
3763 fn to_tokens(&self, tokens: &mut TokenStream) {
3764 outer_attrs_to_tokens(&self.attrs, tokens);
3765 self.let_token.to_tokens(tokens);
3766 self.pats.to_tokens(tokens);
3767 if let Some((ref colon_token, ref ty)) = self.ty {
3768 colon_token.to_tokens(tokens);
3769 ty.to_tokens(tokens);
3770 }
3771 if let Some((ref eq_token, ref init)) = self.init {
3772 eq_token.to_tokens(tokens);
3773 init.to_tokens(tokens);
3774 }
3775 self.semi_token.to_tokens(tokens);
3776 }
3777 }
3778 }