diff options
Diffstat (limited to 'compiler/rustc_const_eval/src')
8 files changed, 66 insertions, 53 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index d7cbc48e032..0c20324e452 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -60,7 +60,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.push_stack_frame( cid.instance, body, - Some(&ret.into()), + &ret.into(), StackPopCleanup::Root { cleanup: false }, )?; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 9e5b00462f3..9de5541bfe3 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -265,7 +265,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, instance: ty::Instance<'tcx>, _abi: Abi, args: &[OpTy<'tcx>], - _ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, + _dest: &PlaceTy<'tcx>, + _ret: Option<mir::BasicBlock>, _unwind: StackPopUnwind, // unwinding is not supported in consts ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { debug!("find_mir_or_eval_fn: {:?}", instance); @@ -293,6 +294,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, new_instance, _abi, args, + _dest, _ret, _unwind, )? @@ -307,17 +309,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], - ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, + dest: &PlaceTy<'tcx, Self::PointerTag>, + target: Option<mir::BasicBlock>, _unwind: StackPopUnwind, ) -> InterpResult<'tcx> { // Shared intrinsics. - if ecx.emulate_intrinsic(instance, args, ret)? { + if ecx.emulate_intrinsic(instance, args, dest, target)? { return Ok(()); } let intrinsic_name = ecx.tcx.item_name(instance.def_id()); // CTFE-specific intrinsics. - let Some((dest, ret)) = ret else { + let Some(ret) = target else { return Err(ConstEvalErrKind::NeedsRfc(format!( "calling intrinsic `{}`", intrinsic_name diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index dfb81a2afc4..4c84bd090cb 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -105,7 +105,7 @@ pub struct Frame<'mir, 'tcx, Tag: Provenance = AllocId, Extra = ()> { /// The location where the result of the current stack frame should be written to, /// and its layout in the caller. - pub return_place: Option<PlaceTy<'tcx, Tag>>, + pub return_place: PlaceTy<'tcx, Tag>, /// The list of locals for this stack frame, stored in order as /// `[return_ptr, arguments..., variables..., temporaries...]`. @@ -676,7 +676,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, body: &'mir mir::Body<'tcx>, - return_place: Option<&PlaceTy<'tcx, M::PointerTag>>, + return_place: &PlaceTy<'tcx, M::PointerTag>, return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { trace!("body: {:#?}", body); @@ -685,7 +685,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { body, loc: Err(body.span), // Span used for errors caused during preamble. return_to_block, - return_place: return_place.copied(), + return_place: *return_place, // empty local array, we fill it in below, after we are inside the stack frame and // all methods actually know about the frame locals: IndexVec::new(), @@ -807,14 +807,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); if !unwinding { - // Copy the return value to the caller's stack frame. - if let Some(ref return_place) = frame.return_place { - let op = self.access_local(&frame, mir::RETURN_PLACE, None)?; - self.copy_op_transmute(&op, return_place)?; - trace!("{:?}", self.dump_place(**return_place)); - } else { - throw_ub!(Unreachable); - } + let op = self.access_local(&frame, mir::RETURN_PLACE, None)?; + self.copy_op_transmute(&op, &frame.return_place)?; + trace!("{:?}", self.dump_place(*frame.return_place)); } let return_to_block = frame.return_to_block; @@ -1055,7 +1050,7 @@ where body.hash_stable(hcx, hasher); instance.hash_stable(hcx, hasher); return_to_block.hash_stable(hcx, hasher); - return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher); + return_place.hash_stable(hcx, hasher); locals.hash_stable(hcx, hasher); loc.hash_stable(hcx, hasher); extra.hash_stable(hcx, hasher); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 5e0d1abd6c1..b747be3a636 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -115,13 +115,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::PointerTag>], - ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, + dest: &PlaceTy<'tcx, M::PointerTag>, + ret: Option<mir::BasicBlock>, ) -> InterpResult<'tcx, bool> { let substs = instance.substs; let intrinsic_name = self.tcx.item_name(instance.def_id()); // First handle intrinsics without return place. - let (dest, ret) = match ret { + let ret = match ret { None => match intrinsic_name { sym::transmute => throw_ub_format!("transmuting to uninhabited type"), sym::abort => M::abort(self, "the program aborted execution".to_owned())?, diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 1dcd50a5b70..3572a9cc681 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -169,7 +169,8 @@ pub trait Machine<'mir, 'tcx>: Sized { instance: ty::Instance<'tcx>, abi: Abi, args: &[OpTy<'tcx, Self::PointerTag>], - ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, Self::PointerTag>, + target: Option<mir::BasicBlock>, unwind: StackPopUnwind, ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>; @@ -180,7 +181,8 @@ pub trait Machine<'mir, 'tcx>: Sized { fn_val: Self::ExtraFnVal, abi: Abi, args: &[OpTy<'tcx, Self::PointerTag>], - ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, Self::PointerTag>, + target: Option<mir::BasicBlock>, unwind: StackPopUnwind, ) -> InterpResult<'tcx>; @@ -190,7 +192,8 @@ pub trait Machine<'mir, 'tcx>: Sized { ecx: &mut InterpCx<'mir, 'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::PointerTag>], - ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, Self::PointerTag>, + target: Option<mir::BasicBlock>, unwind: StackPopUnwind, ) -> InterpResult<'tcx>; @@ -470,7 +473,8 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { fn_val: !, _abi: Abi, _args: &[OpTy<$tcx>], - _ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>, + _destination: &PlaceTy<$tcx, Self::PointerTag>, + _target: Option<mir::BasicBlock>, _unwind: StackPopUnwind, ) -> InterpResult<$tcx> { match fn_val {} diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 25f9d4baca3..a5c7d4c8e20 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -57,7 +57,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.go_to_block(target_block); } - Call { ref func, ref args, destination, ref cleanup, from_hir_call: _, fn_span: _ } => { + Call { + ref func, + ref args, + destination, + target, + ref cleanup, + from_hir_call: _, + fn_span: _, + } => { let old_stack = self.frame_idx(); let old_loc = self.frame().loc; let func = self.eval_operand(func, None)?; @@ -91,20 +99,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ), }; - let dest_place; - let ret = match destination { - Some((dest, ret)) => { - dest_place = self.eval_place(dest)?; - Some((&dest_place, ret)) - } - None => None, - }; + let destination = self.eval_place(destination)?; self.eval_fn_call( fn_val, (fn_sig.abi, fn_abi), &args, with_caller_location, - ret, + &destination, + target, match (cleanup, fn_abi.can_unwind) { (Some(cleanup), true) => StackPopUnwind::Cleanup(*cleanup), (None, true) => StackPopUnwind::Skip, @@ -299,7 +301,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (caller_abi, caller_fn_abi): (Abi, &FnAbi<'tcx, Ty<'tcx>>), args: &[OpTy<'tcx, M::PointerTag>], with_caller_location: bool, - ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, + destination: &PlaceTy<'tcx, M::PointerTag>, + target: Option<mir::BasicBlock>, mut unwind: StackPopUnwind, ) -> InterpResult<'tcx> { trace!("eval_fn_call: {:#?}", fn_val); @@ -307,7 +310,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let instance = match fn_val { FnVal::Instance(instance) => instance, FnVal::Other(extra) => { - return M::call_extra_fn(self, extra, caller_abi, args, ret, unwind); + return M::call_extra_fn( + self, + extra, + caller_abi, + args, + destination, + target, + unwind, + ); } }; @@ -315,7 +326,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::InstanceDef::Intrinsic(def_id) => { assert!(self.tcx.is_intrinsic(def_id)); // caller_fn_abi is not relevant here, we interpret the arguments directly for each intrinsic. - M::call_intrinsic(self, instance, args, ret, unwind) + M::call_intrinsic(self, instance, args, destination, target, unwind) } ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) @@ -326,7 +337,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::InstanceDef::Item(_) => { // We need MIR for this fn let Some((body, instance)) = - M::find_mir_or_eval_fn(self, instance, caller_abi, args, ret, unwind)? else { + M::find_mir_or_eval_fn(self, instance, caller_abi, args, destination, target, unwind)? else { return Ok(()); }; @@ -362,8 +373,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.push_stack_frame( instance, body, - ret.map(|p| p.0), - StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind }, + destination, + StackPopCleanup::Goto { ret: target, unwind }, )?; // If an error is raised here, pop the frame again to get an accurate backtrace. @@ -540,7 +551,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (caller_abi, caller_fn_abi), &args, with_caller_location, - ret, + destination, + target, unwind, ) } @@ -582,7 +594,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (Abi::Rust, fn_abi), &[arg.into()], false, - Some((&dest.into(), target)), + &dest.into(), + Some(target), match unwind { Some(cleanup) => StackPopUnwind::Cleanup(cleanup), None => StackPopUnwind::Skip, diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index f88538f61ec..fc6b8a1a723 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -788,7 +788,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } else { let terminator = self.source[loc.block].terminator_mut(); let target = match terminator.kind { - TerminatorKind::Call { destination: Some((_, target)), .. } => target, + TerminatorKind::Call { target: Some(target), .. } => target, ref kind => { span_bug!(terminator.source_info.span, "{:?} not promotable", kind); } @@ -814,7 +814,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { func, args, cleanup: None, - destination: Some((Place::from(new_temp), new_target)), + destination: Place::from(new_temp), + target: Some(new_target), from_hir_call, fn_span, }, @@ -1054,11 +1055,9 @@ pub fn is_const_fn_in_array_repeat_expression<'tcx>( { if let Operand::Constant(box Constant { literal, .. }) = func { if let ty::FnDef(def_id, _) = *literal.ty().kind() { - if let Some((destination_place, _)) = destination { - if destination_place == place { - if ccx.tcx.is_const_fn(def_id) { - return true; - } + if destination == place { + if ccx.tcx.is_const_fn(def_id) { + return true; } } } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 3ce33d547c5..54c2daf9ac2 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -673,7 +673,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.check_edge(location, *unwind, EdgeKind::Unwind); } } - TerminatorKind::Call { func, args, destination, cleanup, .. } => { + TerminatorKind::Call { func, args, destination, target, cleanup, .. } => { let func_ty = func.ty(&self.body.local_decls, self.tcx); match func_ty.kind() { ty::FnPtr(..) | ty::FnDef(..) => {} @@ -682,7 +682,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { format!("encountered non-callable type {} in `Call` terminator", func_ty), ), } - if let Some((_, target)) = destination { + if let Some(target) = target { self.check_edge(location, *target, EdgeKind::Normal); } if let Some(cleanup) = cleanup { @@ -693,9 +693,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // passed by a reference to the callee. Consequently they must be non-overlapping. // Currently this simply checks for duplicate places. self.place_cache.clear(); - if let Some((destination, _)) = destination { - self.place_cache.push(destination.as_ref()); - } + self.place_cache.push(destination.as_ref()); for arg in args { if let Operand::Move(place) = arg { self.place_cache.push(place.as_ref()); |
