Skip to content

Commit

Permalink
!! (WIP) store THIR patterns in Arc instead of Box
Browse files Browse the repository at this point in the history
  • Loading branch information
Zalathar committed Feb 2, 2025
1 parent 2d4bf4a commit 0201b00
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 134 deletions.
37 changes: 19 additions & 18 deletions compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::cmp::Ordering;
use std::fmt;
use std::ops::Index;
use std::sync::Arc;

use rustc_abi::{FieldIdx, Integer, Size, VariantIdx};
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
Expand Down Expand Up @@ -108,7 +109,7 @@ pub enum BodyTy<'tcx> {
#[derive(Clone, Debug, HashStable)]
pub struct Param<'tcx> {
/// The pattern that appears in the parameter list, or None for implicit parameters.
pub pat: Option<Box<Pat<'tcx>>>,
pub pat: Option<Arc<Pat<'tcx>>>,
/// The possibly inferred type.
pub ty: Ty<'tcx>,
/// Span of the explicitly provided type, or None if inferred for closures.
Expand Down Expand Up @@ -231,7 +232,7 @@ pub enum StmtKind<'tcx> {
/// `let <PAT> = ...`
///
/// If a type annotation is included, it is added as an ascription pattern.
pattern: Box<Pat<'tcx>>,
pattern: Arc<Pat<'tcx>>,

/// `let pat: ty = <INIT>`
initializer: Option<ExprId>,
Expand Down Expand Up @@ -379,7 +380,7 @@ pub enum ExprKind<'tcx> {
/// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
Let {
expr: ExprId,
pat: Box<Pat<'tcx>>,
pat: Arc<Pat<'tcx>>,
},
/// A `match` expression.
Match {
Expand Down Expand Up @@ -571,7 +572,7 @@ pub struct FruInfo<'tcx> {
/// A `match` arm.
#[derive(Clone, Debug, HashStable)]
pub struct Arm<'tcx> {
pub pattern: Box<Pat<'tcx>>,
pub pattern: Arc<Pat<'tcx>>,
pub guard: Option<ExprId>,
pub body: ExprId,
pub lint_level: LintLevel,
Expand Down Expand Up @@ -628,7 +629,7 @@ pub enum InlineAsmOperand<'tcx> {
#[derive(Clone, Debug, HashStable, TypeVisitable)]
pub struct FieldPat<'tcx> {
pub field: FieldIdx,
pub pattern: Box<Pat<'tcx>>,
pub pattern: Arc<Pat<'tcx>>,
}

#[derive(Clone, Debug, HashStable, TypeVisitable)]
Expand Down Expand Up @@ -778,7 +779,7 @@ pub enum PatKind<'tcx> {

AscribeUserType {
ascription: Ascription<'tcx>,
subpattern: Box<Pat<'tcx>>,
subpattern: Arc<Pat<'tcx>>,
},

/// `x`, `ref x`, `x @ P`, etc.
Expand All @@ -789,7 +790,7 @@ pub enum PatKind<'tcx> {
#[type_visitable(ignore)]
var: LocalVarId,
ty: Ty<'tcx>,
subpattern: Option<Box<Pat<'tcx>>>,
subpattern: Option<Arc<Pat<'tcx>>>,
/// Is this the leftmost occurrence of the binding, i.e., is `var` the
/// `HirId` of this pattern?
is_primary: bool,
Expand All @@ -812,12 +813,12 @@ pub enum PatKind<'tcx> {

/// `box P`, `&P`, `&mut P`, etc.
Deref {
subpattern: Box<Pat<'tcx>>,
subpattern: Arc<Pat<'tcx>>,
},

/// Deref pattern, written `box P` for now.
DerefPattern {
subpattern: Box<Pat<'tcx>>,
subpattern: Arc<Pat<'tcx>>,
mutability: hir::Mutability,
},

Expand Down Expand Up @@ -851,31 +852,31 @@ pub enum PatKind<'tcx> {
/// Otherwise, the actual pattern that the constant lowered to. As with
/// other constants, inline constants are matched structurally where
/// possible.
subpattern: Box<Pat<'tcx>>,
subpattern: Arc<Pat<'tcx>>,
},

Range(Box<PatRange<'tcx>>),
Range(Arc<PatRange<'tcx>>),

/// Matches against a slice, checking the length and extracting elements.
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
/// e.g., `&[ref xs @ ..]`.
Slice {
prefix: Box<[Box<Pat<'tcx>>]>,
slice: Option<Box<Pat<'tcx>>>,
suffix: Box<[Box<Pat<'tcx>>]>,
prefix: Box<[Arc<Pat<'tcx>>]>,
slice: Option<Arc<Pat<'tcx>>>,
suffix: Box<[Arc<Pat<'tcx>>]>,
},

/// Fixed match against an array; irrefutable.
Array {
prefix: Box<[Box<Pat<'tcx>>]>,
slice: Option<Box<Pat<'tcx>>>,
suffix: Box<[Box<Pat<'tcx>>]>,
prefix: Box<[Arc<Pat<'tcx>>]>,
slice: Option<Arc<Pat<'tcx>>>,
suffix: Box<[Arc<Pat<'tcx>>]>,
},

/// An or-pattern, e.g. `p | q`.
/// Invariant: `pats.len() >= 2`.
Or {
pats: Box<[Box<Pat<'tcx>>]>,
pats: Box<[Arc<Pat<'tcx>>]>,
},

/// A never pattern `!`.
Expand Down
28 changes: 16 additions & 12 deletions compiler/rustc_mir_build/src/builder/matches/match_pair.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::Arc;

use rustc_middle::mir::*;
use rustc_middle::thir::{self, *};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
Expand All @@ -12,11 +14,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// [`PatKind::Leaf`].
///
/// Used internally by [`MatchPairTree::for_pattern`].
fn field_match_pairs<'pat>(
fn field_match_pairs(
&mut self,
place: PlaceBuilder<'tcx>,
subpatterns: &'pat [FieldPat<'tcx>],
) -> Vec<MatchPairTree<'pat, 'tcx>> {
subpatterns: &[FieldPat<'tcx>],
) -> Vec<MatchPairTree<'tcx>> {
subpatterns
.iter()
.map(|fieldpat| {
Expand All @@ -31,13 +33,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// array pattern or slice pattern, and adds those trees to `match_pairs`.
///
/// Used internally by [`MatchPairTree::for_pattern`].
fn prefix_slice_suffix<'pat>(
fn prefix_slice_suffix(
&mut self,
match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
match_pairs: &mut Vec<MatchPairTree<'tcx>>,
place: &PlaceBuilder<'tcx>,
prefix: &'pat [Box<Pat<'tcx>>],
opt_slice: &'pat Option<Box<Pat<'tcx>>>,
suffix: &'pat [Box<Pat<'tcx>>],
prefix: &[Arc<Pat<'tcx>>],
opt_slice: &Option<Arc<Pat<'tcx>>>,
suffix: &[Arc<Pat<'tcx>>],
) {
let tcx = self.tcx;
let (min_length, exact_size) = if let Some(place_resolved) = place.try_to_place(self) {
Expand Down Expand Up @@ -83,14 +85,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
impl<'tcx> MatchPairTree<'tcx> {
/// Recursively builds a match pair tree for the given pattern and its
/// subpatterns.
pub(in crate::builder) fn for_pattern(
mut place_builder: PlaceBuilder<'tcx>,
pattern: &'pat Pat<'tcx>,
pattern: &Arc<Pat<'tcx>>,
cx: &mut Builder<'_, 'tcx>,
) -> MatchPairTree<'pat, 'tcx> {
) -> MatchPairTree<'tcx> {
let pattern = Arc::clone(pattern);

// Force the place type to the pattern's type.
// FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
if let Some(resolved) = place_builder.resolve_upvar(cx) {
Expand Down Expand Up @@ -125,7 +129,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
if range.is_full_range(cx.tcx) == Some(true) {
default_irrefutable()
} else {
TestCase::Range(range)
TestCase::Range(Arc::clone(range))
}
}

Expand Down
Loading

0 comments on commit 0201b00

Please sign in to comment.