Fix switch on discriminant detection in a presence of coverage counters

This commit is contained in:
Tomasz Miąsko 2022-02-10 00:00:00 +00:00
parent 502d6aa47b
commit 63bf601537
2 changed files with 32 additions and 13 deletions

View file

@ -710,24 +710,27 @@ fn switch_on_enum_discriminant<'mir, 'tcx>(
block: &'mir mir::BasicBlockData<'tcx>,
switch_on: mir::Place<'tcx>,
) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
match block.statements.last().map(|stmt| &stmt.kind) {
Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))))
if *lhs == switch_on =>
{
match &discriminated.ty(body, tcx).ty.kind() {
ty::Adt(def, _) => Some((*discriminated, def)),
for statement in block.statements.iter().rev() {
match &statement.kind {
mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))
if *lhs == switch_on =>
{
match &discriminated.ty(body, tcx).ty.kind() {
ty::Adt(def, _) => return Some((*discriminated, def)),
// `Rvalue::Discriminant` is also used to get the active yield point for a
// generator, but we do not need edge-specific effects in that case. This may
// change in the future.
ty::Generator(..) => None,
// `Rvalue::Discriminant` is also used to get the active yield point for a
// generator, but we do not need edge-specific effects in that case. This may
// change in the future.
ty::Generator(..) => return None,
t => bug!("`discriminant` called on unexpected type {:?}", t),
t => bug!("`discriminant` called on unexpected type {:?}", t),
}
}
mir::StatementKind::Coverage(_) => continue,
_ => return None,
}
_ => None,
}
None
}
struct OnMutBorrow<F>(F);