Skip to content

Commit e22cc99

Browse files
Visit move out of _0 when visiting return
1 parent 7c59a81 commit e22cc99

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

src/librustc_middle/mir/visit.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,29 @@ macro_rules! make_mir_visitor {
427427
TerminatorKind::Goto { .. } |
428428
TerminatorKind::Resume |
429429
TerminatorKind::Abort |
430-
TerminatorKind::Return |
431430
TerminatorKind::GeneratorDrop |
432431
TerminatorKind::Unreachable |
433432
TerminatorKind::FalseEdges { .. } |
434433
TerminatorKind::FalseUnwind { .. } => {
435434
}
436435

436+
TerminatorKind::Return => {
437+
// `return` logically moves from the return place `_0`. Note that the place
438+
// cannot be changed by any visitor, though.
439+
let $($mutability)? local = RETURN_PLACE;
440+
self.visit_local(
441+
& $($mutability)? local,
442+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
443+
source_location,
444+
);
445+
446+
assert_eq!(
447+
local,
448+
RETURN_PLACE,
449+
"`MutVisitor` tried to mutate return place of `return` terminator"
450+
);
451+
}
452+
437453
TerminatorKind::SwitchInt {
438454
discr,
439455
switch_ty,

src/librustc_mir/transform/copy_prop.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,12 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
7373
}
7474
// Conservatively gives up if the dest is an argument,
7575
// because there may be uses of the original argument value.
76-
if body.local_kind(dest_local) == LocalKind::Arg {
76+
// Also gives up on the return place, as we cannot propagate into its implicit
77+
// use by `return`.
78+
if matches!(
79+
body.local_kind(dest_local),
80+
LocalKind::Arg | LocalKind::ReturnPointer
81+
) {
7782
debug!(" Can't copy-propagate local: dest {:?} (argument)", dest_local);
7883
continue;
7984
}

src/librustc_mir/transform/generator.rs

+10
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
9191
*local = self.to;
9292
}
9393
}
94+
95+
fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, location: Location) {
96+
match kind {
97+
TerminatorKind::Return => {
98+
// Do not replace the implicit `_0` access here, as that's not possible. The
99+
// transform already handles `return` correctly.
100+
}
101+
_ => self.super_terminator_kind(kind, location),
102+
}
103+
}
94104
}
95105

96106
struct DerefArgVisitor<'tcx> {

src/librustc_mir/transform/inline.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
732732
}
733733

734734
fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, loc: Location) {
735-
self.super_terminator_kind(kind, loc);
735+
// Don't try to modify the implicit `_0` access on return (`return` terminators are
736+
// replaced down below anyways).
737+
if !matches!(kind, TerminatorKind::Return) {
738+
self.super_terminator_kind(kind, loc);
739+
}
736740

737741
match *kind {
738742
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => bug!(),

0 commit comments

Comments
 (0)