Skip to content

Commit 18826bf

Browse files
committed
!! (WIP) convert all THIR patterns and subpatterns (2)
1 parent 1202fab commit 18826bf

File tree

16 files changed

+263
-240
lines changed

16 files changed

+263
-240
lines changed

compiler/rustc_middle/src/thir.rs

+40-32
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
1010
1111
use std::cmp::Ordering;
12-
use std::fmt;
1312
use std::ops::Index;
1413
use std::sync::Arc;
14+
use std::{fmt, mem};
1515

1616
use rustc_abi::{FieldIdx, Integer, Size, VariantIdx};
1717
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
@@ -84,10 +84,10 @@ macro_rules! thir_with_elements {
8484
}
8585

8686
thir_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)]
104104
pub 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
}

compiler/rustc_middle/src/thir/visit.rs

+22-25
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ pub trait Visitor<'thir, 'tcx: 'thir>: Sized {
1010
walk_expr(self, expr);
1111
}
1212

13-
fn visit_stmt(&mut self, stmt: &'thir Stmt<'tcx>) {
13+
fn visit_stmt(&mut self, stmt: &'thir Stmt) {
1414
walk_stmt(self, stmt);
1515
}
1616

1717
fn visit_block(&mut self, block: &'thir Block) {
1818
walk_block(self, block);
1919
}
2020

21-
fn visit_arm(&mut self, arm: &'thir Arm<'tcx>) {
21+
fn visit_arm(&mut self, arm: &'thir Arm) {
2222
walk_arm(self, arm);
2323
}
2424

@@ -71,9 +71,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
7171
PointerCoercion { source, cast: _, is_from_as_cast: _ } => {
7272
visitor.visit_expr(&visitor.thir()[source])
7373
}
74-
Let { expr, ref pat } => {
74+
Let { expr, pat } => {
7575
visitor.visit_expr(&visitor.thir()[expr]);
76-
visitor.visit_pat(pat);
76+
visitor.visit_pat(&visitor.thir()[pat]);
7777
}
7878
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
7979
Match { scrutinee, ref arms, .. } => {
@@ -184,10 +184,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
184184
}
185185
}
186186

187-
pub fn walk_stmt<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
188-
visitor: &mut V,
189-
stmt: &'thir Stmt<'tcx>,
190-
) {
187+
pub fn walk_stmt<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(visitor: &mut V, stmt: &'thir Stmt) {
191188
match &stmt.kind {
192189
StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
193190
StmtKind::Let {
@@ -202,7 +199,7 @@ pub fn walk_stmt<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
202199
if let Some(init) = initializer {
203200
visitor.visit_expr(&visitor.thir()[*init]);
204201
}
205-
visitor.visit_pat(pattern);
202+
visitor.visit_pat(&visitor.thir()[*pattern]);
206203
if let Some(block) = else_block {
207204
visitor.visit_block(&visitor.thir()[*block])
208205
}
@@ -222,30 +219,30 @@ pub fn walk_block<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
222219
}
223220
}
224221

225-
pub fn walk_arm<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
226-
visitor: &mut V,
227-
arm: &'thir Arm<'tcx>,
228-
) {
222+
pub fn walk_arm<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(visitor: &mut V, arm: &'thir Arm) {
229223
if let Some(expr) = arm.guard {
230224
visitor.visit_expr(&visitor.thir()[expr])
231225
}
232-
visitor.visit_pat(&arm.pattern);
226+
visitor.visit_pat(&visitor.thir()[arm.pattern]);
233227
visitor.visit_expr(&visitor.thir()[arm.body]);
234228
}
235229

236230
pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
237231
visitor: &mut V,
238232
pat: &'thir Pat<'tcx>,
239233
) {
240-
for_each_immediate_subpat(pat, |p| visitor.visit_pat(p));
234+
for_each_immediate_subpat(visitor.thir(), pat, |p| visitor.visit_pat(p));
241235
}
242236

243237
/// Invokes `callback` on each immediate subpattern of `pat`, if any.
244238
/// A building block for assembling THIR pattern visitors.
245239
pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
240+
thir: &'a Thir<'tcx>,
246241
pat: &'a Pat<'tcx>,
247242
mut callback: impl FnMut(&'a Pat<'tcx>),
248243
) {
244+
let mut callback_id = |pat_id| callback(&thir[pat_id]);
245+
249246
match pat.kind {
250247
PatKind::Wild
251248
| PatKind::Binding { subpattern: None, .. }
@@ -254,28 +251,28 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
254251
| PatKind::Never
255252
| PatKind::Error(_) => {}
256253

257-
PatKind::AscribeUserType { ref subpattern, .. }
258-
| PatKind::Binding { subpattern: Some(ref subpattern), .. }
259-
| PatKind::Deref { ref subpattern }
260-
| PatKind::DerefPattern { ref subpattern, .. }
261-
| PatKind::ExpandedConstant { ref subpattern, .. } => callback(subpattern),
254+
PatKind::AscribeUserType { subpattern, .. }
255+
| PatKind::Binding { subpattern: Some(subpattern), .. }
256+
| PatKind::Deref { subpattern }
257+
| PatKind::DerefPattern { subpattern, .. }
258+
| PatKind::ExpandedConstant { subpattern, .. } => callback_id(subpattern),
262259

263260
PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
264261
for field_pat in subpatterns {
265-
callback(&field_pat.pattern);
262+
callback_id(field_pat.pattern);
266263
}
267264
}
268265

269266
PatKind::Slice { ref prefix, ref slice, ref suffix }
270267
| PatKind::Array { ref prefix, ref slice, ref suffix } => {
271-
for pat in prefix.iter().chain(slice.as_deref()).chain(suffix) {
272-
callback(pat);
268+
for &pat in prefix.iter().chain(slice).chain(suffix) {
269+
callback_id(pat);
273270
}
274271
}
275272

276273
PatKind::Or { ref pats } => {
277-
for pat in pats {
278-
callback(pat);
274+
for &pat in pats {
275+
callback_id(pat);
279276
}
280277
}
281278
}

compiler/rustc_mir_build/src/builder/block.rs

+2
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
155155
// │Continue... │ └────────────────┘
156156
// └────────────────┘
157157

158+
let pattern = &this.thir[*pattern];
158159
let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
159160
this.block_context.push(BlockFrame::Statement { ignores_expr_result });
160161

@@ -246,6 +247,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
246247
else_block: None,
247248
span: _,
248249
} => {
250+
let pattern = &this.thir[*pattern];
249251
let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
250252
this.block_context.push(BlockFrame::Statement { ignores_expr_result });
251253

0 commit comments

Comments
 (0)