Skip to content

Commit 998d0e9

Browse files
committed
Move the loop out of the function
1 parent e561dbb commit 998d0e9

File tree

1 file changed

+50
-51
lines changed
  • compiler/rustc_mir_build/src/build/matches

1 file changed

+50
-51
lines changed

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

+50-51
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12071207
&mut self,
12081208
span: Span,
12091209
scrutinee_span: Span,
1210-
start_block: BasicBlock,
1210+
mut start_block: BasicBlock,
12111211
otherwise_block: BasicBlock,
12121212
candidates: &mut [&mut Candidate<'_, 'tcx>],
12131213
fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
@@ -1219,14 +1219,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12191219
debug!("match_candidates: {:?} candidates fully matched", fully_matched);
12201220
let (matched_candidates, unmatched_candidates) = candidates.split_at_mut(fully_matched);
12211221

1222-
let block = self.select_matched_candidates(matched_candidates, start_block, fake_borrows);
1222+
for candidate in matched_candidates.iter_mut() {
1223+
start_block = self.select_matched_candidate(candidate, start_block, fake_borrows);
1224+
}
12231225

12241226
// If there are no candidates that still need testing, we're
12251227
// done. Since all matches are exhaustive, execution should
12261228
// never reach this point.
12271229
if unmatched_candidates.is_empty() {
12281230
let source_info = self.source_info(span);
1229-
self.cfg.goto(block, source_info, otherwise_block);
1231+
self.cfg.goto(start_block, source_info, otherwise_block);
12301232
return;
12311233
}
12321234

@@ -1235,7 +1237,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12351237
span,
12361238
scrutinee_span,
12371239
unmatched_candidates,
1238-
block,
1240+
start_block,
12391241
otherwise_block,
12401242
fake_borrows,
12411243
);
@@ -1260,67 +1262,64 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12601262
/// * the [otherwise block] of the third pattern to a block with an
12611263
/// [`Unreachable` terminator](TerminatorKind::Unreachable).
12621264
///
1263-
/// In addition, we add fake edges from the otherwise blocks to the
1265+
/// In addition, we later add fake edges from the otherwise blocks to the
12641266
/// pre-binding block of the next candidate in the original set of
12651267
/// candidates.
12661268
///
12671269
/// [pre-binding block]: Candidate::pre_binding_block
12681270
/// [otherwise block]: Candidate::otherwise_block
1269-
fn select_matched_candidates(
1271+
fn select_matched_candidate(
12701272
&mut self,
1271-
matched_candidates: &mut [&mut Candidate<'_, 'tcx>],
1273+
candidate: &mut Candidate<'_, 'tcx>,
12721274
start_block: BasicBlock,
12731275
fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
12741276
) -> BasicBlock {
1275-
let mut next_prebinding = start_block;
1276-
for candidate in matched_candidates.iter_mut() {
1277-
assert!(candidate.otherwise_block.is_none());
1278-
assert!(candidate.pre_binding_block.is_none());
1279-
debug_assert!(
1280-
candidate.subcandidates.is_empty(),
1281-
"subcandidates should be empty in select_matched_candidates",
1282-
);
1277+
assert!(candidate.otherwise_block.is_none());
1278+
assert!(candidate.pre_binding_block.is_none());
1279+
debug_assert!(
1280+
candidate.subcandidates.is_empty(),
1281+
"subcandidates should be empty in select_matched_candidates",
1282+
);
12831283

1284-
if let Some(fake_borrows) = fake_borrows {
1285-
// Insert a borrows of prefixes of places that are bound and are
1286-
// behind a dereference projection.
1287-
//
1288-
// These borrows are taken to avoid situations like the following:
1289-
//
1290-
// match x[10] {
1291-
// _ if { x = &[0]; false } => (),
1292-
// y => (), // Out of bounds array access!
1293-
// }
1294-
//
1295-
// match *x {
1296-
// // y is bound by reference in the guard and then by copy in the
1297-
// // arm, so y is 2 in the arm!
1298-
// y if { y == 1 && (x = &2) == () } => y,
1299-
// _ => 3,
1300-
// }
1301-
for Binding { source, .. } in &candidate.bindings {
1302-
if let Some(i) =
1303-
source.projection.iter().rposition(|elem| elem == ProjectionElem::Deref)
1304-
{
1305-
let proj_base = &source.projection[..i];
1306-
1307-
fake_borrows.insert(Place {
1308-
local: source.local,
1309-
projection: self.tcx.mk_place_elems(proj_base),
1310-
});
1311-
}
1284+
if let Some(fake_borrows) = fake_borrows {
1285+
// Insert a borrows of prefixes of places that are bound and are
1286+
// behind a dereference projection.
1287+
//
1288+
// These borrows are taken to avoid situations like the following:
1289+
//
1290+
// match x[10] {
1291+
// _ if { x = &[0]; false } => (),
1292+
// y => (), // Out of bounds array access!
1293+
// }
1294+
//
1295+
// match *x {
1296+
// // y is bound by reference in the guard and then by copy in the
1297+
// // arm, so y is 2 in the arm!
1298+
// y if { y == 1 && (x = &2) == () } => y,
1299+
// _ => 3,
1300+
// }
1301+
for Binding { source, .. } in &candidate.bindings {
1302+
if let Some(i) =
1303+
source.projection.iter().rposition(|elem| elem == ProjectionElem::Deref)
1304+
{
1305+
let proj_base = &source.projection[..i];
1306+
1307+
fake_borrows.insert(Place {
1308+
local: source.local,
1309+
projection: self.tcx.mk_place_elems(proj_base),
1310+
});
13121311
}
13131312
}
1313+
}
13141314

1315-
candidate.pre_binding_block = Some(next_prebinding);
1316-
next_prebinding = self.cfg.start_new_block();
1317-
if candidate.has_guard {
1318-
// Create the otherwise block for this candidate, which is the
1319-
// pre-binding block for the next candidate.
1320-
candidate.otherwise_block = Some(next_prebinding);
1321-
}
1315+
candidate.pre_binding_block = Some(start_block);
1316+
let otherwise_block = self.cfg.start_new_block();
1317+
if candidate.has_guard {
1318+
// Create the otherwise block for this candidate, which is the
1319+
// pre-binding block for the next candidate.
1320+
candidate.otherwise_block = Some(otherwise_block);
13221321
}
1323-
next_prebinding
1322+
otherwise_block
13241323
}
13251324

13261325
/// Tests a candidate where there are only or-patterns left to test, or

0 commit comments

Comments
 (0)