Skip to content

Commit

Permalink
Rollup merge of #127858 - Zalathar:pair-tree, r=Nadrieril
Browse files Browse the repository at this point in the history
match lowering: Rename `MatchPair` to `MatchPairTree`

In #120904, `MatchPair` became able to store other match pairs as children, forming a tree. That has made the old name confusing, so this patch renames the type to `MatchPairTree`.

This PR also includes a patch renaming the `test` method to `pick_test_for_match_pair`, since it would conflict with the main change.

r? `@Nadrieril`
  • Loading branch information
matthiaskrgr authored Jul 18, 2024
2 parents 50a90e3 + 411fcb6 commit 4d5ba0d
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 39 deletions.
46 changes: 25 additions & 21 deletions compiler/rustc_mir_build/src/build/matches/match_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,37 @@ use rustc_middle::thir::{self, *};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};

use crate::build::expr::as_place::{PlaceBase, PlaceBuilder};
use crate::build::matches::{FlatPat, MatchPair, TestCase};
use crate::build::matches::{FlatPat, MatchPairTree, TestCase};
use crate::build::Builder;

impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Builds and returns [`MatchPair`] trees, one for each pattern in
/// Builds and returns [`MatchPairTree`] subtrees, one for each pattern in
/// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
/// [`PatKind::Leaf`].
///
/// Used internally by [`MatchPair::new`].
/// Used internally by [`MatchPairTree::for_pattern`].
fn field_match_pairs<'pat>(
&mut self,
place: PlaceBuilder<'tcx>,
subpatterns: &'pat [FieldPat<'tcx>],
) -> Vec<MatchPair<'pat, 'tcx>> {
) -> Vec<MatchPairTree<'pat, 'tcx>> {
subpatterns
.iter()
.map(|fieldpat| {
let place =
place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
MatchPair::new(place, &fieldpat.pattern, self)
MatchPairTree::for_pattern(place, &fieldpat.pattern, self)
})
.collect()
}

/// Builds [`MatchPair`] trees for the prefix/middle/suffix parts of an
/// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
/// array pattern or slice pattern, and adds those trees to `match_pairs`.
///
/// Used internally by [`MatchPair::new`].
/// Used internally by [`MatchPairTree::for_pattern`].
fn prefix_slice_suffix<'pat>(
&mut self,
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
place: &PlaceBuilder<'tcx>,
prefix: &'pat [Box<Pat<'tcx>>],
opt_slice: &'pat Option<Box<Pat<'tcx>>>,
Expand All @@ -52,7 +52,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
let elem =
ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false };
MatchPair::new(place.clone_project(elem), subpattern, self)
MatchPairTree::for_pattern(place.clone_project(elem), subpattern, self)
}));

if let Some(subslice_pat) = opt_slice {
Expand All @@ -62,7 +62,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
to: if exact_size { min_length - suffix_len } else { suffix_len },
from_end: !exact_size,
});
match_pairs.push(MatchPair::new(subslice, subslice_pat, self));
match_pairs.push(MatchPairTree::for_pattern(subslice, subslice_pat, self));
}

match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| {
Expand All @@ -73,19 +73,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
from_end: !exact_size,
};
let place = place.clone_project(elem);
MatchPair::new(place, subpattern, self)
MatchPairTree::for_pattern(place, subpattern, self)
}));
}
}

impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
/// Recursively builds a `MatchPair` tree for the given pattern and its
impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
/// Recursively builds a match pair tree for the given pattern and its
/// subpatterns.
pub(in crate::build) fn new(
pub(in crate::build) fn for_pattern(
mut place_builder: PlaceBuilder<'tcx>,
pattern: &'pat Pat<'tcx>,
cx: &mut Builder<'_, 'tcx>,
) -> MatchPair<'pat, 'tcx> {
) -> MatchPairTree<'pat, 'tcx> {
// 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 @@ -138,7 +138,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
variance,
});

subpairs.push(MatchPair::new(place_builder, subpattern, cx));
subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
TestCase::Irrefutable { ascription, binding: None }
}

Expand All @@ -152,7 +152,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {

if let Some(subpattern) = subpattern.as_ref() {
// this is the `x @ P` case; have to keep matching against `P` now
subpairs.push(MatchPair::new(place_builder, subpattern, cx));
subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
}
TestCase::Irrefutable { ascription: None, binding }
}
Expand Down Expand Up @@ -182,7 +182,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
super::Ascription { annotation, source, variance: ty::Contravariant }
});

subpairs.push(MatchPair::new(place_builder, pattern, cx));
subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
TestCase::Irrefutable { ascription, binding: None }
}

Expand Down Expand Up @@ -231,7 +231,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
}

PatKind::Deref { ref subpattern } => {
subpairs.push(MatchPair::new(place_builder.deref(), subpattern, cx));
subpairs.push(MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx));
default_irrefutable()
}

Expand All @@ -242,13 +242,17 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability),
pattern.span,
);
subpairs.push(MatchPair::new(PlaceBuilder::from(temp).deref(), subpattern, cx));
subpairs.push(MatchPairTree::for_pattern(
PlaceBuilder::from(temp).deref(),
subpattern,
cx,
));
TestCase::Deref { temp, mutability }
}

PatKind::Never => TestCase::Never,
};

MatchPair { place, test_case, subpairs, pattern }
MatchPairTree { place, test_case, subpairs, pattern }
}
}
22 changes: 11 additions & 11 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,23 +1032,23 @@ impl<'tcx> PatternExtraData<'tcx> {
#[derive(Debug, Clone)]
struct FlatPat<'pat, 'tcx> {
/// To match the pattern, all of these must be satisfied...
// Invariant: all the `MatchPair`s are recursively simplified.
// Invariant: all the match pairs are recursively simplified.
// Invariant: or-patterns must be sorted to the end.
match_pairs: Vec<MatchPair<'pat, 'tcx>>,
match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,

extra_data: PatternExtraData<'tcx>,
}

impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
/// Creates a `FlatPat` containing a simplified [`MatchPair`] list/forest
/// Creates a `FlatPat` containing a simplified [`MatchPairTree`] list/forest
/// for the given pattern.
fn new(
place: PlaceBuilder<'tcx>,
pattern: &'pat Pat<'tcx>,
cx: &mut Builder<'_, 'tcx>,
) -> Self {
// First, recursively build a tree of match pairs for the given pattern.
let mut match_pairs = vec![MatchPair::new(place, pattern, cx)];
let mut match_pairs = vec![MatchPairTree::for_pattern(place, pattern, cx)];
let mut extra_data = PatternExtraData {
span: pattern.span,
bindings: Vec::new(),
Expand All @@ -1065,9 +1065,9 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
#[derive(Debug)]
struct Candidate<'pat, 'tcx> {
/// For the candidate to match, all of these must be satisfied...
// Invariant: all the `MatchPair`s are recursively simplified.
// Invariant: all the match pairs are recursively simplified.
// Invariant: or-patterns must be sorted at the end.
match_pairs: Vec<MatchPair<'pat, 'tcx>>,
match_pairs: Vec<MatchPairTree<'pat, 'tcx>>,

/// ...and if this is non-empty, one of these subcandidates also has to match...
// Invariant: at the end of the algorithm, this must never contain a `is_never` candidate
Expand Down Expand Up @@ -1126,7 +1126,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {

/// Returns whether the first match pair of this candidate is an or-pattern.
fn starts_with_or_pattern(&self) -> bool {
matches!(&*self.match_pairs, [MatchPair { test_case: TestCase::Or { .. }, .. }, ..])
matches!(&*self.match_pairs, [MatchPairTree { test_case: TestCase::Or { .. }, .. }, ..])
}

/// Visit the leaf candidates (those with no subcandidates) contained in
Expand Down Expand Up @@ -1206,7 +1206,7 @@ impl<'pat, 'tcx> TestCase<'pat, 'tcx> {
/// Each node also has a list of subpairs (possibly empty) that must also match,
/// and a reference to the THIR pattern it represents.
#[derive(Debug, Clone)]
pub(crate) struct MatchPair<'pat, 'tcx> {
pub(crate) struct MatchPairTree<'pat, 'tcx> {
/// This place...
///
/// ---
Expand Down Expand Up @@ -1629,7 +1629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn create_or_subcandidates<'pat>(
&mut self,
candidate: &mut Candidate<'pat, 'tcx>,
match_pair: MatchPair<'pat, 'tcx>,
match_pair: MatchPairTree<'pat, 'tcx>,
) {
let TestCase::Or { pats } = match_pair.test_case else { bug!() };
debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
Expand Down Expand Up @@ -1813,8 +1813,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// [`Range`]: TestKind::Range
fn pick_test(&mut self, candidates: &[&mut Candidate<'_, 'tcx>]) -> (Place<'tcx>, Test<'tcx>) {
// Extract the match-pair from the highest priority candidate
let match_pair = &candidates.first().unwrap().match_pairs[0];
let test = self.test(match_pair);
let match_pair = &candidates[0].match_pairs[0];
let test = self.pick_test_for_match_pair(match_pair);
// Unwrap is ok after simplification.
let match_place = match_pair.place.unwrap();
debug!(?test, ?match_pair);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! sort of test: for example, testing which variant an enum is, or
//! testing a value against a constant.

use crate::build::matches::{MatchPair, PatternExtraData, TestCase};
use crate::build::matches::{MatchPairTree, PatternExtraData, TestCase};
use crate::build::Builder;
use tracing::{debug, instrument};

Expand All @@ -24,7 +24,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
pub(super) fn simplify_match_pairs<'pat>(
&mut self,
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
match_pairs: &mut Vec<MatchPairTree<'pat, 'tcx>>,
extra_data: &mut PatternExtraData<'tcx>,
) {
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_mir_build/src/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// identify what tests are needed, perform the tests, and then filter
// the candidates based on the result.

use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, TestKind};
use crate::build::matches::{Candidate, MatchPairTree, Test, TestBranch, TestCase, TestKind};
use crate::build::Builder;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::{LangItem, RangeEnd};
Expand All @@ -26,7 +26,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Identifies what test is needed to decide if `match_pair` is applicable.
///
/// It is a bug to call this with a not-fully-simplified pattern.
pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
pub(super) fn pick_test_for_match_pair<'pat>(
&mut self,
match_pair: &MatchPairTree<'pat, 'tcx>,
) -> Test<'tcx> {
let kind = match match_pair.test_case {
TestCase::Variant { adt_def, variant_index: _ } => TestKind::Switch { adt_def },

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_build/src/build/matches/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::marker::PhantomData;

use crate::build::expr::as_place::PlaceBase;
use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase};
use crate::build::matches::{Binding, Candidate, FlatPat, MatchPairTree, TestCase};
use crate::build::Builder;
use rustc_data_structures::fx::FxIndexMap;
use rustc_middle::mir::*;
Expand Down Expand Up @@ -152,7 +152,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
}
}

fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) {
fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
if let TestCase::Or { pats, .. } = &match_pair.test_case {
for flat_pat in pats.iter() {
self.visit_flat_pat(flat_pat)
Expand Down Expand Up @@ -260,7 +260,7 @@ where
}
}

fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) {
fn visit_match_pair(&mut self, match_pair: &MatchPairTree<'_, 'tcx>) {
if let TestCase::Or { pats, .. } = &match_pair.test_case {
// All the or-alternatives should bind the same locals, so we only visit the first one.
self.visit_flat_pat(&pats[0])
Expand Down

0 comments on commit 4d5ba0d

Please sign in to comment.