rustc_middle/
thir.rs

1//! THIR datatypes and definitions. See the [rustc dev guide] for more info.
2//!
3//! If you compare the THIR [`ExprKind`] to [`hir::ExprKind`], you will see it is
4//! a good bit simpler. In fact, a number of the more straight-forward
5//! MIR simplifications are already done in the lowering to THIR. For
6//! example, method calls and overloaded operators are absent: they are
7//! expected to be converted into [`ExprKind::Call`] instances.
8//!
9//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
10
11use std::cmp::Ordering;
12use std::fmt;
13use std::ops::Index;
14use std::sync::Arc;
15
16use rustc_abi::{FieldIdx, Integer, Size, VariantIdx};
17use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
18use rustc_hir as hir;
19use rustc_hir::def_id::DefId;
20use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
21use rustc_index::{IndexVec, newtype_index};
22use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
23use rustc_span::def_id::LocalDefId;
24use rustc_span::{ErrorGuaranteed, Span, Symbol};
25use rustc_target::asm::InlineAsmRegOrRegClass;
26use tracing::instrument;
27
28use crate::middle::region;
29use crate::mir::interpret::AllocId;
30use crate::mir::{self, AssignOp, BinOp, BorrowKind, FakeReadCause, UnOp};
31use crate::thir::visit::for_each_immediate_subpat;
32use crate::ty::adjustment::PointerCoercion;
33use crate::ty::layout::IntegerExt;
34use crate::ty::{
35    self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, List, Ty,
36    TyCtxt, UpvarArgs,
37};
38
39pub mod visit;
40
41macro_rules! thir_with_elements {
42    (
43        $($name:ident: $id:ty => $value:ty => $format:literal,)*
44    ) => {
45        $(
46            newtype_index! {
47                #[derive(HashStable)]
48                #[debug_format = $format]
49                pub struct $id {}
50            }
51        )*
52
53        // Note: Making `Thir` implement `Clone` is useful for external tools that need access to
54        // THIR bodies even after the `Steal` query result has been stolen.
55        // One such tool is https://github.com/rust-corpus/qrates/.
56        /// A container for a THIR body.
57        ///
58        /// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
59        #[derive(Debug, HashStable, Clone)]
60        pub struct Thir<'tcx> {
61            pub body_type: BodyTy<'tcx>,
62            $(
63                pub $name: IndexVec<$id, $value>,
64            )*
65        }
66
67        impl<'tcx> Thir<'tcx> {
68            pub fn new(body_type: BodyTy<'tcx>) -> Thir<'tcx> {
69                Thir {
70                    body_type,
71                    $(
72                        $name: IndexVec::new(),
73                    )*
74                }
75            }
76        }
77
78        $(
79            impl<'tcx> Index<$id> for Thir<'tcx> {
80                type Output = $value;
81                fn index(&self, index: $id) -> &Self::Output {
82                    &self.$name[index]
83                }
84            }
85        )*
86    }
87}
88
89thir_with_elements! {
90    arms: ArmId => Arm<'tcx> => "a{}",
91    blocks: BlockId => Block => "b{}",
92    exprs: ExprId => Expr<'tcx> => "e{}",
93    stmts: StmtId => Stmt<'tcx> => "s{}",
94    params: ParamId => Param<'tcx> => "p{}",
95}
96
97#[derive(Debug, HashStable, Clone)]
98pub enum BodyTy<'tcx> {
99    Const(Ty<'tcx>),
100    Fn(FnSig<'tcx>),
101    GlobalAsm(Ty<'tcx>),
102}
103
104/// Description of a type-checked function parameter.
105#[derive(Clone, Debug, HashStable)]
106pub struct Param<'tcx> {
107    /// The pattern that appears in the parameter list, or None for implicit parameters.
108    pub pat: Option<Box<Pat<'tcx>>>,
109    /// The possibly inferred type.
110    pub ty: Ty<'tcx>,
111    /// Span of the explicitly provided type, or None if inferred for closures.
112    pub ty_span: Option<Span>,
113    /// Whether this param is `self`, and how it is bound.
114    pub self_kind: Option<hir::ImplicitSelfKind>,
115    /// HirId for lints.
116    pub hir_id: Option<HirId>,
117}
118
119#[derive(Copy, Clone, Debug, HashStable)]
120pub enum LintLevel {
121    Inherited,
122    Explicit(HirId),
123}
124
125#[derive(Clone, Debug, HashStable)]
126pub struct Block {
127    /// Whether the block itself has a label. Used by `label: {}`
128    /// and `try` blocks.
129    ///
130    /// This does *not* include labels on loops, e.g. `'label: loop {}`.
131    pub targeted_by_break: bool,
132    pub region_scope: region::Scope,
133    /// The span of the block, including the opening braces,
134    /// the label, and the `unsafe` keyword, if present.
135    pub span: Span,
136    /// The statements in the blocK.
137    pub stmts: Box<[StmtId]>,
138    /// The trailing expression of the block, if any.
139    pub expr: Option<ExprId>,
140    pub safety_mode: BlockSafety,
141}
142
143type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
144
145#[derive(Clone, Debug, HashStable)]
146pub struct AdtExpr<'tcx> {
147    /// The ADT we're constructing.
148    pub adt_def: AdtDef<'tcx>,
149    /// The variant of the ADT.
150    pub variant_index: VariantIdx,
151    pub args: GenericArgsRef<'tcx>,
152
153    /// Optional user-given args: for something like `let x =
154    /// Bar::<T> { ... }`.
155    pub user_ty: UserTy<'tcx>,
156
157    pub fields: Box<[FieldExpr]>,
158    /// The base, e.g. `Foo {x: 1, ..base}`.
159    pub base: AdtExprBase<'tcx>,
160}
161
162#[derive(Clone, Debug, HashStable)]
163pub enum AdtExprBase<'tcx> {
164    /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
165    None,
166    /// A struct expression with a "base", an expression of the same type as the outer struct that
167    /// will be used to populate any fields not explicitly mentioned: `Foo { ..base }`
168    Base(FruInfo<'tcx>),
169    /// A struct expression with a `..` tail but no "base" expression. The values from the struct
170    /// fields' default values will be used to populate any fields not explicitly mentioned:
171    /// `Foo { .. }`.
172    DefaultFields(Box<[Ty<'tcx>]>),
173}
174
175#[derive(Clone, Debug, HashStable)]
176pub struct ClosureExpr<'tcx> {
177    pub closure_id: LocalDefId,
178    pub args: UpvarArgs<'tcx>,
179    pub upvars: Box<[ExprId]>,
180    pub movability: Option<hir::Movability>,
181    pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
182}
183
184#[derive(Clone, Debug, HashStable)]
185pub struct InlineAsmExpr<'tcx> {
186    pub asm_macro: AsmMacro,
187    pub template: &'tcx [InlineAsmTemplatePiece],
188    pub operands: Box<[InlineAsmOperand<'tcx>]>,
189    pub options: InlineAsmOptions,
190    pub line_spans: &'tcx [Span],
191}
192
193#[derive(Copy, Clone, Debug, HashStable)]
194pub enum BlockSafety {
195    Safe,
196    /// A compiler-generated unsafe block
197    BuiltinUnsafe,
198    /// An `unsafe` block. The `HirId` is the ID of the block.
199    ExplicitUnsafe(HirId),
200}
201
202#[derive(Clone, Debug, HashStable)]
203pub struct Stmt<'tcx> {
204    pub kind: StmtKind<'tcx>,
205}
206
207#[derive(Clone, Debug, HashStable)]
208pub enum StmtKind<'tcx> {
209    /// An expression with a trailing semicolon.
210    Expr {
211        /// The scope for this statement; may be used as lifetime of temporaries.
212        scope: region::Scope,
213
214        /// The expression being evaluated in this statement.
215        expr: ExprId,
216    },
217
218    /// A `let` binding.
219    Let {
220        /// The scope for variables bound in this `let`; it covers this and
221        /// all the remaining statements in the block.
222        remainder_scope: region::Scope,
223
224        /// The scope for the initialization itself; might be used as
225        /// lifetime of temporaries.
226        init_scope: region::Scope,
227
228        /// `let <PAT> = ...`
229        ///
230        /// If a type annotation is included, it is added as an ascription pattern.
231        pattern: Box<Pat<'tcx>>,
232
233        /// `let pat: ty = <INIT>`
234        initializer: Option<ExprId>,
235
236        /// `let pat: ty = <INIT> else { <ELSE> }`
237        else_block: Option<BlockId>,
238
239        /// The lint level for this `let` statement.
240        lint_level: LintLevel,
241
242        /// Span of the `let <PAT> = <INIT>` part.
243        span: Span,
244    },
245}
246
247#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
248pub struct LocalVarId(pub HirId);
249
250/// A THIR expression.
251#[derive(Clone, Debug, HashStable)]
252pub struct Expr<'tcx> {
253    /// kind of expression
254    pub kind: ExprKind<'tcx>,
255
256    /// The type of this expression
257    pub ty: Ty<'tcx>,
258
259    /// The lifetime of this expression if it should be spilled into a
260    /// temporary
261    pub temp_lifetime: TempLifetime,
262
263    /// span of the expression in the source
264    pub span: Span,
265}
266
267/// Temporary lifetime information for THIR expressions
268#[derive(Clone, Copy, Debug, HashStable)]
269pub struct TempLifetime {
270    /// Lifetime for temporaries as expected.
271    /// This should be `None` in a constant context.
272    pub temp_lifetime: Option<region::Scope>,
273    /// If `Some(lt)`, indicates that the lifetime of this temporary will change to `lt` in a future edition.
274    /// If `None`, then no changes are expected, or lints are disabled.
275    pub backwards_incompatible: Option<region::Scope>,
276}
277
278#[derive(Clone, Debug, HashStable)]
279pub enum ExprKind<'tcx> {
280    /// `Scope`s are used to explicitly mark destruction scopes,
281    /// and to track the `HirId` of the expressions within the scope.
282    Scope {
283        region_scope: region::Scope,
284        lint_level: LintLevel,
285        value: ExprId,
286    },
287    /// A `box <value>` expression.
288    Box {
289        value: ExprId,
290    },
291    /// An `if` expression.
292    If {
293        if_then_scope: region::Scope,
294        cond: ExprId,
295        /// `then` is always `ExprKind::Block`.
296        then: ExprId,
297        /// If present, the `else_opt` expr is always `ExprKind::Block` (for
298        /// `else`) or `ExprKind::If` (for `else if`).
299        else_opt: Option<ExprId>,
300    },
301    /// A function call. Method calls and overloaded operators are converted to plain function calls.
302    Call {
303        /// The type of the function. This is often a [`FnDef`] or a [`FnPtr`].
304        ///
305        /// [`FnDef`]: ty::TyKind::FnDef
306        /// [`FnPtr`]: ty::TyKind::FnPtr
307        ty: Ty<'tcx>,
308        /// The function itself.
309        fun: ExprId,
310        /// The arguments passed to the function.
311        ///
312        /// Note: in some cases (like calling a closure), the function call `f(...args)` gets
313        /// rewritten as a call to a function trait method (e.g. `FnOnce::call_once(f, (...args))`).
314        args: Box<[ExprId]>,
315        /// Whether this is from an overloaded operator rather than a
316        /// function call from HIR. `true` for overloaded function call.
317        from_hir_call: bool,
318        /// The span of the function, without the dot and receiver
319        /// (e.g. `foo(a, b)` in `x.foo(a, b)`).
320        fn_span: Span,
321    },
322    /// A use expression `x.use`.
323    ByUse {
324        /// The expression on which use is applied.
325        expr: ExprId,
326        /// The span of use, without the dot and receiver
327        /// (e.g. `use` in `x.use`).
328        span: Span,
329    },
330    /// A *non-overloaded* dereference.
331    Deref {
332        arg: ExprId,
333    },
334    /// A *non-overloaded* binary operation.
335    Binary {
336        op: BinOp,
337        lhs: ExprId,
338        rhs: ExprId,
339    },
340    /// A logical operation. This is distinct from `BinaryOp` because
341    /// the operands need to be lazily evaluated.
342    LogicalOp {
343        op: LogicalOp,
344        lhs: ExprId,
345        rhs: ExprId,
346    },
347    /// A *non-overloaded* unary operation. Note that here the deref (`*`)
348    /// operator is represented by `ExprKind::Deref`.
349    Unary {
350        op: UnOp,
351        arg: ExprId,
352    },
353    /// A cast: `<source> as <type>`. The type we cast to is the type of
354    /// the parent expression.
355    Cast {
356        source: ExprId,
357    },
358    /// Forces its contents to be treated as a value expression, not a place
359    /// expression. This is inserted in some places where an operation would
360    /// otherwise be erased completely (e.g. some no-op casts), but we still
361    /// need to ensure that its operand is treated as a value and not a place.
362    Use {
363        source: ExprId,
364    },
365    /// A coercion from `!` to any type.
366    NeverToAny {
367        source: ExprId,
368    },
369    /// A pointer coercion. More information can be found in [`PointerCoercion`].
370    /// Pointer casts that cannot be done by coercions are represented by [`ExprKind::Cast`].
371    PointerCoercion {
372        cast: PointerCoercion,
373        source: ExprId,
374        /// Whether this coercion is written with an `as` cast in the source code.
375        is_from_as_cast: bool,
376    },
377    /// A `loop` expression.
378    Loop {
379        body: ExprId,
380    },
381    /// A `#[loop_match] loop { state = 'blk: { match state { ... } } }` expression.
382    LoopMatch {
383        /// The state variable that is updated.
384        /// The `match_data.scrutinee` is the same variable, but with a different span.
385        state: ExprId,
386        region_scope: region::Scope,
387        match_data: Box<LoopMatchMatchData>,
388    },
389    /// Special expression representing the `let` part of an `if let` or similar construct
390    /// (including `if let` guards in match arms, and let-chains formed by `&&`).
391    ///
392    /// This isn't considered a real expression in surface Rust syntax, so it can
393    /// only appear in specific situations, such as within the condition of an `if`.
394    ///
395    /// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
396    Let {
397        expr: ExprId,
398        pat: Box<Pat<'tcx>>,
399    },
400    /// A `match` expression.
401    Match {
402        scrutinee: ExprId,
403        arms: Box<[ArmId]>,
404        match_source: MatchSource,
405    },
406    /// A block.
407    Block {
408        block: BlockId,
409    },
410    /// An assignment: `lhs = rhs`.
411    Assign {
412        lhs: ExprId,
413        rhs: ExprId,
414    },
415    /// A *non-overloaded* operation assignment, e.g. `lhs += rhs`.
416    AssignOp {
417        op: AssignOp,
418        lhs: ExprId,
419        rhs: ExprId,
420    },
421    /// Access to a field of a struct, a tuple, an union, or an enum.
422    Field {
423        lhs: ExprId,
424        /// Variant containing the field.
425        variant_index: VariantIdx,
426        /// This can be a named (`.foo`) or unnamed (`.0`) field.
427        name: FieldIdx,
428    },
429    /// A *non-overloaded* indexing operation.
430    Index {
431        lhs: ExprId,
432        index: ExprId,
433    },
434    /// A local variable.
435    VarRef {
436        id: LocalVarId,
437    },
438    /// Used to represent upvars mentioned in a closure/coroutine
439    UpvarRef {
440        /// DefId of the closure/coroutine
441        closure_def_id: DefId,
442
443        /// HirId of the root variable
444        var_hir_id: LocalVarId,
445    },
446    /// A borrow, e.g. `&arg`.
447    Borrow {
448        borrow_kind: BorrowKind,
449        arg: ExprId,
450    },
451    /// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
452    RawBorrow {
453        mutability: hir::Mutability,
454        arg: ExprId,
455    },
456    /// A `break` expression.
457    Break {
458        label: region::Scope,
459        value: Option<ExprId>,
460    },
461    /// A `continue` expression.
462    Continue {
463        label: region::Scope,
464    },
465    /// A `#[const_continue] break` expression.
466    ConstContinue {
467        label: region::Scope,
468        value: ExprId,
469    },
470    /// A `return` expression.
471    Return {
472        value: Option<ExprId>,
473    },
474    /// A `become` expression.
475    Become {
476        value: ExprId,
477    },
478    /// An inline `const` block, e.g. `const {}`.
479    ConstBlock {
480        did: DefId,
481        args: GenericArgsRef<'tcx>,
482    },
483    /// An array literal constructed from one repeated element, e.g. `[1; 5]`.
484    Repeat {
485        value: ExprId,
486        count: ty::Const<'tcx>,
487    },
488    /// An array, e.g. `[a, b, c, d]`.
489    Array {
490        fields: Box<[ExprId]>,
491    },
492    /// A tuple, e.g. `(a, b, c, d)`.
493    Tuple {
494        fields: Box<[ExprId]>,
495    },
496    /// An ADT constructor, e.g. `Foo {x: 1, y: 2}`.
497    Adt(Box<AdtExpr<'tcx>>),
498    /// A type ascription on a place.
499    PlaceTypeAscription {
500        source: ExprId,
501        /// Type that the user gave to this expression
502        user_ty: UserTy<'tcx>,
503        user_ty_span: Span,
504    },
505    /// A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`.
506    ValueTypeAscription {
507        source: ExprId,
508        /// Type that the user gave to this expression
509        user_ty: UserTy<'tcx>,
510        user_ty_span: Span,
511    },
512    /// An unsafe binder cast on a place, e.g. `unwrap_binder!(*ptr)`.
513    PlaceUnwrapUnsafeBinder {
514        source: ExprId,
515    },
516    /// An unsafe binder cast on a value, e.g. `unwrap_binder!(rvalue())`,
517    /// which makes a temporary.
518    ValueUnwrapUnsafeBinder {
519        source: ExprId,
520    },
521    /// Construct an unsafe binder, e.g. `wrap_binder(&ref)`.
522    WrapUnsafeBinder {
523        source: ExprId,
524    },
525    /// A closure definition.
526    Closure(Box<ClosureExpr<'tcx>>),
527    /// A literal.
528    Literal {
529        lit: hir::Lit,
530        neg: bool,
531    },
532    /// For literals that don't correspond to anything in the HIR
533    NonHirLiteral {
534        lit: ty::ScalarInt,
535        user_ty: UserTy<'tcx>,
536    },
537    /// A literal of a ZST type.
538    ZstLiteral {
539        user_ty: UserTy<'tcx>,
540    },
541    /// Associated constants and named constants
542    NamedConst {
543        def_id: DefId,
544        args: GenericArgsRef<'tcx>,
545        user_ty: UserTy<'tcx>,
546    },
547    ConstParam {
548        param: ty::ParamConst,
549        def_id: DefId,
550    },
551    // FIXME improve docs for `StaticRef` by distinguishing it from `NamedConst`
552    /// A literal containing the address of a `static`.
553    ///
554    /// This is only distinguished from `Literal` so that we can register some
555    /// info for diagnostics.
556    StaticRef {
557        alloc_id: AllocId,
558        ty: Ty<'tcx>,
559        def_id: DefId,
560    },
561    /// Inline assembly, i.e. `asm!()`.
562    InlineAsm(Box<InlineAsmExpr<'tcx>>),
563    /// Field offset (`offset_of!`)
564    OffsetOf {
565        container: Ty<'tcx>,
566        fields: &'tcx List<(VariantIdx, FieldIdx)>,
567    },
568    /// An expression taking a reference to a thread local.
569    ThreadLocalRef(DefId),
570    /// A `yield` expression.
571    Yield {
572        value: ExprId,
573    },
574}
575
576/// Represents the association of a field identifier and an expression.
577///
578/// This is used in struct constructors.
579#[derive(Clone, Debug, HashStable)]
580pub struct FieldExpr {
581    pub name: FieldIdx,
582    pub expr: ExprId,
583}
584
585#[derive(Clone, Debug, HashStable)]
586pub struct FruInfo<'tcx> {
587    pub base: ExprId,
588    pub field_types: Box<[Ty<'tcx>]>,
589}
590
591/// A `match` arm.
592#[derive(Clone, Debug, HashStable)]
593pub struct Arm<'tcx> {
594    pub pattern: Box<Pat<'tcx>>,
595    pub guard: Option<ExprId>,
596    pub body: ExprId,
597    pub lint_level: LintLevel,
598    pub scope: region::Scope,
599    pub span: Span,
600}
601
602/// The `match` part of a `#[loop_match]`
603#[derive(Clone, Debug, HashStable)]
604pub struct LoopMatchMatchData {
605    pub scrutinee: ExprId,
606    pub arms: Box<[ArmId]>,
607    pub span: Span,
608}
609
610#[derive(Copy, Clone, Debug, HashStable)]
611pub enum LogicalOp {
612    /// The `&&` operator.
613    And,
614    /// The `||` operator.
615    Or,
616}
617
618#[derive(Clone, Debug, HashStable)]
619pub enum InlineAsmOperand<'tcx> {
620    In {
621        reg: InlineAsmRegOrRegClass,
622        expr: ExprId,
623    },
624    Out {
625        reg: InlineAsmRegOrRegClass,
626        late: bool,
627        expr: Option<ExprId>,
628    },
629    InOut {
630        reg: InlineAsmRegOrRegClass,
631        late: bool,
632        expr: ExprId,
633    },
634    SplitInOut {
635        reg: InlineAsmRegOrRegClass,
636        late: bool,
637        in_expr: ExprId,
638        out_expr: Option<ExprId>,
639    },
640    Const {
641        value: mir::Const<'tcx>,
642        span: Span,
643    },
644    SymFn {
645        value: ExprId,
646    },
647    SymStatic {
648        def_id: DefId,
649    },
650    Label {
651        block: BlockId,
652    },
653}
654
655#[derive(Clone, Debug, HashStable, TypeVisitable)]
656pub struct FieldPat<'tcx> {
657    pub field: FieldIdx,
658    pub pattern: Pat<'tcx>,
659}
660
661#[derive(Clone, Debug, HashStable, TypeVisitable)]
662pub struct Pat<'tcx> {
663    pub ty: Ty<'tcx>,
664    pub span: Span,
665    pub kind: PatKind<'tcx>,
666}
667
668impl<'tcx> Pat<'tcx> {
669    pub fn simple_ident(&self) -> Option<Symbol> {
670        match self.kind {
671            PatKind::Binding {
672                name, mode: BindingMode(ByRef::No, _), subpattern: None, ..
673            } => Some(name),
674            _ => None,
675        }
676    }
677
678    /// Call `f` on every "binding" in a pattern, e.g., on `a` in
679    /// `match foo() { Some(a) => (), None => () }`
680    pub fn each_binding(&self, mut f: impl FnMut(Symbol, ByRef, Ty<'tcx>, Span)) {
681        self.walk_always(|p| {
682            if let PatKind::Binding { name, mode, ty, .. } = p.kind {
683                f(name, mode.0, ty, p.span);
684            }
685        });
686    }
687
688    /// Walk the pattern in left-to-right order.
689    ///
690    /// If `it(pat)` returns `false`, the children are not visited.
691    pub fn walk(&self, mut it: impl FnMut(&Pat<'tcx>) -> bool) {
692        self.walk_(&mut it)
693    }
694
695    fn walk_(&self, it: &mut impl FnMut(&Pat<'tcx>) -> bool) {
696        if !it(self) {
697            return;
698        }
699
700        for_each_immediate_subpat(self, |p| p.walk_(it));
701    }
702
703    /// Whether the pattern has a `PatKind::Error` nested within.
704    pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
705        let mut error = None;
706        self.walk(|pat| {
707            if let PatKind::Error(e) = pat.kind
708                && error.is_none()
709            {
710                error = Some(e);
711            }
712            error.is_none()
713        });
714        match error {
715            None => Ok(()),
716            Some(e) => Err(e),
717        }
718    }
719
720    /// Walk the pattern in left-to-right order.
721    ///
722    /// If you always want to recurse, prefer this method over `walk`.
723    pub fn walk_always(&self, mut it: impl FnMut(&Pat<'tcx>)) {
724        self.walk(|p| {
725            it(p);
726            true
727        })
728    }
729
730    /// Whether this a never pattern.
731    pub fn is_never_pattern(&self) -> bool {
732        let mut is_never_pattern = false;
733        self.walk(|pat| match &pat.kind {
734            PatKind::Never => {
735                is_never_pattern = true;
736                false
737            }
738            PatKind::Or { pats } => {
739                is_never_pattern = pats.iter().all(|p| p.is_never_pattern());
740                false
741            }
742            _ => true,
743        });
744        is_never_pattern
745    }
746}
747
748#[derive(Clone, Debug, HashStable, TypeVisitable)]
749pub struct Ascription<'tcx> {
750    pub annotation: CanonicalUserTypeAnnotation<'tcx>,
751    /// Variance to use when relating the `user_ty` to the **type of the value being
752    /// matched**. Typically, this is `Variance::Covariant`, since the value being matched must
753    /// have a type that is some subtype of the ascribed type.
754    ///
755    /// Note that this variance does not apply for any bindings within subpatterns. The type
756    /// assigned to those bindings must be exactly equal to the `user_ty` given here.
757    ///
758    /// The only place where this field is not `Covariant` is when matching constants, where
759    /// we currently use `Contravariant` -- this is because the constant type just needs to
760    /// be "comparable" to the type of the input value. So, for example:
761    ///
762    /// ```text
763    /// match x { "foo" => .. }
764    /// ```
765    ///
766    /// requires that `&'static str <: T_x`, where `T_x` is the type of `x`. Really, we should
767    /// probably be checking for a `PartialEq` impl instead, but this preserves the behavior
768    /// of the old type-check for now. See #57280 for details.
769    pub variance: ty::Variance,
770}
771
772#[derive(Clone, Debug, HashStable, TypeVisitable)]
773pub enum PatKind<'tcx> {
774    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
775    Missing,
776
777    /// A wildcard pattern: `_`.
778    Wild,
779
780    AscribeUserType {
781        ascription: Ascription<'tcx>,
782        subpattern: Box<Pat<'tcx>>,
783    },
784
785    /// `x`, `ref x`, `x @ P`, etc.
786    Binding {
787        name: Symbol,
788        #[type_visitable(ignore)]
789        mode: BindingMode,
790        #[type_visitable(ignore)]
791        var: LocalVarId,
792        ty: Ty<'tcx>,
793        subpattern: Option<Box<Pat<'tcx>>>,
794
795        /// Is this the leftmost occurrence of the binding, i.e., is `var` the
796        /// `HirId` of this pattern?
797        ///
798        /// (The same binding can occur multiple times in different branches of
799        /// an or-pattern, but only one of them will be primary.)
800        is_primary: bool,
801    },
802
803    /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with
804    /// multiple variants.
805    Variant {
806        adt_def: AdtDef<'tcx>,
807        args: GenericArgsRef<'tcx>,
808        variant_index: VariantIdx,
809        subpatterns: Vec<FieldPat<'tcx>>,
810    },
811
812    /// `(...)`, `Foo(...)`, `Foo{...}`, or `Foo`, where `Foo` is a variant name from an ADT with
813    /// a single variant.
814    Leaf {
815        subpatterns: Vec<FieldPat<'tcx>>,
816    },
817
818    /// `box P`, `&P`, `&mut P`, etc.
819    Deref {
820        subpattern: Box<Pat<'tcx>>,
821    },
822
823    /// Deref pattern, written `box P` for now.
824    DerefPattern {
825        subpattern: Box<Pat<'tcx>>,
826        /// Whether the pattern scrutinee needs to be borrowed in order to call `Deref::deref` or
827        /// `DerefMut::deref_mut`, and if so, which. This is `ByRef::No` for deref patterns on
828        /// boxes; they are lowered using a built-in deref rather than a method call, thus they
829        /// don't borrow the scrutinee.
830        #[type_visitable(ignore)]
831        borrow: ByRef,
832    },
833
834    /// One of the following:
835    /// * `&str`, which will be handled as a string pattern and thus
836    ///   exhaustiveness checking will detect if you use the same string twice in different
837    ///   patterns.
838    /// * integer, bool, char or float, which will be handled by
839    ///   exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
840    ///   much simpler.
841    /// * raw pointers derived from integers, other raw pointers will have already resulted in an
842    //    error.
843    /// * `String`, if `string_deref_patterns` is enabled.
844    Constant {
845        value: ty::Value<'tcx>,
846    },
847
848    /// Pattern obtained by converting a constant (inline or named) to its pattern
849    /// representation using `const_to_pat`. This is used for unsafety checking.
850    ExpandedConstant {
851        /// [DefId] of the constant item.
852        def_id: DefId,
853        /// The pattern that the constant lowered to.
854        ///
855        /// HACK: we need to keep the `DefId` of inline constants around for unsafety checking;
856        /// therefore when a range pattern contains inline constants, we re-wrap the range pattern
857        /// with the `ExpandedConstant` nodes that correspond to the range endpoints. Hence
858        /// `subpattern` may actually be a range pattern, and `def_id` be the constant for one of
859        /// its endpoints.
860        subpattern: Box<Pat<'tcx>>,
861    },
862
863    Range(Arc<PatRange<'tcx>>),
864
865    /// Matches against a slice, checking the length and extracting elements.
866    /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
867    /// e.g., `&[ref xs @ ..]`.
868    Slice {
869        prefix: Box<[Pat<'tcx>]>,
870        slice: Option<Box<Pat<'tcx>>>,
871        suffix: Box<[Pat<'tcx>]>,
872    },
873
874    /// Fixed match against an array; irrefutable.
875    Array {
876        prefix: Box<[Pat<'tcx>]>,
877        slice: Option<Box<Pat<'tcx>>>,
878        suffix: Box<[Pat<'tcx>]>,
879    },
880
881    /// An or-pattern, e.g. `p | q`.
882    /// Invariant: `pats.len() >= 2`.
883    Or {
884        pats: Box<[Pat<'tcx>]>,
885    },
886
887    /// A never pattern `!`.
888    Never,
889
890    /// An error has been encountered during lowering. We probably shouldn't report more lints
891    /// related to this pattern.
892    Error(ErrorGuaranteed),
893}
894
895/// A range pattern.
896/// The boundaries must be of the same type and that type must be numeric.
897#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
898pub struct PatRange<'tcx> {
899    /// Must not be `PosInfinity`.
900    pub lo: PatRangeBoundary<'tcx>,
901    /// Must not be `NegInfinity`.
902    pub hi: PatRangeBoundary<'tcx>,
903    #[type_visitable(ignore)]
904    pub end: RangeEnd,
905    pub ty: Ty<'tcx>,
906}
907
908impl<'tcx> PatRange<'tcx> {
909    /// Whether this range covers the full extent of possible values (best-effort, we ignore floats).
910    #[inline]
911    pub fn is_full_range(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
912        let (min, max, size, bias) = match *self.ty.kind() {
913            ty::Char => (0, std::char::MAX as u128, Size::from_bits(32), 0),
914            ty::Int(ity) => {
915                let size = Integer::from_int_ty(&tcx, ity).size();
916                let max = size.truncate(u128::MAX);
917                let bias = 1u128 << (size.bits() - 1);
918                (0, max, size, bias)
919            }
920            ty::Uint(uty) => {
921                let size = Integer::from_uint_ty(&tcx, uty).size();
922                let max = size.unsigned_int_max();
923                (0, max, size, 0)
924            }
925            _ => return None,
926        };
927
928        // We want to compare ranges numerically, but the order of the bitwise representation of
929        // signed integers does not match their numeric order. Thus, to correct the ordering, we
930        // need to shift the range of signed integers to correct the comparison. This is achieved by
931        // XORing with a bias (see pattern/deconstruct_pat.rs for another pertinent example of this
932        // pattern).
933        //
934        // Also, for performance, it's important to only do the second `try_to_bits` if necessary.
935        let lo_is_min = match self.lo {
936            PatRangeBoundary::NegInfinity => true,
937            PatRangeBoundary::Finite(value) => {
938                let lo = value.try_to_scalar_int().unwrap().to_bits(size) ^ bias;
939                lo <= min
940            }
941            PatRangeBoundary::PosInfinity => false,
942        };
943        if lo_is_min {
944            let hi_is_max = match self.hi {
945                PatRangeBoundary::NegInfinity => false,
946                PatRangeBoundary::Finite(value) => {
947                    let hi = value.try_to_scalar_int().unwrap().to_bits(size) ^ bias;
948                    hi > max || hi == max && self.end == RangeEnd::Included
949                }
950                PatRangeBoundary::PosInfinity => true,
951            };
952            if hi_is_max {
953                return Some(true);
954            }
955        }
956        Some(false)
957    }
958
959    #[inline]
960    pub fn contains(&self, value: ty::Value<'tcx>, tcx: TyCtxt<'tcx>) -> Option<bool> {
961        use Ordering::*;
962        debug_assert_eq!(value.ty, self.ty);
963        let ty = self.ty;
964        let value = PatRangeBoundary::Finite(value.valtree);
965        // For performance, it's important to only do the second comparison if necessary.
966        Some(
967            match self.lo.compare_with(value, ty, tcx)? {
968                Less | Equal => true,
969                Greater => false,
970            } && match value.compare_with(self.hi, ty, tcx)? {
971                Less => true,
972                Equal => self.end == RangeEnd::Included,
973                Greater => false,
974            },
975        )
976    }
977
978    #[inline]
979    pub fn overlaps(&self, other: &Self, tcx: TyCtxt<'tcx>) -> Option<bool> {
980        use Ordering::*;
981        debug_assert_eq!(self.ty, other.ty);
982        // For performance, it's important to only do the second comparison if necessary.
983        Some(
984            match other.lo.compare_with(self.hi, self.ty, tcx)? {
985                Less => true,
986                Equal => self.end == RangeEnd::Included,
987                Greater => false,
988            } && match self.lo.compare_with(other.hi, self.ty, tcx)? {
989                Less => true,
990                Equal => other.end == RangeEnd::Included,
991                Greater => false,
992            },
993        )
994    }
995}
996
997impl<'tcx> fmt::Display for PatRange<'tcx> {
998    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
999        if let &PatRangeBoundary::Finite(valtree) = &self.lo {
1000            let value = ty::Value { ty: self.ty, valtree };
1001            write!(f, "{value}")?;
1002        }
1003        if let &PatRangeBoundary::Finite(valtree) = &self.hi {
1004            write!(f, "{}", self.end)?;
1005            let value = ty::Value { ty: self.ty, valtree };
1006            write!(f, "{value}")?;
1007        } else {
1008            // `0..` is parsed as an inclusive range, we must display it correctly.
1009            write!(f, "..")?;
1010        }
1011        Ok(())
1012    }
1013}
1014
1015/// A (possibly open) boundary of a range pattern.
1016/// If present, the const must be of a numeric type.
1017#[derive(Copy, Clone, Debug, PartialEq, HashStable, TypeVisitable)]
1018pub enum PatRangeBoundary<'tcx> {
1019    /// The type of this valtree is stored in the surrounding `PatRange`.
1020    Finite(ty::ValTree<'tcx>),
1021    NegInfinity,
1022    PosInfinity,
1023}
1024
1025impl<'tcx> PatRangeBoundary<'tcx> {
1026    #[inline]
1027    pub fn is_finite(self) -> bool {
1028        matches!(self, Self::Finite(..))
1029    }
1030    #[inline]
1031    pub fn as_finite(self) -> Option<ty::ValTree<'tcx>> {
1032        match self {
1033            Self::Finite(value) => Some(value),
1034            Self::NegInfinity | Self::PosInfinity => None,
1035        }
1036    }
1037    pub fn to_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> u128 {
1038        match self {
1039            Self::Finite(value) => value.try_to_scalar_int().unwrap().to_bits_unchecked(),
1040            Self::NegInfinity => {
1041                // Unwrap is ok because the type is known to be numeric.
1042                ty.numeric_min_and_max_as_bits(tcx).unwrap().0
1043            }
1044            Self::PosInfinity => {
1045                // Unwrap is ok because the type is known to be numeric.
1046                ty.numeric_min_and_max_as_bits(tcx).unwrap().1
1047            }
1048        }
1049    }
1050
1051    #[instrument(skip(tcx), level = "debug", ret)]
1052    pub fn compare_with(self, other: Self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Ordering> {
1053        use PatRangeBoundary::*;
1054        match (self, other) {
1055            // When comparing with infinities, we must remember that `0u8..` and `0u8..=255`
1056            // describe the same range. These two shortcuts are ok, but for the rest we must check
1057            // bit values.
1058            (PosInfinity, PosInfinity) => return Some(Ordering::Equal),
1059            (NegInfinity, NegInfinity) => return Some(Ordering::Equal),
1060
1061            // This code is hot when compiling matches with many ranges. So we
1062            // special-case extraction of evaluated scalars for speed, for types where
1063            // we can do scalar comparisons. E.g. `unicode-normalization` has
1064            // many ranges such as '\u{037A}'..='\u{037F}', and chars can be compared
1065            // in this way.
1066            (Finite(a), Finite(b)) if matches!(ty.kind(), ty::Int(_) | ty::Uint(_) | ty::Char) => {
1067                if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) {
1068                    let sz = ty.primitive_size(tcx);
1069                    let cmp = match ty.kind() {
1070                        ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)),
1071                        ty::Int(_) => a.to_int(sz).cmp(&b.to_int(sz)),
1072                        _ => unreachable!(),
1073                    };
1074                    return Some(cmp);
1075                }
1076            }
1077            _ => {}
1078        }
1079
1080        let a = self.to_bits(ty, tcx);
1081        let b = other.to_bits(ty, tcx);
1082
1083        match ty.kind() {
1084            ty::Float(ty::FloatTy::F16) => {
1085                use rustc_apfloat::Float;
1086                let a = rustc_apfloat::ieee::Half::from_bits(a);
1087                let b = rustc_apfloat::ieee::Half::from_bits(b);
1088                a.partial_cmp(&b)
1089            }
1090            ty::Float(ty::FloatTy::F32) => {
1091                use rustc_apfloat::Float;
1092                let a = rustc_apfloat::ieee::Single::from_bits(a);
1093                let b = rustc_apfloat::ieee::Single::from_bits(b);
1094                a.partial_cmp(&b)
1095            }
1096            ty::Float(ty::FloatTy::F64) => {
1097                use rustc_apfloat::Float;
1098                let a = rustc_apfloat::ieee::Double::from_bits(a);
1099                let b = rustc_apfloat::ieee::Double::from_bits(b);
1100                a.partial_cmp(&b)
1101            }
1102            ty::Float(ty::FloatTy::F128) => {
1103                use rustc_apfloat::Float;
1104                let a = rustc_apfloat::ieee::Quad::from_bits(a);
1105                let b = rustc_apfloat::ieee::Quad::from_bits(b);
1106                a.partial_cmp(&b)
1107            }
1108            ty::Int(ity) => {
1109                let size = rustc_abi::Integer::from_int_ty(&tcx, *ity).size();
1110                let a = size.sign_extend(a) as i128;
1111                let b = size.sign_extend(b) as i128;
1112                Some(a.cmp(&b))
1113            }
1114            ty::Uint(_) | ty::Char => Some(a.cmp(&b)),
1115            _ => bug!(),
1116        }
1117    }
1118}
1119
1120// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
1121#[cfg(target_pointer_width = "64")]
1122mod size_asserts {
1123    use rustc_data_structures::static_assert_size;
1124
1125    use super::*;
1126    // tidy-alphabetical-start
1127    static_assert_size!(Block, 48);
1128    static_assert_size!(Expr<'_>, 72);
1129    static_assert_size!(ExprKind<'_>, 40);
1130    static_assert_size!(Pat<'_>, 64);
1131    static_assert_size!(PatKind<'_>, 48);
1132    static_assert_size!(Stmt<'_>, 48);
1133    static_assert_size!(StmtKind<'_>, 48);
1134    // tidy-alphabetical-end
1135}