rustc_mir_build: use IndexMap in TestKind::SwitchInt
This commit is contained in:
parent
c61f1c8bfa
commit
4efc7e92fa
2 changed files with 17 additions and 23 deletions
|
@ -11,7 +11,7 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
|||
use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode};
|
||||
use crate::thir::{self, *};
|
||||
use rustc_data_structures::{
|
||||
fx::{FxHashMap, FxHashSet},
|
||||
fx::{FxHashSet, FxIndexMap},
|
||||
stack::ensure_sufficient_stack,
|
||||
};
|
||||
use rustc_hir::HirId;
|
||||
|
@ -817,9 +817,7 @@ enum TestKind<'tcx> {
|
|||
///
|
||||
/// For `bool` we always generate two edges, one for `true` and one for
|
||||
/// `false`.
|
||||
options: Vec<u128>,
|
||||
/// Reverse map used to ensure that the values in `options` are unique.
|
||||
indices: FxHashMap<&'tcx ty::Const<'tcx>, usize>,
|
||||
options: FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
|
||||
},
|
||||
|
||||
/// Test for equality with value, possibly after an unsizing coercion to
|
||||
|
@ -1396,14 +1394,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// may want to add cases based on the candidates that are
|
||||
// available
|
||||
match test.kind {
|
||||
TestKind::SwitchInt { switch_ty, ref mut options, ref mut indices } => {
|
||||
TestKind::SwitchInt { switch_ty, ref mut options } => {
|
||||
for candidate in candidates.iter() {
|
||||
if !self.add_cases_to_switch(
|
||||
&match_place,
|
||||
candidate,
|
||||
switch_ty,
|
||||
options,
|
||||
indices,
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::build::matches::{Candidate, MatchPair, Test, TestKind};
|
|||
use crate::build::Builder;
|
||||
use crate::thir::pattern::compare_const_vals;
|
||||
use crate::thir::*;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_hir::RangeEnd;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir::*;
|
||||
|
@ -44,8 +44,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
// these maps are empty to start; cases are
|
||||
// added below in add_cases_to_switch
|
||||
options: vec![],
|
||||
indices: Default::default(),
|
||||
options: Default::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -83,8 +82,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
test_place: &Place<'tcx>,
|
||||
candidate: &Candidate<'pat, 'tcx>,
|
||||
switch_ty: Ty<'tcx>,
|
||||
options: &mut Vec<u128>,
|
||||
indices: &mut FxHashMap<&'tcx ty::Const<'tcx>, usize>,
|
||||
options: &mut FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
|
||||
) -> bool {
|
||||
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
|
||||
Some(match_pair) => match_pair,
|
||||
|
@ -95,9 +93,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
match *match_pair.pattern.kind {
|
||||
PatKind::Constant { value } => {
|
||||
indices.entry(value).or_insert_with(|| {
|
||||
options.push(value.eval_bits(self.hir.tcx(), self.hir.param_env, switch_ty));
|
||||
options.len() - 1
|
||||
options.entry(value).or_insert_with(|| {
|
||||
value.eval_bits(self.hir.tcx(), self.hir.param_env, switch_ty)
|
||||
});
|
||||
true
|
||||
}
|
||||
|
@ -106,7 +103,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
PatKind::Range(range) => {
|
||||
// Check that none of the switch values are in the range.
|
||||
self.values_not_contained_in_range(range, indices).unwrap_or(false)
|
||||
self.values_not_contained_in_range(range, options).unwrap_or(false)
|
||||
}
|
||||
PatKind::Slice { .. }
|
||||
| PatKind::Array { .. }
|
||||
|
@ -216,7 +213,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
TestKind::SwitchInt { switch_ty, ref options, indices: _ } => {
|
||||
TestKind::SwitchInt { switch_ty, ref options } => {
|
||||
let target_blocks = make_target_blocks(self);
|
||||
let terminator = if switch_ty.kind == ty::Bool {
|
||||
assert!(!options.is_empty() && options.len() <= 2);
|
||||
|
@ -236,7 +233,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
TerminatorKind::SwitchInt {
|
||||
discr: Operand::Copy(place),
|
||||
switch_ty,
|
||||
values: options.clone().into(),
|
||||
values: options.values().copied().collect(),
|
||||
targets: target_blocks,
|
||||
}
|
||||
};
|
||||
|
@ -532,20 +529,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// FIXME(#29623) we could use PatKind::Range to rule
|
||||
// things out here, in some cases.
|
||||
(
|
||||
&TestKind::SwitchInt { switch_ty: _, options: _, ref indices },
|
||||
&TestKind::SwitchInt { switch_ty: _, ref options },
|
||||
&PatKind::Constant { ref value },
|
||||
) if is_switch_ty(match_pair.pattern.ty) => {
|
||||
let index = indices[value];
|
||||
let index = options.get_index_of(value).unwrap();
|
||||
self.candidate_without_match_pair(match_pair_index, candidate);
|
||||
Some(index)
|
||||
}
|
||||
|
||||
(
|
||||
&TestKind::SwitchInt { switch_ty: _, ref options, ref indices },
|
||||
&TestKind::SwitchInt { switch_ty: _, ref options },
|
||||
&PatKind::Range(range),
|
||||
) => {
|
||||
let not_contained =
|
||||
self.values_not_contained_in_range(range, indices).unwrap_or(false);
|
||||
self.values_not_contained_in_range(range, options).unwrap_or(false);
|
||||
|
||||
if not_contained {
|
||||
// No switch values are contained in the pattern range,
|
||||
|
@ -777,9 +774,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
fn values_not_contained_in_range(
|
||||
&self,
|
||||
range: PatRange<'tcx>,
|
||||
indices: &FxHashMap<&'tcx ty::Const<'tcx>, usize>,
|
||||
options: &FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
|
||||
) -> Option<bool> {
|
||||
for &val in indices.keys() {
|
||||
for &val in options.keys() {
|
||||
if self.const_range_contains(range, val)? {
|
||||
return Some(false);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue