1
Fork 0

Visit move out of _0 when visiting return

This commit is contained in:
Jonas Schievink 2020-05-09 16:08:04 +02:00
parent 7c59a81a5f
commit e22cc993fb
4 changed files with 38 additions and 3 deletions

View file

@ -427,13 +427,29 @@ macro_rules! make_mir_visitor {
TerminatorKind::Goto { .. } |
TerminatorKind::Resume |
TerminatorKind::Abort |
TerminatorKind::Return |
TerminatorKind::GeneratorDrop |
TerminatorKind::Unreachable |
TerminatorKind::FalseEdges { .. } |
TerminatorKind::FalseUnwind { .. } => {
}
TerminatorKind::Return => {
// `return` logically moves from the return place `_0`. Note that the place
// cannot be changed by any visitor, though.
let $($mutability)? local = RETURN_PLACE;
self.visit_local(
& $($mutability)? local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
source_location,
);
assert_eq!(
local,
RETURN_PLACE,
"`MutVisitor` tried to mutate return place of `return` terminator"
);
}
TerminatorKind::SwitchInt {
discr,
switch_ty,

View file

@ -73,7 +73,12 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
}
// Conservatively gives up if the dest is an argument,
// because there may be uses of the original argument value.
if body.local_kind(dest_local) == LocalKind::Arg {
// Also gives up on the return place, as we cannot propagate into its implicit
// use by `return`.
if matches!(
body.local_kind(dest_local),
LocalKind::Arg | LocalKind::ReturnPointer
) {
debug!(" Can't copy-propagate local: dest {:?} (argument)", dest_local);
continue;
}

View file

@ -91,6 +91,16 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
*local = self.to;
}
}
fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, location: Location) {
match kind {
TerminatorKind::Return => {
// Do not replace the implicit `_0` access here, as that's not possible. The
// transform already handles `return` correctly.
}
_ => self.super_terminator_kind(kind, location),
}
}
}
struct DerefArgVisitor<'tcx> {

View file

@ -732,7 +732,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
}
fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, loc: Location) {
// Don't try to modify the implicit `_0` access on return (`return` terminators are
// replaced down below anyways).
if !matches!(kind, TerminatorKind::Return) {
self.super_terminator_kind(kind, loc);
}
match *kind {
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => bug!(),