rustc_ast/
ast.rs

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 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//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
17//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`]: Macro definition and invocation.
18//! - [`Attribute`]: Metadata associated with item.
19//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.
20
21use std::borrow::{Borrow, Cow};
22use std::{cmp, fmt};
23
24pub use GenericArgs::*;
25pub use UnsafeSource::*;
26pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
27use rustc_data_structures::packed::Pu128;
28use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
29use rustc_data_structures::stack::ensure_sufficient_stack;
30use rustc_data_structures::tagged_ptr::Tag;
31use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
32pub use rustc_span::AttrId;
33use rustc_span::source_map::{Spanned, respan};
34use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
35use thin_vec::{ThinVec, thin_vec};
36
37pub use crate::format::*;
38use crate::token::{self, CommentKind, Delimiter};
39use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
40use crate::util::parser::{ExprPrecedence, Fixity};
41use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};
42
43/// A "Label" is an identifier of some point in sources,
44/// e.g. in the following code:
45///
46/// ```rust
47/// 'outer: loop {
48///     break 'outer;
49/// }
50/// ```
51///
52/// `'outer` is a label.
53#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
54pub struct Label {
55    pub ident: Ident,
56}
57
58impl fmt::Debug for Label {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write!(f, "label({:?})", self.ident)
61    }
62}
63
64/// A "Lifetime" is an annotation of the scope in which variable
65/// can be used, e.g. `'a` in `&'a i32`.
66#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
67pub struct Lifetime {
68    pub id: NodeId,
69    pub ident: Ident,
70}
71
72impl fmt::Debug for Lifetime {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        write!(f, "lifetime({}: {})", self.id, self)
75    }
76}
77
78impl fmt::Display for Lifetime {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        write!(f, "{}", self.ident.name)
81    }
82}
83
84/// A "Path" is essentially Rust's notion of a name.
85///
86/// It's represented as a sequence of identifiers,
87/// along with a bunch of supporting information.
88///
89/// E.g., `std::cmp::PartialEq`.
90#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
91pub struct Path {
92    pub span: Span,
93    /// The segments in the path: the things separated by `::`.
94    /// Global paths begin with `kw::PathRoot`.
95    pub segments: ThinVec<PathSegment>,
96    pub tokens: Option<LazyAttrTokenStream>,
97}
98
99// Succeeds if the path has a single segment that is arg-free and matches the given symbol.
100impl PartialEq<Symbol> for Path {
101    #[inline]
102    fn eq(&self, name: &Symbol) -> bool {
103        if let [segment] = self.segments.as_ref()
104            && segment == name
105        {
106            true
107        } else {
108            false
109        }
110    }
111}
112
113// Succeeds if the path has segments that are arg-free and match the given symbols.
114impl PartialEq<&[Symbol]> for Path {
115    #[inline]
116    fn eq(&self, names: &&[Symbol]) -> bool {
117        self.segments.iter().eq(*names)
118    }
119}
120
121impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
122    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
123        self.segments.len().hash_stable(hcx, hasher);
124        for segment in &self.segments {
125            segment.ident.hash_stable(hcx, hasher);
126        }
127    }
128}
129
130impl Path {
131    /// Convert a span and an identifier to the corresponding
132    /// one-segment path.
133    pub fn from_ident(ident: Ident) -> Path {
134        Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
135    }
136
137    pub fn is_global(&self) -> bool {
138        self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
139    }
140
141    /// Check if this path is potentially a trivial const arg, i.e., one that can _potentially_
142    /// be represented without an anon const in the HIR.
143    ///
144    /// If `allow_mgca_arg` is true (as should be the case in most situations when
145    /// `#![feature(min_generic_const_args)]` is enabled), then this always returns true
146    /// because all paths are valid.
147    ///
148    /// Otherwise, it returns true iff the path has exactly one segment, and it has no generic args
149    /// (i.e., it is _potentially_ a const parameter).
150    #[tracing::instrument(level = "debug", ret)]
151    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
152        allow_mgca_arg
153            || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
154    }
155}
156
157/// Joins multiple symbols with "::" into a path, e.g. "a::b::c". If the first
158/// segment is `kw::PathRoot` it will be printed as empty, e.g. "::b::c".
159///
160/// The generics on the `path` argument mean it can accept many forms, such as:
161/// - `&[Symbol]`
162/// - `Vec<Symbol>`
163/// - `Vec<&Symbol>`
164/// - `impl Iterator<Item = Symbol>`
165/// - `impl Iterator<Item = &Symbol>`
166///
167/// Panics if `path` is empty or a segment after the first is `kw::PathRoot`.
168pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
169    // This is a guess at the needed capacity that works well in practice. It is slightly faster
170    // than (a) starting with an empty string, or (b) computing the exact capacity required.
171    // `8` works well because it's about the right size and jemalloc's size classes are all
172    // multiples of 8.
173    let mut iter = path.into_iter();
174    let len_hint = iter.size_hint().1.unwrap_or(1);
175    let mut s = String::with_capacity(len_hint * 8);
176
177    let first_sym = *iter.next().unwrap().borrow();
178    if first_sym != kw::PathRoot {
179        s.push_str(first_sym.as_str());
180    }
181    for sym in iter {
182        let sym = *sym.borrow();
183        debug_assert_ne!(sym, kw::PathRoot);
184        s.push_str("::");
185        s.push_str(sym.as_str());
186    }
187    s
188}
189
190/// Like `join_path_syms`, but for `Ident`s. This function is necessary because
191/// `Ident::to_string` does more than just print the symbol in the `name` field.
192pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
193    let mut iter = path.into_iter();
194    let len_hint = iter.size_hint().1.unwrap_or(1);
195    let mut s = String::with_capacity(len_hint * 8);
196
197    let first_ident = *iter.next().unwrap().borrow();
198    if first_ident.name != kw::PathRoot {
199        s.push_str(&first_ident.to_string());
200    }
201    for ident in iter {
202        let ident = *ident.borrow();
203        debug_assert_ne!(ident.name, kw::PathRoot);
204        s.push_str("::");
205        s.push_str(&ident.to_string());
206    }
207    s
208}
209
210/// A segment of a path: an identifier, an optional lifetime, and a set of types.
211///
212/// E.g., `std`, `String` or `Box<T>`.
213#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
214pub struct PathSegment {
215    /// The identifier portion of this path segment.
216    pub ident: Ident,
217
218    pub id: NodeId,
219
220    /// Type/lifetime parameters attached to this path. They come in
221    /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
222    /// `None` means that no parameter list is supplied (`Path`),
223    /// `Some` means that parameter list is supplied (`Path<X, Y>`)
224    /// but it can be empty (`Path<>`).
225    /// `P` is used as a size optimization for the common case with no parameters.
226    pub args: Option<Box<GenericArgs>>,
227}
228
229// Succeeds if the path segment is arg-free and matches the given symbol.
230impl PartialEq<Symbol> for PathSegment {
231    #[inline]
232    fn eq(&self, name: &Symbol) -> bool {
233        self.args.is_none() && self.ident.name == *name
234    }
235}
236
237impl PathSegment {
238    pub fn from_ident(ident: Ident) -> Self {
239        PathSegment { ident, id: DUMMY_NODE_ID, args: None }
240    }
241
242    pub fn path_root(span: Span) -> Self {
243        PathSegment::from_ident(Ident::new(kw::PathRoot, span))
244    }
245
246    pub fn span(&self) -> Span {
247        match &self.args {
248            Some(args) => self.ident.span.to(args.span()),
249            None => self.ident.span,
250        }
251    }
252}
253
254/// The generic arguments and associated item constraints of a path segment.
255///
256/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
257#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
258pub enum GenericArgs {
259    /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
260    AngleBracketed(AngleBracketedArgs),
261    /// The `(A, B)` and `C` in `Foo(A, B) -> C`.
262    Parenthesized(ParenthesizedArgs),
263    /// `(..)` in return type notation.
264    ParenthesizedElided(Span),
265}
266
267impl GenericArgs {
268    pub fn is_angle_bracketed(&self) -> bool {
269        matches!(self, AngleBracketed(..))
270    }
271
272    pub fn span(&self) -> Span {
273        match self {
274            AngleBracketed(data) => data.span,
275            Parenthesized(data) => data.span,
276            ParenthesizedElided(span) => *span,
277        }
278    }
279}
280
281/// Concrete argument in the sequence of generic args.
282#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
283pub enum GenericArg {
284    /// `'a` in `Foo<'a>`.
285    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
286    /// `Bar` in `Foo<Bar>`.
287    Type(Box<Ty>),
288    /// `1` in `Foo<1>`.
289    Const(AnonConst),
290}
291
292impl GenericArg {
293    pub fn span(&self) -> Span {
294        match self {
295            GenericArg::Lifetime(lt) => lt.ident.span,
296            GenericArg::Type(ty) => ty.span,
297            GenericArg::Const(ct) => ct.value.span,
298        }
299    }
300}
301
302/// A path like `Foo<'a, T>`.
303#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
304pub struct AngleBracketedArgs {
305    /// The overall span.
306    pub span: Span,
307    /// The comma separated parts in the `<...>`.
308    pub args: ThinVec<AngleBracketedArg>,
309}
310
311/// Either an argument for a generic parameter or a constraint on an associated item.
312#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
313pub enum AngleBracketedArg {
314    /// A generic argument for a generic parameter.
315    Arg(GenericArg),
316    /// A constraint on an associated item.
317    Constraint(AssocItemConstraint),
318}
319
320impl AngleBracketedArg {
321    pub fn span(&self) -> Span {
322        match self {
323            AngleBracketedArg::Arg(arg) => arg.span(),
324            AngleBracketedArg::Constraint(constraint) => constraint.span,
325        }
326    }
327}
328
329impl From<AngleBracketedArgs> for Box<GenericArgs> {
330    fn from(val: AngleBracketedArgs) -> Self {
331        Box::new(GenericArgs::AngleBracketed(val))
332    }
333}
334
335impl From<ParenthesizedArgs> for Box<GenericArgs> {
336    fn from(val: ParenthesizedArgs) -> Self {
337        Box::new(GenericArgs::Parenthesized(val))
338    }
339}
340
341/// A path like `Foo(A, B) -> C`.
342#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
343pub struct ParenthesizedArgs {
344    /// ```text
345    /// Foo(A, B) -> C
346    /// ^^^^^^^^^^^^^^
347    /// ```
348    pub span: Span,
349
350    /// `(A, B)`
351    pub inputs: ThinVec<Box<Ty>>,
352
353    /// ```text
354    /// Foo(A, B) -> C
355    ///    ^^^^^^
356    /// ```
357    pub inputs_span: Span,
358
359    /// `C`
360    pub output: FnRetTy,
361}
362
363impl ParenthesizedArgs {
364    pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
365        let args = self
366            .inputs
367            .iter()
368            .cloned()
369            .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
370            .collect();
371        AngleBracketedArgs { span: self.inputs_span, args }
372    }
373}
374
375pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
376
377/// Modifiers on a trait bound like `[const]`, `?` and `!`.
378#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
379pub struct TraitBoundModifiers {
380    pub constness: BoundConstness,
381    pub asyncness: BoundAsyncness,
382    pub polarity: BoundPolarity,
383}
384
385impl TraitBoundModifiers {
386    pub const NONE: Self = Self {
387        constness: BoundConstness::Never,
388        asyncness: BoundAsyncness::Normal,
389        polarity: BoundPolarity::Positive,
390    };
391}
392
393#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
394pub enum GenericBound {
395    Trait(PolyTraitRef),
396    Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
397    /// Precise capturing syntax: `impl Sized + use<'a>`
398    Use(ThinVec<PreciseCapturingArg>, Span),
399}
400
401impl GenericBound {
402    pub fn span(&self) -> Span {
403        match self {
404            GenericBound::Trait(t, ..) => t.span,
405            GenericBound::Outlives(l) => l.ident.span,
406            GenericBound::Use(_, span) => *span,
407        }
408    }
409}
410
411pub type GenericBounds = Vec<GenericBound>;
412
413/// Specifies the enforced ordering for generic parameters. In the future,
414/// if we wanted to relax this order, we could override `PartialEq` and
415/// `PartialOrd`, to allow the kinds to be unordered.
416#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
417pub enum ParamKindOrd {
418    Lifetime,
419    TypeOrConst,
420}
421
422impl fmt::Display for ParamKindOrd {
423    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424        match self {
425            ParamKindOrd::Lifetime => "lifetime".fmt(f),
426            ParamKindOrd::TypeOrConst => "type and const".fmt(f),
427        }
428    }
429}
430
431#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
432pub enum GenericParamKind {
433    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
434    Lifetime,
435    Type {
436        default: Option<Box<Ty>>,
437    },
438    Const {
439        ty: Box<Ty>,
440        /// Span of the whole parameter definition, including default.
441        span: Span,
442        /// Optional default value for the const generic param.
443        default: Option<AnonConst>,
444    },
445}
446
447#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
448pub struct GenericParam {
449    pub id: NodeId,
450    pub ident: Ident,
451    pub attrs: AttrVec,
452    #[visitable(extra = BoundKind::Bound)]
453    pub bounds: GenericBounds,
454    pub is_placeholder: bool,
455    pub kind: GenericParamKind,
456    pub colon_span: Option<Span>,
457}
458
459impl GenericParam {
460    pub fn span(&self) -> Span {
461        match &self.kind {
462            GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
463                self.ident.span
464            }
465            GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
466            GenericParamKind::Const { span, .. } => *span,
467        }
468    }
469}
470
471/// Represents lifetime, type and const parameters attached to a declaration of
472/// a function, enum, trait, etc.
473#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
474pub struct Generics {
475    pub params: ThinVec<GenericParam>,
476    pub where_clause: WhereClause,
477    pub span: Span,
478}
479
480/// A where-clause in a definition.
481#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
482pub struct WhereClause {
483    /// `true` if we ate a `where` token.
484    ///
485    /// This can happen if we parsed no predicates, e.g., `struct Foo where {}`.
486    /// This allows us to pretty-print accurately and provide correct suggestion diagnostics.
487    pub has_where_token: bool,
488    pub predicates: ThinVec<WherePredicate>,
489    pub span: Span,
490}
491
492impl WhereClause {
493    pub fn is_empty(&self) -> bool {
494        !self.has_where_token && self.predicates.is_empty()
495    }
496}
497
498/// A single predicate in a where-clause.
499#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
500pub struct WherePredicate {
501    pub attrs: AttrVec,
502    pub kind: WherePredicateKind,
503    pub id: NodeId,
504    pub span: Span,
505    pub is_placeholder: bool,
506}
507
508/// Predicate kind in where-clause.
509#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
510pub enum WherePredicateKind {
511    /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
512    BoundPredicate(WhereBoundPredicate),
513    /// A lifetime predicate (e.g., `'a: 'b + 'c`).
514    RegionPredicate(WhereRegionPredicate),
515    /// An equality predicate (unsupported).
516    EqPredicate(WhereEqPredicate),
517}
518
519/// A type bound.
520///
521/// E.g., `for<'c> Foo: Send + Clone + 'c`.
522#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
523pub struct WhereBoundPredicate {
524    /// Any generics from a `for` binding.
525    pub bound_generic_params: ThinVec<GenericParam>,
526    /// The type being bounded.
527    pub bounded_ty: Box<Ty>,
528    /// Trait and lifetime bounds (`Clone + Send + 'static`).
529    #[visitable(extra = BoundKind::Bound)]
530    pub bounds: GenericBounds,
531}
532
533/// A lifetime predicate.
534///
535/// E.g., `'a: 'b + 'c`.
536#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
537pub struct WhereRegionPredicate {
538    #[visitable(extra = LifetimeCtxt::Bound)]
539    pub lifetime: Lifetime,
540    #[visitable(extra = BoundKind::Bound)]
541    pub bounds: GenericBounds,
542}
543
544/// An equality predicate (unsupported).
545///
546/// E.g., `T = int`.
547#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
548pub struct WhereEqPredicate {
549    pub lhs_ty: Box<Ty>,
550    pub rhs_ty: Box<Ty>,
551}
552
553#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
554pub struct Crate {
555    /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
556    /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
557    pub id: NodeId,
558    pub attrs: AttrVec,
559    pub items: ThinVec<Box<Item>>,
560    pub spans: ModSpans,
561    pub is_placeholder: bool,
562}
563
564/// A semantic representation of a meta item. A meta item is a slightly
565/// restricted form of an attribute -- it can only contain expressions in
566/// certain leaf positions, rather than arbitrary token streams -- that is used
567/// for most built-in attributes.
568///
569/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
570#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
571pub struct MetaItem {
572    pub unsafety: Safety,
573    pub path: Path,
574    pub kind: MetaItemKind,
575    pub span: Span,
576}
577
578/// The meta item kind, containing the data after the initial path.
579#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
580pub enum MetaItemKind {
581    /// Word meta item.
582    ///
583    /// E.g., `#[test]`, which lacks any arguments after `test`.
584    Word,
585
586    /// List meta item.
587    ///
588    /// E.g., `#[derive(..)]`, where the field represents the `..`.
589    List(ThinVec<MetaItemInner>),
590
591    /// Name value meta item.
592    ///
593    /// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
594    NameValue(MetaItemLit),
595}
596
597/// Values inside meta item lists.
598///
599/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`.
600#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
601pub enum MetaItemInner {
602    /// A full MetaItem, for recursive meta items.
603    MetaItem(MetaItem),
604
605    /// A literal.
606    ///
607    /// E.g., `"foo"`, `64`, `true`.
608    Lit(MetaItemLit),
609}
610
611/// A block (`{ .. }`).
612///
613/// E.g., `{ .. }` as in `fn foo() { .. }`.
614#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
615pub struct Block {
616    /// The statements in the block.
617    pub stmts: ThinVec<Stmt>,
618    pub id: NodeId,
619    /// Distinguishes between `unsafe { ... }` and `{ ... }`.
620    pub rules: BlockCheckMode,
621    pub span: Span,
622    pub tokens: Option<LazyAttrTokenStream>,
623}
624
625/// A match pattern.
626///
627/// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
628#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
629pub struct Pat {
630    pub id: NodeId,
631    pub kind: PatKind,
632    pub span: Span,
633    pub tokens: Option<LazyAttrTokenStream>,
634}
635
636impl Pat {
637    /// Attempt reparsing the pattern as a type.
638    /// This is intended for use by diagnostics.
639    pub fn to_ty(&self) -> Option<Box<Ty>> {
640        let kind = match &self.kind {
641            PatKind::Missing => unreachable!(),
642            // In a type expression `_` is an inference variable.
643            PatKind::Wild => TyKind::Infer,
644            // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
645            PatKind::Ident(BindingMode::NONE, ident, None) => {
646                TyKind::Path(None, Path::from_ident(*ident))
647            }
648            PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
649            PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
650            // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
651            PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
652                Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }),
653                Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }),
654            })?,
655            // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
656            // when `P` can be reparsed as a type `T`.
657            PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
658                pat.to_ty().map(TyKind::Slice)?
659            }
660            // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
661            // assuming `T0` to `Tn` are all syntactically valid as types.
662            PatKind::Tuple(pats) => {
663                let mut tys = ThinVec::with_capacity(pats.len());
664                // FIXME(#48994) - could just be collected into an Option<Vec>
665                for pat in pats {
666                    tys.push(pat.to_ty()?);
667                }
668                TyKind::Tup(tys)
669            }
670            _ => return None,
671        };
672
673        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
674    }
675
676    /// Walk top-down and call `it` in each place where a pattern occurs
677    /// starting with the root pattern `walk` is called on. If `it` returns
678    /// false then we will descend no further but siblings will be processed.
679    pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
680        if !it(self) {
681            return;
682        }
683
684        match &self.kind {
685            // Walk into the pattern associated with `Ident` (if any).
686            PatKind::Ident(_, _, Some(p)) => p.walk(it),
687
688            // Walk into each field of struct.
689            PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
690
691            // Sequence of patterns.
692            PatKind::TupleStruct(_, _, s)
693            | PatKind::Tuple(s)
694            | PatKind::Slice(s)
695            | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
696
697            // Trivial wrappers over inner patterns.
698            PatKind::Box(s)
699            | PatKind::Deref(s)
700            | PatKind::Ref(s, _, _)
701            | PatKind::Paren(s)
702            | PatKind::Guard(s, _) => s.walk(it),
703
704            // These patterns do not contain subpatterns, skip.
705            PatKind::Missing
706            | PatKind::Wild
707            | PatKind::Rest
708            | PatKind::Never
709            | PatKind::Expr(_)
710            | PatKind::Range(..)
711            | PatKind::Ident(..)
712            | PatKind::Path(..)
713            | PatKind::MacCall(_)
714            | PatKind::Err(_) => {}
715        }
716    }
717
718    /// Strip off all reference patterns (`&`, `&mut`) and return the inner pattern.
719    pub fn peel_refs(&self) -> &Pat {
720        let mut current = self;
721        while let PatKind::Ref(inner, _, _) = &current.kind {
722            current = inner;
723        }
724        current
725    }
726
727    /// Is this a `..` pattern?
728    pub fn is_rest(&self) -> bool {
729        matches!(self.kind, PatKind::Rest)
730    }
731
732    /// Whether this could be a never pattern, taking into account that a macro invocation can
733    /// return a never pattern. Used to inform errors during parsing.
734    pub fn could_be_never_pattern(&self) -> bool {
735        let mut could_be_never_pattern = false;
736        self.walk(&mut |pat| match &pat.kind {
737            PatKind::Never | PatKind::MacCall(_) => {
738                could_be_never_pattern = true;
739                false
740            }
741            PatKind::Or(s) => {
742                could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
743                false
744            }
745            _ => true,
746        });
747        could_be_never_pattern
748    }
749
750    /// Whether this contains a `!` pattern. This in particular means that a feature gate error will
751    /// be raised if the feature is off. Used to avoid gating the feature twice.
752    pub fn contains_never_pattern(&self) -> bool {
753        let mut contains_never_pattern = false;
754        self.walk(&mut |pat| {
755            if matches!(pat.kind, PatKind::Never) {
756                contains_never_pattern = true;
757            }
758            true
759        });
760        contains_never_pattern
761    }
762
763    /// Return a name suitable for diagnostics.
764    pub fn descr(&self) -> Option<String> {
765        match &self.kind {
766            PatKind::Missing => unreachable!(),
767            PatKind::Wild => Some("_".to_string()),
768            PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
769            PatKind::Ref(pat, pinned, mutbl) => {
770                pat.descr().map(|d| format!("&{}{d}", pinned.prefix_str(*mutbl)))
771            }
772            _ => None,
773        }
774    }
775}
776
777impl From<Box<Pat>> for Pat {
778    fn from(value: Box<Pat>) -> Self {
779        *value
780    }
781}
782
783/// A single field in a struct pattern.
784///
785/// Patterns like the fields of `Foo { x, ref y, ref mut z }`
786/// are treated the same as `x: x, y: ref y, z: ref mut z`,
787/// except when `is_shorthand` is true.
788#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
789pub struct PatField {
790    /// The identifier for the field.
791    pub ident: Ident,
792    /// The pattern the field is destructured to.
793    pub pat: Box<Pat>,
794    pub is_shorthand: bool,
795    pub attrs: AttrVec,
796    pub id: NodeId,
797    pub span: Span,
798    pub is_placeholder: bool,
799}
800
801#[derive(Clone, Copy, Debug, Eq, PartialEq)]
802#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
803pub enum ByRef {
804    Yes(Pinnedness, Mutability),
805    No,
806}
807
808impl ByRef {
809    #[must_use]
810    pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
811        if let ByRef::Yes(_, old_mutbl) = &mut self {
812            *old_mutbl = cmp::min(*old_mutbl, mutbl);
813        }
814        self
815    }
816}
817
818/// The mode of a binding (`mut`, `ref mut`, etc).
819/// Used for both the explicit binding annotations given in the HIR for a binding
820/// and the final binding mode that we infer after type inference/match ergonomics.
821/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
822/// `.1` is the mutability of the binding.
823#[derive(Clone, Copy, Debug, Eq, PartialEq)]
824#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
825pub struct BindingMode(pub ByRef, pub Mutability);
826
827impl BindingMode {
828    pub const NONE: Self = Self(ByRef::No, Mutability::Not);
829    pub const REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Not);
830    pub const REF_PIN: Self =
831        Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Not);
832    pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
833    pub const REF_MUT: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Not);
834    pub const REF_PIN_MUT: Self =
835        Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Not);
836    pub const MUT_REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Mut);
837    pub const MUT_REF_PIN: Self =
838        Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Mut);
839    pub const MUT_REF_MUT: Self =
840        Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Mut);
841    pub const MUT_REF_PIN_MUT: Self =
842        Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Mut);
843
844    pub fn prefix_str(self) -> &'static str {
845        match self {
846            Self::NONE => "",
847            Self::REF => "ref ",
848            Self::REF_PIN => "ref pin const ",
849            Self::MUT => "mut ",
850            Self::REF_MUT => "ref mut ",
851            Self::REF_PIN_MUT => "ref pin mut ",
852            Self::MUT_REF => "mut ref ",
853            Self::MUT_REF_PIN => "mut ref pin ",
854            Self::MUT_REF_MUT => "mut ref mut ",
855            Self::MUT_REF_PIN_MUT => "mut ref pin mut ",
856        }
857    }
858}
859
860#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
861pub enum RangeEnd {
862    /// `..=` or `...`
863    Included(RangeSyntax),
864    /// `..`
865    Excluded,
866}
867
868#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
869pub enum RangeSyntax {
870    /// `...`
871    DotDotDot,
872    /// `..=`
873    DotDotEq,
874}
875
876/// All the different flavors of pattern that Rust recognizes.
877//
878// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
879#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
880pub enum PatKind {
881    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
882    Missing,
883
884    /// Represents a wildcard pattern (`_`).
885    Wild,
886
887    /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
888    /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
889    /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
890    /// during name resolution.
891    Ident(BindingMode, Ident, Option<Box<Pat>>),
892
893    /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
894    Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
895
896    /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
897    TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),
898
899    /// An or-pattern `A | B | C`.
900    /// Invariant: `pats.len() >= 2`.
901    Or(ThinVec<Pat>),
902
903    /// A possibly qualified path pattern.
904    /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
905    /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
906    /// only legally refer to associated constants.
907    Path(Option<Box<QSelf>>, Path),
908
909    /// A tuple pattern (`(a, b)`).
910    Tuple(ThinVec<Pat>),
911
912    /// A `box` pattern.
913    Box(Box<Pat>),
914
915    /// A `deref` pattern (currently `deref!()` macro-based syntax).
916    Deref(Box<Pat>),
917
918    /// A reference pattern (e.g., `&mut (a, b)`).
919    Ref(Box<Pat>, Pinnedness, Mutability),
920
921    /// A literal, const block or path.
922    Expr(Box<Expr>),
923
924    /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
925    Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),
926
927    /// A slice pattern `[a, b, c]`.
928    Slice(ThinVec<Pat>),
929
930    /// A rest pattern `..`.
931    ///
932    /// Syntactically it is valid anywhere.
933    ///
934    /// Semantically however, it only has meaning immediately inside:
935    /// - a slice pattern: `[a, .., b]`,
936    /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`,
937    /// - a tuple pattern: `(a, .., b)`,
938    /// - a tuple struct/variant pattern: `$path(a, .., b)`.
939    ///
940    /// In all of these cases, an additional restriction applies,
941    /// only one rest pattern may occur in the pattern sequences.
942    Rest,
943
944    // A never pattern `!`.
945    Never,
946
947    /// A guard pattern (e.g., `x if guard(x)`).
948    Guard(Box<Pat>, Box<Expr>),
949
950    /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
951    Paren(Box<Pat>),
952
953    /// A macro pattern; pre-expansion.
954    MacCall(Box<MacCall>),
955
956    /// Placeholder for a pattern that wasn't syntactically well formed in some way.
957    Err(ErrorGuaranteed),
958}
959
960/// Whether the `..` is present in a struct fields pattern.
961#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
962pub enum PatFieldsRest {
963    /// `module::StructName { field, ..}`
964    Rest(Span),
965    /// `module::StructName { field, syntax error }`
966    Recovered(ErrorGuaranteed),
967    /// `module::StructName { field }`
968    None,
969}
970
971/// The kind of borrow in an `AddrOf` expression,
972/// e.g., `&place` or `&raw const place`.
973#[derive(Clone, Copy, PartialEq, Eq, Debug)]
974#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
975pub enum BorrowKind {
976    /// A normal borrow, `&$expr` or `&mut $expr`.
977    /// The resulting type is either `&'a T` or `&'a mut T`
978    /// where `T = typeof($expr)` and `'a` is some lifetime.
979    Ref,
980    /// A raw borrow, `&raw const $expr` or `&raw mut $expr`.
981    /// The resulting type is either `*const T` or `*mut T`
982    /// where `T = typeof($expr)`.
983    Raw,
984    /// A pinned borrow, `&pin const $expr` or `&pin mut $expr`.
985    /// The resulting type is either `Pin<&'a T>` or `Pin<&'a mut T>`
986    /// where `T = typeof($expr)` and `'a` is some lifetime.
987    Pin,
988}
989
990#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
991pub enum BinOpKind {
992    /// The `+` operator (addition)
993    Add,
994    /// The `-` operator (subtraction)
995    Sub,
996    /// The `*` operator (multiplication)
997    Mul,
998    /// The `/` operator (division)
999    Div,
1000    /// The `%` operator (modulus)
1001    Rem,
1002    /// The `&&` operator (logical and)
1003    And,
1004    /// The `||` operator (logical or)
1005    Or,
1006    /// The `^` operator (bitwise xor)
1007    BitXor,
1008    /// The `&` operator (bitwise and)
1009    BitAnd,
1010    /// The `|` operator (bitwise or)
1011    BitOr,
1012    /// The `<<` operator (shift left)
1013    Shl,
1014    /// The `>>` operator (shift right)
1015    Shr,
1016    /// The `==` operator (equality)
1017    Eq,
1018    /// The `<` operator (less than)
1019    Lt,
1020    /// The `<=` operator (less than or equal to)
1021    Le,
1022    /// The `!=` operator (not equal to)
1023    Ne,
1024    /// The `>=` operator (greater than or equal to)
1025    Ge,
1026    /// The `>` operator (greater than)
1027    Gt,
1028}
1029
1030impl BinOpKind {
1031    pub fn as_str(&self) -> &'static str {
1032        use BinOpKind::*;
1033        match self {
1034            Add => "+",
1035            Sub => "-",
1036            Mul => "*",
1037            Div => "/",
1038            Rem => "%",
1039            And => "&&",
1040            Or => "||",
1041            BitXor => "^",
1042            BitAnd => "&",
1043            BitOr => "|",
1044            Shl => "<<",
1045            Shr => ">>",
1046            Eq => "==",
1047            Lt => "<",
1048            Le => "<=",
1049            Ne => "!=",
1050            Ge => ">=",
1051            Gt => ">",
1052        }
1053    }
1054
1055    pub fn is_lazy(&self) -> bool {
1056        matches!(self, BinOpKind::And | BinOpKind::Or)
1057    }
1058
1059    pub fn precedence(&self) -> ExprPrecedence {
1060        use BinOpKind::*;
1061        match *self {
1062            Mul | Div | Rem => ExprPrecedence::Product,
1063            Add | Sub => ExprPrecedence::Sum,
1064            Shl | Shr => ExprPrecedence::Shift,
1065            BitAnd => ExprPrecedence::BitAnd,
1066            BitXor => ExprPrecedence::BitXor,
1067            BitOr => ExprPrecedence::BitOr,
1068            Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
1069            And => ExprPrecedence::LAnd,
1070            Or => ExprPrecedence::LOr,
1071        }
1072    }
1073
1074    pub fn fixity(&self) -> Fixity {
1075        use BinOpKind::*;
1076        match self {
1077            Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
1078            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
1079                Fixity::Left
1080            }
1081        }
1082    }
1083
1084    pub fn is_comparison(self) -> bool {
1085        use BinOpKind::*;
1086        match self {
1087            Eq | Ne | Lt | Le | Gt | Ge => true,
1088            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
1089        }
1090    }
1091
1092    /// Returns `true` if the binary operator takes its arguments by value.
1093    pub fn is_by_value(self) -> bool {
1094        !self.is_comparison()
1095    }
1096}
1097
1098pub type BinOp = Spanned<BinOpKind>;
1099
1100// Sometimes `BinOpKind` and `AssignOpKind` need the same treatment. The
1101// operations covered by `AssignOpKind` are a subset of those covered by
1102// `BinOpKind`, so it makes sense to convert `AssignOpKind` to `BinOpKind`.
1103impl From<AssignOpKind> for BinOpKind {
1104    fn from(op: AssignOpKind) -> BinOpKind {
1105        match op {
1106            AssignOpKind::AddAssign => BinOpKind::Add,
1107            AssignOpKind::SubAssign => BinOpKind::Sub,
1108            AssignOpKind::MulAssign => BinOpKind::Mul,
1109            AssignOpKind::DivAssign => BinOpKind::Div,
1110            AssignOpKind::RemAssign => BinOpKind::Rem,
1111            AssignOpKind::BitXorAssign => BinOpKind::BitXor,
1112            AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
1113            AssignOpKind::BitOrAssign => BinOpKind::BitOr,
1114            AssignOpKind::ShlAssign => BinOpKind::Shl,
1115            AssignOpKind::ShrAssign => BinOpKind::Shr,
1116        }
1117    }
1118}
1119
1120#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1121pub enum AssignOpKind {
1122    /// The `+=` operator (addition)
1123    AddAssign,
1124    /// The `-=` operator (subtraction)
1125    SubAssign,
1126    /// The `*=` operator (multiplication)
1127    MulAssign,
1128    /// The `/=` operator (division)
1129    DivAssign,
1130    /// The `%=` operator (modulus)
1131    RemAssign,
1132    /// The `^=` operator (bitwise xor)
1133    BitXorAssign,
1134    /// The `&=` operator (bitwise and)
1135    BitAndAssign,
1136    /// The `|=` operator (bitwise or)
1137    BitOrAssign,
1138    /// The `<<=` operator (shift left)
1139    ShlAssign,
1140    /// The `>>=` operator (shift right)
1141    ShrAssign,
1142}
1143
1144impl AssignOpKind {
1145    pub fn as_str(&self) -> &'static str {
1146        use AssignOpKind::*;
1147        match self {
1148            AddAssign => "+=",
1149            SubAssign => "-=",
1150            MulAssign => "*=",
1151            DivAssign => "/=",
1152            RemAssign => "%=",
1153            BitXorAssign => "^=",
1154            BitAndAssign => "&=",
1155            BitOrAssign => "|=",
1156            ShlAssign => "<<=",
1157            ShrAssign => ">>=",
1158        }
1159    }
1160
1161    /// AssignOps are always by value.
1162    pub fn is_by_value(self) -> bool {
1163        true
1164    }
1165}
1166
1167pub type AssignOp = Spanned<AssignOpKind>;
1168
1169/// Unary operator.
1170///
1171/// Note that `&data` is not an operator, it's an `AddrOf` expression.
1172#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
1173pub enum UnOp {
1174    /// The `*` operator for dereferencing
1175    Deref,
1176    /// The `!` operator for logical inversion
1177    Not,
1178    /// The `-` operator for negation
1179    Neg,
1180}
1181
1182impl UnOp {
1183    pub fn as_str(&self) -> &'static str {
1184        match self {
1185            UnOp::Deref => "*",
1186            UnOp::Not => "!",
1187            UnOp::Neg => "-",
1188        }
1189    }
1190
1191    /// Returns `true` if the unary operator takes its argument by value.
1192    pub fn is_by_value(self) -> bool {
1193        matches!(self, Self::Neg | Self::Not)
1194    }
1195}
1196
1197/// A statement. No `attrs` or `tokens` fields because each `StmtKind` variant
1198/// contains an AST node with those fields. (Except for `StmtKind::Empty`,
1199/// which never has attrs or tokens)
1200#[derive(Clone, Encodable, Decodable, Debug)]
1201pub struct Stmt {
1202    pub id: NodeId,
1203    pub kind: StmtKind,
1204    pub span: Span,
1205}
1206
1207impl Stmt {
1208    pub fn has_trailing_semicolon(&self) -> bool {
1209        match &self.kind {
1210            StmtKind::Semi(_) => true,
1211            StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
1212            _ => false,
1213        }
1214    }
1215
1216    /// Converts a parsed `Stmt` to a `Stmt` with
1217    /// a trailing semicolon.
1218    ///
1219    /// This only modifies the parsed AST struct, not the attached
1220    /// `LazyAttrTokenStream`. The parser is responsible for calling
1221    /// `ToAttrTokenStream::add_trailing_semi` when there is actually
1222    /// a semicolon in the tokenstream.
1223    pub fn add_trailing_semicolon(mut self) -> Self {
1224        self.kind = match self.kind {
1225            StmtKind::Expr(expr) => StmtKind::Semi(expr),
1226            StmtKind::MacCall(mut mac) => {
1227                mac.style = MacStmtStyle::Semicolon;
1228                StmtKind::MacCall(mac)
1229            }
1230            kind => kind,
1231        };
1232
1233        self
1234    }
1235
1236    pub fn is_item(&self) -> bool {
1237        matches!(self.kind, StmtKind::Item(_))
1238    }
1239
1240    pub fn is_expr(&self) -> bool {
1241        matches!(self.kind, StmtKind::Expr(_))
1242    }
1243}
1244
1245// Adding a new variant? Please update `test_stmt` in `tests/ui/macros/stringify.rs`.
1246#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1247pub enum StmtKind {
1248    /// A local (let) binding.
1249    Let(Box<Local>),
1250    /// An item definition.
1251    Item(Box<Item>),
1252    /// Expr without trailing semi-colon.
1253    Expr(Box<Expr>),
1254    /// Expr with a trailing semi-colon.
1255    Semi(Box<Expr>),
1256    /// Just a trailing semi-colon.
1257    Empty,
1258    /// Macro.
1259    MacCall(Box<MacCallStmt>),
1260}
1261
1262#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1263pub struct MacCallStmt {
1264    pub mac: Box<MacCall>,
1265    pub style: MacStmtStyle,
1266    pub attrs: AttrVec,
1267    pub tokens: Option<LazyAttrTokenStream>,
1268}
1269
1270#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
1271pub enum MacStmtStyle {
1272    /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
1273    /// `foo!(...);`, `foo![...];`).
1274    Semicolon,
1275    /// The macro statement had braces (e.g., `foo! { ... }`).
1276    Braces,
1277    /// The macro statement had parentheses or brackets and no semicolon (e.g.,
1278    /// `foo!(...)`). All of these will end up being converted into macro
1279    /// expressions.
1280    NoBraces,
1281}
1282
1283/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
1284#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1285pub struct Local {
1286    pub id: NodeId,
1287    pub super_: Option<Span>,
1288    pub pat: Box<Pat>,
1289    pub ty: Option<Box<Ty>>,
1290    pub kind: LocalKind,
1291    pub span: Span,
1292    pub colon_sp: Option<Span>,
1293    pub attrs: AttrVec,
1294    pub tokens: Option<LazyAttrTokenStream>,
1295}
1296
1297#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1298pub enum LocalKind {
1299    /// Local declaration.
1300    /// Example: `let x;`
1301    Decl,
1302    /// Local declaration with an initializer.
1303    /// Example: `let x = y;`
1304    Init(Box<Expr>),
1305    /// Local declaration with an initializer and an `else` clause.
1306    /// Example: `let Some(x) = y else { return };`
1307    InitElse(Box<Expr>, Box<Block>),
1308}
1309
1310impl LocalKind {
1311    pub fn init(&self) -> Option<&Expr> {
1312        match self {
1313            Self::Decl => None,
1314            Self::Init(i) | Self::InitElse(i, _) => Some(i),
1315        }
1316    }
1317
1318    pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
1319        match self {
1320            Self::Decl => None,
1321            Self::Init(init) => Some((init, None)),
1322            Self::InitElse(init, els) => Some((init, Some(els))),
1323        }
1324    }
1325}
1326
1327/// An arm of a 'match'.
1328///
1329/// E.g., `0..=10 => { println!("match!") }` as in
1330///
1331/// ```
1332/// match 123 {
1333///     0..=10 => { println!("match!") },
1334///     _ => { println!("no match!") },
1335/// }
1336/// ```
1337#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1338pub struct Arm {
1339    pub attrs: AttrVec,
1340    /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`.
1341    pub pat: Box<Pat>,
1342    /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`.
1343    pub guard: Option<Box<Expr>>,
1344    /// Match arm body. Omitted if the pattern is a never pattern.
1345    pub body: Option<Box<Expr>>,
1346    pub span: Span,
1347    pub id: NodeId,
1348    pub is_placeholder: bool,
1349}
1350
1351/// A single field in a struct expression, e.g. `x: value` and `y` in `Foo { x: value, y }`.
1352#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1353pub struct ExprField {
1354    pub attrs: AttrVec,
1355    pub id: NodeId,
1356    pub span: Span,
1357    pub ident: Ident,
1358    pub expr: Box<Expr>,
1359    pub is_shorthand: bool,
1360    pub is_placeholder: bool,
1361}
1362
1363#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1364pub enum BlockCheckMode {
1365    Default,
1366    Unsafe(UnsafeSource),
1367}
1368
1369#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
1370pub enum UnsafeSource {
1371    CompilerGenerated,
1372    UserProvided,
1373}
1374
1375/// A constant (expression) that's not an item or associated item,
1376/// but needs its own `DefId` for type-checking, const-eval, etc.
1377/// These are usually found nested inside types (e.g., array lengths)
1378/// or expressions (e.g., repeat counts), and also used to define
1379/// explicit discriminant values for enum variants.
1380#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1381pub struct AnonConst {
1382    pub id: NodeId,
1383    pub value: Box<Expr>,
1384}
1385
1386/// An expression.
1387#[derive(Clone, Encodable, Decodable, Debug)]
1388pub struct Expr {
1389    pub id: NodeId,
1390    pub kind: ExprKind,
1391    pub span: Span,
1392    pub attrs: AttrVec,
1393    pub tokens: Option<LazyAttrTokenStream>,
1394}
1395
1396impl Expr {
1397    /// Check if this expression is potentially a trivial const arg, i.e., one that can _potentially_
1398    /// be represented without an anon const in the HIR.
1399    ///
1400    /// This will unwrap at most one block level (curly braces). After that, if the expression
1401    /// is a path, it mostly dispatches to [`Path::is_potential_trivial_const_arg`].
1402    /// See there for more info about `allow_mgca_arg`.
1403    ///
1404    /// The only additional thing to note is that when `allow_mgca_arg` is false, this function
1405    /// will only allow paths with no qself, before dispatching to the `Path` function of
1406    /// the same name.
1407    ///
1408    /// Does not ensure that the path resolves to a const param/item, the caller should check this.
1409    /// This also does not consider macros, so it's only correct after macro-expansion.
1410    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
1411        let this = self.maybe_unwrap_block();
1412        if allow_mgca_arg {
1413            matches!(this.kind, ExprKind::Path(..))
1414        } else {
1415            if let ExprKind::Path(None, path) = &this.kind
1416                && path.is_potential_trivial_const_arg(allow_mgca_arg)
1417            {
1418                true
1419            } else {
1420                false
1421            }
1422        }
1423    }
1424
1425    /// Returns an expression with (when possible) *one* outer brace removed
1426    pub fn maybe_unwrap_block(&self) -> &Expr {
1427        if let ExprKind::Block(block, None) = &self.kind
1428            && let [stmt] = block.stmts.as_slice()
1429            && let StmtKind::Expr(expr) = &stmt.kind
1430        {
1431            expr
1432        } else {
1433            self
1434        }
1435    }
1436
1437    /// Determines whether this expression is a macro call optionally wrapped in braces . If
1438    /// `already_stripped_block` is set then we do not attempt to peel off a layer of braces.
1439    ///
1440    /// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled
1441    /// either before, or part of, this function.
1442    pub fn optionally_braced_mac_call(
1443        &self,
1444        already_stripped_block: bool,
1445    ) -> Option<(bool, NodeId)> {
1446        match &self.kind {
1447            ExprKind::Block(block, None)
1448                if let [stmt] = &*block.stmts
1449                    && !already_stripped_block =>
1450            {
1451                match &stmt.kind {
1452                    StmtKind::MacCall(_) => Some((true, stmt.id)),
1453                    StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
1454                        Some((true, expr.id))
1455                    }
1456                    _ => None,
1457                }
1458            }
1459            ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
1460            _ => None,
1461        }
1462    }
1463
1464    pub fn to_bound(&self) -> Option<GenericBound> {
1465        match &self.kind {
1466            ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
1467                ThinVec::new(),
1468                path.clone(),
1469                TraitBoundModifiers::NONE,
1470                self.span,
1471                Parens::No,
1472            ))),
1473            _ => None,
1474        }
1475    }
1476
1477    pub fn peel_parens(&self) -> &Expr {
1478        let mut expr = self;
1479        while let ExprKind::Paren(inner) = &expr.kind {
1480            expr = inner;
1481        }
1482        expr
1483    }
1484
1485    pub fn peel_parens_and_refs(&self) -> &Expr {
1486        let mut expr = self;
1487        while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
1488        {
1489            expr = inner;
1490        }
1491        expr
1492    }
1493
1494    /// Attempts to reparse as `Ty` (for diagnostic purposes).
1495    pub fn to_ty(&self) -> Option<Box<Ty>> {
1496        let kind = match &self.kind {
1497            // Trivial conversions.
1498            ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
1499            ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
1500
1501            ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
1502
1503            ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1504                expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1505            }
1506
1507            ExprKind::Repeat(expr, expr_len) => {
1508                expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
1509            }
1510
1511            ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
1512                expr.to_ty().map(TyKind::Slice)?
1513            }
1514
1515            ExprKind::Tup(exprs) => {
1516                let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
1517                TyKind::Tup(tys)
1518            }
1519
1520            // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
1521            // then type of result is trait object.
1522            // Otherwise we don't assume the result type.
1523            ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
1524                if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
1525                    TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1526                } else {
1527                    return None;
1528                }
1529            }
1530
1531            ExprKind::Underscore => TyKind::Infer,
1532
1533            // This expression doesn't look like a type syntactically.
1534            _ => return None,
1535        };
1536
1537        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
1538    }
1539
1540    pub fn precedence(&self) -> ExprPrecedence {
1541        fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
1542            for attr in attrs {
1543                if let AttrStyle::Outer = attr.style {
1544                    return ExprPrecedence::Prefix;
1545                }
1546            }
1547            ExprPrecedence::Unambiguous
1548        }
1549
1550        match &self.kind {
1551            ExprKind::Closure(closure) => {
1552                match closure.fn_decl.output {
1553                    FnRetTy::Default(_) => ExprPrecedence::Jump,
1554                    FnRetTy::Ty(_) => prefix_attrs_precedence(&self.attrs),
1555                }
1556            }
1557
1558            ExprKind::Break(_ /*label*/, value)
1559            | ExprKind::Ret(value)
1560            | ExprKind::Yield(YieldKind::Prefix(value))
1561            | ExprKind::Yeet(value) => match value {
1562                Some(_) => ExprPrecedence::Jump,
1563                None => prefix_attrs_precedence(&self.attrs),
1564            },
1565
1566            ExprKind::Become(_) => ExprPrecedence::Jump,
1567
1568            // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
1569            // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
1570            // ensures that `pprust` will add parentheses in the right places to get the desired
1571            // parse.
1572            ExprKind::Range(..) => ExprPrecedence::Range,
1573
1574            // Binop-like expr kinds, handled by `AssocOp`.
1575            ExprKind::Binary(op, ..) => op.node.precedence(),
1576            ExprKind::Cast(..) => ExprPrecedence::Cast,
1577
1578            ExprKind::Assign(..) |
1579            ExprKind::AssignOp(..) => ExprPrecedence::Assign,
1580
1581            // Unary, prefix
1582            ExprKind::AddrOf(..)
1583            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
1584            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
1585            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
1586            // but we need to print `(let _ = a) < b` as-is with parens.
1587            | ExprKind::Let(..)
1588            | ExprKind::Unary(..) => ExprPrecedence::Prefix,
1589
1590            // Need parens if and only if there are prefix attributes.
1591            ExprKind::Array(_)
1592            | ExprKind::Await(..)
1593            | ExprKind::Use(..)
1594            | ExprKind::Block(..)
1595            | ExprKind::Call(..)
1596            | ExprKind::ConstBlock(_)
1597            | ExprKind::Continue(..)
1598            | ExprKind::Field(..)
1599            | ExprKind::ForLoop { .. }
1600            | ExprKind::FormatArgs(..)
1601            | ExprKind::Gen(..)
1602            | ExprKind::If(..)
1603            | ExprKind::IncludedBytes(..)
1604            | ExprKind::Index(..)
1605            | ExprKind::InlineAsm(..)
1606            | ExprKind::Lit(_)
1607            | ExprKind::Loop(..)
1608            | ExprKind::MacCall(..)
1609            | ExprKind::Match(..)
1610            | ExprKind::MethodCall(..)
1611            | ExprKind::OffsetOf(..)
1612            | ExprKind::Paren(..)
1613            | ExprKind::Path(..)
1614            | ExprKind::Repeat(..)
1615            | ExprKind::Struct(..)
1616            | ExprKind::Try(..)
1617            | ExprKind::TryBlock(..)
1618            | ExprKind::Tup(_)
1619            | ExprKind::Type(..)
1620            | ExprKind::Underscore
1621            | ExprKind::UnsafeBinderCast(..)
1622            | ExprKind::While(..)
1623            | ExprKind::Yield(YieldKind::Postfix(..))
1624            | ExprKind::Err(_)
1625            | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
1626        }
1627    }
1628
1629    /// To a first-order approximation, is this a pattern?
1630    pub fn is_approximately_pattern(&self) -> bool {
1631        matches!(
1632            &self.peel_parens().kind,
1633            ExprKind::Array(_)
1634                | ExprKind::Call(_, _)
1635                | ExprKind::Tup(_)
1636                | ExprKind::Lit(_)
1637                | ExprKind::Range(_, _, _)
1638                | ExprKind::Underscore
1639                | ExprKind::Path(_, _)
1640                | ExprKind::Struct(_)
1641        )
1642    }
1643
1644    /// Creates a dummy `Expr`.
1645    ///
1646    /// Should only be used when it will be replaced afterwards or as a return value when an error was encountered.
1647    pub fn dummy() -> Expr {
1648        Expr {
1649            id: DUMMY_NODE_ID,
1650            kind: ExprKind::Dummy,
1651            span: DUMMY_SP,
1652            attrs: ThinVec::new(),
1653            tokens: None,
1654        }
1655    }
1656}
1657
1658impl From<Box<Expr>> for Expr {
1659    fn from(value: Box<Expr>) -> Self {
1660        *value
1661    }
1662}
1663
1664#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1665pub struct Closure {
1666    pub binder: ClosureBinder,
1667    pub capture_clause: CaptureBy,
1668    pub constness: Const,
1669    pub coroutine_kind: Option<CoroutineKind>,
1670    pub movability: Movability,
1671    pub fn_decl: Box<FnDecl>,
1672    pub body: Box<Expr>,
1673    /// The span of the declaration block: 'move |...| -> ...'
1674    pub fn_decl_span: Span,
1675    /// The span of the argument block `|...|`
1676    pub fn_arg_span: Span,
1677}
1678
1679/// Limit types of a range (inclusive or exclusive).
1680#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
1681pub enum RangeLimits {
1682    /// Inclusive at the beginning, exclusive at the end.
1683    HalfOpen,
1684    /// Inclusive at the beginning and end.
1685    Closed,
1686}
1687
1688impl RangeLimits {
1689    pub fn as_str(&self) -> &'static str {
1690        match self {
1691            RangeLimits::HalfOpen => "..",
1692            RangeLimits::Closed => "..=",
1693        }
1694    }
1695}
1696
1697/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
1698#[derive(Clone, Encodable, Decodable, Debug)]
1699pub struct MethodCall {
1700    /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
1701    pub seg: PathSegment,
1702    /// The receiver, e.g. `x`.
1703    pub receiver: Box<Expr>,
1704    /// The arguments, e.g. `a, b, c`.
1705    pub args: ThinVec<Box<Expr>>,
1706    /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
1707    /// Baz>(a, b, c)`.
1708    pub span: Span,
1709}
1710
1711#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1712pub enum StructRest {
1713    /// `..x`.
1714    Base(Box<Expr>),
1715    /// `..`.
1716    Rest(Span),
1717    /// No trailing `..` or expression.
1718    None,
1719}
1720
1721#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1722pub struct StructExpr {
1723    pub qself: Option<Box<QSelf>>,
1724    pub path: Path,
1725    pub fields: ThinVec<ExprField>,
1726    pub rest: StructRest,
1727}
1728
1729// Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`.
1730#[derive(Clone, Encodable, Decodable, Debug)]
1731pub enum ExprKind {
1732    /// An array (e.g, `[a, b, c, d]`).
1733    Array(ThinVec<Box<Expr>>),
1734    /// Allow anonymous constants from an inline `const` block.
1735    ConstBlock(AnonConst),
1736    /// A function call.
1737    ///
1738    /// The first field resolves to the function itself,
1739    /// and the second field is the list of arguments.
1740    /// This also represents calling the constructor of
1741    /// tuple-like ADTs such as tuple structs and enum variants.
1742    Call(Box<Expr>, ThinVec<Box<Expr>>),
1743    /// A method call (e.g., `x.foo::<Bar, Baz>(a, b, c)`).
1744    MethodCall(Box<MethodCall>),
1745    /// A tuple (e.g., `(a, b, c, d)`).
1746    Tup(ThinVec<Box<Expr>>),
1747    /// A binary operation (e.g., `a + b`, `a * b`).
1748    Binary(BinOp, Box<Expr>, Box<Expr>),
1749    /// A unary operation (e.g., `!x`, `*x`).
1750    Unary(UnOp, Box<Expr>),
1751    /// A literal (e.g., `1`, `"foo"`).
1752    Lit(token::Lit),
1753    /// A cast (e.g., `foo as f64`).
1754    Cast(Box<Expr>, Box<Ty>),
1755    /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
1756    ///
1757    /// Usually not written directly in user code but
1758    /// indirectly via the macro `type_ascribe!(...)`.
1759    Type(Box<Expr>, Box<Ty>),
1760    /// A `let pat = expr` expression that is only semantically allowed in the condition
1761    /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
1762    ///
1763    /// `Span` represents the whole `let pat = expr` statement.
1764    Let(Box<Pat>, Box<Expr>, Span, Recovered),
1765    /// An `if` block, with an optional `else` block.
1766    ///
1767    /// `if expr { block } else { expr }`
1768    ///
1769    /// If present, the "else" expr is always `ExprKind::Block` (for `else`) or
1770    /// `ExprKind::If` (for `else if`).
1771    If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
1772    /// A while loop, with an optional label.
1773    ///
1774    /// `'label: while expr { block }`
1775    While(Box<Expr>, Box<Block>, Option<Label>),
1776    /// A `for` loop, with an optional label.
1777    ///
1778    /// `'label: for await? pat in iter { block }`
1779    ///
1780    /// This is desugared to a combination of `loop` and `match` expressions.
1781    ForLoop {
1782        pat: Box<Pat>,
1783        iter: Box<Expr>,
1784        body: Box<Block>,
1785        label: Option<Label>,
1786        kind: ForLoopKind,
1787    },
1788    /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
1789    ///
1790    /// `'label: loop { block }`
1791    Loop(Box<Block>, Option<Label>, Span),
1792    /// A `match` block.
1793    Match(Box<Expr>, ThinVec<Arm>, MatchKind),
1794    /// A closure (e.g., `move |a, b, c| a + b + c`).
1795    Closure(Box<Closure>),
1796    /// A block (`'label: { ... }`).
1797    Block(Box<Block>, Option<Label>),
1798    /// An `async` block (`async move { ... }`),
1799    /// or a `gen` block (`gen move { ... }`).
1800    ///
1801    /// The span is the "decl", which is the header before the body `{ }`
1802    /// including the `asyng`/`gen` keywords and possibly `move`.
1803    Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
1804    /// An await expression (`my_future.await`). Span is of await keyword.
1805    Await(Box<Expr>, Span),
1806    /// A use expression (`x.use`). Span is of use keyword.
1807    Use(Box<Expr>, Span),
1808
1809    /// A try block (`try { ... }`).
1810    TryBlock(Box<Block>),
1811
1812    /// An assignment (`a = foo()`).
1813    /// The `Span` argument is the span of the `=` token.
1814    Assign(Box<Expr>, Box<Expr>, Span),
1815    /// An assignment with an operator.
1816    ///
1817    /// E.g., `a += 1`.
1818    AssignOp(AssignOp, Box<Expr>, Box<Expr>),
1819    /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
1820    Field(Box<Expr>, Ident),
1821    /// An indexing operation (e.g., `foo[2]`).
1822    /// The span represents the span of the `[2]`, including brackets.
1823    Index(Box<Expr>, Box<Expr>, Span),
1824    /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
1825    Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
1826    /// An underscore, used in destructuring assignment to ignore a value.
1827    Underscore,
1828
1829    /// Variable reference, possibly containing `::` and/or type
1830    /// parameters (e.g., `foo::bar::<baz>`).
1831    ///
1832    /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
1833    Path(Option<Box<QSelf>>, Path),
1834
1835    /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
1836    AddrOf(BorrowKind, Mutability, Box<Expr>),
1837    /// A `break`, with an optional label to break, and an optional expression.
1838    Break(Option<Label>, Option<Box<Expr>>),
1839    /// A `continue`, with an optional label.
1840    Continue(Option<Label>),
1841    /// A `return`, with an optional value to be returned.
1842    Ret(Option<Box<Expr>>),
1843
1844    /// Output of the `asm!()` macro.
1845    InlineAsm(Box<InlineAsm>),
1846
1847    /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
1848    ///
1849    /// Usually not written directly in user code but
1850    /// indirectly via the macro `core::mem::offset_of!(...)`.
1851    OffsetOf(Box<Ty>, Vec<Ident>),
1852
1853    /// A macro invocation; pre-expansion.
1854    MacCall(Box<MacCall>),
1855
1856    /// A struct literal expression.
1857    ///
1858    /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
1859    Struct(Box<StructExpr>),
1860
1861    /// An array literal constructed from one repeated element.
1862    ///
1863    /// E.g., `[1; 5]`. The expression is the element to be
1864    /// repeated; the constant is the number of times to repeat it.
1865    Repeat(Box<Expr>, AnonConst),
1866
1867    /// No-op: used solely so we can pretty-print faithfully.
1868    Paren(Box<Expr>),
1869
1870    /// A try expression (`expr?`).
1871    Try(Box<Expr>),
1872
1873    /// A `yield`, with an optional value to be yielded.
1874    Yield(YieldKind),
1875
1876    /// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
1877    /// with an optional value to be returned.
1878    Yeet(Option<Box<Expr>>),
1879
1880    /// A tail call return, with the value to be returned.
1881    ///
1882    /// While `.0` must be a function call, we check this later, after parsing.
1883    Become(Box<Expr>),
1884
1885    /// Bytes included via `include_bytes!`
1886    ///
1887    /// Added for optimization purposes to avoid the need to escape
1888    /// large binary blobs - should always behave like [`ExprKind::Lit`]
1889    /// with a `ByteStr` literal.
1890    ///
1891    /// The value is stored as a `ByteSymbol`. It's unfortunate that we need to
1892    /// intern (hash) the bytes because they're likely to be large and unique.
1893    /// But it's necessary because this will eventually be lowered to
1894    /// `LitKind::ByteStr`, which needs a `ByteSymbol` to impl `Copy` and avoid
1895    /// arena allocation.
1896    IncludedBytes(ByteSymbol),
1897
1898    /// A `format_args!()` expression.
1899    FormatArgs(Box<FormatArgs>),
1900
1901    UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),
1902
1903    /// Placeholder for an expression that wasn't syntactically well formed in some way.
1904    Err(ErrorGuaranteed),
1905
1906    /// Acts as a null expression. Lowering it will always emit a bug.
1907    Dummy,
1908}
1909
1910/// Used to differentiate between `for` loops and `for await` loops.
1911#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1912pub enum ForLoopKind {
1913    For,
1914    ForAwait,
1915}
1916
1917/// Used to differentiate between `async {}` blocks and `gen {}` blocks.
1918#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
1919pub enum GenBlockKind {
1920    Async,
1921    Gen,
1922    AsyncGen,
1923}
1924
1925impl fmt::Display for GenBlockKind {
1926    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1927        self.modifier().fmt(f)
1928    }
1929}
1930
1931impl GenBlockKind {
1932    pub fn modifier(&self) -> &'static str {
1933        match self {
1934            GenBlockKind::Async => "async",
1935            GenBlockKind::Gen => "gen",
1936            GenBlockKind::AsyncGen => "async gen",
1937        }
1938    }
1939}
1940
1941/// Whether we're unwrapping or wrapping an unsafe binder
1942#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1943#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
1944pub enum UnsafeBinderCastKind {
1945    // e.g. `&i32` -> `unsafe<'a> &'a i32`
1946    Wrap,
1947    // e.g. `unsafe<'a> &'a i32` -> `&i32`
1948    Unwrap,
1949}
1950
1951/// The explicit `Self` type in a "qualified path". The actual
1952/// path, including the trait and the associated item, is stored
1953/// separately. `position` represents the index of the associated
1954/// item qualified with this `Self` type.
1955///
1956/// ```ignore (only-for-syntax-highlight)
1957/// <Vec<T> as a::b::Trait>::AssociatedItem
1958///  ^~~~~     ~~~~~~~~~~~~~~^
1959///  ty        position = 3
1960///
1961/// <Vec<T>>::AssociatedItem
1962///  ^~~~~    ^
1963///  ty       position = 0
1964/// ```
1965#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1966pub struct QSelf {
1967    pub ty: Box<Ty>,
1968
1969    /// The span of `a::b::Trait` in a path like `<Vec<T> as
1970    /// a::b::Trait>::AssociatedItem`; in the case where `position ==
1971    /// 0`, this is an empty span.
1972    pub path_span: Span,
1973    pub position: usize,
1974}
1975
1976/// A capture clause used in closures and `async` blocks.
1977#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
1978pub enum CaptureBy {
1979    /// `move |x| y + x`.
1980    Value {
1981        /// The span of the `move` keyword.
1982        move_kw: Span,
1983    },
1984    /// `move` or `use` keywords were not specified.
1985    Ref,
1986    /// `use |x| y + x`.
1987    ///
1988    /// Note that if you have a regular closure like `|| x.use`, this will *not* result
1989    /// in a `Use` capture. Instead, the `ExprUseVisitor` will look at the type
1990    /// of `x` and treat `x.use` as either a copy/clone/move as appropriate.
1991    Use {
1992        /// The span of the `use` keyword.
1993        use_kw: Span,
1994    },
1995}
1996
1997/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
1998#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
1999pub enum ClosureBinder {
2000    /// The binder is not present, all closure lifetimes are inferred.
2001    NotPresent,
2002    /// The binder is present.
2003    For {
2004        /// Span of the whole `for<>` clause
2005        ///
2006        /// ```text
2007        /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
2008        /// ^^^^^^^^^^^ -- this
2009        /// ```
2010        span: Span,
2011
2012        /// Lifetimes in the `for<>` closure
2013        ///
2014        /// ```text
2015        /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
2016        ///     ^^^^^^ -- this
2017        /// ```
2018        generic_params: ThinVec<GenericParam>,
2019    },
2020}
2021
2022/// Represents a macro invocation. The `path` indicates which macro
2023/// is being invoked, and the `args` are arguments passed to it.
2024#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2025pub struct MacCall {
2026    pub path: Path,
2027    pub args: Box<DelimArgs>,
2028}
2029
2030impl MacCall {
2031    pub fn span(&self) -> Span {
2032        self.path.span.to(self.args.dspan.entire())
2033    }
2034}
2035
2036/// Arguments passed to an attribute macro.
2037#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2038pub enum AttrArgs {
2039    /// No arguments: `#[attr]`.
2040    Empty,
2041    /// Delimited arguments: `#[attr()/[]/{}]`.
2042    Delimited(DelimArgs),
2043    /// Arguments of a key-value attribute: `#[attr = "value"]`.
2044    Eq {
2045        /// Span of the `=` token.
2046        eq_span: Span,
2047        expr: Box<Expr>,
2048    },
2049}
2050
2051impl AttrArgs {
2052    pub fn span(&self) -> Option<Span> {
2053        match self {
2054            AttrArgs::Empty => None,
2055            AttrArgs::Delimited(args) => Some(args.dspan.entire()),
2056            AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
2057        }
2058    }
2059
2060    /// Tokens inside the delimiters or after `=`.
2061    /// Proc macros see these tokens, for example.
2062    pub fn inner_tokens(&self) -> TokenStream {
2063        match self {
2064            AttrArgs::Empty => TokenStream::default(),
2065            AttrArgs::Delimited(args) => args.tokens.clone(),
2066            AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
2067        }
2068    }
2069}
2070
2071/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
2072#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2073pub struct DelimArgs {
2074    pub dspan: DelimSpan,
2075    pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
2076    pub tokens: TokenStream,
2077}
2078
2079impl DelimArgs {
2080    /// Whether a macro with these arguments needs a semicolon
2081    /// when used as a standalone item or statement.
2082    pub fn need_semicolon(&self) -> bool {
2083        !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
2084    }
2085}
2086
2087/// Represents a macro definition.
2088#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2089pub struct MacroDef {
2090    pub body: Box<DelimArgs>,
2091    /// `true` if macro was defined with `macro_rules`.
2092    pub macro_rules: bool,
2093}
2094
2095#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
2096#[derive(HashStable_Generic, Walkable)]
2097pub enum StrStyle {
2098    /// A regular string, like `"foo"`.
2099    Cooked,
2100    /// A raw string, like `r##"foo"##`.
2101    ///
2102    /// The value is the number of `#` symbols used.
2103    Raw(u8),
2104}
2105
2106/// The kind of match expression
2107#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
2108pub enum MatchKind {
2109    /// match expr { ... }
2110    Prefix,
2111    /// expr.match { ... }
2112    Postfix,
2113}
2114
2115/// The kind of yield expression
2116#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2117pub enum YieldKind {
2118    /// yield expr { ... }
2119    Prefix(Option<Box<Expr>>),
2120    /// expr.yield { ... }
2121    Postfix(Box<Expr>),
2122}
2123
2124impl YieldKind {
2125    /// Returns the expression inside the yield expression, if any.
2126    ///
2127    /// For postfix yields, this is guaranteed to be `Some`.
2128    pub const fn expr(&self) -> Option<&Box<Expr>> {
2129        match self {
2130            YieldKind::Prefix(expr) => expr.as_ref(),
2131            YieldKind::Postfix(expr) => Some(expr),
2132        }
2133    }
2134
2135    /// Returns a mutable reference to the expression being yielded, if any.
2136    pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
2137        match self {
2138            YieldKind::Prefix(expr) => expr.as_mut(),
2139            YieldKind::Postfix(expr) => Some(expr),
2140        }
2141    }
2142
2143    /// Returns true if both yields are prefix or both are postfix.
2144    pub const fn same_kind(&self, other: &Self) -> bool {
2145        match (self, other) {
2146            (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
2147            (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
2148            _ => false,
2149        }
2150    }
2151}
2152
2153/// A literal in a meta item.
2154#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
2155pub struct MetaItemLit {
2156    /// The original literal as written in the source code.
2157    pub symbol: Symbol,
2158    /// The original suffix as written in the source code.
2159    pub suffix: Option<Symbol>,
2160    /// The "semantic" representation of the literal lowered from the original tokens.
2161    /// Strings are unescaped, hexadecimal forms are eliminated, etc.
2162    pub kind: LitKind,
2163    pub span: Span,
2164}
2165
2166/// Similar to `MetaItemLit`, but restricted to string literals.
2167#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2168pub struct StrLit {
2169    /// The original literal as written in source code.
2170    pub symbol: Symbol,
2171    /// The original suffix as written in source code.
2172    pub suffix: Option<Symbol>,
2173    /// The semantic (unescaped) representation of the literal.
2174    pub symbol_unescaped: Symbol,
2175    pub style: StrStyle,
2176    pub span: Span,
2177}
2178
2179impl StrLit {
2180    pub fn as_token_lit(&self) -> token::Lit {
2181        let token_kind = match self.style {
2182            StrStyle::Cooked => token::Str,
2183            StrStyle::Raw(n) => token::StrRaw(n),
2184        };
2185        token::Lit::new(token_kind, self.symbol, self.suffix)
2186    }
2187}
2188
2189/// Type of the integer literal based on provided suffix.
2190#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2191#[derive(HashStable_Generic)]
2192pub enum LitIntType {
2193    /// e.g. `42_i32`.
2194    Signed(IntTy),
2195    /// e.g. `42_u32`.
2196    Unsigned(UintTy),
2197    /// e.g. `42`.
2198    Unsuffixed,
2199}
2200
2201/// Type of the float literal based on provided suffix.
2202#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
2203#[derive(HashStable_Generic)]
2204pub enum LitFloatType {
2205    /// A float literal with a suffix (`1f32` or `1E10f32`).
2206    Suffixed(FloatTy),
2207    /// A float literal without a suffix (`1.0 or 1.0E10`).
2208    Unsuffixed,
2209}
2210
2211/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
2212///
2213/// Note that the entire literal (including the suffix) is considered when
2214/// deciding the `LitKind`. This means that float literals like `1f32` are
2215/// classified by this type as `Float`. This is different to `token::LitKind`
2216/// which does *not* consider the suffix.
2217#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
2218pub enum LitKind {
2219    /// A string literal (`"foo"`). The symbol is unescaped, and so may differ
2220    /// from the original token's symbol.
2221    Str(Symbol, StrStyle),
2222    /// A byte string (`b"foo"`). The symbol is unescaped, and so may differ
2223    /// from the original token's symbol.
2224    ByteStr(ByteSymbol, StrStyle),
2225    /// A C String (`c"foo"`). Guaranteed to only have `\0` at the end. The
2226    /// symbol is unescaped, and so may differ from the original token's
2227    /// symbol.
2228    CStr(ByteSymbol, StrStyle),
2229    /// A byte char (`b'f'`).
2230    Byte(u8),
2231    /// A character literal (`'a'`).
2232    Char(char),
2233    /// An integer literal (`1`).
2234    Int(Pu128, LitIntType),
2235    /// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
2236    /// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
2237    /// and `Hash`.
2238    Float(Symbol, LitFloatType),
2239    /// A boolean literal (`true`, `false`).
2240    Bool(bool),
2241    /// Placeholder for a literal that wasn't well-formed in some way.
2242    Err(ErrorGuaranteed),
2243}
2244
2245impl LitKind {
2246    pub fn str(&self) -> Option<Symbol> {
2247        match *self {
2248            LitKind::Str(s, _) => Some(s),
2249            _ => None,
2250        }
2251    }
2252
2253    /// Returns `true` if this literal is a string.
2254    pub fn is_str(&self) -> bool {
2255        matches!(self, LitKind::Str(..))
2256    }
2257
2258    /// Returns `true` if this literal is byte literal string.
2259    pub fn is_bytestr(&self) -> bool {
2260        matches!(self, LitKind::ByteStr(..))
2261    }
2262
2263    /// Returns `true` if this is a numeric literal.
2264    pub fn is_numeric(&self) -> bool {
2265        matches!(self, LitKind::Int(..) | LitKind::Float(..))
2266    }
2267
2268    /// Returns `true` if this literal has no suffix.
2269    /// Note: this will return true for literals with prefixes such as raw strings and byte strings.
2270    pub fn is_unsuffixed(&self) -> bool {
2271        !self.is_suffixed()
2272    }
2273
2274    /// Returns `true` if this literal has a suffix.
2275    pub fn is_suffixed(&self) -> bool {
2276        match *self {
2277            // suffixed variants
2278            LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
2279            | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
2280            // unsuffixed variants
2281            LitKind::Str(..)
2282            | LitKind::ByteStr(..)
2283            | LitKind::CStr(..)
2284            | LitKind::Byte(..)
2285            | LitKind::Char(..)
2286            | LitKind::Int(_, LitIntType::Unsuffixed)
2287            | LitKind::Float(_, LitFloatType::Unsuffixed)
2288            | LitKind::Bool(..)
2289            | LitKind::Err(_) => false,
2290        }
2291    }
2292}
2293
2294// N.B., If you change this, you'll probably want to change the corresponding
2295// type structure in `middle/ty.rs` as well.
2296#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2297pub struct MutTy {
2298    pub ty: Box<Ty>,
2299    pub mutbl: Mutability,
2300}
2301
2302/// Represents a function's signature in a trait declaration,
2303/// trait implementation, or free function.
2304#[derive(Clone, Encodable, Decodable, Debug)]
2305pub struct FnSig {
2306    pub header: FnHeader,
2307    pub decl: Box<FnDecl>,
2308    pub span: Span,
2309}
2310
2311impl FnSig {
2312    /// Return a span encompassing the header, or where to insert it if empty.
2313    pub fn header_span(&self) -> Span {
2314        match self.header.ext {
2315            Extern::Implicit(span) | Extern::Explicit(_, span) => {
2316                return self.span.with_hi(span.hi());
2317            }
2318            Extern::None => {}
2319        }
2320
2321        match self.header.safety {
2322            Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2323            Safety::Default => {}
2324        };
2325
2326        if let Some(coroutine_kind) = self.header.coroutine_kind {
2327            return self.span.with_hi(coroutine_kind.span().hi());
2328        }
2329
2330        if let Const::Yes(span) = self.header.constness {
2331            return self.span.with_hi(span.hi());
2332        }
2333
2334        self.span.shrink_to_lo()
2335    }
2336
2337    /// The span of the header's safety, or where to insert it if empty.
2338    pub fn safety_span(&self) -> Span {
2339        match self.header.safety {
2340            Safety::Unsafe(span) | Safety::Safe(span) => span,
2341            Safety::Default => {
2342                // Insert after the `coroutine_kind` if available.
2343                if let Some(extern_span) = self.header.ext.span() {
2344                    return extern_span.shrink_to_lo();
2345                }
2346
2347                // Insert right at the front of the signature.
2348                self.header_span().shrink_to_hi()
2349            }
2350        }
2351    }
2352
2353    /// The span of the header's extern, or where to insert it if empty.
2354    pub fn extern_span(&self) -> Span {
2355        self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2356    }
2357}
2358
2359/// A constraint on an associated item.
2360///
2361/// ### Examples
2362///
2363/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
2364/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
2365/// * the `A: Bound` in `Trait<A: Bound>`
2366/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
2367/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
2368/// * the `f(..): Bound` in `Trait<f(..): Bound>` (feature `return_type_notation`)
2369#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2370pub struct AssocItemConstraint {
2371    pub id: NodeId,
2372    pub ident: Ident,
2373    pub gen_args: Option<GenericArgs>,
2374    pub kind: AssocItemConstraintKind,
2375    pub span: Span,
2376}
2377
2378#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2379pub enum Term {
2380    Ty(Box<Ty>),
2381    Const(AnonConst),
2382}
2383
2384impl From<Box<Ty>> for Term {
2385    fn from(v: Box<Ty>) -> Self {
2386        Term::Ty(v)
2387    }
2388}
2389
2390impl From<AnonConst> for Term {
2391    fn from(v: AnonConst) -> Self {
2392        Term::Const(v)
2393    }
2394}
2395
2396/// The kind of [associated item constraint][AssocItemConstraint].
2397#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2398pub enum AssocItemConstraintKind {
2399    /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
2400    ///
2401    /// Also known as an *associated item binding* (we *bind* an associated item to a term).
2402    ///
2403    /// Furthermore, associated type equality constraints can also be referred to as *associated type
2404    /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
2405    Equality { term: Term },
2406    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
2407    Bound {
2408        #[visitable(extra = BoundKind::Bound)]
2409        bounds: GenericBounds,
2410    },
2411}
2412
2413#[derive(Encodable, Decodable, Debug, Walkable)]
2414pub struct Ty {
2415    pub id: NodeId,
2416    pub kind: TyKind,
2417    pub span: Span,
2418    pub tokens: Option<LazyAttrTokenStream>,
2419}
2420
2421impl Clone for Ty {
2422    fn clone(&self) -> Self {
2423        ensure_sufficient_stack(|| Self {
2424            id: self.id,
2425            kind: self.kind.clone(),
2426            span: self.span,
2427            tokens: self.tokens.clone(),
2428        })
2429    }
2430}
2431
2432impl From<Box<Ty>> for Ty {
2433    fn from(value: Box<Ty>) -> Self {
2434        *value
2435    }
2436}
2437
2438impl Ty {
2439    pub fn peel_refs(&self) -> &Self {
2440        let mut final_ty = self;
2441        while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2442        {
2443            final_ty = ty;
2444        }
2445        final_ty
2446    }
2447
2448    pub fn is_maybe_parenthesised_infer(&self) -> bool {
2449        match &self.kind {
2450            TyKind::Infer => true,
2451            TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
2452            _ => false,
2453        }
2454    }
2455}
2456
2457#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2458pub struct FnPtrTy {
2459    pub safety: Safety,
2460    pub ext: Extern,
2461    pub generic_params: ThinVec<GenericParam>,
2462    pub decl: Box<FnDecl>,
2463    /// Span of the `[unsafe] [extern] fn(...) -> ...` part, i.e. everything
2464    /// after the generic params (if there are any, e.g. `for<'a>`).
2465    pub decl_span: Span,
2466}
2467
2468#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2469pub struct UnsafeBinderTy {
2470    pub generic_params: ThinVec<GenericParam>,
2471    pub inner_ty: Box<Ty>,
2472}
2473
2474/// The various kinds of type recognized by the compiler.
2475//
2476// Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
2477#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2478pub enum TyKind {
2479    /// A variable-length slice (`[T]`).
2480    Slice(Box<Ty>),
2481    /// A fixed length array (`[T; n]`).
2482    Array(Box<Ty>, AnonConst),
2483    /// A raw pointer (`*const T` or `*mut T`).
2484    Ptr(MutTy),
2485    /// A reference (`&'a T` or `&'a mut T`).
2486    Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2487    /// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
2488    ///
2489    /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
2490    PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2491    /// A function pointer type (e.g., `fn(usize) -> bool`).
2492    FnPtr(Box<FnPtrTy>),
2493    /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
2494    UnsafeBinder(Box<UnsafeBinderTy>),
2495    /// The never type (`!`).
2496    Never,
2497    /// A tuple (`(A, B, C, D,...)`).
2498    Tup(ThinVec<Box<Ty>>),
2499    /// A path (`module::module::...::Type`), optionally
2500    /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
2501    ///
2502    /// Type parameters are stored in the `Path` itself.
2503    Path(Option<Box<QSelf>>, Path),
2504    /// A trait object type `Bound1 + Bound2 + Bound3`
2505    /// where `Bound` is a trait or a lifetime.
2506    TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
2507    /// An `impl Bound1 + Bound2 + Bound3` type
2508    /// where `Bound` is a trait or a lifetime.
2509    ///
2510    /// The `NodeId` exists to prevent lowering from having to
2511    /// generate `NodeId`s on the fly, which would complicate
2512    /// the generation of opaque `type Foo = impl Trait` items significantly.
2513    ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
2514    /// No-op; kept solely so that we can pretty-print faithfully.
2515    Paren(Box<Ty>),
2516    /// This means the type should be inferred instead of it having been
2517    /// specified. This can appear anywhere in a type.
2518    Infer,
2519    /// Inferred type of a `self` or `&self` argument in a method.
2520    ImplicitSelf,
2521    /// A macro in the type position.
2522    MacCall(Box<MacCall>),
2523    /// Placeholder for a `va_list`.
2524    CVarArgs,
2525    /// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
2526    /// just as part of the type system.
2527    Pat(Box<Ty>, Box<TyPat>),
2528    /// Sometimes we need a dummy value when no error has occurred.
2529    Dummy,
2530    /// Placeholder for a kind that has failed to be defined.
2531    Err(ErrorGuaranteed),
2532}
2533
2534impl TyKind {
2535    pub fn is_implicit_self(&self) -> bool {
2536        matches!(self, TyKind::ImplicitSelf)
2537    }
2538
2539    pub fn is_unit(&self) -> bool {
2540        matches!(self, TyKind::Tup(tys) if tys.is_empty())
2541    }
2542
2543    pub fn is_simple_path(&self) -> Option<Symbol> {
2544        if let TyKind::Path(None, Path { segments, .. }) = &self
2545            && let [segment] = &segments[..]
2546            && segment.args.is_none()
2547        {
2548            Some(segment.ident.name)
2549        } else {
2550            None
2551        }
2552    }
2553
2554    /// Returns `true` if this type is considered a scalar primitive (e.g.,
2555    /// `i32`, `u8`, `bool`, etc).
2556    ///
2557    /// This check is based on **symbol equality** and does **not** remove any
2558    /// path prefixes or references. If a type alias or shadowing is present
2559    /// (e.g., `type i32 = CustomType;`), this method will still return `true`
2560    /// for `i32`, even though it may not refer to the primitive type.
2561    pub fn maybe_scalar(&self) -> bool {
2562        let Some(ty_sym) = self.is_simple_path() else {
2563            // unit type
2564            return self.is_unit();
2565        };
2566        matches!(
2567            ty_sym,
2568            sym::i8
2569                | sym::i16
2570                | sym::i32
2571                | sym::i64
2572                | sym::i128
2573                | sym::u8
2574                | sym::u16
2575                | sym::u32
2576                | sym::u64
2577                | sym::u128
2578                | sym::f16
2579                | sym::f32
2580                | sym::f64
2581                | sym::f128
2582                | sym::char
2583                | sym::bool
2584        )
2585    }
2586}
2587
2588/// A pattern type pattern.
2589#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2590pub struct TyPat {
2591    pub id: NodeId,
2592    pub kind: TyPatKind,
2593    pub span: Span,
2594    pub tokens: Option<LazyAttrTokenStream>,
2595}
2596
2597/// All the different flavors of pattern that Rust recognizes.
2598//
2599// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
2600#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2601pub enum TyPatKind {
2602    /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
2603    Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
2604
2605    /// A `!null` pattern for raw pointers.
2606    NotNull,
2607
2608    Or(ThinVec<TyPat>),
2609
2610    /// Placeholder for a pattern that wasn't syntactically well formed in some way.
2611    Err(ErrorGuaranteed),
2612}
2613
2614/// Syntax used to declare a trait object.
2615#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
2616#[repr(u8)]
2617pub enum TraitObjectSyntax {
2618    // SAFETY: When adding new variants make sure to update the `Tag` impl.
2619    Dyn = 0,
2620    None = 1,
2621}
2622
2623/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
2624/// it can be represented with a `u2`. We use `repr(u8)` to guarantee the
2625/// discriminants of the variants are no greater than `3`.
2626unsafe impl Tag for TraitObjectSyntax {
2627    const BITS: u32 = 2;
2628
2629    fn into_usize(self) -> usize {
2630        self as u8 as usize
2631    }
2632
2633    unsafe fn from_usize(tag: usize) -> Self {
2634        match tag {
2635            0 => TraitObjectSyntax::Dyn,
2636            1 => TraitObjectSyntax::None,
2637            _ => unreachable!(),
2638        }
2639    }
2640}
2641
2642#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2643pub enum PreciseCapturingArg {
2644    /// Lifetime parameter.
2645    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
2646    /// Type or const parameter.
2647    Arg(Path, NodeId),
2648}
2649
2650/// Inline assembly operand explicit register or register class.
2651///
2652/// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
2653#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
2654pub enum InlineAsmRegOrRegClass {
2655    Reg(Symbol),
2656    RegClass(Symbol),
2657}
2658
2659#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
2660pub struct InlineAsmOptions(u16);
2661bitflags::bitflags! {
2662    impl InlineAsmOptions: u16 {
2663        const PURE            = 1 << 0;
2664        const NOMEM           = 1 << 1;
2665        const READONLY        = 1 << 2;
2666        const PRESERVES_FLAGS = 1 << 3;
2667        const NORETURN        = 1 << 4;
2668        const NOSTACK         = 1 << 5;
2669        const ATT_SYNTAX      = 1 << 6;
2670        const RAW             = 1 << 7;
2671        const MAY_UNWIND      = 1 << 8;
2672    }
2673}
2674
2675impl InlineAsmOptions {
2676    pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2677
2678    pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2679    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2680
2681    pub fn human_readable_names(&self) -> Vec<&'static str> {
2682        let mut options = vec![];
2683
2684        if self.contains(InlineAsmOptions::PURE) {
2685            options.push("pure");
2686        }
2687        if self.contains(InlineAsmOptions::NOMEM) {
2688            options.push("nomem");
2689        }
2690        if self.contains(InlineAsmOptions::READONLY) {
2691            options.push("readonly");
2692        }
2693        if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
2694            options.push("preserves_flags");
2695        }
2696        if self.contains(InlineAsmOptions::NORETURN) {
2697            options.push("noreturn");
2698        }
2699        if self.contains(InlineAsmOptions::NOSTACK) {
2700            options.push("nostack");
2701        }
2702        if self.contains(InlineAsmOptions::ATT_SYNTAX) {
2703            options.push("att_syntax");
2704        }
2705        if self.contains(InlineAsmOptions::RAW) {
2706            options.push("raw");
2707        }
2708        if self.contains(InlineAsmOptions::MAY_UNWIND) {
2709            options.push("may_unwind");
2710        }
2711
2712        options
2713    }
2714}
2715
2716impl std::fmt::Debug for InlineAsmOptions {
2717    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2718        bitflags::parser::to_writer(self, f)
2719    }
2720}
2721
2722#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
2723pub enum InlineAsmTemplatePiece {
2724    String(Cow<'static, str>),
2725    Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
2726}
2727
2728impl fmt::Display for InlineAsmTemplatePiece {
2729    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2730        match self {
2731            Self::String(s) => {
2732                for c in s.chars() {
2733                    match c {
2734                        '{' => f.write_str("{{")?,
2735                        '}' => f.write_str("}}")?,
2736                        _ => c.fmt(f)?,
2737                    }
2738                }
2739                Ok(())
2740            }
2741            Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
2742                write!(f, "{{{operand_idx}:{modifier}}}")
2743            }
2744            Self::Placeholder { operand_idx, modifier: None, .. } => {
2745                write!(f, "{{{operand_idx}}}")
2746            }
2747        }
2748    }
2749}
2750
2751impl InlineAsmTemplatePiece {
2752    /// Rebuilds the asm template string from its pieces.
2753    pub fn to_string(s: &[Self]) -> String {
2754        use fmt::Write;
2755        let mut out = String::new();
2756        for p in s.iter() {
2757            let _ = write!(out, "{p}");
2758        }
2759        out
2760    }
2761}
2762
2763/// Inline assembly symbol operands get their own AST node that is somewhat
2764/// similar to `AnonConst`.
2765///
2766/// The main difference is that we specifically don't assign it `DefId` in
2767/// `DefCollector`. Instead this is deferred until AST lowering where we
2768/// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
2769/// depending on what the path resolves to.
2770#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2771pub struct InlineAsmSym {
2772    pub id: NodeId,
2773    pub qself: Option<Box<QSelf>>,
2774    pub path: Path,
2775}
2776
2777/// Inline assembly operand.
2778///
2779/// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
2780#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2781pub enum InlineAsmOperand {
2782    In {
2783        reg: InlineAsmRegOrRegClass,
2784        expr: Box<Expr>,
2785    },
2786    Out {
2787        reg: InlineAsmRegOrRegClass,
2788        late: bool,
2789        expr: Option<Box<Expr>>,
2790    },
2791    InOut {
2792        reg: InlineAsmRegOrRegClass,
2793        late: bool,
2794        expr: Box<Expr>,
2795    },
2796    SplitInOut {
2797        reg: InlineAsmRegOrRegClass,
2798        late: bool,
2799        in_expr: Box<Expr>,
2800        out_expr: Option<Box<Expr>>,
2801    },
2802    Const {
2803        anon_const: AnonConst,
2804    },
2805    Sym {
2806        sym: InlineAsmSym,
2807    },
2808    Label {
2809        block: Box<Block>,
2810    },
2811}
2812
2813impl InlineAsmOperand {
2814    pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
2815        match self {
2816            Self::In { reg, .. }
2817            | Self::Out { reg, .. }
2818            | Self::InOut { reg, .. }
2819            | Self::SplitInOut { reg, .. } => Some(reg),
2820            Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
2821        }
2822    }
2823}
2824
2825#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
2826pub enum AsmMacro {
2827    /// The `asm!` macro
2828    Asm,
2829    /// The `global_asm!` macro
2830    GlobalAsm,
2831    /// The `naked_asm!` macro
2832    NakedAsm,
2833}
2834
2835impl AsmMacro {
2836    pub const fn macro_name(self) -> &'static str {
2837        match self {
2838            AsmMacro::Asm => "asm",
2839            AsmMacro::GlobalAsm => "global_asm",
2840            AsmMacro::NakedAsm => "naked_asm",
2841        }
2842    }
2843
2844    pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
2845        match self {
2846            AsmMacro::Asm => true,
2847            AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
2848            AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
2849        }
2850    }
2851
2852    pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2853        match self {
2854            AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2855            AsmMacro::GlobalAsm => true,
2856            AsmMacro::NakedAsm => true,
2857        }
2858    }
2859}
2860
2861/// Inline assembly.
2862///
2863/// E.g., `asm!("NOP");`.
2864#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2865pub struct InlineAsm {
2866    pub asm_macro: AsmMacro,
2867    pub template: Vec<InlineAsmTemplatePiece>,
2868    pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
2869    pub operands: Vec<(InlineAsmOperand, Span)>,
2870    pub clobber_abis: Vec<(Symbol, Span)>,
2871    #[visitable(ignore)]
2872    pub options: InlineAsmOptions,
2873    pub line_spans: Vec<Span>,
2874}
2875
2876/// A parameter in a function header.
2877///
2878/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
2879#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2880pub struct Param {
2881    pub attrs: AttrVec,
2882    pub ty: Box<Ty>,
2883    pub pat: Box<Pat>,
2884    pub id: NodeId,
2885    pub span: Span,
2886    pub is_placeholder: bool,
2887}
2888
2889/// Alternative representation for `Arg`s describing `self` parameter of methods.
2890///
2891/// E.g., `&mut self` as in `fn foo(&mut self)`.
2892#[derive(Clone, Encodable, Decodable, Debug)]
2893pub enum SelfKind {
2894    /// `self`, `mut self`
2895    Value(Mutability),
2896    /// `&'lt self`, `&'lt mut self`
2897    Region(Option<Lifetime>, Mutability),
2898    /// `&'lt pin const self`, `&'lt pin mut self`
2899    Pinned(Option<Lifetime>, Mutability),
2900    /// `self: TYPE`, `mut self: TYPE`
2901    Explicit(Box<Ty>, Mutability),
2902}
2903
2904impl SelfKind {
2905    pub fn to_ref_suggestion(&self) -> String {
2906        match self {
2907            SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2908            SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2909            SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2910            SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2911            SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
2912                unreachable!("if we had an explicit self, we wouldn't be here")
2913            }
2914        }
2915    }
2916}
2917
2918pub type ExplicitSelf = Spanned<SelfKind>;
2919
2920impl Param {
2921    /// Attempts to cast parameter to `ExplicitSelf`.
2922    pub fn to_self(&self) -> Option<ExplicitSelf> {
2923        if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
2924            if ident.name == kw::SelfLower {
2925                return match self.ty.kind {
2926                    TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2927                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2928                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2929                    }
2930                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2931                        if ty.kind.is_implicit_self() =>
2932                    {
2933                        Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2934                    }
2935                    _ => Some(respan(
2936                        self.pat.span.to(self.ty.span),
2937                        SelfKind::Explicit(self.ty.clone(), mutbl),
2938                    )),
2939                };
2940            }
2941        }
2942        None
2943    }
2944
2945    /// Returns `true` if parameter is `self`.
2946    pub fn is_self(&self) -> bool {
2947        if let PatKind::Ident(_, ident, _) = self.pat.kind {
2948            ident.name == kw::SelfLower
2949        } else {
2950            false
2951        }
2952    }
2953
2954    /// Builds a `Param` object from `ExplicitSelf`.
2955    pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
2956        let span = eself.span.to(eself_ident.span);
2957        let infer_ty = Box::new(Ty {
2958            id: DUMMY_NODE_ID,
2959            kind: TyKind::ImplicitSelf,
2960            span: eself_ident.span,
2961            tokens: None,
2962        });
2963        let (mutbl, ty) = match eself.node {
2964            SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2965            SelfKind::Value(mutbl) => (mutbl, infer_ty),
2966            SelfKind::Region(lt, mutbl) => (
2967                Mutability::Not,
2968                Box::new(Ty {
2969                    id: DUMMY_NODE_ID,
2970                    kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
2971                    span,
2972                    tokens: None,
2973                }),
2974            ),
2975            SelfKind::Pinned(lt, mutbl) => (
2976                mutbl,
2977                Box::new(Ty {
2978                    id: DUMMY_NODE_ID,
2979                    kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2980                    span,
2981                    tokens: None,
2982                }),
2983            ),
2984        };
2985        Param {
2986            attrs,
2987            pat: Box::new(Pat {
2988                id: DUMMY_NODE_ID,
2989                kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
2990                span,
2991                tokens: None,
2992            }),
2993            span,
2994            ty,
2995            id: DUMMY_NODE_ID,
2996            is_placeholder: false,
2997        }
2998    }
2999}
3000
3001/// A signature (not the body) of a function declaration.
3002///
3003/// E.g., `fn foo(bar: baz)`.
3004///
3005/// Please note that it's different from `FnHeader` structure
3006/// which contains metadata about function safety, asyncness, constness and ABI.
3007#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3008pub struct FnDecl {
3009    pub inputs: ThinVec<Param>,
3010    pub output: FnRetTy,
3011}
3012
3013impl FnDecl {
3014    pub fn has_self(&self) -> bool {
3015        self.inputs.get(0).is_some_and(Param::is_self)
3016    }
3017    pub fn c_variadic(&self) -> bool {
3018        self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
3019    }
3020}
3021
3022/// Is the trait definition an auto trait?
3023#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3024pub enum IsAuto {
3025    Yes,
3026    No,
3027}
3028
3029/// Safety of items.
3030#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3031#[derive(HashStable_Generic, Walkable)]
3032pub enum Safety {
3033    /// `unsafe` an item is explicitly marked as `unsafe`.
3034    Unsafe(Span),
3035    /// `safe` an item is explicitly marked as `safe`.
3036    Safe(Span),
3037    /// Default means no value was provided, it will take a default value given the context in
3038    /// which is used.
3039    Default,
3040}
3041
3042/// Describes what kind of coroutine markers, if any, a function has.
3043///
3044/// Coroutine markers are things that cause the function to generate a coroutine, such as `async`,
3045/// which makes the function return `impl Future`, or `gen`, which makes the function return `impl
3046/// Iterator`.
3047#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
3048pub enum CoroutineKind {
3049    /// `async`, which returns an `impl Future`.
3050    Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3051    /// `gen`, which returns an `impl Iterator`.
3052    Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3053    /// `async gen`, which returns an `impl AsyncIterator`.
3054    AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
3055}
3056
3057impl CoroutineKind {
3058    pub fn span(self) -> Span {
3059        match self {
3060            CoroutineKind::Async { span, .. } => span,
3061            CoroutineKind::Gen { span, .. } => span,
3062            CoroutineKind::AsyncGen { span, .. } => span,
3063        }
3064    }
3065
3066    pub fn as_str(self) -> &'static str {
3067        match self {
3068            CoroutineKind::Async { .. } => "async",
3069            CoroutineKind::Gen { .. } => "gen",
3070            CoroutineKind::AsyncGen { .. } => "async gen",
3071        }
3072    }
3073
3074    pub fn closure_id(self) -> NodeId {
3075        match self {
3076            CoroutineKind::Async { closure_id, .. }
3077            | CoroutineKind::Gen { closure_id, .. }
3078            | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
3079        }
3080    }
3081
3082    /// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait`
3083    /// item.
3084    pub fn return_id(self) -> (NodeId, Span) {
3085        match self {
3086            CoroutineKind::Async { return_impl_trait_id, span, .. }
3087            | CoroutineKind::Gen { return_impl_trait_id, span, .. }
3088            | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
3089                (return_impl_trait_id, span)
3090            }
3091        }
3092    }
3093}
3094
3095#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
3096#[derive(HashStable_Generic, Walkable)]
3097pub enum Const {
3098    Yes(Span),
3099    No,
3100}
3101
3102/// Item defaultness.
3103/// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
3104#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
3105pub enum Defaultness {
3106    Default(Span),
3107    Final,
3108}
3109
3110#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
3111pub enum ImplPolarity {
3112    /// `impl Trait for Type`
3113    Positive,
3114    /// `impl !Trait for Type`
3115    Negative(Span),
3116}
3117
3118impl fmt::Debug for ImplPolarity {
3119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3120        match *self {
3121            ImplPolarity::Positive => "positive".fmt(f),
3122            ImplPolarity::Negative(_) => "negative".fmt(f),
3123        }
3124    }
3125}
3126
3127/// The polarity of a trait bound.
3128#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3129#[derive(HashStable_Generic, Walkable)]
3130pub enum BoundPolarity {
3131    /// `Type: Trait`
3132    Positive,
3133    /// `Type: !Trait`
3134    Negative(Span),
3135    /// `Type: ?Trait`
3136    Maybe(Span),
3137}
3138
3139impl BoundPolarity {
3140    pub fn as_str(self) -> &'static str {
3141        match self {
3142            Self::Positive => "",
3143            Self::Negative(_) => "!",
3144            Self::Maybe(_) => "?",
3145        }
3146    }
3147}
3148
3149/// The constness of a trait bound.
3150#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
3151#[derive(HashStable_Generic, Walkable)]
3152pub enum BoundConstness {
3153    /// `Type: Trait`
3154    Never,
3155    /// `Type: const Trait`
3156    Always(Span),
3157    /// `Type: [const] Trait`
3158    Maybe(Span),
3159}
3160
3161impl BoundConstness {
3162    pub fn as_str(self) -> &'static str {
3163        match self {
3164            Self::Never => "",
3165            Self::Always(_) => "const",
3166            Self::Maybe(_) => "[const]",
3167        }
3168    }
3169}
3170
3171/// The asyncness of a trait bound.
3172#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
3173#[derive(HashStable_Generic, Walkable)]
3174pub enum BoundAsyncness {
3175    /// `Type: Trait`
3176    Normal,
3177    /// `Type: async Trait`
3178    Async(Span),
3179}
3180
3181impl BoundAsyncness {
3182    pub fn as_str(self) -> &'static str {
3183        match self {
3184            Self::Normal => "",
3185            Self::Async(_) => "async",
3186        }
3187    }
3188}
3189
3190#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3191pub enum FnRetTy {
3192    /// Returns type is not specified.
3193    ///
3194    /// Functions default to `()` and closures default to inference.
3195    /// Span points to where return type would be inserted.
3196    Default(Span),
3197    /// Everything else.
3198    Ty(Box<Ty>),
3199}
3200
3201impl FnRetTy {
3202    pub fn span(&self) -> Span {
3203        match self {
3204            &FnRetTy::Default(span) => span,
3205            FnRetTy::Ty(ty) => ty.span,
3206        }
3207    }
3208}
3209
3210#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
3211pub enum Inline {
3212    Yes,
3213    No { had_parse_error: Result<(), ErrorGuaranteed> },
3214}
3215
3216/// Module item kind.
3217#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3218pub enum ModKind {
3219    /// Module with inlined definition `mod foo { ... }`,
3220    /// or with definition outlined to a separate file `mod foo;` and already loaded from it.
3221    /// The inner span is from the first token past `{` to the last token until `}`,
3222    /// or from the first to the last token in the loaded file.
3223    Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
3224    /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
3225    Unloaded,
3226}
3227
3228#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
3229pub struct ModSpans {
3230    /// `inner_span` covers the body of the module; for a file module, its the whole file.
3231    /// For an inline module, its the span inside the `{ ... }`, not including the curly braces.
3232    pub inner_span: Span,
3233    pub inject_use_span: Span,
3234}
3235
3236/// Foreign module declaration.
3237///
3238/// E.g., `extern { .. }` or `extern "C" { .. }`.
3239#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3240pub struct ForeignMod {
3241    /// Span of the `extern` keyword.
3242    pub extern_span: Span,
3243    /// `unsafe` keyword accepted syntactically for macro DSLs, but not
3244    /// semantically by Rust.
3245    pub safety: Safety,
3246    pub abi: Option<StrLit>,
3247    pub items: ThinVec<Box<ForeignItem>>,
3248}
3249
3250#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3251pub struct EnumDef {
3252    pub variants: ThinVec<Variant>,
3253}
3254
3255/// Enum variant.
3256#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3257pub struct Variant {
3258    /// Attributes of the variant.
3259    pub attrs: AttrVec,
3260    /// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
3261    pub id: NodeId,
3262    /// Span
3263    pub span: Span,
3264    /// The visibility of the variant. Syntactically accepted but not semantically.
3265    pub vis: Visibility,
3266    /// Name of the variant.
3267    pub ident: Ident,
3268
3269    /// Fields and constructor id of the variant.
3270    pub data: VariantData,
3271    /// Explicit discriminant, e.g., `Foo = 1`.
3272    pub disr_expr: Option<AnonConst>,
3273    /// Is a macro placeholder.
3274    pub is_placeholder: bool,
3275}
3276
3277/// Part of `use` item to the right of its prefix.
3278#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3279pub enum UseTreeKind {
3280    /// `use prefix` or `use prefix as rename`
3281    Simple(Option<Ident>),
3282    /// `use prefix::{...}`
3283    ///
3284    /// The span represents the braces of the nested group and all elements within:
3285    ///
3286    /// ```text
3287    /// use foo::{bar, baz};
3288    ///          ^^^^^^^^^^
3289    /// ```
3290    Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
3291    /// `use prefix::*`
3292    Glob,
3293}
3294
3295/// A tree of paths sharing common prefixes.
3296/// Used in `use` items both at top-level and inside of braces in import groups.
3297#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3298pub struct UseTree {
3299    pub prefix: Path,
3300    pub kind: UseTreeKind,
3301    pub span: Span,
3302}
3303
3304impl UseTree {
3305    pub fn ident(&self) -> Ident {
3306        match self.kind {
3307            UseTreeKind::Simple(Some(rename)) => rename,
3308            UseTreeKind::Simple(None) => {
3309                self.prefix.segments.last().expect("empty prefix in a simple import").ident
3310            }
3311            _ => panic!("`UseTree::ident` can only be used on a simple import"),
3312        }
3313    }
3314}
3315
3316/// Distinguishes between `Attribute`s that decorate items and Attributes that
3317/// are contained as statements within items. These two cases need to be
3318/// distinguished for pretty-printing.
3319#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
3320pub enum AttrStyle {
3321    Outer,
3322    Inner,
3323}
3324
3325/// A list of attributes.
3326pub type AttrVec = ThinVec<Attribute>;
3327
3328/// A syntax-level representation of an attribute.
3329#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3330pub struct Attribute {
3331    pub kind: AttrKind,
3332    pub id: AttrId,
3333    /// Denotes if the attribute decorates the following construct (outer)
3334    /// or the construct this attribute is contained within (inner).
3335    pub style: AttrStyle,
3336    pub span: Span,
3337}
3338
3339#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3340pub enum AttrKind {
3341    /// A normal attribute.
3342    Normal(Box<NormalAttr>),
3343
3344    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
3345    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
3346    /// variant (which is much less compact and thus more expensive).
3347    DocComment(CommentKind, Symbol),
3348}
3349
3350#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3351pub struct NormalAttr {
3352    pub item: AttrItem,
3353    // Tokens for the full attribute, e.g. `#[foo]`, `#![bar]`.
3354    pub tokens: Option<LazyAttrTokenStream>,
3355}
3356
3357impl NormalAttr {
3358    pub fn from_ident(ident: Ident) -> Self {
3359        Self {
3360            item: AttrItem {
3361                unsafety: Safety::Default,
3362                path: Path::from_ident(ident),
3363                args: AttrArgs::Empty,
3364                tokens: None,
3365            },
3366            tokens: None,
3367        }
3368    }
3369}
3370
3371#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3372pub struct AttrItem {
3373    pub unsafety: Safety,
3374    pub path: Path,
3375    pub args: AttrArgs,
3376    // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`.
3377    pub tokens: Option<LazyAttrTokenStream>,
3378}
3379
3380impl AttrItem {
3381    pub fn is_valid_for_outer_style(&self) -> bool {
3382        self.path == sym::cfg_attr
3383            || self.path == sym::cfg
3384            || self.path == sym::forbid
3385            || self.path == sym::warn
3386            || self.path == sym::allow
3387            || self.path == sym::deny
3388    }
3389}
3390
3391/// `TraitRef`s appear in impls.
3392///
3393/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
3394/// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
3395/// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
3396/// same as the impl's `NodeId`).
3397#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3398pub struct TraitRef {
3399    pub path: Path,
3400    pub ref_id: NodeId,
3401}
3402
3403/// Whether enclosing parentheses are present or not.
3404#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3405pub enum Parens {
3406    Yes,
3407    No,
3408}
3409
3410#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3411pub struct PolyTraitRef {
3412    /// The `'a` in `for<'a> Foo<&'a T>`.
3413    pub bound_generic_params: ThinVec<GenericParam>,
3414
3415    // Optional constness, asyncness, or polarity.
3416    pub modifiers: TraitBoundModifiers,
3417
3418    /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
3419    pub trait_ref: TraitRef,
3420
3421    pub span: Span,
3422
3423    /// When `Yes`, the first and last character of `span` are an opening
3424    /// and a closing paren respectively.
3425    pub parens: Parens,
3426}
3427
3428impl PolyTraitRef {
3429    pub fn new(
3430        generic_params: ThinVec<GenericParam>,
3431        path: Path,
3432        modifiers: TraitBoundModifiers,
3433        span: Span,
3434        parens: Parens,
3435    ) -> Self {
3436        PolyTraitRef {
3437            bound_generic_params: generic_params,
3438            modifiers,
3439            trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
3440            span,
3441            parens,
3442        }
3443    }
3444}
3445
3446#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3447pub struct Visibility {
3448    pub kind: VisibilityKind,
3449    pub span: Span,
3450    pub tokens: Option<LazyAttrTokenStream>,
3451}
3452
3453#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3454pub enum VisibilityKind {
3455    Public,
3456    Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
3457    Inherited,
3458}
3459
3460impl VisibilityKind {
3461    pub fn is_pub(&self) -> bool {
3462        matches!(self, VisibilityKind::Public)
3463    }
3464}
3465
3466/// Field definition in a struct, variant or union.
3467///
3468/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
3469#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3470pub struct FieldDef {
3471    pub attrs: AttrVec,
3472    pub id: NodeId,
3473    pub span: Span,
3474    pub vis: Visibility,
3475    pub safety: Safety,
3476    pub ident: Option<Ident>,
3477
3478    pub ty: Box<Ty>,
3479    pub default: Option<AnonConst>,
3480    pub is_placeholder: bool,
3481}
3482
3483/// Was parsing recovery performed?
3484#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
3485pub enum Recovered {
3486    No,
3487    Yes(ErrorGuaranteed),
3488}
3489
3490/// Fields and constructor ids of enum variants and structs.
3491#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3492pub enum VariantData {
3493    /// Struct variant.
3494    ///
3495    /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
3496    Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
3497    /// Tuple variant.
3498    ///
3499    /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
3500    Tuple(ThinVec<FieldDef>, NodeId),
3501    /// Unit variant.
3502    ///
3503    /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
3504    Unit(NodeId),
3505}
3506
3507impl VariantData {
3508    /// Return the fields of this variant.
3509    pub fn fields(&self) -> &[FieldDef] {
3510        match self {
3511            VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
3512            _ => &[],
3513        }
3514    }
3515
3516    /// Return the `NodeId` of this variant's constructor, if it has one.
3517    pub fn ctor_node_id(&self) -> Option<NodeId> {
3518        match *self {
3519            VariantData::Struct { .. } => None,
3520            VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
3521        }
3522    }
3523}
3524
3525/// An item definition.
3526#[derive(Clone, Encodable, Decodable, Debug)]
3527pub struct Item<K = ItemKind> {
3528    pub attrs: AttrVec,
3529    pub id: NodeId,
3530    pub span: Span,
3531    pub vis: Visibility,
3532
3533    pub kind: K,
3534
3535    /// Original tokens this item was parsed from. This isn't necessarily
3536    /// available for all items, although over time more and more items should
3537    /// have this be `Some`. Right now this is primarily used for procedural
3538    /// macros, notably custom attributes.
3539    ///
3540    /// Note that the tokens here do not include the outer attributes, but will
3541    /// include inner attributes.
3542    pub tokens: Option<LazyAttrTokenStream>,
3543}
3544
3545impl Item {
3546    /// Return the span that encompasses the attributes.
3547    pub fn span_with_attributes(&self) -> Span {
3548        self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
3549    }
3550
3551    pub fn opt_generics(&self) -> Option<&Generics> {
3552        match &self.kind {
3553            ItemKind::ExternCrate(..)
3554            | ItemKind::Use(_)
3555            | ItemKind::Mod(..)
3556            | ItemKind::ForeignMod(_)
3557            | ItemKind::GlobalAsm(_)
3558            | ItemKind::MacCall(_)
3559            | ItemKind::Delegation(_)
3560            | ItemKind::DelegationMac(_)
3561            | ItemKind::MacroDef(..) => None,
3562            ItemKind::Static(_) => None,
3563            ItemKind::Const(i) => Some(&i.generics),
3564            ItemKind::Fn(i) => Some(&i.generics),
3565            ItemKind::TyAlias(i) => Some(&i.generics),
3566            ItemKind::TraitAlias(i) => Some(&i.generics),
3567
3568            ItemKind::Enum(_, generics, _)
3569            | ItemKind::Struct(_, generics, _)
3570            | ItemKind::Union(_, generics, _) => Some(&generics),
3571            ItemKind::Trait(i) => Some(&i.generics),
3572            ItemKind::Impl(i) => Some(&i.generics),
3573        }
3574    }
3575}
3576
3577/// `extern` qualifier on a function item or function type.
3578#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3579pub enum Extern {
3580    /// No explicit extern keyword was used.
3581    ///
3582    /// E.g. `fn foo() {}`.
3583    None,
3584    /// An explicit extern keyword was used, but with implicit ABI.
3585    ///
3586    /// E.g. `extern fn foo() {}`.
3587    ///
3588    /// This is just `extern "C"` (see `rustc_abi::ExternAbi::FALLBACK`).
3589    Implicit(Span),
3590    /// An explicit extern keyword was used with an explicit ABI.
3591    ///
3592    /// E.g. `extern "C" fn foo() {}`.
3593    Explicit(StrLit, Span),
3594}
3595
3596impl Extern {
3597    pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
3598        match abi {
3599            Some(name) => Extern::Explicit(name, span),
3600            None => Extern::Implicit(span),
3601        }
3602    }
3603
3604    pub fn span(self) -> Option<Span> {
3605        match self {
3606            Extern::None => None,
3607            Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3608        }
3609    }
3610}
3611
3612/// A function header.
3613///
3614/// All the information between the visibility and the name of the function is
3615/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
3616#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
3617pub struct FnHeader {
3618    /// The `const` keyword, if any
3619    pub constness: Const,
3620    /// Whether this is `async`, `gen`, or nothing.
3621    pub coroutine_kind: Option<CoroutineKind>,
3622    /// Whether this is `unsafe`, or has a default safety.
3623    pub safety: Safety,
3624    /// The `extern` keyword and corresponding ABI string, if any.
3625    pub ext: Extern,
3626}
3627
3628impl FnHeader {
3629    /// Does this function header have any qualifiers or is it empty?
3630    pub fn has_qualifiers(&self) -> bool {
3631        let Self { safety, coroutine_kind, constness, ext } = self;
3632        matches!(safety, Safety::Unsafe(_))
3633            || coroutine_kind.is_some()
3634            || matches!(constness, Const::Yes(_))
3635            || !matches!(ext, Extern::None)
3636    }
3637}
3638
3639impl Default for FnHeader {
3640    fn default() -> FnHeader {
3641        FnHeader {
3642            safety: Safety::Default,
3643            coroutine_kind: None,
3644            constness: Const::No,
3645            ext: Extern::None,
3646        }
3647    }
3648}
3649
3650#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3651pub struct TraitAlias {
3652    pub constness: Const,
3653    pub ident: Ident,
3654    pub generics: Generics,
3655    #[visitable(extra = BoundKind::Bound)]
3656    pub bounds: GenericBounds,
3657}
3658
3659#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3660pub struct Trait {
3661    pub constness: Const,
3662    pub safety: Safety,
3663    pub is_auto: IsAuto,
3664    pub ident: Ident,
3665    pub generics: Generics,
3666    #[visitable(extra = BoundKind::SuperTraits)]
3667    pub bounds: GenericBounds,
3668    #[visitable(extra = AssocCtxt::Trait)]
3669    pub items: ThinVec<Box<AssocItem>>,
3670}
3671
3672#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3673pub struct TyAlias {
3674    pub defaultness: Defaultness,
3675    pub ident: Ident,
3676    pub generics: Generics,
3677    /// There are two locations for where clause on type aliases. This represents the second
3678    /// where clause, before the semicolon. The first where clause is stored inside `generics`.
3679    ///
3680    /// Take this example:
3681    /// ```ignore (only-for-syntax-highlight)
3682    /// trait Foo {
3683    ///   type Assoc<'a, 'b> where Self: 'a, Self: 'b;
3684    /// }
3685    /// impl Foo for () {
3686    ///   type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
3687    ///   //                 ^^^^^^^^^^^^^^ before where clause
3688    ///   //                                     ^^^^^^^^^^^^^^ after where clause
3689    /// }
3690    /// ```
3691    pub after_where_clause: WhereClause,
3692    #[visitable(extra = BoundKind::Bound)]
3693    pub bounds: GenericBounds,
3694    pub ty: Option<Box<Ty>>,
3695}
3696
3697#[derive(Clone, Encodable, Decodable, Debug)]
3698pub struct Impl {
3699    pub generics: Generics,
3700    pub constness: Const,
3701    pub of_trait: Option<Box<TraitImplHeader>>,
3702    pub self_ty: Box<Ty>,
3703    pub items: ThinVec<Box<AssocItem>>,
3704}
3705
3706#[derive(Clone, Encodable, Decodable, Debug)]
3707pub struct TraitImplHeader {
3708    pub defaultness: Defaultness,
3709    pub safety: Safety,
3710    pub polarity: ImplPolarity,
3711    pub trait_ref: TraitRef,
3712}
3713
3714#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
3715pub struct FnContract {
3716    /// Declarations of variables accessible both in the `requires` and
3717    /// `ensures` clauses.
3718    pub declarations: ThinVec<Stmt>,
3719    pub requires: Option<Box<Expr>>,
3720    pub ensures: Option<Box<Expr>>,
3721}
3722
3723#[derive(Clone, Encodable, Decodable, Debug)]
3724pub struct Fn {
3725    pub defaultness: Defaultness,
3726    pub ident: Ident,
3727    pub generics: Generics,
3728    pub sig: FnSig,
3729    pub contract: Option<Box<FnContract>>,
3730    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3731    pub body: Option<Box<Block>>,
3732}
3733
3734#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3735pub struct Delegation {
3736    /// Path resolution id.
3737    pub id: NodeId,
3738    pub qself: Option<Box<QSelf>>,
3739    pub path: Path,
3740    pub ident: Ident,
3741    pub rename: Option<Ident>,
3742    pub body: Option<Box<Block>>,
3743    /// The item was expanded from a glob delegation item.
3744    pub from_glob: bool,
3745}
3746
3747#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3748pub struct DelegationMac {
3749    pub qself: Option<Box<QSelf>>,
3750    pub prefix: Path,
3751    // Some for list delegation, and None for glob delegation.
3752    pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3753    pub body: Option<Box<Block>>,
3754}
3755
3756#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3757pub struct StaticItem {
3758    pub ident: Ident,
3759    pub ty: Box<Ty>,
3760    pub safety: Safety,
3761    pub mutability: Mutability,
3762    pub expr: Option<Box<Expr>>,
3763    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3764}
3765
3766#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3767pub struct ConstItem {
3768    pub defaultness: Defaultness,
3769    pub ident: Ident,
3770    pub generics: Generics,
3771    pub ty: Box<Ty>,
3772    pub rhs: Option<ConstItemRhs>,
3773    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
3774}
3775
3776#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3777pub enum ConstItemRhs {
3778    TypeConst(AnonConst),
3779    Body(Box<Expr>),
3780}
3781
3782impl ConstItemRhs {
3783    pub fn span(&self) -> Span {
3784        self.expr().span
3785    }
3786
3787    pub fn expr(&self) -> &Expr {
3788        match self {
3789            ConstItemRhs::TypeConst(anon_const) => &anon_const.value,
3790            ConstItemRhs::Body(expr) => expr,
3791        }
3792    }
3793}
3794
3795// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
3796#[derive(Clone, Encodable, Decodable, Debug)]
3797pub enum ItemKind {
3798    /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
3799    ///
3800    /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
3801    ExternCrate(Option<Symbol>, Ident),
3802    /// A use declaration item (`use`).
3803    ///
3804    /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
3805    Use(UseTree),
3806    /// A static item (`static`).
3807    ///
3808    /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
3809    Static(Box<StaticItem>),
3810    /// A constant item (`const`).
3811    ///
3812    /// E.g., `const FOO: i32 = 42;`.
3813    Const(Box<ConstItem>),
3814    /// A function declaration (`fn`).
3815    ///
3816    /// E.g., `fn foo(bar: usize) -> usize { .. }`.
3817    Fn(Box<Fn>),
3818    /// A module declaration (`mod`).
3819    ///
3820    /// E.g., `mod foo;` or `mod foo { .. }`.
3821    /// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
3822    /// semantically by Rust.
3823    Mod(Safety, Ident, ModKind),
3824    /// An external module (`extern`).
3825    ///
3826    /// E.g., `extern {}` or `extern "C" {}`.
3827    ForeignMod(ForeignMod),
3828    /// Module-level inline assembly (from `global_asm!()`).
3829    GlobalAsm(Box<InlineAsm>),
3830    /// A type alias (`type`).
3831    ///
3832    /// E.g., `type Foo = Bar<u8>;`.
3833    TyAlias(Box<TyAlias>),
3834    /// An enum definition (`enum`).
3835    ///
3836    /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
3837    Enum(Ident, Generics, EnumDef),
3838    /// A struct definition (`struct`).
3839    ///
3840    /// E.g., `struct Foo<A> { x: A }`.
3841    Struct(Ident, Generics, VariantData),
3842    /// A union definition (`union`).
3843    ///
3844    /// E.g., `union Foo<A, B> { x: A, y: B }`.
3845    Union(Ident, Generics, VariantData),
3846    /// A trait declaration (`trait`).
3847    ///
3848    /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
3849    Trait(Box<Trait>),
3850    /// Trait alias.
3851    ///
3852    /// E.g., `trait Foo = Bar + Quux;`.
3853    TraitAlias(Box<TraitAlias>),
3854    /// An implementation.
3855    ///
3856    /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
3857    Impl(Impl),
3858    /// A macro invocation.
3859    ///
3860    /// E.g., `foo!(..)`.
3861    MacCall(Box<MacCall>),
3862    /// A macro definition.
3863    MacroDef(Ident, MacroDef),
3864    /// A single delegation item (`reuse`).
3865    ///
3866    /// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
3867    Delegation(Box<Delegation>),
3868    /// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`).
3869    /// Treated similarly to a macro call and expanded early.
3870    DelegationMac(Box<DelegationMac>),
3871}
3872
3873impl ItemKind {
3874    pub fn ident(&self) -> Option<Ident> {
3875        match *self {
3876            ItemKind::ExternCrate(_, ident)
3877            | ItemKind::Static(box StaticItem { ident, .. })
3878            | ItemKind::Const(box ConstItem { ident, .. })
3879            | ItemKind::Fn(box Fn { ident, .. })
3880            | ItemKind::Mod(_, ident, _)
3881            | ItemKind::TyAlias(box TyAlias { ident, .. })
3882            | ItemKind::Enum(ident, ..)
3883            | ItemKind::Struct(ident, ..)
3884            | ItemKind::Union(ident, ..)
3885            | ItemKind::Trait(box Trait { ident, .. })
3886            | ItemKind::TraitAlias(box TraitAlias { ident, .. })
3887            | ItemKind::MacroDef(ident, _)
3888            | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3889
3890            ItemKind::Use(_)
3891            | ItemKind::ForeignMod(_)
3892            | ItemKind::GlobalAsm(_)
3893            | ItemKind::Impl(_)
3894            | ItemKind::MacCall(_)
3895            | ItemKind::DelegationMac(_) => None,
3896        }
3897    }
3898
3899    /// "a" or "an"
3900    pub fn article(&self) -> &'static str {
3901        use ItemKind::*;
3902        match self {
3903            Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
3904            | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
3905            | Delegation(..) | DelegationMac(..) => "a",
3906            ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3907        }
3908    }
3909
3910    pub fn descr(&self) -> &'static str {
3911        match self {
3912            ItemKind::ExternCrate(..) => "extern crate",
3913            ItemKind::Use(..) => "`use` import",
3914            ItemKind::Static(..) => "static item",
3915            ItemKind::Const(..) => "constant item",
3916            ItemKind::Fn(..) => "function",
3917            ItemKind::Mod(..) => "module",
3918            ItemKind::ForeignMod(..) => "extern block",
3919            ItemKind::GlobalAsm(..) => "global asm item",
3920            ItemKind::TyAlias(..) => "type alias",
3921            ItemKind::Enum(..) => "enum",
3922            ItemKind::Struct(..) => "struct",
3923            ItemKind::Union(..) => "union",
3924            ItemKind::Trait(..) => "trait",
3925            ItemKind::TraitAlias(..) => "trait alias",
3926            ItemKind::MacCall(..) => "item macro invocation",
3927            ItemKind::MacroDef(..) => "macro definition",
3928            ItemKind::Impl { .. } => "implementation",
3929            ItemKind::Delegation(..) => "delegated function",
3930            ItemKind::DelegationMac(..) => "delegation",
3931        }
3932    }
3933
3934    pub fn generics(&self) -> Option<&Generics> {
3935        match self {
3936            Self::Fn(box Fn { generics, .. })
3937            | Self::TyAlias(box TyAlias { generics, .. })
3938            | Self::Const(box ConstItem { generics, .. })
3939            | Self::Enum(_, generics, _)
3940            | Self::Struct(_, generics, _)
3941            | Self::Union(_, generics, _)
3942            | Self::Trait(box Trait { generics, .. })
3943            | Self::TraitAlias(box TraitAlias { generics, .. })
3944            | Self::Impl(Impl { generics, .. }) => Some(generics),
3945            _ => None,
3946        }
3947    }
3948}
3949
3950/// Represents associated items.
3951/// These include items in `impl` and `trait` definitions.
3952pub type AssocItem = Item<AssocItemKind>;
3953
3954/// Represents associated item kinds.
3955///
3956/// The term "provided" in the variants below refers to the item having a default
3957/// definition / body. Meanwhile, a "required" item lacks a definition / body.
3958/// In an implementation, all items must be provided.
3959/// The `Option`s below denote the bodies, where `Some(_)`
3960/// means "provided" and conversely `None` means "required".
3961#[derive(Clone, Encodable, Decodable, Debug)]
3962pub enum AssocItemKind {
3963    /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
3964    /// If `def` is parsed, then the constant is provided, and otherwise required.
3965    Const(Box<ConstItem>),
3966    /// An associated function.
3967    Fn(Box<Fn>),
3968    /// An associated type.
3969    Type(Box<TyAlias>),
3970    /// A macro expanding to associated items.
3971    MacCall(Box<MacCall>),
3972    /// An associated delegation item.
3973    Delegation(Box<Delegation>),
3974    /// An associated list or glob delegation item.
3975    DelegationMac(Box<DelegationMac>),
3976}
3977
3978impl AssocItemKind {
3979    pub fn ident(&self) -> Option<Ident> {
3980        match *self {
3981            AssocItemKind::Const(box ConstItem { ident, .. })
3982            | AssocItemKind::Fn(box Fn { ident, .. })
3983            | AssocItemKind::Type(box TyAlias { ident, .. })
3984            | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
3985
3986            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
3987        }
3988    }
3989
3990    pub fn defaultness(&self) -> Defaultness {
3991        match *self {
3992            Self::Const(box ConstItem { defaultness, .. })
3993            | Self::Fn(box Fn { defaultness, .. })
3994            | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
3995            Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
3996                Defaultness::Final
3997            }
3998        }
3999    }
4000}
4001
4002impl From<AssocItemKind> for ItemKind {
4003    fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
4004        match assoc_item_kind {
4005            AssocItemKind::Const(item) => ItemKind::Const(item),
4006            AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4007            AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4008            AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
4009            AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
4010            AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
4011        }
4012    }
4013}
4014
4015impl TryFrom<ItemKind> for AssocItemKind {
4016    type Error = ItemKind;
4017
4018    fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
4019        Ok(match item_kind {
4020            ItemKind::Const(item) => AssocItemKind::Const(item),
4021            ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
4022            ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
4023            ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
4024            ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
4025            ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
4026            _ => return Err(item_kind),
4027        })
4028    }
4029}
4030
4031/// An item in `extern` block.
4032#[derive(Clone, Encodable, Decodable, Debug)]
4033pub enum ForeignItemKind {
4034    /// A foreign static item (`static FOO: u8`).
4035    Static(Box<StaticItem>),
4036    /// A foreign function.
4037    Fn(Box<Fn>),
4038    /// A foreign type.
4039    TyAlias(Box<TyAlias>),
4040    /// A macro expanding to foreign items.
4041    MacCall(Box<MacCall>),
4042}
4043
4044impl ForeignItemKind {
4045    pub fn ident(&self) -> Option<Ident> {
4046        match *self {
4047            ForeignItemKind::Static(box StaticItem { ident, .. })
4048            | ForeignItemKind::Fn(box Fn { ident, .. })
4049            | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),
4050
4051            ForeignItemKind::MacCall(_) => None,
4052        }
4053    }
4054}
4055
4056impl From<ForeignItemKind> for ItemKind {
4057    fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
4058        match foreign_item_kind {
4059            ForeignItemKind::Static(box static_foreign_item) => {
4060                ItemKind::Static(Box::new(static_foreign_item))
4061            }
4062            ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
4063            ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
4064            ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
4065        }
4066    }
4067}
4068
4069impl TryFrom<ItemKind> for ForeignItemKind {
4070    type Error = ItemKind;
4071
4072    fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
4073        Ok(match item_kind {
4074            ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
4075            ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
4076            ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
4077            ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
4078            _ => return Err(item_kind),
4079        })
4080    }
4081}
4082
4083pub type ForeignItem = Item<ForeignItemKind>;
4084
4085// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
4086#[cfg(target_pointer_width = "64")]
4087mod size_asserts {
4088    use rustc_data_structures::static_assert_size;
4089
4090    use super::*;
4091    // tidy-alphabetical-start
4092    static_assert_size!(AssocItem, 80);
4093    static_assert_size!(AssocItemKind, 16);
4094    static_assert_size!(Attribute, 32);
4095    static_assert_size!(Block, 32);
4096    static_assert_size!(Expr, 72);
4097    static_assert_size!(ExprKind, 40);
4098    static_assert_size!(Fn, 184);
4099    static_assert_size!(ForeignItem, 80);
4100    static_assert_size!(ForeignItemKind, 16);
4101    static_assert_size!(GenericArg, 24);
4102    static_assert_size!(GenericBound, 88);
4103    static_assert_size!(Generics, 40);
4104    static_assert_size!(Impl, 80);
4105    static_assert_size!(Item, 152);
4106    static_assert_size!(ItemKind, 88);
4107    static_assert_size!(LitKind, 24);
4108    static_assert_size!(Local, 96);
4109    static_assert_size!(MetaItemLit, 40);
4110    static_assert_size!(Param, 40);
4111    static_assert_size!(Pat, 80);
4112    static_assert_size!(PatKind, 56);
4113    static_assert_size!(Path, 24);
4114    static_assert_size!(PathSegment, 24);
4115    static_assert_size!(Stmt, 32);
4116    static_assert_size!(StmtKind, 16);
4117    static_assert_size!(TraitImplHeader, 72);
4118    static_assert_size!(Ty, 64);
4119    static_assert_size!(TyKind, 40);
4120    // tidy-alphabetical-end
4121}