99//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
1010
1111use std:: cmp:: Ordering ;
12- use std:: fmt;
1312use std:: ops:: Index ;
1413use std:: sync:: Arc ;
14+ use std:: { fmt, mem} ;
1515
1616use rustc_abi:: { FieldIdx , Integer , Size , VariantIdx } ;
1717use rustc_ast:: { AsmMacro , InlineAsmOptions , InlineAsmTemplatePiece } ;
@@ -84,10 +84,10 @@ macro_rules! thir_with_elements {
8484}
8585
8686thir_with_elements ! {
87- arms: ArmId => Arm < ' tcx> => "a{}" ,
87+ arms: ArmId => Arm => "a{}" ,
8888 blocks: BlockId => Block => "b{}" ,
8989 exprs: ExprId => Expr <' tcx> => "e{}" ,
90- stmts: StmtId => Stmt < ' tcx> => "s{}" ,
90+ stmts: StmtId => Stmt => "s{}" ,
9191 params: ParamId => Param <' tcx> => "p{}" ,
9292 pats: PatId => Pat <' tcx> => "pat{}" ,
9393}
@@ -103,7 +103,7 @@ pub enum BodyTy<'tcx> {
103103#[ derive( Debug , HashStable ) ]
104104pub struct Param < ' tcx > {
105105 /// The pattern that appears in the parameter list, or None for implicit parameters.
106- pub pat : Option < Box < Pat < ' tcx > > > ,
106+ pub pat : Option < PatId > ,
107107 /// The possibly inferred type.
108108 pub ty : Ty < ' tcx > ,
109109 /// Span of the explicitly provided type, or None if inferred for closures.
@@ -198,12 +198,12 @@ pub enum BlockSafety {
198198}
199199
200200#[ derive( Debug , HashStable ) ]
201- pub struct Stmt < ' tcx > {
202- pub kind : StmtKind < ' tcx > ,
201+ pub struct Stmt {
202+ pub kind : StmtKind ,
203203}
204204
205205#[ derive( Debug , HashStable ) ]
206- pub enum StmtKind < ' tcx > {
206+ pub enum StmtKind {
207207 /// An expression with a trailing semicolon.
208208 Expr {
209209 /// The scope for this statement; may be used as lifetime of temporaries.
@@ -226,7 +226,7 @@ pub enum StmtKind<'tcx> {
226226 /// `let <PAT> = ...`
227227 ///
228228 /// If a type annotation is included, it is added as an ascription pattern.
229- pattern : Box < Pat < ' tcx > > ,
229+ pattern : PatId ,
230230
231231 /// `let pat: ty = <INIT>`
232232 initializer : Option < ExprId > ,
@@ -374,7 +374,7 @@ pub enum ExprKind<'tcx> {
374374 /// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
375375 Let {
376376 expr : ExprId ,
377- pat : Box < Pat < ' tcx > > ,
377+ pat : PatId ,
378378 } ,
379379 /// A `match` expression.
380380 Match {
@@ -564,8 +564,8 @@ pub struct FruInfo<'tcx> {
564564
565565/// A `match` arm.
566566#[ derive( Debug , HashStable ) ]
567- pub struct Arm < ' tcx > {
568- pub pattern : Box < Pat < ' tcx > > ,
567+ pub struct Arm {
568+ pub pattern : PatId ,
569569 pub guard : Option < ExprId > ,
570570 pub body : ExprId ,
571571 pub lint_level : LintLevel ,
@@ -619,9 +619,9 @@ pub enum InlineAsmOperand<'tcx> {
619619}
620620
621621#[ derive( Debug , HashStable , TypeVisitable ) ]
622- pub struct FieldPat < ' tcx > {
622+ pub struct FieldPat {
623623 pub field : FieldIdx ,
624- pub pattern : Pat < ' tcx > ,
624+ pub pattern : PatId ,
625625}
626626
627627#[ derive( Debug , HashStable , TypeVisitable ) ]
@@ -669,7 +669,7 @@ impl<'tcx> Thir<'tcx> {
669669 return ;
670670 }
671671
672- for_each_immediate_subpat ( pat, |p| self . walk_pat_inner ( p, it) ) ;
672+ for_each_immediate_subpat ( self , pat, |p| self . walk_pat_inner ( p, it) ) ;
673673 }
674674
675675 /// Whether the pattern has a `PatKind::Error` nested within.
@@ -694,7 +694,7 @@ impl<'tcx> Thir<'tcx> {
694694
695695 let mut references_error = TypeVisitableExt :: references_error ( pat) ;
696696 if !references_error {
697- for_each_immediate_subpat ( pat, |p| {
697+ for_each_immediate_subpat ( self , pat, |p| {
698698 references_error = references_error || self . pat_references_error ( p) ;
699699 } ) ;
700700 }
@@ -721,13 +721,21 @@ impl<'tcx> Thir<'tcx> {
721721 false
722722 }
723723 PatKind :: Or { pats } => {
724- is_never_pattern = pats. iter ( ) . all ( |p| self . is_never_pattern ( p ) ) ;
724+ is_never_pattern = pats. iter ( ) . all ( |& p| self . is_never_pattern ( & self [ p ] ) ) ;
725725 false
726726 }
727727 _ => true ,
728728 } ) ;
729729 is_never_pattern
730730 }
731+
732+ /// FIXME(Zalathar): This method is a concession to existing code that was
733+ /// extracting `PatKind` from owned patterns nodes, before `PatId` was
734+ /// introduced. Ideally all callers should be modified to not need this.
735+ pub fn take_pat_kind ( & mut self , pat_id : PatId ) -> PatKind < ' tcx > {
736+ // Replace the existing kind with an arbitrary dummy kind.
737+ mem:: replace ( & mut self . pats [ pat_id] . kind , PatKind :: Wild )
738+ }
731739}
732740
733741#[ derive( Debug , HashStable , TypeVisitable ) ]
@@ -761,7 +769,7 @@ pub enum PatKind<'tcx> {
761769
762770 AscribeUserType {
763771 ascription : Ascription < ' tcx > ,
764- subpattern : Box < Pat < ' tcx > > ,
772+ subpattern : PatId ,
765773 } ,
766774
767775 /// `x`, `ref x`, `x @ P`, etc.
@@ -772,7 +780,7 @@ pub enum PatKind<'tcx> {
772780 #[ type_visitable( ignore) ]
773781 var : LocalVarId ,
774782 ty : Ty < ' tcx > ,
775- subpattern : Option < Box < Pat < ' tcx > > > ,
783+ subpattern : Option < PatId > ,
776784
777785 /// Is this the leftmost occurrence of the binding, i.e., is `var` the
778786 /// `HirId` of this pattern?
@@ -788,23 +796,23 @@ pub enum PatKind<'tcx> {
788796 adt_def : AdtDef < ' tcx > ,
789797 args : GenericArgsRef < ' tcx > ,
790798 variant_index : VariantIdx ,
791- subpatterns : Vec < FieldPat < ' tcx > > ,
799+ subpatterns : Vec < FieldPat > ,
792800 } ,
793801
794802 /// `(...)`, `Foo(...)`, `Foo{...}`, or `Foo`, where `Foo` is a variant name from an ADT with
795803 /// a single variant.
796804 Leaf {
797- subpatterns : Vec < FieldPat < ' tcx > > ,
805+ subpatterns : Vec < FieldPat > ,
798806 } ,
799807
800808 /// `box P`, `&P`, `&mut P`, etc.
801809 Deref {
802- subpattern : Box < Pat < ' tcx > > ,
810+ subpattern : PatId ,
803811 } ,
804812
805813 /// Deref pattern, written `box P` for now.
806814 DerefPattern {
807- subpattern : Box < Pat < ' tcx > > ,
815+ subpattern : PatId ,
808816 mutability : hir:: Mutability ,
809817 } ,
810818
@@ -838,7 +846,7 @@ pub enum PatKind<'tcx> {
838846 /// Otherwise, the actual pattern that the constant lowered to. As with
839847 /// other constants, inline constants are matched structurally where
840848 /// possible.
841- subpattern : Box < Pat < ' tcx > > ,
849+ subpattern : PatId ,
842850 } ,
843851
844852 Range ( Arc < PatRange < ' tcx > > ) ,
@@ -847,22 +855,22 @@ pub enum PatKind<'tcx> {
847855 /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
848856 /// e.g., `&[ref xs @ ..]`.
849857 Slice {
850- prefix : Box < [ Pat < ' tcx > ] > ,
851- slice : Option < Box < Pat < ' tcx > > > ,
852- suffix : Box < [ Pat < ' tcx > ] > ,
858+ prefix : Box < [ PatId ] > ,
859+ slice : Option < PatId > ,
860+ suffix : Box < [ PatId ] > ,
853861 } ,
854862
855863 /// Fixed match against an array; irrefutable.
856864 Array {
857- prefix : Box < [ Pat < ' tcx > ] > ,
858- slice : Option < Box < Pat < ' tcx > > > ,
859- suffix : Box < [ Pat < ' tcx > ] > ,
865+ prefix : Box < [ PatId ] > ,
866+ slice : Option < PatId > ,
867+ suffix : Box < [ PatId ] > ,
860868 } ,
861869
862870 /// An or-pattern, e.g. `p | q`.
863871 /// Invariant: `pats.len() >= 2`.
864872 Or {
865- pats : Box < [ Pat < ' tcx > ] > ,
873+ pats : Box < [ PatId ] > ,
866874 } ,
867875
868876 /// A never pattern `!`.
@@ -1128,7 +1136,7 @@ mod size_asserts {
11281136 static_assert_size ! ( ExprKind <' _>, 40 ) ;
11291137 static_assert_size ! ( Pat <' _>, 64 ) ;
11301138 static_assert_size ! ( PatKind <' _>, 48 ) ;
1131- static_assert_size ! ( Stmt < ' _> , 48 ) ;
1132- static_assert_size ! ( StmtKind < ' _> , 48 ) ;
1139+ static_assert_size ! ( Stmt , 44 ) ;
1140+ static_assert_size ! ( StmtKind , 44 ) ;
11331141 // tidy-alphabetical-end
11341142}
0 commit comments