Skip to content

Commit 98a9d5c

Browse files
committed
Arena-allocate PatStack
1 parent ab2a92a commit 98a9d5c

File tree

2 files changed

+37
-26
lines changed

2 files changed

+37
-26
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::usefulness::{
55

66
use crate::errors::*;
77

8-
use rustc_arena::TypedArena;
8+
use rustc_arena::{DroplessArena, TypedArena};
99
use rustc_ast::Mutability;
1010
use rustc_data_structures::fx::FxHashSet;
1111
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -29,13 +29,15 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
2929
let (thir, expr) = tcx.thir_body(def_id)?;
3030
let thir = thir.borrow();
3131
let pattern_arena = TypedArena::default();
32+
let dropless_arena = DroplessArena::default();
3233
let mut visitor = MatchVisitor {
3334
tcx,
3435
thir: &*thir,
3536
param_env: tcx.param_env(def_id),
3637
lint_level: tcx.local_def_id_to_hir_id(def_id),
3738
let_source: LetSource::None,
3839
pattern_arena: &pattern_arena,
40+
dropless_arena: &dropless_arena,
3941
error: Ok(()),
4042
};
4143
visitor.visit_expr(&thir[expr]);
@@ -80,6 +82,7 @@ struct MatchVisitor<'thir, 'p, 'tcx> {
8082
lint_level: HirId,
8183
let_source: LetSource,
8284
pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
85+
dropless_arena: &'p DroplessArena,
8386
/// Tracks if we encountered an error while checking this body. That the first function to
8487
/// report it stores it here. Some functions return `Result` to allow callers to short-circuit
8588
/// on error, but callers don't need to store it here again.
@@ -302,6 +305,7 @@ impl<'thir, 'p, 'tcx> MatchVisitor<'thir, 'p, 'tcx> {
302305
param_env: self.param_env,
303306
module: self.tcx.parent_module(self.lint_level).to_def_id(),
304307
pattern_arena: self.pattern_arena,
308+
dropless_arena: self.dropless_arena,
305309
match_lint_level: self.lint_level,
306310
match_span,
307311
scrut_span,

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

+32-25
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ use crate::errors::{
499499

500500
use rustc_data_structures::captures::Captures;
501501

502-
use rustc_arena::TypedArena;
502+
use rustc_arena::{DroplessArena, TypedArena};
503503
use rustc_data_structures::stack::ensure_sufficient_stack;
504504
use rustc_hir::def_id::DefId;
505505
use rustc_hir::HirId;
@@ -508,8 +508,8 @@ use rustc_session::lint;
508508
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
509509
use rustc_span::{Span, DUMMY_SP};
510510

511-
use smallvec::{smallvec, SmallVec};
512-
use std::fmt;
511+
use smallvec::SmallVec;
512+
use std::{fmt, iter::once};
513513

514514
pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
515515
pub(crate) tcx: TyCtxt<'tcx>,
@@ -521,6 +521,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
521521
pub(crate) module: DefId,
522522
pub(crate) param_env: ty::ParamEnv<'tcx>,
523523
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
524+
pub(crate) dropless_arena: &'p DroplessArena,
524525
/// Lint level at the match.
525526
pub(crate) match_lint_level: HirId,
526527
/// The span of the whole match, if applicable.
@@ -570,13 +571,12 @@ impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> {
570571
/// Represents a pattern-tuple under investigation.
571572
#[derive(Clone)]
572573
struct PatStack<'p, 'tcx> {
573-
// Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
574-
pats: SmallVec<[&'p DeconstructedPat<'p, 'tcx>; 2]>,
574+
pats: &'p [&'p DeconstructedPat<'p, 'tcx>],
575575
}
576576

577577
impl<'p, 'tcx> PatStack<'p, 'tcx> {
578-
fn from_pattern(pat: &'p DeconstructedPat<'p, 'tcx>) -> Self {
579-
PatStack { pats: smallvec![pat] }
578+
fn from_pattern(cx: &MatchCheckCtxt<'p, '_>, pat: &'p DeconstructedPat<'p, 'tcx>) -> Self {
579+
PatStack { pats: cx.dropless_arena.alloc_from_iter(once(pat)) }
580580
}
581581

582582
fn is_empty(&self) -> bool {
@@ -597,12 +597,14 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
597597

598598
// Recursively expand the first or-pattern into its subpatterns. Only useful if the pattern is
599599
// an or-pattern. Panics if `self` is empty.
600-
fn expand_or_pat<'a>(&'a self) -> impl Iterator<Item = PatStack<'p, 'tcx>> + Captures<'a> {
601-
self.head().flatten_or_pat().into_iter().map(move |pat| {
602-
let mut new_pats = SmallVec::<[_; 2]>::with_capacity(self.len());
603-
new_pats.push(pat);
604-
new_pats.extend_from_slice(&self.pats[1..]);
605-
PatStack { pats: new_pats }
600+
fn expand_or_pat<'a>(
601+
&'a self,
602+
cx: &'a MatchCheckCtxt<'p, 'tcx>,
603+
) -> impl Iterator<Item = PatStack<'p, 'tcx>> + Captures<'a> {
604+
self.head().flatten_or_pat().into_iter().map(move |pat| PatStack {
605+
pats: cx
606+
.dropless_arena
607+
.alloc_from_iter(once(pat).chain(self.pats[1..].iter().copied())),
606608
})
607609
}
608610

@@ -616,10 +618,12 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
616618
// We pop the head pattern and push the new fields extracted from the arguments of
617619
// `self.head()`.
618620
let ctor_fields = self.head().specialize(pcx, ctor);
619-
let mut new_pats = SmallVec::<[_; 2]>::with_capacity(self.len() + ctor_fields.len() - 1);
620-
new_pats.extend_from_slice(&ctor_fields);
621-
new_pats.extend_from_slice(&self.pats[1..]);
622-
PatStack { pats: new_pats }
621+
PatStack {
622+
pats: pcx
623+
.cx
624+
.dropless_arena
625+
.alloc_from_iter(ctor_fields.into_iter().chain(self.pats[1..].iter().copied())),
626+
}
623627
}
624628
}
625629

@@ -670,8 +674,11 @@ impl<'p, 'tcx> MatrixRow<'p, 'tcx> {
670674

671675
// Recursively expand the first or-pattern into its subpatterns. Only useful if the pattern is
672676
// an or-pattern. Panics if `self` is empty.
673-
fn expand_or_pat<'a>(&'a self) -> impl Iterator<Item = MatrixRow<'p, 'tcx>> + Captures<'a> {
674-
self.pats.expand_or_pat().map(|patstack| MatrixRow {
677+
fn expand_or_pat<'a>(
678+
&'a self,
679+
cx: &'a MatchCheckCtxt<'p, 'tcx>,
680+
) -> impl Iterator<Item = MatrixRow<'p, 'tcx>> + Captures<'a> {
681+
self.pats.expand_or_pat(cx).map(|patstack| MatrixRow {
675682
pats: patstack,
676683
parent_row: self.parent_row,
677684
is_under_guard: self.is_under_guard,
@@ -723,10 +730,10 @@ struct Matrix<'p, 'tcx> {
723730
impl<'p, 'tcx> Matrix<'p, 'tcx> {
724731
/// Pushes a new row to the matrix. If the row starts with an or-pattern, this recursively
725732
/// expands it. Internal method, prefer [`Matrix::new`].
726-
fn expand_and_push(&mut self, row: MatrixRow<'p, 'tcx>) {
733+
fn expand_and_push(&mut self, cx: &MatchCheckCtxt<'p, 'tcx>, row: MatrixRow<'p, 'tcx>) {
727734
if !row.is_empty() && row.head().is_or_pat() {
728735
// Expand nested or-patterns.
729-
for new_row in row.expand_or_pat() {
736+
for new_row in row.expand_or_pat(cx) {
730737
self.rows.push(new_row);
731738
}
732739
} else {
@@ -737,16 +744,16 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
737744
/// Build a new matrix from an iterator of `MatchArm`s.
738745
fn new(cx: &MatchCheckCtxt<'p, 'tcx>, arms: &[MatchArm<'p, 'tcx>], scrut_ty: Ty<'tcx>) -> Self {
739746
let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty, DUMMY_SP));
740-
let wildcard_row = PatStack::from_pattern(wild_pattern);
747+
let wildcard_row = PatStack::from_pattern(cx, wild_pattern);
741748
let mut matrix = Matrix { rows: Vec::with_capacity(arms.len()), wildcard_row };
742749
for (row_id, arm) in arms.iter().enumerate() {
743750
let v = MatrixRow {
744-
pats: PatStack::from_pattern(arm.pat),
751+
pats: PatStack::from_pattern(cx, arm.pat),
745752
parent_row: row_id, // dummy, we won't read it
746753
is_under_guard: arm.has_guard,
747754
reachable: false,
748755
};
749-
matrix.expand_and_push(v);
756+
matrix.expand_and_push(cx, v);
750757
}
751758
matrix
752759
}
@@ -807,7 +814,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
807814
for (i, row) in self.rows().enumerate() {
808815
if ctor.is_covered_by(pcx, row.head().ctor()) {
809816
let new_row = row.pop_head_constructor(pcx, ctor, i);
810-
matrix.expand_and_push(new_row);
817+
matrix.expand_and_push(pcx.cx, new_row);
811818
}
812819
}
813820
matrix

0 commit comments

Comments
 (0)