diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index f18afe7b6327..6df43596673c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1196,8 +1196,8 @@ pub enum TerminatorKind<'tcx> { FalseEdges { /// The target normal control flow will take real_target: BasicBlock, - /// A block control flow could conceptually take, but won't - /// in practice + /// A block control flow could conceptually jump to, but won't in + /// practice imaginary_target: BasicBlock, }, /// A terminator for blocks that only take one path in reality, but where we diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index db4f9e55df66..254f2a4e2a25 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -715,29 +715,46 @@ pub struct MatchPair<'pat, 'tcx: 'pat> { #[derive(Clone, Debug, PartialEq)] enum TestKind<'tcx> { - // test the branches of enum + /// Test the branches of enum. Switch { + /// The enum being tested adt_def: &'tcx ty::AdtDef, + /// The set of variants that we should create a branch for. We also + /// create an additional "otherwise" case. variants: BitSet, }, - // test the branches of enum + /// Test what value an `integer`, `bool` or `char` has. SwitchInt { + /// The type of the value that we're testing. switch_ty: Ty<'tcx>, + /// The (ordered) set of values that we test for. + /// + /// For integers and `char`s we create a branch to each of the values in + /// `options`, as well as an "otherwise" branch for all other values, even + /// in the (rare) case that options is exhaustive. + /// + /// For `bool` we always generate two edges, one for `true` and one for + /// `false`. options: Vec, + /// Reverse map used to ensure that the values in `options` are unique. indices: FxHashMap<&'tcx ty::Const<'tcx>, usize>, }, - // test for equality + /// Test for equality with value, possibly after an unsizing coercion to + /// `ty`, Eq { value: &'tcx ty::Const<'tcx>, + // Integer types are handled by `SwitchInt`, and constants with ADT + // types are converted back into patterns, so this can only be `&str`, + // `&[T]`, `f32` or `f64`. ty: Ty<'tcx>, }, - // test whether the value falls within an inclusive or exclusive range + /// Test whether the value falls within an inclusive or exclusive range Range(PatternRange<'tcx>), - // test length of the slice is equal to len + /// Test length of the slice is equal to len Len { len: u64, op: BinOp, diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index f93ca4b31b3a..21ff16104dcf 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -807,10 +807,16 @@ impl Test<'_> { 2 } TestKind::Switch { adt_def, .. } => { + // While the switch that we generate doesn't test for all + // variants, we have a target for each variant and the + // otherwise case, and we make sure that all of the cases not + // specified have the same block. adt_def.variants.len() + 1 } TestKind::SwitchInt { switch_ty, ref options, .. } => { if switch_ty.is_bool() { + // `bool` is special cased in `perform_test` to always + // branch to two blocks. 2 } else { options.len() + 1