blob: a66792d7d0ab70b120d0fa56eee2f0c28ce8b855 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub enum Expr {
5 /// A `box x` expression.
6 Box(Box<Expr>),
7 /// First expr is the place; second expr is the value.
8 InPlace(Box<Expr>, Box<Expr>),
9 /// An array (`[a, b, c, d]`)
10 Vec(Vec<Expr>),
11 /// A function call
12 ///
13 /// The first field resolves to the function itself,
14 /// and the second field is the list of arguments
15 Call(Box<Expr>, Vec<Expr>),
16 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
17 ///
18 /// The `Ident` is the identifier for the method name.
19 /// The vector of `Ty`s are the ascripted type parameters for the method
20 /// (within the angle brackets).
21 ///
22 /// The first element of the vector of `Expr`s is the expression that evaluates
23 /// to the object on which the method is being called on (the receiver),
24 /// and the remaining elements are the rest of the arguments.
25 ///
26 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
27 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
28 MethodCall(Ident, Vec<Ty>, Vec<Expr>),
29 /// A tuple (`(a, b, c, d)`)
30 Tup(Vec<Expr>),
31 /// A binary operation (For example: `a + b`, `a * b`)
32 Binary(BinOp, Box<Expr>, Box<Expr>),
33 /// A unary operation (For example: `!x`, `*x`)
34 Unary(UnOp, Box<Expr>),
35 /// A literal (For example: `1`, `"foo"`)
36 Lit(Lit),
37 /// A cast (`foo as f64`)
38 Cast(Box<Expr>, Box<Ty>),
39 Type(Box<Expr>, Box<Ty>),
40 /// An `if` block, with an optional else block
41 ///
42 /// `if expr { block } else { expr }`
43 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
44 /// An `if let` expression with an optional else block
45 ///
46 /// `if let pat = expr { block } else { expr }`
47 ///
48 /// This is desugared to a `match` expression.
49 IfLet(Box<Pat>, Box<Expr>, Box<Block>, Option<Box<Expr>>),
50 /// A while loop, with an optional label
51 ///
52 /// `'label: while expr { block }`
53 While(Box<Expr>, Box<Block>, Option<Ident>),
54 /// A while-let loop, with an optional label
55 ///
56 /// `'label: while let pat = expr { block }`
57 ///
58 /// This is desugared to a combination of `loop` and `match` expressions.
59 WhileLet(Box<Pat>, Box<Expr>, Box<Block>, Option<Ident>),
60 /// A for loop, with an optional label
61 ///
62 /// `'label: for pat in expr { block }`
63 ///
64 /// This is desugared to a combination of `loop` and `match` expressions.
65 ForLoop(Box<Pat>, Box<Expr>, Box<Block>, Option<Ident>),
66 /// Conditionless loop (can be exited with break, continue, or return)
67 ///
68 /// `'label: loop { block }`
69 Loop(Box<Block>, Option<Ident>),
70 /// A `match` block.
71 Match(Box<Expr>, Vec<Arm>),
72 /// A closure (for example, `move |a, b, c| {a + b + c}`)
73 Closure(CaptureBy, Box<FnDecl>, Box<Block>),
74 /// A block (`{ ... }`)
75 Block(Box<Block>),
76
77 /// An assignment (`a = foo()`)
78 Assign(Box<Expr>, Box<Expr>),
79 /// An assignment with an operator
80 ///
81 /// For example, `a += 1`.
82 AssignOp(BinOp, Box<Expr>, Box<Expr>),
83 /// Access of a named struct field (`obj.foo`)
84 Field(Box<Expr>, Ident),
85 /// Access of an unnamed field of a struct or tuple-struct
86 ///
87 /// For example, `foo.0`.
88 TupField(Box<Expr>, usize),
89 /// An indexing operation (`foo[2]`)
90 Index(Box<Expr>, Box<Expr>),
91 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
92 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
93
94 /// Variable reference, possibly containing `::` and/or type
95 /// parameters, e.g. foo::bar::<baz>.
96 ///
97 /// Optionally "qualified",
98 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
99 Path(Option<QSelf>, Path),
100
101 /// A referencing operation (`&a` or `&mut a`)
102 AddrOf(Mutability, Box<Expr>),
103 /// A `break`, with an optional label to break
104 Break(Option<Ident>),
105 /// A `continue`, with an optional label
106 Continue(Option<Ident>),
107 /// A `return`, with an optional value to be returned
108 Ret(Option<Box<Expr>>),
109
110 /// A macro invocation; pre-expansion
111 Mac(Mac),
112
113 /// A struct literal expression.
114 ///
115 /// For example, `Foo {x: 1, y: 2}`, or
116 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
117 Struct(Path, Vec<Field>, Option<Box<Expr>>),
118
119 /// An array literal constructed from one repeated element.
120 ///
121 /// For example, `[1; 5]`. The first expression is the element
122 /// to be repeated; the second is the number of times to repeat it.
123 Repeat(Box<Expr>, Box<Expr>),
124
125 /// No-op: used solely so we can pretty-print faithfully
126 Paren(Box<Expr>),
127
128 /// `expr?`
129 Try(Box<Expr>),
130}
131
132/// A Block (`{ .. }`).
133///
134/// E.g. `{ .. }` as in `fn foo() { .. }`
135#[derive(Debug, Clone, Eq, PartialEq)]
136pub struct Block {
137 /// Statements in a block
138 pub stmts: Vec<Stmt>,
139 /// Distinguishes between `unsafe { ... }` and `{ ... }`
140 pub rules: BlockCheckMode,
141}
142
143#[derive(Debug, Copy, Clone, Eq, PartialEq)]
144pub enum BlockCheckMode {
145 Default,
146 Unsafe,
147}
148
149#[derive(Debug, Clone, Eq, PartialEq)]
150pub enum Stmt {
151 /// A local (let) binding.
152 Local(Box<Local>),
153
154 /// An item definition.
155 Item(Box<Item>),
156
157 /// Expr without trailing semi-colon.
158 Expr(Box<Expr>),
159
160 Semi(Box<Expr>),
161
162 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
163}
164
165#[derive(Debug, Copy, Clone, Eq, PartialEq)]
166pub enum MacStmtStyle {
167 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
168 /// `foo!(...);`, `foo![...];`
169 Semicolon,
170 /// The macro statement had braces; e.g. foo! { ... }
171 Braces,
172 /// The macro statement had parentheses or brackets and no semicolon; e.g.
173 /// `foo!(...)`. All of these will end up being converted into macro
174 /// expressions.
175 NoBraces,
176}
177
178/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
179#[derive(Debug, Clone, Eq, PartialEq)]
180pub struct Local {
181 pub pat: Box<Pat>,
182 pub ty: Option<Box<Ty>>,
183 /// Initializer expression to set the value, if any
184 pub init: Option<Box<Expr>>,
185 pub attrs: Vec<Attribute>,
186}
187
188#[derive(Debug, Copy, Clone, Eq, PartialEq)]
189pub enum BinOp {
190 /// The `+` operator (addition)
191 Add,
192 /// The `-` operator (subtraction)
193 Sub,
194 /// The `*` operator (multiplication)
195 Mul,
196 /// The `/` operator (division)
197 Div,
198 /// The `%` operator (modulus)
199 Rem,
200 /// The `&&` operator (logical and)
201 And,
202 /// The `||` operator (logical or)
203 Or,
204 /// The `^` operator (bitwise xor)
205 BitXor,
206 /// The `&` operator (bitwise and)
207 BitAnd,
208 /// The `|` operator (bitwise or)
209 BitOr,
210 /// The `<<` operator (shift left)
211 Shl,
212 /// The `>>` operator (shift right)
213 Shr,
214 /// The `==` operator (equality)
215 Eq,
216 /// The `<` operator (less than)
217 Lt,
218 /// The `<=` operator (less than or equal to)
219 Le,
220 /// The `!=` operator (not equal to)
221 Ne,
222 /// The `>=` operator (greater than or equal to)
223 Ge,
224 /// The `>` operator (greater than)
225 Gt,
226}
227
228#[derive(Debug, Copy, Clone, Eq, PartialEq)]
229pub enum UnOp {
230 /// The `*` operator for dereferencing
231 Deref,
232 /// The `!` operator for logical inversion
233 Not,
234 /// The `-` operator for negation
235 Neg,
236}
237
238#[derive(Debug, Clone, Eq, PartialEq)]
239pub enum Pat {
240 /// Represents a wildcard pattern (`_`)
241 Wild,
242
243 /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
244 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
245 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
246 /// during name resolution.
247 Ident(BindingMode, Ident, Option<Box<Pat>>),
248
249 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
250 /// The `bool` is `true` in the presence of a `..`.
251 Struct(Path, Vec<FieldPat>, bool),
252
253 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
254 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
255 /// 0 <= position <= subpats.len()
256 TupleStruct(Path, Vec<Pat>, Option<usize>),
257
258 /// A possibly qualified path pattern.
259 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
260 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
261 /// only legally refer to associated constants.
262 Path(Option<QSelf>, Path),
263
264 /// A tuple pattern `(a, b)`.
265 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
266 /// 0 <= position <= subpats.len()
267 Tuple(Vec<Pat>, Option<usize>),
268 /// A `box` pattern
269 Box(Box<Pat>),
270 /// A reference pattern, e.g. `&mut (a, b)`
271 Ref(Box<Pat>, Mutability),
272 /// A literal
273 Lit(Box<Expr>),
274 /// A range pattern, e.g. `1...2`
275 Range(Box<Expr>, Box<Expr>),
276 /// `[a, b, ..i, y, z]` is represented as:
277 /// `PatKind::Vec(box [a, b], Some(i), box [y, z])`
278 Vec(Vec<Pat>, Option<Box<Pat>>, Vec<Pat>),
279 /// A macro pattern; pre-expansion
280 Mac(Mac),
281}
282
David Tolnay771ecf42016-09-23 19:26:37 -0700283/// An arm of a 'match'.
284///
285/// E.g. `0...10 => { println!("match!") }` as in
286///
287/// ```rust,ignore
288/// match n {
289/// 0...10 => { println!("match!") },
290/// // ..
291/// }
292/// ```
David Tolnayf4bbbd92016-09-23 14:41:55 -0700293#[derive(Debug, Clone, Eq, PartialEq)]
294pub struct Arm {
295 pub attrs: Vec<Attribute>,
296 pub pats: Vec<Pat>,
297 pub guard: Option<Box<Expr>>,
298 pub body: Box<Expr>,
299}
300
301/// A capture clause
302#[derive(Debug, Copy, Clone, Eq, PartialEq)]
303pub enum CaptureBy {
304 Value,
305 Ref,
306}
307
308/// Limit types of a range (inclusive or exclusive)
309#[derive(Debug, Copy, Clone, Eq, PartialEq)]
310pub enum RangeLimits {
311 /// Inclusive at the beginning, exclusive at the end
312 HalfOpen,
313 /// Inclusive at the beginning and end
314 Closed,
315}
316
317/// A single field in a struct pattern
318///
319/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
320/// are treated the same as` x: x, y: ref y, z: ref mut z`,
321/// except is_shorthand is true
322#[derive(Debug, Clone, Eq, PartialEq)]
323pub struct FieldPat {
324 /// The identifier for the field
325 pub ident: Ident,
326 /// The pattern the field is destructured to
327 pub pat: Box<Pat>,
328 pub is_shorthand: bool,
329}
330
331#[derive(Debug, Copy, Clone, Eq, PartialEq)]
332pub enum BindingMode {
333 ByRef(Mutability),
334 ByValue(Mutability),
335}
336
David Tolnayf4bbbd92016-09-23 14:41:55 -0700337#[cfg(feature = "printing")]
338mod printing {
339 use super::*;
340 use quote::{Tokens, ToTokens};
341
342 impl ToTokens for Expr {
343 fn to_tokens(&self, tokens: &mut Tokens) {
344 match *self {
345 Expr::Lit(ref lit) => lit.to_tokens(tokens),
346 _ => unimplemented!(),
347 }
348 }
349 }
350}