Refactor call terminator to always hold a destination place
This commit is contained in:
@@ -250,8 +250,10 @@ pub enum TerminatorKind<'tcx> {
|
||||
/// This allows the memory occupied by "by-value" arguments to be
|
||||
/// reused across function calls without duplicating the contents.
|
||||
args: Vec<Operand<'tcx>>,
|
||||
/// Destination for the return value. If none, the call necessarily diverges.
|
||||
destination: Option<(Place<'tcx>, BasicBlock)>,
|
||||
/// Where the returned value will be written
|
||||
destination: Place<'tcx>,
|
||||
/// Where to go after this call returns. If none, the call necessarily diverges.
|
||||
target: Option<BasicBlock>,
|
||||
/// Cleanups to be done if the call unwinds.
|
||||
cleanup: Option<BasicBlock>,
|
||||
/// `true` if this is from a call in HIR rather than from an overloaded
|
||||
@@ -415,13 +417,13 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
| GeneratorDrop
|
||||
| Return
|
||||
| Unreachable
|
||||
| Call { destination: None, cleanup: None, .. }
|
||||
| Call { target: None, cleanup: None, .. }
|
||||
| InlineAsm { destination: None, cleanup: None, .. } => {
|
||||
None.into_iter().chain((&[]).into_iter().copied())
|
||||
}
|
||||
Goto { target: t }
|
||||
| Call { destination: None, cleanup: Some(t), .. }
|
||||
| Call { destination: Some((_, t)), cleanup: None, .. }
|
||||
| Call { target: None, cleanup: Some(t), .. }
|
||||
| Call { target: Some(t), cleanup: None, .. }
|
||||
| Yield { resume: t, drop: None, .. }
|
||||
| DropAndReplace { target: t, unwind: None, .. }
|
||||
| Drop { target: t, unwind: None, .. }
|
||||
@@ -431,7 +433,7 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
| InlineAsm { destination: None, cleanup: Some(t), .. } => {
|
||||
Some(t).into_iter().chain((&[]).into_iter().copied())
|
||||
}
|
||||
Call { destination: Some((_, t)), cleanup: Some(ref u), .. }
|
||||
Call { target: Some(t), cleanup: Some(ref u), .. }
|
||||
| Yield { resume: t, drop: Some(ref u), .. }
|
||||
| DropAndReplace { target: t, unwind: Some(ref u), .. }
|
||||
| Drop { target: t, unwind: Some(ref u), .. }
|
||||
@@ -457,11 +459,11 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
| GeneratorDrop
|
||||
| Return
|
||||
| Unreachable
|
||||
| Call { destination: None, cleanup: None, .. }
|
||||
| Call { target: None, cleanup: None, .. }
|
||||
| InlineAsm { destination: None, cleanup: None, .. } => None.into_iter().chain(&mut []),
|
||||
Goto { target: ref mut t }
|
||||
| Call { destination: None, cleanup: Some(ref mut t), .. }
|
||||
| Call { destination: Some((_, ref mut t)), cleanup: None, .. }
|
||||
| Call { target: None, cleanup: Some(ref mut t), .. }
|
||||
| Call { target: Some(ref mut t), cleanup: None, .. }
|
||||
| Yield { resume: ref mut t, drop: None, .. }
|
||||
| DropAndReplace { target: ref mut t, unwind: None, .. }
|
||||
| Drop { target: ref mut t, unwind: None, .. }
|
||||
@@ -471,7 +473,7 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
| InlineAsm { destination: None, cleanup: Some(ref mut t), .. } => {
|
||||
Some(t).into_iter().chain(&mut [])
|
||||
}
|
||||
Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. }
|
||||
Call { target: Some(ref mut t), cleanup: Some(ref mut u), .. }
|
||||
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
||||
| DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. }
|
||||
| Drop { target: ref mut t, unwind: Some(ref mut u), .. }
|
||||
@@ -590,9 +592,7 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
write!(fmt, "replace({:?} <- {:?})", place, value)
|
||||
}
|
||||
Call { func, args, destination, .. } => {
|
||||
if let Some((destination, _)) = destination {
|
||||
write!(fmt, "{:?} = ", destination)?;
|
||||
}
|
||||
write!(fmt, "{:?} = ", destination)?;
|
||||
write!(fmt, "{:?}(", func)?;
|
||||
for (index, arg) in args.iter().enumerate() {
|
||||
if index > 0 {
|
||||
@@ -683,12 +683,12 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
.chain(iter::once("otherwise".into()))
|
||||
.collect()
|
||||
}),
|
||||
Call { destination: Some(_), cleanup: Some(_), .. } => {
|
||||
Call { target: Some(_), cleanup: Some(_), .. } => {
|
||||
vec!["return".into(), "unwind".into()]
|
||||
}
|
||||
Call { destination: Some(_), cleanup: None, .. } => vec!["return".into()],
|
||||
Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()],
|
||||
Call { destination: None, cleanup: None, .. } => vec![],
|
||||
Call { target: Some(_), cleanup: None, .. } => vec!["return".into()],
|
||||
Call { target: None, cleanup: Some(_), .. } => vec!["unwind".into()],
|
||||
Call { target: None, cleanup: None, .. } => vec![],
|
||||
Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()],
|
||||
Yield { drop: None, .. } => vec!["resume".into()],
|
||||
DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => {
|
||||
|
||||
@@ -44,20 +44,15 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
resume_arg: resume_arg.try_fold_with(folder)?,
|
||||
drop,
|
||||
},
|
||||
Call { func, args, destination, cleanup, from_hir_call, fn_span } => {
|
||||
let dest = destination
|
||||
.map(|(loc, dest)| (loc.try_fold_with(folder).map(|loc| (loc, dest))))
|
||||
.transpose()?;
|
||||
|
||||
Call {
|
||||
func: func.try_fold_with(folder)?,
|
||||
args: args.try_fold_with(folder)?,
|
||||
destination: dest,
|
||||
cleanup,
|
||||
from_hir_call,
|
||||
fn_span,
|
||||
}
|
||||
}
|
||||
Call { func, args, destination, target, cleanup, from_hir_call, fn_span } => Call {
|
||||
func: func.try_fold_with(folder)?,
|
||||
args: args.try_fold_with(folder)?,
|
||||
destination: destination.try_fold_with(folder)?,
|
||||
target,
|
||||
cleanup,
|
||||
from_hir_call,
|
||||
fn_span,
|
||||
},
|
||||
Assert { cond, expected, msg, target, cleanup } => {
|
||||
use AssertKind::*;
|
||||
let msg = match msg {
|
||||
@@ -113,9 +108,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
}
|
||||
Yield { ref value, .. } => value.visit_with(visitor),
|
||||
Call { ref func, ref args, ref destination, .. } => {
|
||||
if let Some((ref loc, _)) = *destination {
|
||||
loc.visit_with(visitor)?;
|
||||
};
|
||||
destination.visit_with(visitor)?;
|
||||
func.visit_with(visitor)?;
|
||||
args.visit_with(visitor)
|
||||
}
|
||||
|
||||
@@ -534,6 +534,7 @@ macro_rules! make_mir_visitor {
|
||||
func,
|
||||
args,
|
||||
destination,
|
||||
target: _,
|
||||
cleanup: _,
|
||||
from_hir_call: _,
|
||||
fn_span: _
|
||||
@@ -542,13 +543,11 @@ macro_rules! make_mir_visitor {
|
||||
for arg in args {
|
||||
self.visit_operand(arg, location);
|
||||
}
|
||||
if let Some((destination, _)) = destination {
|
||||
self.visit_place(
|
||||
destination,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Call),
|
||||
location
|
||||
);
|
||||
}
|
||||
self.visit_place(
|
||||
destination,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Call),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
TerminatorKind::Assert {
|
||||
|
||||
Reference in New Issue
Block a user