1
Fork 0

On TerminatorKind::DropAndReplace still handle unused_mut correctly

This commit is contained in:
Chris Gregory 2019-06-01 18:42:59 -05:00
parent 03ee55bb1c
commit 911d205b1f

View file

@ -52,6 +52,24 @@ struct GatherUsedMutsVisitor<'visit, 'cx: 'visit, 'gcx: 'tcx, 'tcx: 'cx> {
mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>, mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
} }
impl<'visit, 'cx, 'gcx, 'tcx> GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
fn remove_never_initialized_mut_locals(into: &Place) {
// Remove any locals that we found were initialized from the
// `never_initialized_mut_locals` set. At the end, the only remaining locals will
// be those that were never initialized - we will consider those as being used as
// they will either have been removed by unreachable code optimizations; or linted
// as unused variables.
if let Some(local) = into.base_local() {
debug!(
"visit_statement: statement={:?} local={:?} \
never_initialized_mut_locals={:?}",
statement, local, self.never_initialized_mut_locals
);
let _ = self.never_initialized_mut_locals.remove(&local);
}
}
}
impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> { impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
fn visit_terminator_kind( fn visit_terminator_kind(
&mut self, &mut self,
@ -61,14 +79,10 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c
debug!("visit_terminator_kind: kind={:?}", kind); debug!("visit_terminator_kind: kind={:?}", kind);
match &kind { match &kind {
TerminatorKind::Call { destination: Some((into, _)), .. } => { TerminatorKind::Call { destination: Some((into, _)), .. } => {
if let Some(local) = into.base_local() { self.remove_never_initialized_mut_locals(&into);
debug!( },
"visit_terminator_kind: kind={:?} local={:?} \ TerminatorKind::DropAndReplace { location, .. } => {
never_initialized_mut_locals={:?}", self.remove_never_initialized_mut_locals(&location);
kind, local, self.never_initialized_mut_locals
);
let _ = self.never_initialized_mut_locals.remove(&local);
}
}, },
_ => {}, _ => {},
} }
@ -81,19 +95,7 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c
) { ) {
match &statement.kind { match &statement.kind {
StatementKind::Assign(into, _) => { StatementKind::Assign(into, _) => {
// Remove any locals that we found were initialized from the self.remove_never_initialized_mut_locals(into);
// `never_initialized_mut_locals` set. At the end, the only remaining locals will
// be those that were never initialized - we will consider those as being used as
// they will either have been removed by unreachable code optimizations; or linted
// as unused variables.
if let Some(local) = into.base_local() {
debug!(
"visit_statement: statement={:?} local={:?} \
never_initialized_mut_locals={:?}",
statement, local, self.never_initialized_mut_locals
);
let _ = self.never_initialized_mut_locals.remove(&local);
}
}, },
_ => {}, _ => {},
} }