Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a7d791b

Browse files
committedNov 26, 2019
Auto merge of #66646 - RalfJung:unwind_to_block, r=oli-obk
refactor goto_block and also add unwind_to_block r? @oli-obk
2 parents 797fd92 + 6797d52 commit a7d791b

File tree

6 files changed

+136
-135
lines changed

6 files changed

+136
-135
lines changed
 

‎src/librustc_mir/const_eval.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
323323
ecx: &mut InterpCx<'mir, 'tcx, Self>,
324324
instance: ty::Instance<'tcx>,
325325
args: &[OpTy<'tcx>],
326-
dest: Option<PlaceTy<'tcx>>,
327-
ret: Option<mir::BasicBlock>,
326+
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
328327
_unwind: Option<mir::BasicBlock> // unwinding is not supported in consts
329328
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
330329
debug!("eval_fn_call: {:?}", instance);
@@ -337,8 +336,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
337336
// Some functions we support even if they are non-const -- but avoid testing
338337
// that for const fn! We certainly do *not* want to actually call the fn
339338
// though, so be sure we return here.
340-
return if ecx.hook_panic_fn(instance, args, dest)? {
341-
ecx.goto_block(ret)?; // fully evaluated and done
339+
return if ecx.hook_panic_fn(instance, args, ret)? {
342340
Ok(None)
343341
} else {
344342
throw_unsup_format!("calling non-const function `{}`", instance)
@@ -364,8 +362,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
364362
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
365363
fn_val: !,
366364
_args: &[OpTy<'tcx>],
367-
_dest: Option<PlaceTy<'tcx>>,
368-
_ret: Option<mir::BasicBlock>,
365+
_ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
366+
_unwind: Option<mir::BasicBlock>
369367
) -> InterpResult<'tcx> {
370368
match fn_val {}
371369
}
@@ -375,11 +373,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
375373
span: Span,
376374
instance: ty::Instance<'tcx>,
377375
args: &[OpTy<'tcx>],
378-
dest: Option<PlaceTy<'tcx>>,
379-
_ret: Option<mir::BasicBlock>,
376+
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
380377
_unwind: Option<mir::BasicBlock>
381378
) -> InterpResult<'tcx> {
382-
if ecx.emulate_intrinsic(span, instance, args, dest)? {
379+
if ecx.emulate_intrinsic(span, instance, args, ret)? {
383380
return Ok(());
384381
}
385382
// An intrinsic that we do not support

‎src/librustc_mir/interpret/eval_context.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,37 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
555555
}
556556
}
557557

558+
/// Jump to the given block.
559+
#[inline]
560+
pub fn go_to_block(&mut self, target: mir::BasicBlock) {
561+
let frame = self.frame_mut();
562+
frame.block = Some(target);
563+
frame.stmt = 0;
564+
}
565+
566+
/// *Return* to the given `target` basic block.
567+
/// Do *not* use for unwinding! Use `unwind_to_block` instead.
568+
///
569+
/// If `target` is `None`, that indicates the function cannot return, so we raise UB.
570+
pub fn return_to_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
571+
if let Some(target) = target {
572+
Ok(self.go_to_block(target))
573+
} else {
574+
throw_ub!(Unreachable)
575+
}
576+
}
577+
578+
/// *Unwind* to the given `target` basic block.
579+
/// Do *not* use for returning! Use `return_to_block` instead.
580+
///
581+
/// If `target` is `None`, that indicates the function does not need cleanup during
582+
/// unwinding, and we will just keep propagating that upwards.
583+
pub fn unwind_to_block(&mut self, target: Option<mir::BasicBlock>) {
584+
let frame = self.frame_mut();
585+
frame.block = target;
586+
frame.stmt = 0;
587+
}
588+
558589
/// Pops the current frame from the stack, deallocating the
559590
/// memory for allocated locals.
560591
///
@@ -630,10 +661,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
630661
if cur_unwinding {
631662
// Follow the unwind edge.
632663
let unwind = next_block.expect("Encounted StackPopCleanup::None when unwinding!");
633-
let next_frame = self.frame_mut();
634-
// If `unwind` is `None`, we'll leave that function immediately again.
635-
next_frame.block = unwind;
636-
next_frame.stmt = 0;
664+
self.unwind_to_block(unwind);
637665
} else {
638666
// Follow the normal return edge.
639667
// Validate the return value. Do this after deallocating so that we catch dangling
@@ -660,7 +688,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
660688

661689
// Jump to new block -- *after* validation so that the spans make more sense.
662690
if let Some(ret) = next_block {
663-
self.goto_block(ret)?;
691+
self.return_to_block(ret)?;
664692
}
665693
}
666694

‎src/librustc_mir/interpret/intrinsics.rs

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use rustc::ty::layout::{LayoutOf, Primitive, Size};
99
use rustc::ty::subst::SubstsRef;
1010
use rustc::hir::def_id::DefId;
1111
use rustc::ty::TyCtxt;
12-
use rustc::mir::BinOp;
13-
use rustc::mir::interpret::{InterpResult, Scalar, GlobalId, ConstValue};
12+
use rustc::mir::{
13+
self, BinOp,
14+
interpret::{InterpResult, Scalar, GlobalId, ConstValue}
15+
};
1416

1517
use super::{
1618
Machine, PlaceTy, OpTy, InterpCx, ImmTy,
@@ -91,16 +93,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9193
span: Span,
9294
instance: ty::Instance<'tcx>,
9395
args: &[OpTy<'tcx, M::PointerTag>],
94-
dest: Option<PlaceTy<'tcx, M::PointerTag>>,
96+
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
9597
) -> InterpResult<'tcx, bool> {
9698
let substs = instance.substs;
99+
let intrinsic_name = &*self.tcx.item_name(instance.def_id()).as_str();
97100

98-
// We currently do not handle any diverging intrinsics.
99-
let dest = match dest {
100-
Some(dest) => dest,
101-
None => return Ok(false)
101+
// We currently do not handle any intrinsics that are *allowed* to diverge,
102+
// but `transmute` could lack a return place in case of UB.
103+
let (dest, ret) = match ret {
104+
Some(p) => p,
105+
None => match intrinsic_name {
106+
"transmute" => throw_ub!(Unreachable),
107+
_ => return Ok(false),
108+
}
102109
};
103-
let intrinsic_name = &*self.tcx.item_name(instance.def_id()).as_str();
104110

105111
match intrinsic_name {
106112
"caller_location" => {
@@ -268,34 +274,39 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
268274
// exception from the exception.)
269275
// This is the dual to the special exception for offset-by-0
270276
// in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`).
271-
if a.is_bits() && b.is_bits() {
277+
//
278+
// Control flow is weird because we cannot early-return (to reach the
279+
// `go_to_block` at the end).
280+
let done = if a.is_bits() && b.is_bits() {
272281
let a = a.to_machine_usize(self)?;
273282
let b = b.to_machine_usize(self)?;
274283
if a == b && a != 0 {
275284
self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?;
276-
return Ok(true);
277-
}
278-
}
285+
true
286+
} else { false }
287+
} else { false };
279288

280-
// General case: we need two pointers.
281-
let a = self.force_ptr(a)?;
282-
let b = self.force_ptr(b)?;
283-
if a.alloc_id != b.alloc_id {
284-
throw_ub_format!(
285-
"ptr_offset_from cannot compute offset of pointers into different \
286-
allocations.",
287-
);
289+
if !done {
290+
// General case: we need two pointers.
291+
let a = self.force_ptr(a)?;
292+
let b = self.force_ptr(b)?;
293+
if a.alloc_id != b.alloc_id {
294+
throw_ub_format!(
295+
"ptr_offset_from cannot compute offset of pointers into different \
296+
allocations.",
297+
);
298+
}
299+
let usize_layout = self.layout_of(self.tcx.types.usize)?;
300+
let a_offset = ImmTy::from_uint(a.offset.bytes(), usize_layout);
301+
let b_offset = ImmTy::from_uint(b.offset.bytes(), usize_layout);
302+
let (val, _overflowed, _ty) = self.overflowing_binary_op(
303+
BinOp::Sub, a_offset, b_offset,
304+
)?;
305+
let pointee_layout = self.layout_of(substs.type_at(0))?;
306+
let val = ImmTy::from_scalar(val, isize_layout);
307+
let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
308+
self.exact_div(val, size, dest)?;
288309
}
289-
let usize_layout = self.layout_of(self.tcx.types.usize)?;
290-
let a_offset = ImmTy::from_uint(a.offset.bytes(), usize_layout);
291-
let b_offset = ImmTy::from_uint(b.offset.bytes(), usize_layout);
292-
let (val, _overflowed, _ty) = self.overflowing_binary_op(
293-
BinOp::Sub, a_offset, b_offset,
294-
)?;
295-
let pointee_layout = self.layout_of(substs.type_at(0))?;
296-
let val = ImmTy::from_scalar(val, isize_layout);
297-
let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout);
298-
self.exact_div(val, size, dest)?;
299310
}
300311

301312
"transmute" => {
@@ -350,6 +361,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
350361
_ => return Ok(false),
351362
}
352363

364+
self.dump_place(*dest);
365+
self.go_to_block(ret);
353366
Ok(true)
354367
}
355368

@@ -360,7 +373,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
360373
&mut self,
361374
instance: ty::Instance<'tcx>,
362375
args: &[OpTy<'tcx, M::PointerTag>],
363-
_dest: Option<PlaceTy<'tcx, M::PointerTag>>,
376+
_ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
364377
) -> InterpResult<'tcx, bool> {
365378
let def_id = instance.def_id();
366379
if Some(def_id) == self.tcx.lang_items().panic_fn() {

‎src/librustc_mir/interpret/machine.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
141141
/// Returns either the mir to use for the call, or `None` if execution should
142142
/// just proceed (which usually means this hook did all the work that the
143143
/// called function should usually have done). In the latter case, it is
144-
/// this hook's responsibility to call `goto_block(ret)` to advance the instruction pointer!
144+
/// this hook's responsibility to advance the instruction pointer!
145145
/// (This is to support functions like `__rust_maybe_catch_panic` that neither find a MIR
146146
/// nor just jump to `ret`, but instead push their own stack frame.)
147147
/// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
@@ -150,30 +150,28 @@ pub trait Machine<'mir, 'tcx>: Sized {
150150
ecx: &mut InterpCx<'mir, 'tcx, Self>,
151151
instance: ty::Instance<'tcx>,
152152
args: &[OpTy<'tcx, Self::PointerTag>],
153-
dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
154-
ret: Option<mir::BasicBlock>,
155-
unwind: Option<mir::BasicBlock>
153+
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
154+
unwind: Option<mir::BasicBlock>,
156155
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
157156

158-
/// Execute `fn_val`. it is the hook's responsibility to advance the instruction
157+
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction
159158
/// pointer as appropriate.
160159
fn call_extra_fn(
161160
ecx: &mut InterpCx<'mir, 'tcx, Self>,
162161
fn_val: Self::ExtraFnVal,
163162
args: &[OpTy<'tcx, Self::PointerTag>],
164-
dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
165-
ret: Option<mir::BasicBlock>,
163+
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
164+
unwind: Option<mir::BasicBlock>,
166165
) -> InterpResult<'tcx>;
167166

168-
/// Directly process an intrinsic without pushing a stack frame.
169-
/// If this returns successfully, the engine will take care of jumping to the next block.
167+
/// Directly process an intrinsic without pushing a stack frame. It is the hook's
168+
/// responsibility to advance the instruction pointer as appropriate.
170169
fn call_intrinsic(
171170
ecx: &mut InterpCx<'mir, 'tcx, Self>,
172171
span: Span,
173172
instance: ty::Instance<'tcx>,
174173
args: &[OpTy<'tcx, Self::PointerTag>],
175-
dest: Option<PlaceTy<'tcx, Self::PointerTag>>,
176-
ret: Option<mir::BasicBlock>,
174+
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
177175
unwind: Option<mir::BasicBlock>,
178176
) -> InterpResult<'tcx>;
179177

‎src/librustc_mir/interpret/terminator.rs

Lines changed: 40 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@ use super::{
1212
};
1313

1414
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
15-
#[inline]
16-
pub fn goto_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
17-
if let Some(target) = target {
18-
self.frame_mut().block = Some(target);
19-
self.frame_mut().stmt = 0;
20-
Ok(())
21-
} else {
22-
throw_ub!(Unreachable)
23-
}
24-
}
25-
2615
pub(super) fn eval_terminator(
2716
&mut self,
2817
terminator: &mir::Terminator<'tcx>,
@@ -34,7 +23,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3423
self.pop_stack_frame(/* unwinding */ false)?
3524
}
3625

37-
Goto { target } => self.goto_block(Some(target))?,
26+
Goto { target } => self.go_to_block(target),
3827

3928
SwitchInt {
4029
ref discr,
@@ -60,7 +49,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6049
}
6150
}
6251

63-
self.goto_block(Some(target_block))?;
52+
self.go_to_block(target_block);
6453
}
6554

6655
Call {
@@ -70,11 +59,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
7059
ref cleanup,
7160
..
7261
} => {
73-
let (dest, ret) = match *destination {
74-
Some((ref lv, target)) => (Some(self.eval_place(lv)?), Some(target)),
75-
None => (None, None),
76-
};
77-
7862
let func = self.eval_operand(func, None)?;
7963
let (fn_val, abi) = match func.layout.ty.kind {
8064
ty::FnPtr(sig) => {
@@ -92,12 +76,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9276
}
9377
};
9478
let args = self.eval_operands(args)?;
79+
let ret = match destination {
80+
Some((dest, ret)) => Some((self.eval_place(dest)?, *ret)),
81+
None => None,
82+
};
9583
self.eval_fn_call(
9684
fn_val,
9785
terminator.source_info.span,
9886
abi,
9987
&args[..],
100-
dest,
10188
ret,
10289
*cleanup
10390
)?;
@@ -133,7 +120,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
133120
let cond_val = self.read_immediate(self.eval_operand(cond, None)?)?
134121
.to_scalar()?.to_bool()?;
135122
if expected == cond_val {
136-
self.goto_block(Some(target))?;
123+
self.go_to_block(target);
137124
} else {
138125
// Compute error message
139126
use rustc::mir::interpret::PanicInfo::*;
@@ -249,41 +236,46 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
249236
span: Span,
250237
caller_abi: Abi,
251238
args: &[OpTy<'tcx, M::PointerTag>],
252-
dest: Option<PlaceTy<'tcx, M::PointerTag>>,
253-
ret: Option<mir::BasicBlock>,
239+
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
254240
unwind: Option<mir::BasicBlock>
255241
) -> InterpResult<'tcx> {
256242
trace!("eval_fn_call: {:#?}", fn_val);
257243

258244
let instance = match fn_val {
259245
FnVal::Instance(instance) => instance,
260246
FnVal::Other(extra) => {
261-
return M::call_extra_fn(self, extra, args, dest, ret);
247+
return M::call_extra_fn(self, extra, args, ret, unwind);
262248
}
263249
};
264250

251+
// ABI check
252+
{
253+
let callee_abi = {
254+
let instance_ty = instance.ty(*self.tcx);
255+
match instance_ty.kind {
256+
ty::FnDef(..) =>
257+
instance_ty.fn_sig(*self.tcx).abi(),
258+
ty::Closure(..) => Abi::RustCall,
259+
ty::Generator(..) => Abi::Rust,
260+
_ => bug!("unexpected callee ty: {:?}", instance_ty),
261+
}
262+
};
263+
let normalize_abi = |abi| match abi {
264+
Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic =>
265+
// These are all the same ABI, really.
266+
Abi::Rust,
267+
abi =>
268+
abi,
269+
};
270+
if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
271+
throw_unsup!(FunctionAbiMismatch(caller_abi, callee_abi))
272+
}
273+
}
274+
265275
match instance.def {
266276
ty::InstanceDef::Intrinsic(..) => {
267277
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
268-
269-
let old_stack = self.cur_frame();
270-
let old_bb = self.frame().block;
271-
M::call_intrinsic(self, span, instance, args, dest, ret, unwind)?;
272-
// No stack frame gets pushed, the main loop will just act as if the
273-
// call completed.
274-
if ret.is_some() {
275-
self.goto_block(ret)?;
276-
} else {
277-
// If this intrinsic call doesn't have a ret block,
278-
// then the intrinsic implementation should have
279-
// changed the stack frame (otherwise, we'll end
280-
// up trying to execute this intrinsic call again)
281-
debug_assert!(self.cur_frame() != old_stack || self.frame().block != old_bb);
282-
}
283-
if let Some(dest) = dest {
284-
self.dump_place(*dest)
285-
}
286-
Ok(())
278+
return M::call_intrinsic(self, span, instance, args, ret, unwind);
287279
}
288280
ty::InstanceDef::VtableShim(..) |
289281
ty::InstanceDef::ReifyShim(..) |
@@ -292,32 +284,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
292284
ty::InstanceDef::DropGlue(..) |
293285
ty::InstanceDef::CloneShim(..) |
294286
ty::InstanceDef::Item(_) => {
295-
// ABI check
296-
{
297-
let callee_abi = {
298-
let instance_ty = instance.ty(*self.tcx);
299-
match instance_ty.kind {
300-
ty::FnDef(..) =>
301-
instance_ty.fn_sig(*self.tcx).abi(),
302-
ty::Closure(..) => Abi::RustCall,
303-
ty::Generator(..) => Abi::Rust,
304-
_ => bug!("unexpected callee ty: {:?}", instance_ty),
305-
}
306-
};
307-
let normalize_abi = |abi| match abi {
308-
Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic =>
309-
// These are all the same ABI, really.
310-
Abi::Rust,
311-
abi =>
312-
abi,
313-
};
314-
if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
315-
throw_unsup!(FunctionAbiMismatch(caller_abi, callee_abi))
316-
}
317-
}
318-
319287
// We need MIR for this fn
320-
let body = match M::find_fn(self, instance, args, dest, ret, unwind)? {
288+
let body = match M::find_fn(self, instance, args, ret, unwind)? {
321289
Some(body) => body,
322290
None => return Ok(()),
323291
};
@@ -326,8 +294,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
326294
instance,
327295
span,
328296
body,
329-
dest,
330-
StackPopCleanup::Goto { ret, unwind }
297+
ret.map(|p| p.0),
298+
StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind }
331299
)?;
332300

333301
// We want to pop this frame again in case there was an error, to put
@@ -410,7 +378,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
410378
throw_unsup!(FunctionArgCountMismatch)
411379
}
412380
// Don't forget to check the return type!
413-
if let Some(caller_ret) = dest {
381+
if let Some((caller_ret, _)) = ret {
414382
let callee_ret = self.eval_place(
415383
&mir::Place::return_place()
416384
)?;
@@ -476,7 +444,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
476444
});
477445
trace!("Patched self operand to {:#?}", args[0]);
478446
// recurse with concrete function
479-
self.eval_fn_call(drop_fn, span, caller_abi, &args, dest, ret, unwind)
447+
self.eval_fn_call(drop_fn, span, caller_abi, &args, ret, unwind)
480448
}
481449
}
482450
}
@@ -516,8 +484,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
516484
span,
517485
Abi::Rust,
518486
&[arg.into()],
519-
Some(dest.into()),
520-
Some(target),
487+
Some((dest.into(), target)),
521488
unwind
522489
)
523490
}

‎src/librustc_mir/transform/const_prop.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
144144
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
145145
_instance: ty::Instance<'tcx>,
146146
_args: &[OpTy<'tcx>],
147-
_dest: Option<PlaceTy<'tcx>>,
148-
_ret: Option<BasicBlock>,
147+
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
149148
_unwind: Option<BasicBlock>,
150149
) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> {
151150
Ok(None)
@@ -155,8 +154,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
155154
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
156155
fn_val: !,
157156
_args: &[OpTy<'tcx>],
158-
_dest: Option<PlaceTy<'tcx>>,
159-
_ret: Option<BasicBlock>,
157+
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
158+
_unwind: Option<BasicBlock>
160159
) -> InterpResult<'tcx> {
161160
match fn_val {}
162161
}
@@ -166,8 +165,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
166165
_span: Span,
167166
_instance: ty::Instance<'tcx>,
168167
_args: &[OpTy<'tcx>],
169-
_dest: Option<PlaceTy<'tcx>>,
170-
_ret: Option<BasicBlock>,
168+
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
171169
_unwind: Option<BasicBlock>
172170
) -> InterpResult<'tcx> {
173171
throw_unsup_format!("calling intrinsics isn't supported in ConstProp");

0 commit comments

Comments
 (0)
Please sign in to comment.