Skip to content

Commit c0c6c32

Browse files
committed
Move lower_match_tree
1 parent 878ccd2 commit c0c6c32

File tree

1 file changed

+64
-65
lines changed
  • compiler/rustc_mir_build/src/build/matches

1 file changed

+64
-65
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

Lines changed: 64 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -380,71 +380,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
380380
.collect()
381381
}
382382

383-
/// Create the decision tree for the match expression, starting from `block`.
384-
///
385-
/// Modifies `candidates` to store the bindings and type ascriptions for
386-
/// that candidate.
387-
fn lower_match_tree<'pat>(
388-
&mut self,
389-
block: BasicBlock,
390-
scrutinee_span: Span,
391-
scrutinee_place_builder: &PlaceBuilder<'tcx>,
392-
match_start_span: Span,
393-
candidates: &mut [&mut Candidate<'pat, 'tcx>],
394-
) {
395-
// See the doc comment on `match_candidates` for why we have an
396-
// otherwise block. Match checking will ensure this is actually
397-
// unreachable.
398-
let otherwise_block = self.cfg.start_new_block();
399-
400-
// This will generate code to test scrutinee_place and
401-
// branch to the appropriate arm block
402-
self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates);
403-
404-
let source_info = self.source_info(scrutinee_span);
405-
406-
// Matching on a `scrutinee_place` with an uninhabited type doesn't
407-
// generate any memory reads by itself, and so if the place "expression"
408-
// contains unsafe operations like raw pointer dereferences or union
409-
// field projections, we wouldn't know to require an `unsafe` block
410-
// around a `match` equivalent to `std::intrinsics::unreachable()`.
411-
// See issue #47412 for this hole being discovered in the wild.
412-
//
413-
// HACK(eddyb) Work around the above issue by adding a dummy inspection
414-
// of `scrutinee_place`, specifically by applying `ReadForMatch`.
415-
//
416-
// NOTE: ReadForMatch also checks that the scrutinee is initialized.
417-
// This is currently needed to not allow matching on an uninitialized,
418-
// uninhabited value. If we get never patterns, those will check that
419-
// the place is initialized, and so this read would only be used to
420-
// check safety.
421-
let cause_matched_place = FakeReadCause::ForMatchedPlace(None);
422-
423-
if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) {
424-
self.cfg.push_fake_read(
425-
otherwise_block,
426-
source_info,
427-
cause_matched_place,
428-
scrutinee_place,
429-
);
430-
}
431-
432-
self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable);
433-
434-
// Link each leaf candidate to the `pre_binding_block` of the next one.
435-
let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None;
436-
437-
for candidate in candidates {
438-
candidate.visit_leaves(|leaf_candidate| {
439-
if let Some(ref mut prev) = previous_candidate {
440-
assert!(leaf_candidate.false_edge_start_block.is_some());
441-
prev.next_candidate_start_block = leaf_candidate.false_edge_start_block;
442-
}
443-
previous_candidate = Some(leaf_candidate);
444-
});
445-
}
446-
}
447-
448383
/// Lower the bindings, guards and arm bodies of a `match` expression.
449384
///
450385
/// The decision tree should have already been created
@@ -1275,6 +1210,70 @@ pub(crate) struct ArmHasGuard(pub(crate) bool);
12751210
// Main matching algorithm
12761211

12771212
impl<'a, 'tcx> Builder<'a, 'tcx> {
1213+
/// The entrypoint of the matching algorithm. Create the decision tree for the match expression,
1214+
/// starting from `block`.
1215+
///
1216+
/// Modifies `candidates` to store the bindings and type ascriptions for
1217+
/// that candidate.
1218+
fn lower_match_tree<'pat>(
1219+
&mut self,
1220+
block: BasicBlock,
1221+
scrutinee_span: Span,
1222+
scrutinee_place_builder: &PlaceBuilder<'tcx>,
1223+
match_start_span: Span,
1224+
candidates: &mut [&mut Candidate<'pat, 'tcx>],
1225+
) {
1226+
// See the doc comment on `match_candidates` for why we have an
1227+
// otherwise block. Match checking will ensure this is actually
1228+
// unreachable.
1229+
let otherwise_block = self.cfg.start_new_block();
1230+
1231+
// This will generate code to test scrutinee_place and branch to the appropriate arm block
1232+
self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates);
1233+
1234+
let source_info = self.source_info(scrutinee_span);
1235+
1236+
// Matching on a `scrutinee_place` with an uninhabited type doesn't
1237+
// generate any memory reads by itself, and so if the place "expression"
1238+
// contains unsafe operations like raw pointer dereferences or union
1239+
// field projections, we wouldn't know to require an `unsafe` block
1240+
// around a `match` equivalent to `std::intrinsics::unreachable()`.
1241+
// See issue #47412 for this hole being discovered in the wild.
1242+
//
1243+
// HACK(eddyb) Work around the above issue by adding a dummy inspection
1244+
// of `scrutinee_place`, specifically by applying `ReadForMatch`.
1245+
//
1246+
// NOTE: ReadForMatch also checks that the scrutinee is initialized.
1247+
// This is currently needed to not allow matching on an uninitialized,
1248+
// uninhabited value. If we get never patterns, those will check that
1249+
// the place is initialized, and so this read would only be used to
1250+
// check safety.
1251+
let cause_matched_place = FakeReadCause::ForMatchedPlace(None);
1252+
1253+
if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) {
1254+
self.cfg.push_fake_read(
1255+
otherwise_block,
1256+
source_info,
1257+
cause_matched_place,
1258+
scrutinee_place,
1259+
);
1260+
}
1261+
1262+
self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable);
1263+
1264+
// Link each leaf candidate to the `false_edge_start_block` of the next one.
1265+
let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None;
1266+
for candidate in candidates {
1267+
candidate.visit_leaves(|leaf_candidate| {
1268+
if let Some(ref mut prev) = previous_candidate {
1269+
assert!(leaf_candidate.false_edge_start_block.is_some());
1270+
prev.next_candidate_start_block = leaf_candidate.false_edge_start_block;
1271+
}
1272+
previous_candidate = Some(leaf_candidate);
1273+
});
1274+
}
1275+
}
1276+
12781277
/// The main match algorithm. It begins with a set of candidates
12791278
/// `candidates` and has the job of generating code to determine
12801279
/// which of these candidates, if any, is the correct one. The

0 commit comments

Comments
 (0)