]> git.proxmox.com Git - rustc.git/blame - src/librustc_ast/ast.rs
New upstream version 1.43.0+dfsg1
[rustc.git] / src / librustc_ast / ast.rs
CommitLineData
e74abb32
XL
1//! The Rust abstract syntax tree module.
2//!
3//! This module contains common structures forming the language AST.
4//! Two main entities in the module are [`Item`] (which represents an AST element with
5//! additional metadata), and [`ItemKind`] (which represents a concrete type and contains
6//! information specific to the type of the item).
7//!
8//! Other module items that worth mentioning:
9//! - [`Ty`] and [`TyKind`]: A parsed Rust type.
10//! - [`Expr`] and [`ExprKind`]: A parsed Rust expression.
11//! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions.
12//! - [`Stmt`] and [`StmtKind`]: An executable action that does not return a value.
13//! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
14//! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
15//! - [`EnumDef`] and [`Variant`]: Enum declaration.
16//! - [`Lit`] and [`LitKind`]: Literal expressions.
17//! - [`MacroDef`], [`MacStmtStyle`], [`Mac`], [`MacDelimeter`]: Macro definition and invocation.
18//! - [`Attribute`]: Metadata associated with item.
19//! - [`UnOp`], [`UnOpKind`], [`BinOp`], [`BinOpKind`]: Unary and binary operators.
223e47cc 20
dfeec247 21pub use crate::util::parser::ExprPrecedence;
9fa01778
XL
22pub use GenericArgs::*;
23pub use UnsafeSource::*;
9fa01778 24
dfeec247 25pub use rustc_span::symbol::{Ident, Symbol as Name};
e74abb32 26
9fa01778 27use crate::ptr::P;
60c5eb7d 28use crate::token::{self, DelimToken};
dfeec247 29use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
1a4d82fc 30
60c5eb7d 31use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
0531ce1d 32use rustc_data_structures::sync::Lrc;
e74abb32
XL
33use rustc_data_structures::thin_vec::ThinVec;
34use rustc_index::vec::Idx;
60c5eb7d 35use rustc_macros::HashStable_Generic;
dfeec247 36use rustc_serialize::{self, Decoder, Encoder};
74b04a01 37use rustc_span::source_map::{respan, Spanned};
dfeec247
XL
38use rustc_span::symbol::{kw, sym, Symbol};
39use rustc_span::{Span, DUMMY_SP};
e74abb32 40
74b04a01 41use std::convert::TryFrom;
e74abb32 42use std::fmt;
dfeec247 43use std::iter;
94b46f34 44
416331ca
XL
45#[cfg(test)]
46mod tests;
47
e74abb32
XL
48/// A "Label" is an identifier of some point in sources,
49/// e.g. in the following code:
50///
51/// ```rust
52/// 'outer: loop {
53/// break 'outer;
54/// }
55/// ```
56///
57/// `'outer` is a label.
60c5eb7d 58#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable_Generic)]
2c00a5a8
XL
59pub struct Label {
60 pub ident: Ident,
2c00a5a8
XL
61}
62
63impl fmt::Debug for Label {
9fa01778 64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2c00a5a8
XL
65 write!(f, "label({:?})", self.ident)
66 }
67}
68
e74abb32
XL
69/// A "Lifetime" is an annotation of the scope in which variable
70/// can be used, e.g. `'a` in `&'a i32`.
8faf50e0 71#[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
223e47cc 72pub struct Lifetime {
1a4d82fc 73 pub id: NodeId,
7cac9316 74 pub ident: Ident,
1a4d82fc
JJ
75}
76
62682a34 77impl fmt::Debug for Lifetime {
9fa01778 78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
dfeec247 79 write!(f, "lifetime({}: {})", self.id, self)
62682a34
SL
80 }
81}
82
416331ca
XL
83impl fmt::Display for Lifetime {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60c5eb7d 85 write!(f, "{}", self.ident.name)
416331ca
XL
86 }
87}
88
3157f602
XL
89/// A "Path" is essentially Rust's notion of a name.
90///
91/// It's represented as a sequence of identifiers,
1a4d82fc 92/// along with a bunch of supporting information.
3157f602 93///
0731742a 94/// E.g., `std::cmp::PartialEq`.
e74abb32 95#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
970d7e83 96pub struct Path {
1a4d82fc 97 pub span: Span,
1a4d82fc 98 /// The segments in the path: the things separated by `::`.
dc9dc135 99 /// Global paths begin with `kw::PathRoot`.
1a4d82fc
JJ
100 pub segments: Vec<PathSegment>,
101}
102
48663c56
XL
103impl PartialEq<Symbol> for Path {
104 fn eq(&self, symbol: &Symbol) -> bool {
dfeec247 105 self.segments.len() == 1 && { self.segments[0].ident.name == *symbol }
cc61c64b
XL
106 }
107}
108
60c5eb7d
XL
109impl<CTX> HashStable<CTX> for Path {
110 fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
111 self.segments.len().hash_stable(hcx, hasher);
112 for segment in &self.segments {
113 segment.ident.name.hash_stable(hcx, hasher);
114 }
115 }
116}
117
54a0048b 118impl Path {
0731742a
XL
119 // Convert a span and an identifier to the corresponding
120 // one-segment path.
83c7162d 121 pub fn from_ident(ident: Ident) -> Path {
dfeec247 122 Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span }
54a0048b 123 }
32a655c1 124
32a655c1 125 pub fn is_global(&self) -> bool {
dc9dc135 126 !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
32a655c1 127 }
54a0048b
SL
128}
129
3157f602
XL
130/// A segment of a path: an identifier, an optional lifetime, and a set of types.
131///
0731742a 132/// E.g., `std`, `String` or `Box<T>`.
8faf50e0 133#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
134pub struct PathSegment {
135 /// The identifier portion of this path segment.
83c7162d 136 pub ident: Ident,
1a4d82fc 137
13cf67c4
XL
138 pub id: NodeId,
139
1a4d82fc 140 /// Type/lifetime parameters attached to this path. They come in
3b2f2976
XL
141 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
142 /// `None` means that no parameter list is supplied (`Path`),
143 /// `Some` means that parameter list is supplied (`Path<X, Y>`)
144 /// but it can be empty (`Path<>`).
145 /// `P` is used as a size optimization for the common case with no parameters.
8faf50e0 146 pub args: Option<P<GenericArgs>>,
32a655c1
SL
147}
148
32a655c1 149impl PathSegment {
83c7162d 150 pub fn from_ident(ident: Ident) -> Self {
13cf67c4 151 PathSegment { ident, id: DUMMY_NODE_ID, args: None }
8bb4bdeb 152 }
0731742a 153 pub fn path_root(span: Span) -> Self {
dc9dc135 154 PathSegment::from_ident(Ident::new(kw::PathRoot, span))
32a655c1 155 }
1a4d82fc
JJ
156}
157
9fa01778 158/// The arguments of a path segment.
3157f602 159///
0731742a 160/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
8faf50e0
XL
161#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
162pub enum GenericArgs {
9fa01778 163 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
8faf50e0 164 AngleBracketed(AngleBracketedArgs),
9fa01778
XL
165 /// The `(A, B)` and `C` in `Foo(A, B) -> C`.
166 Parenthesized(ParenthesizedArgs),
1a4d82fc
JJ
167}
168
8faf50e0 169impl GenericArgs {
9fa01778
XL
170 pub fn is_parenthesized(&self) -> bool {
171 match *self {
172 Parenthesized(..) => true,
173 _ => false,
174 }
175 }
176
177 pub fn is_angle_bracketed(&self) -> bool {
178 match *self {
179 AngleBracketed(..) => true,
180 _ => false,
181 }
182 }
183
3b2f2976
XL
184 pub fn span(&self) -> Span {
185 match *self {
186 AngleBracketed(ref data) => data.span,
187 Parenthesized(ref data) => data.span,
188 }
189 }
190}
191
e74abb32 192/// Concrete argument in the sequence of generic args.
8faf50e0
XL
193#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
194pub enum GenericArg {
e74abb32 195 /// `'a` in `Foo<'a>`
8faf50e0 196 Lifetime(Lifetime),
e74abb32 197 /// `Bar` in `Foo<Bar>`
8faf50e0 198 Type(P<Ty>),
e74abb32 199 /// `1` in `Foo<1>`
9fa01778 200 Const(AnonConst),
8faf50e0
XL
201}
202
9fa01778
XL
203impl GenericArg {
204 pub fn span(&self) -> Span {
205 match self {
206 GenericArg::Lifetime(lt) => lt.ident.span,
207 GenericArg::Type(ty) => ty.span,
208 GenericArg::Const(ct) => ct.value.span,
209 }
210 }
211}
212
213/// A path like `Foo<'a, T>`.
8faf50e0
XL
214#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
215pub struct AngleBracketedArgs {
9fa01778 216 /// The overall span.
3b2f2976 217 pub span: Span,
8faf50e0
XL
218 /// The arguments for this path segment.
219 pub args: Vec<GenericArg>,
dc9dc135
XL
220 /// Constraints on associated types, if any.
221 /// E.g., `Foo<A = Bar, B: Baz>`.
222 pub constraints: Vec<AssocTyConstraint>,
223e47cc
LB
223}
224
8faf50e0
XL
225impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
226 fn into(self) -> Option<P<GenericArgs>> {
227 Some(P(GenericArgs::AngleBracketed(self)))
3b2f2976
XL
228 }
229}
230
9fa01778 231impl Into<Option<P<GenericArgs>>> for ParenthesizedArgs {
8faf50e0
XL
232 fn into(self) -> Option<P<GenericArgs>> {
233 Some(P(GenericArgs::Parenthesized(self)))
1a4d82fc
JJ
234 }
235}
236
9fa01778 237/// A path like `Foo(A, B) -> C`.
8faf50e0 238#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
9fa01778 239pub struct ParenthesizedArgs {
85aaf69f
SL
240 /// Overall span
241 pub span: Span,
242
dc9dc135 243 /// `(A, B)`
1a4d82fc
JJ
244 pub inputs: Vec<P<Ty>>,
245
246 /// `C`
74b04a01 247 pub output: FnRetTy,
1a4d82fc
JJ
248}
249
9fa01778
XL
250impl ParenthesizedArgs {
251 pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
252 AngleBracketedArgs {
253 span: self.span,
254 args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(),
dc9dc135 255 constraints: vec![],
9fa01778
XL
256 }
257 }
258}
259
74b04a01 260pub use crate::node_id::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
1a4d82fc 261
dfeec247
XL
262/// A modifier on a bound, e.g., `?Sized` or `?const Trait`.
263///
264/// Negative bounds should also be handled here.
8faf50e0
XL
265#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
266pub enum TraitBoundModifier {
dfeec247 267 /// No modifiers
8faf50e0 268 None,
dfeec247
XL
269
270 /// `?Trait`
8faf50e0 271 Maybe,
dfeec247
XL
272
273 /// `?const Trait`
274 MaybeConst,
275
276 /// `?const ?Trait`
277 //
278 // This parses but will be rejected during AST validation.
279 MaybeConstMaybe,
8faf50e0
XL
280}
281
1a4d82fc 282/// The AST represents all type param bounds as types.
a1dfa0c6
XL
283/// `typeck::collect::compute_bounds` matches these against
284/// the "special" built-in traits (see `middle::lang_items`) and
285/// detects `Copy`, `Send` and `Sync`.
8faf50e0
XL
286#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
287pub enum GenericBound {
288 Trait(PolyTraitRef, TraitBoundModifier),
0bf4aa26 289 Outlives(Lifetime),
223e47cc
LB
290}
291
8faf50e0 292impl GenericBound {
0531ce1d
XL
293 pub fn span(&self) -> Span {
294 match self {
8faf50e0
XL
295 &GenericBound::Trait(ref t, ..) => t.span,
296 &GenericBound::Outlives(ref l) => l.ident.span,
0531ce1d
XL
297 }
298 }
299}
300
8faf50e0 301pub type GenericBounds = Vec<GenericBound>;
1a4d82fc 302
9fa01778
XL
303/// Specifies the enforced ordering for generic parameters. In the future,
304/// if we wanted to relax this order, we could override `PartialEq` and
305/// `PartialOrd`, to allow the kinds to be unordered.
306#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
307pub enum ParamKindOrd {
308 Lifetime,
309 Type,
310 Const,
311}
312
313impl fmt::Display for ParamKindOrd {
314 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
315 match self {
316 ParamKindOrd::Lifetime => "lifetime".fmt(f),
317 ParamKindOrd::Type => "type".fmt(f),
318 ParamKindOrd::Const => "const".fmt(f),
319 }
320 }
321}
322
8faf50e0
XL
323#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
324pub enum GenericParamKind {
0731742a 325 /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
8faf50e0 326 Lifetime,
dfeec247
XL
327 Type {
328 default: Option<P<Ty>>,
329 },
330 Const {
331 ty: P<Ty>,
332 },
ff7c6d11
XL
333}
334
8faf50e0
XL
335#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
336pub struct GenericParam {
337 pub id: NodeId,
338 pub ident: Ident,
dfeec247 339 pub attrs: AttrVec,
8faf50e0 340 pub bounds: GenericBounds,
e1599b0c 341 pub is_placeholder: bool,
8faf50e0 342 pub kind: GenericParamKind,
ff7c6d11
XL
343}
344
345/// Represents lifetime, type and const parameters attached to a declaration of
346/// a function, enum, trait, etc.
8faf50e0 347#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
223e47cc 348pub struct Generics {
ff7c6d11 349 pub params: Vec<GenericParam>,
1a4d82fc 350 pub where_clause: WhereClause,
9e0c209e 351 pub span: Span,
223e47cc
LB
352}
353
9cc50fc6 354impl Default for Generics {
9e0c209e 355 /// Creates an instance of `Generics`.
0bf4aa26 356 fn default() -> Generics {
9cc50fc6 357 Generics {
ff7c6d11 358 params: Vec::new(),
dfeec247 359 where_clause: WhereClause { predicates: Vec::new(), span: DUMMY_SP },
9e0c209e 360 span: DUMMY_SP,
9cc50fc6
SL
361 }
362 }
363}
364
9fa01778 365/// A where-clause in a definition.
8faf50e0 366#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 367pub struct WhereClause {
1a4d82fc 368 pub predicates: Vec<WherePredicate>,
3b2f2976 369 pub span: Span,
223e47cc
LB
370}
371
9fa01778 372/// A single predicate in a where-clause.
8faf50e0 373#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 374pub enum WherePredicate {
0731742a 375 /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
1a4d82fc 376 BoundPredicate(WhereBoundPredicate),
0731742a 377 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
1a4d82fc 378 RegionPredicate(WhereRegionPredicate),
0731742a 379 /// An equality predicate (unsupported).
e9174d1e 380 EqPredicate(WhereEqPredicate),
223e47cc
LB
381}
382
0531ce1d
XL
383impl WherePredicate {
384 pub fn span(&self) -> Span {
385 match self {
386 &WherePredicate::BoundPredicate(ref p) => p.span,
387 &WherePredicate::RegionPredicate(ref p) => p.span,
388 &WherePredicate::EqPredicate(ref p) => p.span,
389 }
390 }
391}
392
3157f602
XL
393/// A type bound.
394///
0731742a 395/// E.g., `for<'c> Foo: Send + Clone + 'c`.
8faf50e0 396#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
397pub struct WhereBoundPredicate {
398 pub span: Span,
e1599b0c 399 /// Any generics from a `for` binding.
ff7c6d11 400 pub bound_generic_params: Vec<GenericParam>,
e1599b0c 401 /// The type being bounded.
1a4d82fc 402 pub bounded_ty: P<Ty>,
e1599b0c 403 /// Trait and lifetime bounds (`Clone + Send + 'static`).
8faf50e0 404 pub bounds: GenericBounds,
223e47cc
LB
405}
406
3157f602
XL
407/// A lifetime predicate.
408///
0731742a 409/// E.g., `'a: 'b + 'c`.
8faf50e0 410#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
411pub struct WhereRegionPredicate {
412 pub span: Span,
413 pub lifetime: Lifetime,
8faf50e0 414 pub bounds: GenericBounds,
1a4d82fc 415}
223e47cc 416
3157f602
XL
417/// An equality predicate (unsupported).
418///
0731742a 419/// E.g., `T = int`.
8faf50e0 420#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
421pub struct WhereEqPredicate {
422 pub id: NodeId,
423 pub span: Span,
32a655c1
SL
424 pub lhs_ty: P<Ty>,
425 pub rhs_ty: P<Ty>,
1a4d82fc
JJ
426}
427
8faf50e0 428#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
429pub struct Crate {
430 pub module: Mod,
431 pub attrs: Vec<Attribute>,
1a4d82fc 432 pub span: Span,
74b04a01
XL
433 /// The order of items in the HIR is unrelated to the order of
434 /// items in the AST. However, we generate proc macro harnesses
435 /// based on the AST order, and later refer to these harnesses
436 /// from the HIR. This field keeps track of the order in which
437 /// we generated proc macros harnesses, so that we can map
438 /// HIR proc macros items back to their harness items.
439 pub proc_macros: Vec<NodeId>,
970d7e83 440}
223e47cc 441
9e0c209e
SL
442/// Possible values inside of compile-time attribute lists.
443///
0731742a 444/// E.g., the '..' in `#[name(..)]`.
60c5eb7d 445#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
532ac7d7 446pub enum NestedMetaItem {
9e0c209e 447 /// A full MetaItem, for recursive meta items.
476ff2be 448 MetaItem(MetaItem),
9e0c209e
SL
449 /// A literal.
450 ///
0731742a 451 /// E.g., `"foo"`, `64`, `true`.
9e0c209e
SL
452 Literal(Lit),
453}
454
3157f602
XL
455/// A spanned compile-time attribute item.
456///
0731742a 457/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
60c5eb7d 458#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
476ff2be 459pub struct MetaItem {
532ac7d7 460 pub path: Path,
e74abb32 461 pub kind: MetaItemKind,
476ff2be
SL
462 pub span: Span,
463}
1a4d82fc 464
3157f602
XL
465/// A compile-time attribute item.
466///
0731742a 467/// E.g., `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`.
60c5eb7d 468#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
7453a54e 469pub enum MetaItemKind {
3157f602
XL
470 /// Word meta item.
471 ///
0731742a 472 /// E.g., `test` as in `#[test]`.
476ff2be 473 Word,
3157f602
XL
474 /// List meta item.
475 ///
0731742a 476 /// E.g., `derive(..)` as in `#[derive(..)]`.
476ff2be 477 List(Vec<NestedMetaItem>),
3157f602
XL
478 /// Name value meta item.
479 ///
0731742a 480 /// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
0bf4aa26 481 NameValue(Lit),
223e47cc
LB
482}
483
e1599b0c 484/// A block (`{ .. }`).
3157f602 485///
0731742a 486/// E.g., `{ .. }` as in `fn foo() { .. }`.
8faf50e0 487#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 488pub struct Block {
e1599b0c 489 /// The statements in the block.
7453a54e 490 pub stmts: Vec<Stmt>,
1a4d82fc 491 pub id: NodeId,
e1599b0c 492 /// Distinguishes between `unsafe { ... }` and `{ ... }`.
1a4d82fc
JJ
493 pub rules: BlockCheckMode,
494 pub span: Span,
495}
496
e74abb32 497#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
498pub struct Pat {
499 pub id: NodeId,
e74abb32 500 pub kind: PatKind,
1a4d82fc
JJ
501 pub span: Span,
502}
503
a7813a04 504impl Pat {
416331ca
XL
505 /// Attempt reparsing the pattern as a type.
506 /// This is intended for use by diagnostics.
60c5eb7d 507 pub fn to_ty(&self) -> Option<P<Ty>> {
e74abb32 508 let kind = match &self.kind {
416331ca 509 // In a type expression `_` is an inference variable.
ff7c6d11 510 PatKind::Wild => TyKind::Infer,
416331ca 511 // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
dfeec247 512 PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => {
0bf4aa26
XL
513 TyKind::Path(None, Path::from_ident(*ident))
514 }
ff7c6d11
XL
515 PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
516 PatKind::Mac(mac) => TyKind::Mac(mac.clone()),
416331ca 517 // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
dfeec247
XL
518 PatKind::Ref(pat, mutbl) => {
519 pat.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?
520 }
416331ca
XL
521 // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
522 // when `P` can be reparsed as a type `T`.
523 PatKind::Slice(pats) if pats.len() == 1 => pats[0].to_ty().map(TyKind::Slice)?,
524 // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
525 // assuming `T0` to `Tn` are all syntactically valid as types.
526 PatKind::Tuple(pats) => {
b7449926
XL
527 let mut tys = Vec::with_capacity(pats.len());
528 // FIXME(#48994) - could just be collected into an Option<Vec>
529 for pat in pats {
530 tys.push(pat.to_ty()?);
531 }
ff7c6d11
XL
532 TyKind::Tup(tys)
533 }
534 _ => return None,
535 };
536
dfeec247 537 Some(P(Ty { kind, id: self.id, span: self.span }))
ff7c6d11
XL
538 }
539
e1599b0c
XL
540 /// Walk top-down and call `it` in each place where a pattern occurs
541 /// starting with the root pattern `walk` is called on. If `it` returns
542 /// false then we will descend no further but siblings will be processed.
543 pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
a7813a04 544 if !it(self) {
e1599b0c 545 return;
a7813a04
XL
546 }
547
e74abb32
XL
548 match &self.kind {
549 // Walk into the pattern associated with `Ident` (if any).
416331ca 550 PatKind::Ident(_, _, Some(p)) => p.walk(it),
e74abb32
XL
551
552 // Walk into each field of struct.
e1599b0c 553 PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
e74abb32
XL
554
555 // Sequence of patterns.
dfeec247
XL
556 PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) | PatKind::Or(s) => {
557 s.iter().for_each(|p| p.walk(it))
558 }
e74abb32
XL
559
560 // Trivial wrappers over inner patterns.
dfeec247 561 PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
e74abb32
XL
562
563 // These patterns do not contain subpatterns, skip.
0bf4aa26 564 PatKind::Wild
416331ca 565 | PatKind::Rest
0bf4aa26
XL
566 | PatKind::Lit(_)
567 | PatKind::Range(..)
568 | PatKind::Ident(..)
569 | PatKind::Path(..)
dfeec247 570 | PatKind::Mac(_) => {}
a7813a04
XL
571 }
572 }
416331ca
XL
573
574 /// Is this a `..` pattern?
575 pub fn is_rest(&self) -> bool {
e74abb32 576 match self.kind {
416331ca
XL
577 PatKind::Rest => true,
578 _ => false,
579 }
580 }
a7813a04
XL
581}
582
c34b1796
AL
583/// A single field in a struct pattern
584///
585/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
586/// are treated the same as` x: x, y: ref y, z: ref mut z`,
587/// except is_shorthand is true
8faf50e0 588#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 589pub struct FieldPat {
c34b1796 590 /// The identifier for the field
1a4d82fc 591 pub ident: Ident,
c34b1796 592 /// The pattern the field is destructured to
1a4d82fc
JJ
593 pub pat: P<Pat>,
594 pub is_shorthand: bool,
dfeec247 595 pub attrs: AttrVec,
e1599b0c
XL
596 pub id: NodeId,
597 pub span: Span,
598 pub is_placeholder: bool,
1a4d82fc
JJ
599}
600
8faf50e0 601#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
1a4d82fc 602pub enum BindingMode {
9cc50fc6
SL
603 ByRef(Mutability),
604 ByValue(Mutability),
1a4d82fc
JJ
605}
606
8faf50e0 607#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
32a655c1 608pub enum RangeEnd {
ea8adc8c 609 Included(RangeSyntax),
32a655c1
SL
610 Excluded,
611}
612
8faf50e0 613#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
ea8adc8c 614pub enum RangeSyntax {
e74abb32 615 /// `...`
ea8adc8c 616 DotDotDot,
e74abb32 617 /// `..=`
ea8adc8c
XL
618 DotDotEq,
619}
620
8faf50e0 621#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7453a54e 622pub enum PatKind {
0731742a 623 /// Represents a wildcard pattern (`_`).
7453a54e 624 Wild,
1a4d82fc 625
3157f602
XL
626 /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
627 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
628 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
629 /// during name resolution.
83c7162d 630 Ident(BindingMode, Ident, Option<P<Pat>>),
1a4d82fc 631
0731742a 632 /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
7453a54e 633 /// The `bool` is `true` in the presence of a `..`.
e1599b0c 634 Struct(Path, Vec<FieldPat>, /* recovered */ bool),
7453a54e 635
0731742a 636 /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
416331ca 637 TupleStruct(Path, Vec<P<Pat>>),
1a4d82fc 638
e1599b0c
XL
639 /// An or-pattern `A | B | C`.
640 /// Invariant: `pats.len() >= 2`.
641 Or(Vec<P<Pat>>),
642
3157f602 643 /// A possibly qualified path pattern.
3b2f2976
XL
644 /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
645 /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
3157f602
XL
646 /// only legally refer to associated constants.
647 Path(Option<QSelf>, Path),
d9579d0f 648
0731742a 649 /// A tuple pattern (`(a, b)`).
416331ca 650 Tuple(Vec<P<Pat>>),
9fa01778 651
0731742a 652 /// A `box` pattern.
7453a54e 653 Box(P<Pat>),
9fa01778 654
0731742a 655 /// A reference pattern (e.g., `&mut (a, b)`).
7453a54e 656 Ref(P<Pat>, Mutability),
9fa01778 657
0731742a 658 /// A literal.
7453a54e 659 Lit(P<Expr>),
9fa01778 660
0731742a 661 /// A range pattern (e.g., `1...2`, `1..=2` or `1..2`).
dfeec247 662 Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>),
9fa01778 663
416331ca
XL
664 /// A slice pattern `[a, b, c]`.
665 Slice(Vec<P<Pat>>),
666
667 /// A rest pattern `..`.
668 ///
669 /// Syntactically it is valid anywhere.
670 ///
671 /// Semantically however, it only has meaning immediately inside:
672 /// - a slice pattern: `[a, .., b]`,
673 /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`,
674 /// - a tuple pattern: `(a, .., b)`,
675 /// - a tuple struct/variant pattern: `$path(a, .., b)`.
676 ///
677 /// In all of these cases, an additional restriction applies,
678 /// only one rest pattern may occur in the pattern sequences.
679 Rest,
9fa01778 680
0731742a 681 /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
0531ce1d 682 Paren(P<Pat>),
9fa01778 683
0731742a 684 /// A macro pattern; pre-expansion.
7453a54e 685 Mac(Mac),
1a4d82fc
JJ
686}
687
dfeec247
XL
688#[derive(
689 Clone,
690 PartialEq,
691 Eq,
692 PartialOrd,
693 Ord,
694 Hash,
695 RustcEncodable,
696 RustcDecodable,
697 Debug,
698 Copy,
699 HashStable_Generic
700)]
1a4d82fc 701pub enum Mutability {
dfeec247
XL
702 Mut,
703 Not,
1a4d82fc
JJ
704}
705
60c5eb7d
XL
706impl Mutability {
707 /// Returns `MutMutable` only if both `self` and `other` are mutable.
708 pub fn and(self, other: Self) -> Self {
709 match self {
dfeec247
XL
710 Mutability::Mut => other,
711 Mutability::Not => Mutability::Not,
60c5eb7d
XL
712 }
713 }
714
715 pub fn invert(self) -> Self {
716 match self {
dfeec247
XL
717 Mutability::Mut => Mutability::Not,
718 Mutability::Not => Mutability::Mut,
60c5eb7d
XL
719 }
720 }
721
722 pub fn prefix_str(&self) -> &'static str {
723 match self {
dfeec247
XL
724 Mutability::Mut => "mut ",
725 Mutability::Not => "",
60c5eb7d
XL
726 }
727 }
728}
729
730/// The kind of borrow in an `AddrOf` expression,
731/// e.g., `&place` or `&raw const place`.
732#[derive(Clone, Copy, PartialEq, Eq, Debug)]
733#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)]
734pub enum BorrowKind {
60c5eb7d
XL
735 /// A normal borrow, `&$expr` or `&mut $expr`.
736 /// The resulting type is either `&'a T` or `&'a mut T`
737 /// where `T = typeof($expr)` and `'a` is some lifetime.
dfeec247
XL
738 Ref,
739 /// A raw borrow, `&raw const $expr` or `&raw mut $expr`.
740 /// The resulting type is either `*const T` or `*mut T`
741 /// where `T = typeof($expr)`.
60c5eb7d
XL
742 Raw,
743}
744
8faf50e0 745#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
7453a54e 746pub enum BinOpKind {
c34b1796 747 /// The `+` operator (addition)
7453a54e 748 Add,
c34b1796 749 /// The `-` operator (subtraction)
7453a54e 750 Sub,
c34b1796 751 /// The `*` operator (multiplication)
7453a54e 752 Mul,
c34b1796 753 /// The `/` operator (division)
7453a54e 754 Div,
c34b1796 755 /// The `%` operator (modulus)
7453a54e 756 Rem,
c34b1796 757 /// The `&&` operator (logical and)
7453a54e 758 And,
c34b1796 759 /// The `||` operator (logical or)
7453a54e 760 Or,
c34b1796 761 /// The `^` operator (bitwise xor)
7453a54e 762 BitXor,
c34b1796 763 /// The `&` operator (bitwise and)
7453a54e 764 BitAnd,
c34b1796 765 /// The `|` operator (bitwise or)
7453a54e 766 BitOr,
c34b1796 767 /// The `<<` operator (shift left)
7453a54e 768 Shl,
c34b1796 769 /// The `>>` operator (shift right)
7453a54e 770 Shr,
c34b1796 771 /// The `==` operator (equality)
7453a54e 772 Eq,
c34b1796 773 /// The `<` operator (less than)
7453a54e 774 Lt,
c34b1796 775 /// The `<=` operator (less than or equal to)
7453a54e 776 Le,
c34b1796 777 /// The `!=` operator (not equal to)
7453a54e 778 Ne,
c34b1796 779 /// The `>=` operator (greater than or equal to)
7453a54e 780 Ge,
c34b1796 781 /// The `>` operator (greater than)
7453a54e 782 Gt,
1a4d82fc
JJ
783}
784
7453a54e 785impl BinOpKind {
9cc50fc6 786 pub fn to_string(&self) -> &'static str {
9fa01778 787 use BinOpKind::*;
9cc50fc6 788 match *self {
7453a54e
SL
789 Add => "+",
790 Sub => "-",
791 Mul => "*",
792 Div => "/",
793 Rem => "%",
794 And => "&&",
795 Or => "||",
796 BitXor => "^",
797 BitAnd => "&",
798 BitOr => "|",
799 Shl => "<<",
800 Shr => ">>",
801 Eq => "==",
802 Lt => "<",
803 Le => "<=",
804 Ne => "!=",
805 Ge => ">=",
806 Gt => ">",
9cc50fc6
SL
807 }
808 }
809 pub fn lazy(&self) -> bool {
810 match *self {
7453a54e 811 BinOpKind::And | BinOpKind::Or => true,
0bf4aa26 812 _ => false,
9cc50fc6
SL
813 }
814 }
815
816 pub fn is_shift(&self) -> bool {
817 match *self {
7453a54e 818 BinOpKind::Shl | BinOpKind::Shr => true,
0bf4aa26 819 _ => false,
9cc50fc6
SL
820 }
821 }
2c00a5a8 822
9cc50fc6 823 pub fn is_comparison(&self) -> bool {
9fa01778 824 use BinOpKind::*;
e74abb32
XL
825 // Note for developers: please keep this as is;
826 // we want compilation to fail if another variant is added.
9cc50fc6 827 match *self {
0bf4aa26
XL
828 Eq | Lt | Le | Ne | Gt | Ge => true,
829 And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
9cc50fc6
SL
830 }
831 }
2c00a5a8 832
9cc50fc6
SL
833 /// Returns `true` if the binary operator takes its arguments by value
834 pub fn is_by_value(&self) -> bool {
7453a54e 835 !self.is_comparison()
9cc50fc6
SL
836 }
837}
838
7453a54e 839pub type BinOp = Spanned<BinOpKind>;
85aaf69f 840
e74abb32
XL
841/// Unary operator.
842///
843/// Note that `&data` is not an operator, it's an `AddrOf` expression.
8faf50e0 844#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
1a4d82fc 845pub enum UnOp {
c34b1796 846 /// The `*` operator for dereferencing
7453a54e 847 Deref,
c34b1796 848 /// The `!` operator for logical inversion
7453a54e 849 Not,
c34b1796 850 /// The `-` operator for negation
7453a54e 851 Neg,
1a4d82fc
JJ
852}
853
9cc50fc6
SL
854impl UnOp {
855 /// Returns `true` if the unary operator takes its argument by value
856 pub fn is_by_value(u: UnOp) -> bool {
857 match u {
7453a54e 858 UnOp::Neg | UnOp::Not => true,
9cc50fc6
SL
859 _ => false,
860 }
861 }
862
863 pub fn to_string(op: UnOp) -> &'static str {
864 match op {
7453a54e
SL
865 UnOp::Deref => "*",
866 UnOp::Not => "!",
867 UnOp::Neg => "-",
9cc50fc6
SL
868 }
869 }
870}
871
c34b1796 872/// A statement
e74abb32 873#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
3157f602
XL
874pub struct Stmt {
875 pub id: NodeId,
e74abb32 876 pub kind: StmtKind,
3157f602
XL
877 pub span: Span,
878}
1a4d82fc 879
5bcae85e
SL
880impl Stmt {
881 pub fn add_trailing_semicolon(mut self) -> Self {
e74abb32 882 self.kind = match self.kind {
5bcae85e 883 StmtKind::Expr(expr) => StmtKind::Semi(expr),
0bf4aa26
XL
884 StmtKind::Mac(mac) => {
885 StmtKind::Mac(mac.map(|(mac, _style, attrs)| (mac, MacStmtStyle::Semicolon, attrs)))
886 }
e74abb32 887 kind => kind,
5bcae85e
SL
888 };
889 self
890 }
3b2f2976
XL
891
892 pub fn is_item(&self) -> bool {
e74abb32 893 match self.kind {
0531ce1d
XL
894 StmtKind::Item(_) => true,
895 _ => false,
896 }
897 }
898
899 pub fn is_expr(&self) -> bool {
e74abb32 900 match self.kind {
0531ce1d 901 StmtKind::Expr(_) => true,
3b2f2976
XL
902 _ => false,
903 }
904 }
5bcae85e
SL
905}
906
e74abb32 907#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7453a54e 908pub enum StmtKind {
3157f602
XL
909 /// A local (let) binding.
910 Local(P<Local>),
3157f602
XL
911 /// An item definition.
912 Item(P<Item>),
3157f602
XL
913 /// Expr without trailing semi-colon.
914 Expr(P<Expr>),
ea8adc8c 915 /// Expr with a trailing semi-colon.
3157f602 916 Semi(P<Expr>),
74b04a01
XL
917 /// Just a trailing semi-colon.
918 Empty,
ea8adc8c 919 /// Macro.
dfeec247 920 Mac(P<(Mac, MacStmtStyle, AttrVec)>),
92a42be0
SL
921}
922
8faf50e0 923#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 924pub enum MacStmtStyle {
0731742a
XL
925 /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
926 /// `foo!(...);`, `foo![...];`).
7453a54e 927 Semicolon,
0731742a 928 /// The macro statement had braces (e.g., `foo! { ... }`).
7453a54e 929 Braces,
0731742a
XL
930 /// The macro statement had parentheses or brackets and no semicolon (e.g.,
931 /// `foo!(...)`). All of these will end up being converted into macro
1a4d82fc 932 /// expressions.
7453a54e 933 NoBraces,
1a4d82fc
JJ
934}
935
0731742a 936/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
8faf50e0 937#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 938pub struct Local {
e1599b0c 939 pub id: NodeId,
1a4d82fc
JJ
940 pub pat: P<Pat>,
941 pub ty: Option<P<Ty>>,
0731742a 942 /// Initializer expression to set the value, if any.
1a4d82fc 943 pub init: Option<P<Expr>>,
1a4d82fc 944 pub span: Span,
dfeec247 945 pub attrs: AttrVec,
1a4d82fc
JJ
946}
947
3157f602
XL
948/// An arm of a 'match'.
949///
0731742a 950/// E.g., `0..=10 => { println!("match!") }` as in
3157f602 951///
041b39d2
XL
952/// ```
953/// match 123 {
8faf50e0 954/// 0..=10 => { println!("match!") },
041b39d2 955/// _ => { println!("no match!") },
3157f602
XL
956/// }
957/// ```
8faf50e0 958#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
959pub struct Arm {
960 pub attrs: Vec<Attribute>,
e74abb32 961 /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`
e1599b0c 962 pub pat: P<Pat>,
e74abb32 963 /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`
dc9dc135 964 pub guard: Option<P<Expr>>,
e74abb32 965 /// Match arm body.
1a4d82fc 966 pub body: P<Expr>,
dc9dc135 967 pub span: Span,
e1599b0c
XL
968 pub id: NodeId,
969 pub is_placeholder: bool,
b7449926
XL
970}
971
e74abb32 972/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
8faf50e0 973#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 974pub struct Field {
dfeec247 975 pub attrs: AttrVec,
60c5eb7d
XL
976 pub id: NodeId,
977 pub span: Span,
83c7162d 978 pub ident: Ident,
1a4d82fc 979 pub expr: P<Expr>,
c30ab7b3 980 pub is_shorthand: bool,
e1599b0c 981 pub is_placeholder: bool,
1a4d82fc
JJ
982}
983
0731742a 984#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
1a4d82fc 985pub enum BlockCheckMode {
7453a54e
SL
986 Default,
987 Unsafe(UnsafeSource),
1a4d82fc
JJ
988}
989
0731742a 990#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
1a4d82fc
JJ
991pub enum UnsafeSource {
992 CompilerGenerated,
993 UserProvided,
994}
995
94b46f34
XL
996/// A constant (expression) that's not an item or associated item,
997/// but needs its own `DefId` for type-checking, const-eval, etc.
0731742a
XL
998/// These are usually found nested inside types (e.g., array lengths)
999/// or expressions (e.g., repeat counts), and also used to define
94b46f34 1000/// explicit discriminant values for enum variants.
8faf50e0 1001#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
94b46f34
XL
1002pub struct AnonConst {
1003 pub id: NodeId,
1004 pub value: P<Expr>,
1005}
1006
e1599b0c 1007/// An expression.
e74abb32 1008#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
1009pub struct Expr {
1010 pub id: NodeId,
e74abb32 1011 pub kind: ExprKind,
1a4d82fc 1012 pub span: Span,
dfeec247 1013 pub attrs: AttrVec,
1a4d82fc
JJ
1014}
1015
a1dfa0c6
XL
1016// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
1017#[cfg(target_arch = "x86_64")]
60c5eb7d 1018rustc_data_structures::static_assert_size!(Expr, 96);
a1dfa0c6 1019
3b2f2976 1020impl Expr {
e1599b0c
XL
1021 /// Returns `true` if this expression would be valid somewhere that expects a value;
1022 /// for example, an `if` condition.
3b2f2976 1023 pub fn returns(&self) -> bool {
e74abb32
XL
1024 if let ExprKind::Block(ref block, _) = self.kind {
1025 match block.stmts.last().map(|last_stmt| &last_stmt.kind) {
e1599b0c 1026 // Implicit return
3b2f2976
XL
1027 Some(&StmtKind::Expr(_)) => true,
1028 Some(&StmtKind::Semi(ref expr)) => {
e74abb32 1029 if let ExprKind::Ret(_) = expr.kind {
e1599b0c 1030 // Last statement is explicit return.
3b2f2976
XL
1031 true
1032 } else {
1033 false
1034 }
1035 }
e1599b0c 1036 // This is a block that doesn't end in either an implicit or explicit return.
3b2f2976
XL
1037 _ => false,
1038 }
1039 } else {
e1599b0c 1040 // This is not a block, it is a value.
3b2f2976
XL
1041 true
1042 }
1043 }
ff7c6d11 1044
60c5eb7d 1045 pub fn to_bound(&self) -> Option<GenericBound> {
e74abb32 1046 match &self.kind {
0bf4aa26
XL
1047 ExprKind::Path(None, path) => Some(GenericBound::Trait(
1048 PolyTraitRef::new(Vec::new(), path.clone(), self.span),
1049 TraitBoundModifier::None,
1050 )),
ff7c6d11
XL
1051 _ => None,
1052 }
1053 }
1054
e74abb32 1055 /// Attempts to reparse as `Ty` (for diagnostic purposes).
60c5eb7d 1056 pub fn to_ty(&self) -> Option<P<Ty>> {
e74abb32
XL
1057 let kind = match &self.kind {
1058 // Trivial conversions.
ff7c6d11
XL
1059 ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1060 ExprKind::Mac(mac) => TyKind::Mac(mac.clone()),
e74abb32 1061
ff7c6d11 1062 ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
e74abb32 1063
dfeec247
XL
1064 ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1065 expr.to_ty().map(|ty| TyKind::Rptr(None, MutTy { ty, mutbl: *mutbl }))?
1066 }
e74abb32 1067
0bf4aa26
XL
1068 ExprKind::Repeat(expr, expr_len) => {
1069 expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1070 }
e74abb32 1071
0bf4aa26 1072 ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?,
e74abb32 1073
ff7c6d11 1074 ExprKind::Tup(exprs) => {
dfeec247 1075 let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<Vec<_>>>()?;
ff7c6d11
XL
1076 TyKind::Tup(tys)
1077 }
e74abb32
XL
1078
1079 // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
1080 // then type of result is trait object.
74b04a01 1081 // Otherwise we don't assume the result type.
0bf4aa26 1082 ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
ff7c6d11
XL
1083 if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1084 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1085 } else {
1086 return None;
1087 }
0bf4aa26 1088 }
e74abb32
XL
1089
1090 // This expression doesn't look like a type syntactically.
ff7c6d11
XL
1091 _ => return None,
1092 };
1093
dfeec247 1094 Some(P(Ty { kind, id: self.id, span: self.span }))
ff7c6d11 1095 }
2c00a5a8
XL
1096
1097 pub fn precedence(&self) -> ExprPrecedence {
e74abb32 1098 match self.kind {
2c00a5a8 1099 ExprKind::Box(_) => ExprPrecedence::Box,
2c00a5a8
XL
1100 ExprKind::Array(_) => ExprPrecedence::Array,
1101 ExprKind::Call(..) => ExprPrecedence::Call,
1102 ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
1103 ExprKind::Tup(_) => ExprPrecedence::Tup,
1104 ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
1105 ExprKind::Unary(..) => ExprPrecedence::Unary,
1106 ExprKind::Lit(_) => ExprPrecedence::Lit,
1107 ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
dc9dc135 1108 ExprKind::Let(..) => ExprPrecedence::Let,
2c00a5a8 1109 ExprKind::If(..) => ExprPrecedence::If,
2c00a5a8 1110 ExprKind::While(..) => ExprPrecedence::While,
2c00a5a8
XL
1111 ExprKind::ForLoop(..) => ExprPrecedence::ForLoop,
1112 ExprKind::Loop(..) => ExprPrecedence::Loop,
1113 ExprKind::Match(..) => ExprPrecedence::Match,
1114 ExprKind::Closure(..) => ExprPrecedence::Closure,
1115 ExprKind::Block(..) => ExprPrecedence::Block,
b7449926 1116 ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
8faf50e0 1117 ExprKind::Async(..) => ExprPrecedence::Async,
48663c56 1118 ExprKind::Await(..) => ExprPrecedence::Await,
2c00a5a8
XL
1119 ExprKind::Assign(..) => ExprPrecedence::Assign,
1120 ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
1121 ExprKind::Field(..) => ExprPrecedence::Field,
2c00a5a8
XL
1122 ExprKind::Index(..) => ExprPrecedence::Index,
1123 ExprKind::Range(..) => ExprPrecedence::Range,
1124 ExprKind::Path(..) => ExprPrecedence::Path,
1125 ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
1126 ExprKind::Break(..) => ExprPrecedence::Break,
1127 ExprKind::Continue(..) => ExprPrecedence::Continue,
1128 ExprKind::Ret(..) => ExprPrecedence::Ret,
1129 ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
1130 ExprKind::Mac(..) => ExprPrecedence::Mac,
1131 ExprKind::Struct(..) => ExprPrecedence::Struct,
1132 ExprKind::Repeat(..) => ExprPrecedence::Repeat,
1133 ExprKind::Paren(..) => ExprPrecedence::Paren,
1134 ExprKind::Try(..) => ExprPrecedence::Try,
1135 ExprKind::Yield(..) => ExprPrecedence::Yield,
0731742a 1136 ExprKind::Err => ExprPrecedence::Err,
2c00a5a8
XL
1137 }
1138 }
3b2f2976
XL
1139}
1140
54a0048b 1141/// Limit types of a range (inclusive or exclusive)
8faf50e0 1142#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
54a0048b
SL
1143pub enum RangeLimits {
1144 /// Inclusive at the beginning, exclusive at the end
1145 HalfOpen,
1146 /// Inclusive at the beginning and end
1147 Closed,
1148}
1149
8faf50e0 1150#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7453a54e 1151pub enum ExprKind {
b039eaaf 1152 /// A `box x` expression.
7453a54e 1153 Box(P<Expr>),
c34b1796 1154 /// An array (`[a, b, c, d]`)
32a655c1 1155 Array(Vec<P<Expr>>),
c34b1796
AL
1156 /// A function call
1157 ///
1158 /// The first field resolves to the function itself,
abe05a73
XL
1159 /// and the second field is the list of arguments.
1160 /// This also represents calling the constructor of
1161 /// tuple-like ADTs such as tuple structs and enum variants.
7453a54e 1162 Call(P<Expr>, Vec<P<Expr>>),
041b39d2 1163 /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`)
c34b1796 1164 ///
041b39d2 1165 /// The `PathSegment` represents the method name and its generic arguments
c34b1796 1166 /// (within the angle brackets).
0731742a 1167 /// The first element of the vector of an `Expr` is the expression that evaluates
c34b1796
AL
1168 /// to the object on which the method is being called on (the receiver),
1169 /// and the remaining elements are the rest of the arguments.
c34b1796 1170 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
041b39d2
XL
1171 /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
1172 MethodCall(PathSegment, Vec<P<Expr>>),
0731742a 1173 /// A tuple (e.g., `(a, b, c, d)`).
7453a54e 1174 Tup(Vec<P<Expr>>),
0731742a 1175 /// A binary operation (e.g., `a + b`, `a * b`).
7453a54e 1176 Binary(BinOp, P<Expr>, P<Expr>),
0731742a 1177 /// A unary operation (e.g., `!x`, `*x`).
7453a54e 1178 Unary(UnOp, P<Expr>),
0731742a 1179 /// A literal (e.g., `1`, `"foo"`).
a1dfa0c6 1180 Lit(Lit),
0731742a 1181 /// A cast (e.g., `foo as f64`).
7453a54e 1182 Cast(P<Expr>, P<Ty>),
48663c56 1183 /// A type ascription (e.g., `42: usize`).
7453a54e 1184 Type(P<Expr>, P<Ty>),
e1599b0c 1185 /// A `let pat = expr` expression that is only semantically allowed in the condition
dc9dc135 1186 /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
e1599b0c 1187 Let(P<Pat>, P<Expr>),
0731742a 1188 /// An `if` block, with an optional `else` block.
c34b1796
AL
1189 ///
1190 /// `if expr { block } else { expr }`
7453a54e 1191 If(P<Expr>, P<Block>, Option<P<Expr>>),
dc9dc135 1192 /// A while loop, with an optional label.
c34b1796
AL
1193 ///
1194 /// `'label: while expr { block }`
2c00a5a8 1195 While(P<Expr>, P<Block>, Option<Label>),
0731742a 1196 /// A `for` loop, with an optional label.
c34b1796
AL
1197 ///
1198 /// `'label: for pat in expr { block }`
1199 ///
1200 /// This is desugared to a combination of `loop` and `match` expressions.
2c00a5a8 1201 ForLoop(P<Pat>, P<Expr>, P<Block>, Option<Label>),
0731742a 1202 /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
c34b1796
AL
1203 ///
1204 /// `'label: loop { block }`
2c00a5a8 1205 Loop(P<Block>, Option<Label>),
b039eaaf 1206 /// A `match` block.
7453a54e 1207 Match(P<Expr>, Vec<Arm>),
0731742a 1208 /// A closure (e.g., `move |a, b, c| a + b + c`).
a7813a04 1209 ///
0731742a 1210 /// The final span is the span of the argument block `|...|`.
74b04a01 1211 Closure(CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span),
0731742a 1212 /// A block (`'label: { ... }`).
94b46f34 1213 Block(P<Block>, Option<Label>),
0731742a 1214 /// An async block (`async move { ... }`).
8faf50e0
XL
1215 ///
1216 /// The `NodeId` is the `NodeId` for the closure that results from
1217 /// desugaring an async block, just like the NodeId field in the
74b04a01 1218 /// `Async::Yes` variant. This is necessary in order to create a def for the
8faf50e0
XL
1219 /// closure which can be used as a parent of any child defs. Defs
1220 /// created during lowering cannot be made the parent of any other
1221 /// preexisting defs.
1222 Async(CaptureBy, NodeId, P<Block>),
48663c56 1223 /// An await expression (`my_future.await`).
416331ca 1224 Await(P<Expr>),
48663c56 1225
0731742a 1226 /// A try block (`try { ... }`).
b7449926 1227 TryBlock(P<Block>),
1a4d82fc 1228
0731742a 1229 /// An assignment (`a = foo()`).
dfeec247
XL
1230 /// The `Span` argument is the span of the `=` token.
1231 Assign(P<Expr>, P<Expr>, Span),
0731742a 1232 /// An assignment with an operator.
c34b1796 1233 ///
0731742a 1234 /// E.g., `a += 1`.
7453a54e 1235 AssignOp(BinOp, P<Expr>, P<Expr>),
0731742a 1236 /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
83c7162d 1237 Field(P<Expr>, Ident),
0731742a 1238 /// An indexing operation (e.g., `foo[2]`).
7453a54e 1239 Index(P<Expr>, P<Expr>),
dc9dc135 1240 /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
54a0048b 1241 Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
1a4d82fc 1242
c34b1796 1243 /// Variable reference, possibly containing `::` and/or type
0731742a 1244 /// parameters (e.g., `foo::bar::<baz>`).
c34b1796 1245 ///
0731742a 1246 /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
7453a54e 1247 Path(Option<QSelf>, Path),
1a4d82fc 1248
60c5eb7d
XL
1249 /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
1250 AddrOf(BorrowKind, Mutability, P<Expr>),
0731742a 1251 /// A `break`, with an optional label to break, and an optional expression.
2c00a5a8 1252 Break(Option<Label>, Option<P<Expr>>),
0731742a 1253 /// A `continue`, with an optional label.
2c00a5a8 1254 Continue(Option<Label>),
0731742a 1255 /// A `return`, with an optional value to be returned.
7453a54e 1256 Ret(Option<P<Expr>>),
1a4d82fc 1257
0731742a 1258 /// Output of the `asm!()` macro.
c30ab7b3 1259 InlineAsm(P<InlineAsm>),
1a4d82fc 1260
0731742a 1261 /// A macro invocation; pre-expansion.
7453a54e 1262 Mac(Mac),
1a4d82fc
JJ
1263
1264 /// A struct literal expression.
c34b1796 1265 ///
0731742a
XL
1266 /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
1267 /// where `base` is the `Option<Expr>`.
7453a54e 1268 Struct(Path, Vec<Field>, Option<P<Expr>>),
1a4d82fc 1269
e9174d1e 1270 /// An array literal constructed from one repeated element.
c34b1796 1271 ///
0731742a 1272 /// E.g., `[1; 5]`. The expression is the element to be
94b46f34
XL
1273 /// repeated; the constant is the number of times to repeat it.
1274 Repeat(P<Expr>, AnonConst),
1a4d82fc 1275
0731742a 1276 /// No-op: used solely so we can pretty-print faithfully.
7453a54e 1277 Paren(P<Expr>),
54a0048b 1278
0731742a 1279 /// A try expression (`expr?`).
54a0048b 1280 Try(P<Expr>),
ea8adc8c 1281
0731742a 1282 /// A `yield`, with an optional value to be yielded.
ea8adc8c 1283 Yield(Option<P<Expr>>),
0731742a
XL
1284
1285 /// Placeholder for an expression that wasn't syntactically well formed in some way.
1286 Err,
1a4d82fc
JJ
1287}
1288
0731742a 1289/// The explicit `Self` type in a "qualified path". The actual
c34b1796
AL
1290/// path, including the trait and the associated item, is stored
1291/// separately. `position` represents the index of the associated
0731742a 1292/// item qualified with this `Self` type.
c34b1796 1293///
041b39d2 1294/// ```ignore (only-for-syntax-highlight)
92a42be0
SL
1295/// <Vec<T> as a::b::Trait>::AssociatedItem
1296/// ^~~~~ ~~~~~~~~~~~~~~^
1297/// ty position = 3
1a4d82fc 1298///
92a42be0
SL
1299/// <Vec<T>>::AssociatedItem
1300/// ^~~~~ ^
1301/// ty position = 0
1302/// ```
8faf50e0 1303#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
c34b1796
AL
1304pub struct QSelf {
1305 pub ty: P<Ty>,
94b46f34
XL
1306
1307 /// The span of `a::b::Trait` in a path like `<Vec<T> as
1308 /// a::b::Trait>::AssociatedItem`; in the case where `position ==
1309 /// 0`, this is an empty span.
1310 pub path_span: Span,
0bf4aa26 1311 pub position: usize,
1a4d82fc
JJ
1312}
1313
e74abb32 1314/// A capture clause used in closures and `async` blocks.
60c5eb7d 1315#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
7453a54e 1316pub enum CaptureBy {
e74abb32 1317 /// `move |x| y + x`.
7453a54e 1318 Value,
e74abb32 1319 /// `move` keyword was not specified.
7453a54e 1320 Ref,
1a4d82fc
JJ
1321}
1322
60c5eb7d
XL
1323/// The movability of a generator / closure literal:
1324/// whether a generator contains self-references, causing it to be `!Unpin`.
dfeec247
XL
1325#[derive(
1326 Clone,
1327 PartialEq,
1328 Eq,
1329 PartialOrd,
1330 Ord,
1331 Hash,
1332 RustcEncodable,
1333 RustcDecodable,
1334 Debug,
1335 Copy,
1336 HashStable_Generic
1337)]
2c00a5a8 1338pub enum Movability {
60c5eb7d 1339 /// May contain self-references, `!Unpin`.
2c00a5a8 1340 Static,
60c5eb7d 1341 /// Must not contain self-references, `Unpin`.
2c00a5a8
XL
1342 Movable,
1343}
1344
60c5eb7d
XL
1345/// Represents a macro invocation. The `path` indicates which macro
1346/// is being invoked, and the `args` are arguments passed to it.
8faf50e0 1347#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
e1599b0c 1348pub struct Mac {
b039eaaf 1349 pub path: Path,
60c5eb7d 1350 pub args: P<MacArgs>,
416331ca 1351 pub prior_type_ascription: Option<(Span, bool)>,
8bb4bdeb
XL
1352}
1353
60c5eb7d
XL
1354impl Mac {
1355 pub fn span(&self) -> Span {
1356 self.path.span.to(self.args.span().unwrap_or(self.path.span))
1357 }
1358}
1359
1360/// Arguments passed to an attribute or a function-like macro.
1361#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
1362pub enum MacArgs {
1363 /// No arguments - `#[attr]`.
1364 Empty,
1365 /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
1366 Delimited(DelimSpan, MacDelimiter, TokenStream),
1367 /// Arguments of a key-value attribute - `#[attr = "value"]`.
1368 Eq(
1369 /// Span of the `=` token.
1370 Span,
1371 /// Token stream of the "value".
1372 TokenStream,
1373 ),
1374}
1375
1376impl MacArgs {
1377 pub fn delim(&self) -> DelimToken {
1378 match self {
1379 MacArgs::Delimited(_, delim, _) => delim.to_token(),
1380 MacArgs::Empty | MacArgs::Eq(..) => token::NoDelim,
1381 }
1382 }
1383
1384 pub fn span(&self) -> Option<Span> {
1385 match *self {
1386 MacArgs::Empty => None,
1387 MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
1388 MacArgs::Eq(eq_span, ref tokens) => Some(eq_span.to(tokens.span().unwrap_or(eq_span))),
1389 }
1390 }
1391
1392 /// Tokens inside the delimiters or after `=`.
1393 /// Proc macros see these tokens, for example.
1394 pub fn inner_tokens(&self) -> TokenStream {
1395 match self {
1396 MacArgs::Empty => TokenStream::default(),
dfeec247 1397 MacArgs::Delimited(.., tokens) | MacArgs::Eq(.., tokens) => tokens.clone(),
60c5eb7d
XL
1398 }
1399 }
1400
1401 /// Tokens together with the delimiters or `=`.
1402 /// Use of this method generally means that something suboptimal or hacky is happening.
1403 pub fn outer_tokens(&self) -> TokenStream {
1404 match *self {
1405 MacArgs::Empty => TokenStream::default(),
dfeec247
XL
1406 MacArgs::Delimited(dspan, delim, ref tokens) => {
1407 TokenTree::Delimited(dspan, delim.to_token(), tokens.clone()).into()
1408 }
1409 MacArgs::Eq(eq_span, ref tokens) => {
1410 iter::once(TokenTree::token(token::Eq, eq_span)).chain(tokens.trees()).collect()
1411 }
60c5eb7d
XL
1412 }
1413 }
1414
1415 /// Whether a macro with these arguments needs a semicolon
1416 /// when used as a standalone item or statement.
1417 pub fn need_semicolon(&self) -> bool {
dfeec247 1418 !matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _))
60c5eb7d
XL
1419 }
1420}
1421
1422#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
94b46f34
XL
1423pub enum MacDelimiter {
1424 Parenthesis,
1425 Bracket,
1426 Brace,
1427}
1428
416331ca 1429impl MacDelimiter {
74b04a01 1430 pub fn to_token(self) -> DelimToken {
416331ca
XL
1431 match self {
1432 MacDelimiter::Parenthesis => DelimToken::Paren,
1433 MacDelimiter::Bracket => DelimToken::Bracket,
1434 MacDelimiter::Brace => DelimToken::Brace,
1435 }
1436 }
60c5eb7d
XL
1437
1438 pub fn from_token(delim: DelimToken) -> Option<MacDelimiter> {
1439 match delim {
1440 token::Paren => Some(MacDelimiter::Parenthesis),
1441 token::Bracket => Some(MacDelimiter::Bracket),
1442 token::Brace => Some(MacDelimiter::Brace),
1443 token::NoDelim => None,
1444 }
1445 }
416331ca
XL
1446}
1447
e74abb32 1448/// Represents a macro definition.
8faf50e0 1449#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7cac9316 1450pub struct MacroDef {
60c5eb7d 1451 pub body: P<MacArgs>,
e74abb32 1452 /// `true` if macro was defined with `macro_rules`.
7cac9316
XL
1453 pub legacy: bool,
1454}
1455
dfeec247
XL
1456#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)]
1457#[derive(HashStable_Generic)]
1a4d82fc 1458pub enum StrStyle {
0731742a 1459 /// A regular string, like `"foo"`.
7453a54e 1460 Cooked,
0731742a 1461 /// A raw string, like `r##"foo"##`.
c34b1796 1462 ///
83c7162d 1463 /// The value is the number of `#` symbols used.
0bf4aa26 1464 Raw(u16),
223e47cc
LB
1465}
1466
48663c56 1467/// An AST literal.
60c5eb7d 1468#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
48663c56
XL
1469pub struct Lit {
1470 /// The original literal token as written in source code.
1471 pub token: token::Lit,
48663c56
XL
1472 /// The "semantic" representation of the literal lowered from the original tokens.
1473 /// Strings are unescaped, hexadecimal forms are eliminated, etc.
1474 /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
e74abb32 1475 pub kind: LitKind,
48663c56
XL
1476 pub span: Span,
1477}
9346a6ac 1478
60c5eb7d
XL
1479/// Same as `Lit`, but restricted to string literals.
1480#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
1481pub struct StrLit {
1482 /// The original literal token as written in source code.
1483 pub style: StrStyle,
1484 pub symbol: Symbol,
1485 pub suffix: Option<Symbol>,
1486 pub span: Span,
1487 /// The unescaped "semantic" representation of the literal lowered from the original token.
1488 /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
1489 pub symbol_unescaped: Symbol,
1490}
1491
1492impl StrLit {
74b04a01 1493 pub fn as_lit(&self) -> Lit {
60c5eb7d
XL
1494 let token_kind = match self.style {
1495 StrStyle::Cooked => token::Str,
1496 StrStyle::Raw(n) => token::StrRaw(n),
1497 };
1498 Lit {
1499 token: token::Lit::new(token_kind, self.symbol, self.suffix),
1500 span: self.span,
1501 kind: LitKind::Str(self.symbol_unescaped, self.style),
1502 }
1503 }
1504}
1505
e74abb32 1506/// Type of the integer literal based on provided suffix.
dfeec247
XL
1507#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)]
1508#[derive(HashStable_Generic)]
1a4d82fc 1509pub enum LitIntType {
e74abb32 1510 /// e.g. `42_i32`.
7453a54e 1511 Signed(IntTy),
e74abb32 1512 /// e.g. `42_u32`.
7453a54e 1513 Unsigned(UintTy),
e74abb32 1514 /// e.g. `42`.
7453a54e 1515 Unsuffixed,
223e47cc
LB
1516}
1517
60c5eb7d 1518/// Type of the float literal based on provided suffix.
dfeec247
XL
1519#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)]
1520#[derive(HashStable_Generic)]
60c5eb7d
XL
1521pub enum LitFloatType {
1522 /// A float literal with a suffix (`1f32` or `1E10f32`).
1523 Suffixed(FloatTy),
1524 /// A float literal without a suffix (`1.0 or 1.0E10`).
1525 Unsuffixed,
1526}
1527
3157f602
XL
1528/// Literal kind.
1529///
0731742a 1530/// E.g., `"foo"`, `42`, `12.34`, or `bool`.
dfeec247 1531#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
7453a54e 1532pub enum LitKind {
0731742a 1533 /// A string literal (`"foo"`).
476ff2be 1534 Str(Symbol, StrStyle),
0731742a 1535 /// A byte string (`b"foo"`).
0531ce1d 1536 ByteStr(Lrc<Vec<u8>>),
0731742a 1537 /// A byte char (`b'f'`).
7453a54e 1538 Byte(u8),
0731742a 1539 /// A character literal (`'a'`).
7453a54e 1540 Char(char),
0731742a 1541 /// An integer literal (`1`).
32a655c1 1542 Int(u128, LitIntType),
0731742a 1543 /// A float literal (`1f64` or `1E10f64`).
60c5eb7d 1544 Float(Symbol, LitFloatType),
0731742a 1545 /// A boolean literal.
7453a54e 1546 Bool(bool),
dc9dc135 1547 /// Placeholder for a literal that wasn't well-formed in some way.
9fa01778 1548 Err(Symbol),
223e47cc
LB
1549}
1550
7453a54e 1551impl LitKind {
0731742a 1552 /// Returns `true` if this literal is a string.
9cc50fc6
SL
1553 pub fn is_str(&self) -> bool {
1554 match *self {
7453a54e 1555 LitKind::Str(..) => true,
9cc50fc6
SL
1556 _ => false,
1557 }
1558 }
9e0c209e 1559
0731742a 1560 /// Returns `true` if this literal is byte literal string.
a1dfa0c6
XL
1561 pub fn is_bytestr(&self) -> bool {
1562 match self {
1563 LitKind::ByteStr(_) => true,
1564 _ => false,
1565 }
1566 }
1567
0731742a 1568 /// Returns `true` if this is a numeric literal.
8faf50e0
XL
1569 pub fn is_numeric(&self) -> bool {
1570 match *self {
60c5eb7d 1571 LitKind::Int(..) | LitKind::Float(..) => true,
8faf50e0
XL
1572 _ => false,
1573 }
1574 }
1575
0731742a
XL
1576 /// Returns `true` if this literal has no suffix.
1577 /// Note: this will return true for literals with prefixes such as raw strings and byte strings.
9e0c209e 1578 pub fn is_unsuffixed(&self) -> bool {
e74abb32
XL
1579 !self.is_suffixed()
1580 }
1581
1582 /// Returns `true` if this literal has a suffix.
1583 pub fn is_suffixed(&self) -> bool {
9e0c209e 1584 match *self {
e74abb32
XL
1585 // suffixed variants
1586 LitKind::Int(_, LitIntType::Signed(..))
1587 | LitKind::Int(_, LitIntType::Unsigned(..))
60c5eb7d 1588 | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
9e0c209e 1589 // unsuffixed variants
0bf4aa26
XL
1590 LitKind::Str(..)
1591 | LitKind::ByteStr(..)
1592 | LitKind::Byte(..)
1593 | LitKind::Char(..)
1594 | LitKind::Int(_, LitIntType::Unsuffixed)
60c5eb7d 1595 | LitKind::Float(_, LitFloatType::Unsuffixed)
dc9dc135 1596 | LitKind::Bool(..)
e74abb32 1597 | LitKind::Err(..) => false,
9e0c209e
SL
1598 }
1599 }
9cc50fc6
SL
1600}
1601
0731742a
XL
1602// N.B., If you change this, you'll probably want to change the corresponding
1603// type structure in `middle/ty.rs` as well.
8faf50e0 1604#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
1605pub struct MutTy {
1606 pub ty: P<Ty>,
1607 pub mutbl: Mutability,
1608}
1609
60c5eb7d
XL
1610/// Represents a function's signature in a trait declaration,
1611/// trait implementation, or free function.
8faf50e0 1612#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
60c5eb7d 1613pub struct FnSig {
8faf50e0 1614 pub header: FnHeader,
1a4d82fc 1615 pub decl: P<FnDecl>,
1a4d82fc
JJ
1616}
1617
dfeec247
XL
1618#[derive(
1619 Clone,
1620 Copy,
1621 PartialEq,
1622 Eq,
1623 PartialOrd,
1624 Ord,
1625 Hash,
1626 HashStable_Generic,
1627 RustcEncodable,
1628 RustcDecodable,
1629 Debug
1630)]
60c5eb7d
XL
1631pub enum FloatTy {
1632 F32,
1633 F64,
1634}
1635
1636impl FloatTy {
1637 pub fn name_str(self) -> &'static str {
1638 match self {
1639 FloatTy::F32 => "f32",
1640 FloatTy::F64 => "f64",
1641 }
1642 }
1643
1644 pub fn name(self) -> Symbol {
1645 match self {
1646 FloatTy::F32 => sym::f32,
1647 FloatTy::F64 => sym::f64,
1648 }
1649 }
1650
1651 pub fn bit_width(self) -> usize {
1652 match self {
1653 FloatTy::F32 => 32,
1654 FloatTy::F64 => 64,
1655 }
1656 }
1657}
1658
dfeec247
XL
1659#[derive(
1660 Clone,
1661 Copy,
1662 PartialEq,
1663 Eq,
1664 PartialOrd,
1665 Ord,
1666 Hash,
1667 HashStable_Generic,
1668 RustcEncodable,
1669 RustcDecodable,
1670 Debug
1671)]
1a4d82fc 1672pub enum IntTy {
2c00a5a8 1673 Isize,
7453a54e
SL
1674 I8,
1675 I16,
1676 I32,
1677 I64,
32a655c1 1678 I128,
1a4d82fc
JJ
1679}
1680
1a4d82fc 1681impl IntTy {
60c5eb7d 1682 pub fn name_str(&self) -> &'static str {
9cc50fc6 1683 match *self {
2c00a5a8 1684 IntTy::Isize => "isize",
7453a54e
SL
1685 IntTy::I8 => "i8",
1686 IntTy::I16 => "i16",
1687 IntTy::I32 => "i32",
32a655c1
SL
1688 IntTy::I64 => "i64",
1689 IntTy::I128 => "i128",
9cc50fc6
SL
1690 }
1691 }
1692
60c5eb7d 1693 pub fn name(&self) -> Symbol {
dc9dc135
XL
1694 match *self {
1695 IntTy::Isize => sym::isize,
1696 IntTy::I8 => sym::i8,
1697 IntTy::I16 => sym::i16,
1698 IntTy::I32 => sym::i32,
1699 IntTy::I64 => sym::i64,
1700 IntTy::I128 => sym::i128,
1701 }
1702 }
1703
32a655c1 1704 pub fn val_to_string(&self, val: i128) -> String {
0731742a
XL
1705 // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
1706 // are parsed as `u128`, so we wouldn't want to print an extra negative
9cc50fc6 1707 // sign.
60c5eb7d 1708 format!("{}{}", val as u128, self.name_str())
9cc50fc6
SL
1709 }
1710
e9174d1e
SL
1711 pub fn bit_width(&self) -> Option<usize> {
1712 Some(match *self {
2c00a5a8 1713 IntTy::Isize => return None,
7453a54e
SL
1714 IntTy::I8 => 8,
1715 IntTy::I16 => 16,
1716 IntTy::I32 => 32,
1717 IntTy::I64 => 64,
32a655c1 1718 IntTy::I128 => 128,
e9174d1e 1719 })
1a4d82fc 1720 }
60c5eb7d
XL
1721
1722 pub fn normalize(&self, target_width: u32) -> Self {
1723 match self {
1724 IntTy::Isize => match target_width {
1725 16 => IntTy::I16,
1726 32 => IntTy::I32,
1727 64 => IntTy::I64,
1728 _ => unreachable!(),
1729 },
1730 _ => *self,
1731 }
1732 }
223e47cc
LB
1733}
1734
dfeec247
XL
1735#[derive(
1736 Clone,
1737 PartialEq,
1738 Eq,
1739 PartialOrd,
1740 Ord,
1741 Hash,
1742 HashStable_Generic,
1743 RustcEncodable,
1744 RustcDecodable,
1745 Copy,
1746 Debug
1747)]
1a4d82fc 1748pub enum UintTy {
2c00a5a8 1749 Usize,
7453a54e
SL
1750 U8,
1751 U16,
1752 U32,
1753 U64,
32a655c1 1754 U128,
1a4d82fc
JJ
1755}
1756
1a4d82fc 1757impl UintTy {
60c5eb7d 1758 pub fn name_str(&self) -> &'static str {
9cc50fc6 1759 match *self {
2c00a5a8 1760 UintTy::Usize => "usize",
7453a54e
SL
1761 UintTy::U8 => "u8",
1762 UintTy::U16 => "u16",
1763 UintTy::U32 => "u32",
32a655c1
SL
1764 UintTy::U64 => "u64",
1765 UintTy::U128 => "u128",
9cc50fc6
SL
1766 }
1767 }
1768
60c5eb7d 1769 pub fn name(&self) -> Symbol {
dc9dc135
XL
1770 match *self {
1771 UintTy::Usize => sym::usize,
1772 UintTy::U8 => sym::u8,
1773 UintTy::U16 => sym::u16,
1774 UintTy::U32 => sym::u32,
1775 UintTy::U64 => sym::u64,
1776 UintTy::U128 => sym::u128,
1777 }
1778 }
1779
32a655c1 1780 pub fn val_to_string(&self, val: u128) -> String {
60c5eb7d 1781 format!("{}{}", val, self.name_str())
9cc50fc6
SL
1782 }
1783
e9174d1e
SL
1784 pub fn bit_width(&self) -> Option<usize> {
1785 Some(match *self {
2c00a5a8 1786 UintTy::Usize => return None,
7453a54e
SL
1787 UintTy::U8 => 8,
1788 UintTy::U16 => 16,
1789 UintTy::U32 => 32,
1790 UintTy::U64 => 64,
32a655c1 1791 UintTy::U128 => 128,
e9174d1e 1792 })
1a4d82fc 1793 }
223e47cc 1794
60c5eb7d
XL
1795 pub fn normalize(&self, target_width: u32) -> Self {
1796 match self {
1797 UintTy::Usize => match target_width {
1798 16 => UintTy::U16,
1799 32 => UintTy::U32,
1800 64 => UintTy::U64,
1801 _ => unreachable!(),
1802 },
1803 _ => *self,
1804 }
1a4d82fc
JJ
1805 }
1806}
1807
dc9dc135
XL
1808/// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
1809/// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
8faf50e0 1810#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
dc9dc135 1811pub struct AssocTyConstraint {
1a4d82fc
JJ
1812 pub id: NodeId,
1813 pub ident: Ident,
dc9dc135 1814 pub kind: AssocTyConstraintKind,
1a4d82fc
JJ
1815 pub span: Span,
1816}
1817
dc9dc135
XL
1818/// The kinds of an `AssocTyConstraint`.
1819#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1820pub enum AssocTyConstraintKind {
1821 /// E.g., `A = Bar` in `Foo<A = Bar>`.
dfeec247 1822 Equality { ty: P<Ty> },
dc9dc135 1823 /// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
dfeec247 1824 Bound { bounds: GenericBounds },
dc9dc135
XL
1825}
1826
e74abb32 1827#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
223e47cc 1828pub struct Ty {
1a4d82fc 1829 pub id: NodeId,
e74abb32 1830 pub kind: TyKind,
1a4d82fc 1831 pub span: Span,
223e47cc
LB
1832}
1833
8faf50e0 1834#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 1835pub struct BareFnTy {
74b04a01 1836 pub unsafety: Unsafe,
60c5eb7d 1837 pub ext: Extern,
ff7c6d11 1838 pub generic_params: Vec<GenericParam>,
0bf4aa26 1839 pub decl: P<FnDecl>,
1a4d82fc
JJ
1840}
1841
9fa01778 1842/// The various kinds of type recognized by the compiler.
8faf50e0 1843#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7453a54e 1844pub enum TyKind {
0731742a 1845 /// A variable-length slice (`[T]`).
c30ab7b3 1846 Slice(P<Ty>),
0731742a 1847 /// A fixed length array (`[T; n]`).
94b46f34 1848 Array(P<Ty>, AnonConst),
0731742a 1849 /// A raw pointer (`*const T` or `*mut T`).
7453a54e 1850 Ptr(MutTy),
0731742a 1851 /// A reference (`&'a T` or `&'a mut T`).
7453a54e 1852 Rptr(Option<Lifetime>, MutTy),
0731742a 1853 /// A bare function (e.g., `fn(usize) -> bool`).
7453a54e 1854 BareFn(P<BareFnTy>),
0731742a 1855 /// The never type (`!`).
5bcae85e 1856 Never,
0731742a 1857 /// A tuple (`(A, B, C, D,...)`).
0bf4aa26 1858 Tup(Vec<P<Ty>>),
c34b1796 1859 /// A path (`module::module::...::Type`), optionally
0731742a 1860 /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
1a4d82fc 1861 ///
0731742a 1862 /// Type parameters are stored in the `Path` itself.
7453a54e 1863 Path(Option<QSelf>, Path),
32a655c1
SL
1864 /// A trait object type `Bound1 + Bound2 + Bound3`
1865 /// where `Bound` is a trait or a lifetime.
8faf50e0 1866 TraitObject(GenericBounds, TraitObjectSyntax),
32a655c1
SL
1867 /// An `impl Bound1 + Bound2 + Bound3` type
1868 /// where `Bound` is a trait or a lifetime.
8faf50e0
XL
1869 ///
1870 /// The `NodeId` exists to prevent lowering from having to
1871 /// generate `NodeId`s on the fly, which would complicate
416331ca 1872 /// the generation of opaque `type Foo = impl Trait` items significantly.
8faf50e0 1873 ImplTrait(NodeId, GenericBounds),
0731742a 1874 /// No-op; kept solely so that we can pretty-print faithfully.
7453a54e 1875 Paren(P<Ty>),
0731742a 1876 /// Unused for now.
94b46f34 1877 Typeof(AnonConst),
0731742a 1878 /// This means the type should be inferred instead of it having been
1a4d82fc 1879 /// specified. This can appear anywhere in a type.
7453a54e 1880 Infer,
3157f602
XL
1881 /// Inferred type of a `self` or `&self` argument in a method.
1882 ImplicitSelf,
0731742a 1883 /// A macro in the type position.
7453a54e 1884 Mac(Mac),
cc61c64b
XL
1885 /// Placeholder for a kind that has failed to be defined.
1886 Err,
532ac7d7
XL
1887 /// Placeholder for a `va_list`.
1888 CVarArgs,
1a4d82fc
JJ
1889}
1890
8faf50e0
XL
1891impl TyKind {
1892 pub fn is_implicit_self(&self) -> bool {
dfeec247 1893 if let TyKind::ImplicitSelf = *self { true } else { false }
8faf50e0
XL
1894 }
1895
b7449926 1896 pub fn is_unit(&self) -> bool {
dfeec247 1897 if let TyKind::Tup(ref tys) = *self { tys.is_empty() } else { false }
8faf50e0 1898 }
60c5eb7d
XL
1899
1900 /// HACK(type_alias_impl_trait, Centril): A temporary crutch used
1901 /// in lowering to avoid making larger changes there and beyond.
1902 pub fn opaque_top_hack(&self) -> Option<&GenericBounds> {
1903 match self {
1904 Self::ImplTrait(_, bounds) => Some(bounds),
1905 _ => None,
1906 }
1907 }
8faf50e0
XL
1908}
1909
abe05a73 1910/// Syntax used to declare a trait object.
8faf50e0 1911#[derive(Clone, Copy, PartialEq, RustcEncodable, RustcDecodable, Debug)]
abe05a73
XL
1912pub enum TraitObjectSyntax {
1913 Dyn,
1914 None,
1915}
1916
3157f602
XL
1917/// Inline assembly dialect.
1918///
0731742a 1919/// E.g., `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
60c5eb7d 1920#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)]
1a4d82fc 1921pub enum AsmDialect {
b039eaaf
SL
1922 Att,
1923 Intel,
1a4d82fc
JJ
1924}
1925
3157f602
XL
1926/// Inline assembly.
1927///
0731742a 1928/// E.g., `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
8faf50e0 1929#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
9cc50fc6 1930pub struct InlineAsmOutput {
476ff2be 1931 pub constraint: Symbol,
9cc50fc6
SL
1932 pub expr: P<Expr>,
1933 pub is_rw: bool,
1934 pub is_indirect: bool,
1935}
1936
3157f602
XL
1937/// Inline assembly.
1938///
0731742a 1939/// E.g., `asm!("NOP");`.
8faf50e0 1940#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 1941pub struct InlineAsm {
476ff2be 1942 pub asm: Symbol,
1a4d82fc 1943 pub asm_str_style: StrStyle,
9cc50fc6 1944 pub outputs: Vec<InlineAsmOutput>,
476ff2be
SL
1945 pub inputs: Vec<(Symbol, P<Expr>)>,
1946 pub clobbers: Vec<Symbol>,
1a4d82fc
JJ
1947 pub volatile: bool,
1948 pub alignstack: bool,
1949 pub dialect: AsmDialect,
1a4d82fc
JJ
1950}
1951
e1599b0c 1952/// A parameter in a function header.
3157f602 1953///
0731742a 1954/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
8faf50e0 1955#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
e1599b0c 1956pub struct Param {
dfeec247 1957 pub attrs: AttrVec,
1a4d82fc
JJ
1958 pub ty: P<Ty>,
1959 pub pat: P<Pat>,
1960 pub id: NodeId,
416331ca 1961 pub span: Span,
e1599b0c 1962 pub is_placeholder: bool,
1a4d82fc
JJ
1963}
1964
3157f602
XL
1965/// Alternative representation for `Arg`s describing `self` parameter of methods.
1966///
0731742a 1967/// E.g., `&mut self` as in `fn foo(&mut self)`.
8faf50e0 1968#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
a7813a04 1969pub enum SelfKind {
a7813a04 1970 /// `self`, `mut self`
3157f602 1971 Value(Mutability),
a7813a04 1972 /// `&'lt self`, `&'lt mut self`
3157f602 1973 Region(Option<Lifetime>, Mutability),
a7813a04 1974 /// `self: TYPE`, `mut self: TYPE`
3157f602 1975 Explicit(P<Ty>, Mutability),
a7813a04
XL
1976}
1977
1978pub type ExplicitSelf = Spanned<SelfKind>;
1979
e1599b0c 1980impl Param {
e74abb32 1981 /// Attempts to cast parameter to `ExplicitSelf`.
a7813a04 1982 pub fn to_self(&self) -> Option<ExplicitSelf> {
e74abb32 1983 if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind {
dc9dc135 1984 if ident.name == kw::SelfLower {
e74abb32 1985 return match self.ty.kind {
3157f602 1986 TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
e74abb32 1987 TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
3157f602 1988 Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
a7813a04 1989 }
0bf4aa26
XL
1990 _ => Some(respan(
1991 self.pat.span.to(self.ty.span),
1992 SelfKind::Explicit(self.ty.clone(), mutbl),
1993 )),
1994 };
a7813a04
XL
1995 }
1996 }
1997 None
1998 }
1999
e74abb32 2000 /// Returns `true` if parameter is `self`.
3157f602 2001 pub fn is_self(&self) -> bool {
e74abb32 2002 if let PatKind::Ident(_, ident, _) = self.pat.kind {
dc9dc135 2003 ident.name == kw::SelfLower
3157f602
XL
2004 } else {
2005 false
2006 }
2007 }
2008
e74abb32 2009 /// Builds a `Param` object from `ExplicitSelf`.
dfeec247 2010 pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
cc61c64b 2011 let span = eself.span.to(eself_ident.span);
dfeec247 2012 let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span });
e1599b0c 2013 let param = |mutbl, ty| Param {
dc9dc135 2014 attrs,
3157f602
XL
2015 pat: P(Pat {
2016 id: DUMMY_NODE_ID,
e74abb32 2017 kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
3b2f2976 2018 span,
3157f602 2019 }),
416331ca 2020 span,
3b2f2976 2021 ty,
a7813a04 2022 id: DUMMY_NODE_ID,
dfeec247 2023 is_placeholder: false,
a7813a04
XL
2024 };
2025 match eself.node {
e1599b0c
XL
2026 SelfKind::Explicit(ty, mutbl) => param(mutbl, ty),
2027 SelfKind::Value(mutbl) => param(mutbl, infer_ty),
2028 SelfKind::Region(lt, mutbl) => param(
dfeec247 2029 Mutability::Not,
0bf4aa26
XL
2030 P(Ty {
2031 id: DUMMY_NODE_ID,
dfeec247 2032 kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }),
0bf4aa26
XL
2033 span,
2034 }),
2035 ),
a7813a04
XL
2036 }
2037 }
223e47cc
LB
2038}
2039
e74abb32 2040/// A signature (not the body) of a function declaration.
3157f602 2041///
0731742a 2042/// E.g., `fn foo(bar: baz)`.
e74abb32
XL
2043///
2044/// Please note that it's different from `FnHeader` structure
2045/// which contains metadata about function safety, asyncness, constness and ABI.
8faf50e0 2046#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 2047pub struct FnDecl {
e1599b0c 2048 pub inputs: Vec<Param>,
74b04a01 2049 pub output: FnRetTy,
1a4d82fc
JJ
2050}
2051
3157f602
XL
2052impl FnDecl {
2053 pub fn get_self(&self) -> Option<ExplicitSelf> {
e1599b0c 2054 self.inputs.get(0).and_then(Param::to_self)
3157f602
XL
2055 }
2056 pub fn has_self(&self) -> bool {
e74abb32
XL
2057 self.inputs.get(0).map_or(false, Param::is_self)
2058 }
2059 pub fn c_variadic(&self) -> bool {
2060 self.inputs.last().map_or(false, |arg| match arg.ty.kind {
2061 TyKind::CVarArgs => true,
2062 _ => false,
2063 })
3157f602
XL
2064 }
2065}
2066
abe05a73 2067/// Is the trait definition an auto trait?
60c5eb7d 2068#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
abe05a73
XL
2069pub enum IsAuto {
2070 Yes,
0bf4aa26 2071 No,
abe05a73
XL
2072}
2073
74b04a01
XL
2074#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
2075#[derive(HashStable_Generic)]
2076pub enum Unsafe {
2077 Yes(Span),
2078 No,
60c5eb7d
XL
2079}
2080
dc9dc135 2081#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
74b04a01
XL
2082pub enum Async {
2083 Yes { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
2084 No,
8faf50e0
XL
2085}
2086
74b04a01 2087impl Async {
dc9dc135 2088 pub fn is_async(self) -> bool {
74b04a01 2089 if let Async::Yes { .. } = self { true } else { false }
8faf50e0 2090 }
0731742a 2091
74b04a01 2092 /// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
dc9dc135 2093 pub fn opt_return_id(self) -> Option<NodeId> {
8faf50e0 2094 match self {
74b04a01
XL
2095 Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id),
2096 Async::No => None,
8faf50e0
XL
2097 }
2098 }
2099}
2100
dfeec247
XL
2101#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
2102#[derive(HashStable_Generic)]
74b04a01
XL
2103pub enum Const {
2104 Yes(Span),
2105 No,
62682a34
SL
2106}
2107
e74abb32
XL
2108/// Item defaultness.
2109/// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
60c5eb7d 2110#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
54a0048b 2111pub enum Defaultness {
74b04a01 2112 Default(Span),
54a0048b
SL
2113 Final,
2114}
2115
60c5eb7d 2116#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable_Generic)]
1a4d82fc 2117pub enum ImplPolarity {
c34b1796 2118 /// `impl Trait for Type`
1a4d82fc 2119 Positive,
c34b1796 2120 /// `impl !Trait for Type`
1a4d82fc
JJ
2121 Negative,
2122}
2123
85aaf69f 2124impl fmt::Debug for ImplPolarity {
9fa01778 2125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223e47cc 2126 match *self {
1a4d82fc
JJ
2127 ImplPolarity::Positive => "positive".fmt(f),
2128 ImplPolarity::Negative => "negative".fmt(f),
223e47cc
LB
2129 }
2130 }
2131}
2132
8faf50e0 2133#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
74b04a01 2134pub enum FnRetTy {
9fa01778 2135 /// Returns type is not specified.
c34b1796 2136 ///
0731742a
XL
2137 /// Functions default to `()` and closures default to inference.
2138 /// Span points to where return type would be inserted.
7453a54e 2139 Default(Span),
0731742a 2140 /// Everything else.
7453a54e 2141 Ty(P<Ty>),
1a4d82fc
JJ
2142}
2143
74b04a01 2144impl FnRetTy {
1a4d82fc
JJ
2145 pub fn span(&self) -> Span {
2146 match *self {
74b04a01
XL
2147 FnRetTy::Default(span) => span,
2148 FnRetTy::Ty(ref ty) => ty.span,
1a4d82fc
JJ
2149 }
2150 }
223e47cc
LB
2151}
2152
3157f602
XL
2153/// Module declaration.
2154///
0731742a 2155/// E.g., `mod foo;` or `mod foo { .. }`.
8faf50e0 2156#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
2157pub struct Mod {
2158 /// A span from the first token past `{` to the last token until `}`.
2159 /// For `mod foo;`, the inner span ranges from the first token
2160 /// to the last token in the external file.
2161 pub inner: Span,
1a4d82fc 2162 pub items: Vec<P<Item>>,
0731742a 2163 /// `true` for `mod foo { .. }`; `false` for `mod foo;`.
0bf4aa26 2164 pub inline: bool,
1a4d82fc 2165}
223e47cc 2166
3157f602
XL
2167/// Foreign module declaration.
2168///
0731742a 2169/// E.g., `extern { .. }` or `extern C { .. }`.
8faf50e0 2170#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 2171pub struct ForeignMod {
60c5eb7d 2172 pub abi: Option<StrLit>,
74b04a01 2173 pub items: Vec<P<ForeignItem>>,
223e47cc
LB
2174}
2175
0731742a 2176/// Global inline assembly.
cc61c64b 2177///
0731742a 2178/// Also known as "module-level assembly" or "file-scoped assembly".
8faf50e0 2179#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
cc61c64b
XL
2180pub struct GlobalAsm {
2181 pub asm: Symbol,
cc61c64b
XL
2182}
2183
8faf50e0 2184#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 2185pub struct EnumDef {
7453a54e 2186 pub variants: Vec<Variant>,
223e47cc 2187}
e74abb32 2188/// Enum variant.
8faf50e0 2189#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
e1599b0c 2190pub struct Variant {
532ac7d7 2191 /// Attributes of the variant.
1a4d82fc 2192 pub attrs: Vec<Attribute>,
532ac7d7
XL
2193 /// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
2194 pub id: NodeId,
60c5eb7d
XL
2195 /// Span
2196 pub span: Span,
2197 /// The visibility of the variant. Syntactically accepted but not semantically.
2198 pub vis: Visibility,
2199 /// Name of the variant.
2200 pub ident: Ident,
2201
532ac7d7 2202 /// Fields and constructor id of the variant.
b039eaaf 2203 pub data: VariantData,
0731742a 2204 /// Explicit discriminant, e.g., `Foo = 1`.
94b46f34 2205 pub disr_expr: Option<AnonConst>,
e1599b0c
XL
2206 /// Is a macro placeholder
2207 pub is_placeholder: bool,
223e47cc
LB
2208}
2209
0531ce1d 2210/// Part of `use` item to the right of its prefix.
8faf50e0 2211#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
ff7c6d11 2212pub enum UseTreeKind {
0531ce1d 2213 /// `use prefix` or `use prefix as rename`
94b46f34
XL
2214 ///
2215 /// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
2216 /// namespace.
2217 Simple(Option<Ident>, NodeId, NodeId),
0531ce1d 2218 /// `use prefix::{...}`
ff7c6d11 2219 Nested(Vec<(UseTree, NodeId)>),
0531ce1d
XL
2220 /// `use prefix::*`
2221 Glob,
223e47cc
LB
2222}
2223
0531ce1d
XL
2224/// A tree of paths sharing common prefixes.
2225/// Used in `use` items both at top-level and inside of braces in import groups.
8faf50e0 2226#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
ff7c6d11 2227pub struct UseTree {
ff7c6d11 2228 pub prefix: Path,
0531ce1d 2229 pub kind: UseTreeKind,
ff7c6d11 2230 pub span: Span,
3157f602
XL
2231}
2232
0531ce1d
XL
2233impl UseTree {
2234 pub fn ident(&self) -> Ident {
2235 match self.kind {
94b46f34 2236 UseTreeKind::Simple(Some(rename), ..) => rename,
0bf4aa26 2237 UseTreeKind::Simple(None, ..) => {
dfeec247 2238 self.prefix.segments.last().expect("empty prefix in a simple import").ident
0bf4aa26 2239 }
0531ce1d
XL
2240 _ => panic!("`UseTree::ident` can only be used on a simple import"),
2241 }
2242 }
2243}
2244
0731742a 2245/// Distinguishes between `Attribute`s that decorate items and Attributes that
1a4d82fc
JJ
2246/// are contained as statements within items. These two cases need to be
2247/// distinguished for pretty-printing.
60c5eb7d 2248#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable_Generic)]
1a4d82fc 2249pub enum AttrStyle {
b039eaaf
SL
2250 Outer,
2251 Inner,
1a4d82fc 2252}
223e47cc 2253
416331ca 2254#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy)]
85aaf69f 2255pub struct AttrId(pub usize);
1a4d82fc 2256
b7449926
XL
2257impl Idx for AttrId {
2258 fn new(idx: usize) -> Self {
2259 AttrId(idx)
2260 }
2261 fn index(self) -> usize {
2262 self.0
2263 }
2264}
2265
416331ca
XL
2266impl rustc_serialize::Encodable for AttrId {
2267 fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
2268 s.emit_unit()
2269 }
2270}
2271
2272impl rustc_serialize::Decodable for AttrId {
2273 fn decode<D: Decoder>(d: &mut D) -> Result<AttrId, D::Error> {
2274 d.read_nil().map(|_| crate::attr::mk_attr_id())
2275 }
2276}
2277
60c5eb7d 2278#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
e74abb32
XL
2279pub struct AttrItem {
2280 pub path: Path,
60c5eb7d 2281 pub args: MacArgs,
e74abb32
XL
2282}
2283
dfeec247
XL
2284/// A list of attributes.
2285pub type AttrVec = ThinVec<Attribute>;
2286
0731742a 2287/// Metadata associated with an item.
8faf50e0 2288#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
476ff2be 2289pub struct Attribute {
60c5eb7d 2290 pub kind: AttrKind,
1a4d82fc 2291 pub id: AttrId,
e74abb32
XL
2292 /// Denotes if the attribute decorates the following construct (outer)
2293 /// or the construct this attribute is contained within (inner).
1a4d82fc 2294 pub style: AttrStyle,
476ff2be 2295 pub span: Span,
223e47cc
LB
2296}
2297
60c5eb7d
XL
2298#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2299pub enum AttrKind {
2300 /// A normal attribute.
2301 Normal(AttrItem),
2302
2303 /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
2304 /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
2305 /// variant (which is much less compact and thus more expensive).
60c5eb7d 2306 DocComment(Symbol),
e74abb32
XL
2307}
2308
0731742a 2309/// `TraitRef`s appear in impls.
c34b1796 2310///
9fa01778 2311/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
0731742a
XL
2312/// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
2313/// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
9fa01778 2314/// same as the impl's `NodeId`).
8faf50e0 2315#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc
JJ
2316pub struct TraitRef {
2317 pub path: Path,
2318 pub ref_id: NodeId,
223e47cc
LB
2319}
2320
8faf50e0 2321#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1a4d82fc 2322pub struct PolyTraitRef {
dc9dc135 2323 /// The `'a` in `<'a> Foo<&'a T>`.
ff7c6d11 2324 pub bound_generic_params: Vec<GenericParam>,
223e47cc 2325
dc9dc135 2326 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
1a4d82fc 2327 pub trait_ref: TraitRef,
85aaf69f
SL
2328
2329 pub span: Span,
1a4d82fc
JJ
2330}
2331
cc61c64b 2332impl PolyTraitRef {
ff7c6d11 2333 pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
cc61c64b 2334 PolyTraitRef {
ff7c6d11 2335 bound_generic_params: generic_params,
dfeec247 2336 trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3b2f2976 2337 span,
cc61c64b
XL
2338 }
2339 }
2340}
2341
60c5eb7d 2342#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
abe05a73 2343pub enum CrateSugar {
0731742a 2344 /// Source is `pub(crate)`.
abe05a73
XL
2345 PubCrate,
2346
0731742a 2347 /// Source is (just) `crate`.
abe05a73
XL
2348 JustCrate,
2349}
2350
0531ce1d
XL
2351pub type Visibility = Spanned<VisibilityKind>;
2352
8faf50e0 2353#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
0531ce1d 2354pub enum VisibilityKind {
1a4d82fc 2355 Public,
0531ce1d 2356 Crate(CrateSugar),
54a0048b 2357 Restricted { path: P<Path>, id: NodeId },
1a4d82fc
JJ
2358 Inherited,
2359}
2360
8faf50e0
XL
2361impl VisibilityKind {
2362 pub fn is_pub(&self) -> bool {
dfeec247 2363 if let VisibilityKind::Public = *self { true } else { false }
8faf50e0
XL
2364 }
2365}
2366
3157f602
XL
2367/// Field of a struct.
2368///
0731742a 2369/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
8faf50e0 2370#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
54a0048b 2371pub struct StructField {
60c5eb7d
XL
2372 pub attrs: Vec<Attribute>,
2373 pub id: NodeId,
54a0048b 2374 pub span: Span,
54a0048b 2375 pub vis: Visibility,
60c5eb7d
XL
2376 pub ident: Option<Ident>,
2377
1a4d82fc 2378 pub ty: P<Ty>,
e1599b0c 2379 pub is_placeholder: bool,
1a4d82fc
JJ
2380}
2381
532ac7d7 2382/// Fields and constructor ids of enum variants and structs.
8faf50e0 2383#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
b039eaaf 2384pub enum VariantData {
3157f602
XL
2385 /// Struct variant.
2386 ///
0731742a 2387 /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
532ac7d7 2388 Struct(Vec<StructField>, bool),
3157f602
XL
2389 /// Tuple variant.
2390 ///
0731742a 2391 /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
b039eaaf 2392 Tuple(Vec<StructField>, NodeId),
3157f602
XL
2393 /// Unit variant.
2394 ///
0731742a 2395 /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
b039eaaf
SL
2396 Unit(NodeId),
2397}
2398
2399impl VariantData {
532ac7d7 2400 /// Return the fields of this variant.
b039eaaf
SL
2401 pub fn fields(&self) -> &[StructField] {
2402 match *self {
532ac7d7 2403 VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields,
b039eaaf
SL
2404 _ => &[],
2405 }
2406 }
532ac7d7
XL
2407
2408 /// Return the `NodeId` of this variant's constructor, if it has one.
2409 pub fn ctor_id(&self) -> Option<NodeId> {
b039eaaf 2410 match *self {
532ac7d7
XL
2411 VariantData::Struct(..) => None,
2412 VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
0bf4aa26 2413 }
b039eaaf 2414 }
223e47cc
LB
2415}
2416
74b04a01 2417/// An item definition.
8faf50e0 2418#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
60c5eb7d 2419pub struct Item<K = ItemKind> {
1a4d82fc
JJ
2420 pub attrs: Vec<Attribute>,
2421 pub id: NodeId,
1a4d82fc 2422 pub span: Span,
60c5eb7d 2423 pub vis: Visibility,
74b04a01
XL
2424 /// The name of the item.
2425 /// It might be a dummy name in case of anonymous items.
60c5eb7d
XL
2426 pub ident: Ident,
2427
2428 pub kind: K,
3b2f2976
XL
2429
2430 /// Original tokens this item was parsed from. This isn't necessarily
2431 /// available for all items, although over time more and more items should
2432 /// have this be `Some`. Right now this is primarily used for procedural
2433 /// macros, notably custom attributes.
2434 ///
2435 /// Note that the tokens here do not include the outer attributes, but will
2436 /// include inner attributes.
2437 pub tokens: Option<TokenStream>,
1a4d82fc
JJ
2438}
2439
9fa01778
XL
2440impl Item {
2441 /// Return the span that encompasses the attributes.
2442 pub fn span_with_attributes(&self) -> Span {
532ac7d7 2443 self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
9fa01778
XL
2444 }
2445}
2446
74b04a01
XL
2447impl<K: Into<ItemKind>> Item<K> {
2448 pub fn into_item(self) -> Item {
2449 let Item { attrs, id, span, vis, ident, kind, tokens } = self;
2450 Item { attrs, id, span, vis, ident, kind: kind.into(), tokens }
2451 }
2452}
2453
60c5eb7d
XL
2454/// `extern` qualifier on a function item or function type.
2455#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
2456pub enum Extern {
2457 None,
2458 Implicit,
2459 Explicit(StrLit),
2460}
2461
2462impl Extern {
2463 pub fn from_abi(abi: Option<StrLit>) -> Extern {
2464 abi.map_or(Extern::Implicit, Extern::Explicit)
2465 }
2466}
2467
0731742a 2468/// A function header.
8faf50e0 2469///
0731742a
XL
2470/// All the information between the visibility and the name of the function is
2471/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
dc9dc135 2472#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
8faf50e0 2473pub struct FnHeader {
74b04a01
XL
2474 pub unsafety: Unsafe,
2475 pub asyncness: Async,
2476 pub constness: Const,
60c5eb7d 2477 pub ext: Extern,
8faf50e0
XL
2478}
2479
74b04a01
XL
2480impl FnHeader {
2481 /// Does this function header have any qualifiers or is it empty?
2482 pub fn has_qualifiers(&self) -> bool {
2483 let Self { unsafety, asyncness, constness, ext } = self;
2484 matches!(unsafety, Unsafe::Yes(_))
2485 || asyncness.is_async()
2486 || matches!(constness, Const::Yes(_))
2487 || !matches!(ext, Extern::None)
2488 }
2489}
2490
8faf50e0
XL
2491impl Default for FnHeader {
2492 fn default() -> FnHeader {
2493 FnHeader {
74b04a01
XL
2494 unsafety: Unsafe::No,
2495 asyncness: Async::No,
2496 constness: Const::No,
60c5eb7d 2497 ext: Extern::None,
8faf50e0
XL
2498 }
2499 }
2500}
2501
2502#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7453a54e 2503pub enum ItemKind {
e1599b0c 2504 /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
c34b1796 2505 ///
0731742a 2506 /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
7453a54e 2507 ExternCrate(Option<Name>),
e1599b0c 2508 /// A use declaration item (`use`).
3157f602 2509 ///
0731742a 2510 /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
ff7c6d11 2511 Use(P<UseTree>),
e1599b0c 2512 /// A static item (`static`).
3157f602 2513 ///
0731742a 2514 /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
74b04a01 2515 Static(P<Ty>, Mutability, Option<P<Expr>>),
e1599b0c 2516 /// A constant item (`const`).
3157f602 2517 ///
0731742a 2518 /// E.g., `const FOO: i32 = 42;`.
74b04a01 2519 Const(Defaultness, P<Ty>, Option<P<Expr>>),
e1599b0c 2520 /// A function declaration (`fn`).
3157f602 2521 ///
0731742a 2522 /// E.g., `fn foo(bar: usize) -> usize { .. }`.
74b04a01 2523 Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
e1599b0c 2524 /// A module declaration (`mod`).
3157f602 2525 ///
0731742a 2526 /// E.g., `mod foo;` or `mod foo { .. }`.
7453a54e 2527 Mod(Mod),
e1599b0c 2528 /// An external module (`extern`).
3157f602 2529 ///
0731742a 2530 /// E.g., `extern {}` or `extern "C" {}`.
7453a54e 2531 ForeignMod(ForeignMod),
0731742a 2532 /// Module-level inline assembly (from `global_asm!()`).
cc61c64b 2533 GlobalAsm(P<GlobalAsm>),
e1599b0c 2534 /// A type alias (`type`).
3157f602 2535 ///
0731742a 2536 /// E.g., `type Foo = Bar<u8>;`.
74b04a01 2537 TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
e1599b0c 2538 /// An enum definition (`enum`).
3157f602 2539 ///
0731742a 2540 /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
7453a54e 2541 Enum(EnumDef, Generics),
e1599b0c 2542 /// A struct definition (`struct`).
3157f602 2543 ///
0731742a 2544 /// E.g., `struct Foo<A> { x: A }`.
7453a54e 2545 Struct(VariantData, Generics),
e1599b0c 2546 /// A union definition (`union`).
9e0c209e 2547 ///
0731742a 2548 /// E.g., `union Foo<A, B> { x: A, y: B }`.
9e0c209e 2549 Union(VariantData, Generics),
e1599b0c 2550 /// A trait declaration (`trait`).
3157f602 2551 ///
0731742a 2552 /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
74b04a01 2553 Trait(IsAuto, Unsafe, Generics, GenericBounds, Vec<P<AssocItem>>),
ff7c6d11
XL
2554 /// Trait alias
2555 ///
0731742a 2556 /// E.g., `trait Foo = Bar + Quux;`.
8faf50e0 2557 TraitAlias(Generics, GenericBounds),
3157f602
XL
2558 /// An implementation.
2559 ///
0731742a 2560 /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
dfeec247 2561 Impl {
74b04a01 2562 unsafety: Unsafe,
dfeec247
XL
2563 polarity: ImplPolarity,
2564 defaultness: Defaultness,
74b04a01 2565 constness: Const,
dfeec247
XL
2566 generics: Generics,
2567
2568 /// The trait being implemented, if any.
2569 of_trait: Option<TraitRef>,
2570
2571 self_ty: P<Ty>,
74b04a01 2572 items: Vec<P<AssocItem>>,
dfeec247 2573 },
8bb4bdeb 2574 /// A macro invocation.
3157f602 2575 ///
e1599b0c 2576 /// E.g., `foo!(..)`.
7453a54e 2577 Mac(Mac),
8bb4bdeb
XL
2578
2579 /// A macro definition.
7cac9316 2580 MacroDef(MacroDef),
1a4d82fc
JJ
2581}
2582
7453a54e 2583impl ItemKind {
74b04a01
XL
2584 pub fn article(&self) -> &str {
2585 use ItemKind::*;
2586 match self {
2587 Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
2588 | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..) => "a",
2589 ExternCrate(..) | ForeignMod(..) | Mac(..) | Enum(..) | Impl { .. } => "an",
2590 }
2591 }
2592
2593 pub fn descr(&self) -> &str {
2594 match self {
7453a54e 2595 ItemKind::ExternCrate(..) => "extern crate",
74b04a01 2596 ItemKind::Use(..) => "`use` import",
7453a54e
SL
2597 ItemKind::Static(..) => "static item",
2598 ItemKind::Const(..) => "constant item",
2599 ItemKind::Fn(..) => "function",
2600 ItemKind::Mod(..) => "module",
74b04a01
XL
2601 ItemKind::ForeignMod(..) => "extern block",
2602 ItemKind::GlobalAsm(..) => "global asm item",
416331ca 2603 ItemKind::TyAlias(..) => "type alias",
7453a54e
SL
2604 ItemKind::Enum(..) => "enum",
2605 ItemKind::Struct(..) => "struct",
9e0c209e 2606 ItemKind::Union(..) => "union",
7453a54e 2607 ItemKind::Trait(..) => "trait",
ff7c6d11 2608 ItemKind::TraitAlias(..) => "trait alias",
74b04a01
XL
2609 ItemKind::Mac(..) => "item macro invocation",
2610 ItemKind::MacroDef(..) => "macro definition",
2611 ItemKind::Impl { .. } => "implementation",
dfeec247
XL
2612 }
2613 }
2614
2615 pub fn generics(&self) -> Option<&Generics> {
2616 match self {
74b04a01
XL
2617 Self::Fn(_, _, generics, _)
2618 | Self::TyAlias(_, generics, ..)
dfeec247
XL
2619 | Self::Enum(_, generics)
2620 | Self::Struct(_, generics)
2621 | Self::Union(_, generics)
2622 | Self::Trait(_, _, generics, ..)
2623 | Self::TraitAlias(generics, _)
2624 | Self::Impl { generics, .. } => Some(generics),
2625 _ => None,
1a4d82fc 2626 }
970d7e83 2627 }
1a4d82fc 2628}
970d7e83 2629
74b04a01
XL
2630/// Represents associated items.
2631/// These include items in `impl` and `trait` definitions.
2632pub type AssocItem = Item<AssocItemKind>;
2633
2634/// Represents associated item kinds.
2635///
2636/// The term "provided" in the variants below refers to the item having a default
2637/// definition / body. Meanwhile, a "required" item lacks a definition / body.
2638/// In an implementation, all items must be provided.
2639/// The `Option`s below denote the bodies, where `Some(_)`
2640/// means "provided" and conversely `None` means "required".
2641#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
2642pub enum AssocItemKind {
2643 /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
2644 /// If `def` is parsed, then the constant is provided, and otherwise required.
2645 Const(Defaultness, P<Ty>, Option<P<Expr>>),
2646 /// An associated function.
2647 Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
2648 /// An associated type.
2649 TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
2650 /// A macro expanding to associated items.
2651 Macro(Mac),
2652}
2653
2654impl AssocItemKind {
2655 pub fn defaultness(&self) -> Defaultness {
2656 match *self {
2657 Self::Const(def, ..) | Self::Fn(def, ..) | Self::TyAlias(def, ..) => def,
2658 Self::Macro(..) => Defaultness::Final,
2659 }
2660 }
2661}
2662
2663impl From<AssocItemKind> for ItemKind {
2664 fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
2665 match assoc_item_kind {
2666 AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c),
2667 AssocItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d),
2668 AssocItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d),
2669 AssocItemKind::Macro(a) => ItemKind::Mac(a),
2670 }
2671 }
2672}
970d7e83 2673
74b04a01
XL
2674impl TryFrom<ItemKind> for AssocItemKind {
2675 type Error = ItemKind;
2676
2677 fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
2678 Ok(match item_kind {
2679 ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
2680 ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d),
2681 ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d),
2682 ItemKind::Mac(a) => AssocItemKind::Macro(a),
2683 _ => return Err(item_kind),
2684 })
2685 }
2686}
2687
2688/// An item in `extern` block.
8faf50e0 2689#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
7453a54e 2690pub enum ForeignItemKind {
74b04a01
XL
2691 /// A foreign static item (`static FOO: u8`).
2692 Static(P<Ty>, Mutability, Option<P<Expr>>),
0731742a 2693 /// A foreign function.
74b04a01 2694 Fn(Defaultness, FnSig, Generics, Option<P<Block>>),
0731742a 2695 /// A foreign type.
74b04a01
XL
2696 TyAlias(Defaultness, Generics, GenericBounds, Option<P<Ty>>),
2697 /// A macro expanding to foreign items.
83c7162d 2698 Macro(Mac),
1a4d82fc 2699}
970d7e83 2700
74b04a01
XL
2701impl From<ForeignItemKind> for ItemKind {
2702 fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
2703 match foreign_item_kind {
2704 ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c),
2705 ForeignItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d),
2706 ForeignItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d),
2707 ForeignItemKind::Macro(a) => ItemKind::Mac(a),
1a4d82fc 2708 }
223e47cc 2709 }
1a4d82fc 2710}
74b04a01
XL
2711
2712impl TryFrom<ItemKind> for ForeignItemKind {
2713 type Error = ItemKind;
2714
2715 fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
2716 Ok(match item_kind {
2717 ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
2718 ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d),
2719 ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d),
2720 ItemKind::Mac(a) => ForeignItemKind::Macro(a),
2721 _ => return Err(item_kind),
2722 })
2723 }
2724}
2725
2726pub type ForeignItem = Item<ForeignItemKind>;