diff options
| author | Jakob Degen <jakob.e.degen@gmail.com> | 2022-04-16 09:27:54 -0400 |
|---|---|---|
| committer | Jakob Degen <jakob.e.degen@gmail.com> | 2022-05-23 17:49:04 -0400 |
| commit | 09b0936db2bb3be67451c6f8948e90987e764f81 (patch) | |
| tree | 33c3a24a12791982173c389fabd5d317223beb9a /compiler | |
| parent | 222c5724ecc922fe67815f428c19f82c129d9386 (diff) | |
| download | rust-09b0936db2bb3be67451c6f8948e90987e764f81.tar.gz rust-09b0936db2bb3be67451c6f8948e90987e764f81.zip | |
Refactor call terminator to always hold a destination place
Diffstat (limited to 'compiler')
48 files changed, 340 insertions, 333 deletions
diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 22edee33c5c..e4ffae38c33 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -140,9 +140,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { // A `Call` terminator's return value can be a local which has borrows, // so we need to record those as `killed` as well. if let TerminatorKind::Call { destination, .. } = terminator.kind { - if let Some((place, _)) = destination { - self.record_killed_borrows_for_place(place, location); - } + self.record_killed_borrows_for_place(destination, location); } self.super_terminator(terminator, location); diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 84ff33fe1d8..da5f56704d4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2198,10 +2198,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}", target, terminator ); - if let TerminatorKind::Call { destination: Some((place, _)), args, .. } = + if let TerminatorKind::Call { destination, target: Some(_), args, .. } = &terminator.kind { - if let Some(assigned_to) = place.as_local() { + if let Some(assigned_to) = destination.as_local() { debug!( "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}", assigned_to, args diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 6ec6b76bb5f..0b6be453b92 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -705,10 +705,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let terminator = block.terminator(); debug!("was_captured_by_trait_object: terminator={:?}", terminator); - if let TerminatorKind::Call { destination: Some((place, block)), args, .. } = + if let TerminatorKind::Call { destination, target: Some(block), args, .. } = &terminator.kind { - if let Some(dest) = place.as_local() { + if let Some(dest) = destination.as_local() { debug!( "was_captured_by_trait_object: target={:?} dest={:?} args={:?}", target, dest, args diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 76d240bb89f..0425c53d9dc 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -124,6 +124,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { ref func, ref args, destination, + target: _, cleanup: _, from_hir_call: _, fn_span: _, @@ -132,9 +133,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { for arg in args { self.consume_operand(location, arg); } - if let Some((dest, _ /*bb*/)) = destination { - self.mutate_place(location, *dest, Deep); - } + self.mutate_place(location, *destination, Deep); } TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(location, cond); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a3e7c953ee3..d3aea1fd61c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -661,7 +661,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx TerminatorKind::Call { ref func, ref args, - ref destination, + destination, + target: _, cleanup: _, from_hir_call: _, fn_span: _, @@ -670,9 +671,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx for arg in args { self.consume_operand(loc, (arg, span), flow_state); } - if let Some((dest, _ /*bb*/)) = *destination { - self.mutate_place(loc, (dest, span), Deep, flow_state); - } + self.mutate_place(loc, (destination, span), Deep, flow_state); } TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(loc, (cond, span), flow_state); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 405fd9198d3..34bc87b20c7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1403,7 +1403,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // FIXME: check the values } - TerminatorKind::Call { ref func, ref args, ref destination, from_hir_call, .. } => { + TerminatorKind::Call { + ref func, ref args, destination, target, from_hir_call, .. + } => { self.check_operand(func, term_location); for arg in args { self.check_operand(arg, term_location); @@ -1424,7 +1426,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { sig, ); let sig = self.normalize(sig, term_location); - self.check_call_dest(body, term, &sig, destination, term_location); + self.check_call_dest(body, term, &sig, destination, target, term_location); self.prove_predicates( sig.inputs_and_output @@ -1502,15 +1504,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { body: &Body<'tcx>, term: &Terminator<'tcx>, sig: &ty::FnSig<'tcx>, - destination: &Option<(Place<'tcx>, BasicBlock)>, + destination: Place<'tcx>, + target: Option<BasicBlock>, term_location: Location, ) { let tcx = self.tcx(); - match *destination { - Some((ref dest, _target_block)) => { - let dest_ty = dest.ty(body, tcx).ty; + match target { + Some(_) => { + let dest_ty = destination.ty(body, tcx).ty; let dest_ty = self.normalize(dest_ty, term_location); - let category = match dest.as_local() { + let category = match destination.as_local() { Some(RETURN_PLACE) => { if let BorrowCheckContext { universal_regions: @@ -1659,8 +1662,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.assert_iscleanup(body, block_data, unwind, true); } } - TerminatorKind::Call { ref destination, cleanup, .. } => { - if let &Some((_, target)) = destination { + TerminatorKind::Call { ref target, cleanup, .. } => { + if let &Some(target) = target { self.assert_iscleanup(body, block_data, target, is_cleanup); } if let Some(cleanup) = cleanup { diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index cdbb60b878a..1093167fa82 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -66,8 +66,8 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { debug!("visit_terminator: terminator={:?}", terminator); match &terminator.kind { - TerminatorKind::Call { destination: Some((into, _)), .. } => { - self.remove_never_initialized_mut_locals(*into); + TerminatorKind::Call { destination, .. } => { + self.remove_never_initialized_mut_locals(*destination); } TerminatorKind::DropAndReplace { place, .. } => { self.remove_never_initialized_mut_locals(*place); diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index b163a426191..decb7841990 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -312,13 +312,14 @@ pub(crate) fn codegen_terminator_call<'tcx>( source_info: mir::SourceInfo, func: &Operand<'tcx>, args: &[Operand<'tcx>], - mir_dest: Option<(Place<'tcx>, BasicBlock)>, + destination: Place<'tcx>, + target: Option<BasicBlock>, ) { let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); let fn_sig = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); - let destination = mir_dest.map(|(place, bb)| (codegen_place(fx, place), bb)); + let ret_place = codegen_place(fx, destination); // Handle special calls like instrinsics and empty drop glue. let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() { @@ -333,7 +334,8 @@ pub(crate) fn codegen_terminator_call<'tcx>( &fx.tcx.symbol_name(instance).name, substs, args, - destination, + ret_place, + target, ); return; } @@ -344,14 +346,15 @@ pub(crate) fn codegen_terminator_call<'tcx>( fx, instance, args, - destination, + ret_place, + target, source_info, ); return; } InstanceDef::DropGlue(_, None) => { // empty drop glue - a nop. - let (_, dest) = destination.expect("Non terminating drop_in_place_real???"); + let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); return; @@ -377,7 +380,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( .unwrap_or(false); if is_cold { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); - if let Some((_place, destination_block)) = destination { + if let Some(destination_block) = target { fx.bcx.set_cold_block(fx.get_block(destination_block)); } } @@ -459,7 +462,6 @@ pub(crate) fn codegen_terminator_call<'tcx>( } }; - let ret_place = destination.map(|(place, _)| place); self::returning::codegen_with_call_return_arg(fx, &fn_abi.ret, ret_place, |fx, return_ptr| { let call_args = return_ptr .into_iter() @@ -511,7 +513,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( call_inst }); - if let Some((_, dest)) = destination { + if let Some(dest) = target { let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); } else { diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs index c1bdba43e6c..ff3bb2dfd00 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs @@ -56,23 +56,22 @@ pub(super) fn codegen_return_param<'tcx>( pub(super) fn codegen_with_call_return_arg<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, ret_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, - ret_place: Option<CPlace<'tcx>>, + ret_place: CPlace<'tcx>, f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option<Value>) -> Inst, ) { let (ret_temp_place, return_ptr) = match ret_arg_abi.mode { PassMode::Ignore => (None, None), - PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => match ret_place { - Some(ret_place) if matches!(ret_place.inner(), CPlaceInner::Addr(_, None)) => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { + if matches!(ret_place.inner(), CPlaceInner::Addr(_, None)) { // This is an optimization to prevent unnecessary copies of the return value when // the return place is already a memory place as opposed to a register. // This match arm can be safely removed. (None, Some(ret_place.to_ptr().get_addr(fx))) - } - _ => { + } else { let place = CPlace::new_stack_slot(fx, ret_arg_abi.layout); (Some(place), Some(place.to_ptr().get_addr(fx))) } - }, + } PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") } @@ -84,39 +83,25 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( match ret_arg_abi.mode { PassMode::Ignore => {} PassMode::Direct(_) => { - if let Some(ret_place) = ret_place { - let ret_val = fx.bcx.inst_results(call_inst)[0]; - ret_place.write_cvalue(fx, CValue::by_val(ret_val, ret_arg_abi.layout)); - } + let ret_val = fx.bcx.inst_results(call_inst)[0]; + ret_place.write_cvalue(fx, CValue::by_val(ret_val, ret_arg_abi.layout)); } PassMode::Pair(_, _) => { - if let Some(ret_place) = ret_place { - let ret_val_a = fx.bcx.inst_results(call_inst)[0]; - let ret_val_b = fx.bcx.inst_results(call_inst)[1]; - ret_place.write_cvalue( - fx, - CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout), - ); - } + let ret_val_a = fx.bcx.inst_results(call_inst)[0]; + let ret_val_b = fx.bcx.inst_results(call_inst)[1]; + ret_place + .write_cvalue(fx, CValue::by_val_pair(ret_val_a, ret_val_b, ret_arg_abi.layout)); } PassMode::Cast(cast) => { - if let Some(ret_place) = ret_place { - let results = fx - .bcx - .inst_results(call_inst) - .iter() - .copied() - .collect::<SmallVec<[Value; 2]>>(); - let result = - super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast); - ret_place.write_cvalue(fx, result); - } + let results = + fx.bcx.inst_results(call_inst).iter().copied().collect::<SmallVec<[Value; 2]>>(); + let result = + super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast); + ret_place.write_cvalue(fx, result); } PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { - if let (Some(ret_place), Some(ret_temp_place)) = (ret_place, ret_temp_place) { - // Both ret_place and ret_temp_place must be Some. If ret_place is None, this is - // a non-returning call. If ret_temp_place is None, it is not necessary to copy the - // return value. + if let Some(ret_temp_place) = ret_temp_place { + // If ret_temp_place is None, it is not necessary to copy the return value. let ret_temp_value = ret_temp_place.to_cvalue(fx); ret_place.write_cvalue(fx, ret_temp_value); } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 65e5812a8a5..3fe112d794b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -393,6 +393,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { func, args, destination, + target, fn_span, cleanup: _, from_hir_call: _, @@ -404,6 +405,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { func, args, *destination, + *target, ) }); } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 57074f00210..7d2e3e52f34 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -542,8 +542,8 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => unreachable!(), TerminatorKind::InlineAsm { .. } => return None, - TerminatorKind::Call { destination: Some((call_place, _)), .. } - if call_place == place => + TerminatorKind::Call { destination, target: Some(_), .. } + if destination == place => { return None; } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs index 0e4f7ee907a..77ac46540a9 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs @@ -10,10 +10,9 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( intrinsic: &str, _substs: SubstsRef<'tcx>, args: &[mir::Operand<'tcx>], - destination: Option<(CPlace<'tcx>, BasicBlock)>, + ret: CPlace<'tcx>, + target: Option<BasicBlock>, ) { - let ret = destination.unwrap().0; - intrinsic_match! { fx, intrinsic, args, _ => { @@ -126,7 +125,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( }; } - let dest = destination.expect("all llvm intrinsics used by stdlib should return").1; + let dest = target.expect("all llvm intrinsics used by stdlib should return"); let ret_block = fx.get_block(dest); fx.bcx.ins().jump(ret_block, &[]); } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 29b3f36b2be..f8c69d46d1f 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -217,35 +217,42 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, instance: Instance<'tcx>, args: &[mir::Operand<'tcx>], - destination: Option<(CPlace<'tcx>, BasicBlock)>, + destination: CPlace<'tcx>, + target: Option<BasicBlock>, source_info: mir::SourceInfo, ) { let intrinsic = fx.tcx.item_name(instance.def_id()); let substs = instance.substs; - let ret = match destination { - Some((place, _)) => place, - None => { - // Insert non returning intrinsics here - match intrinsic { - sym::abort => { - fx.bcx.ins().trap(TrapCode::User(0)); - } - sym::transmute => { - crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info); - } - _ => unimplemented!("unsupported instrinsic {}", intrinsic), + let target = if let Some(target) = target { + target + } else { + // Insert non returning intrinsics here + match intrinsic { + sym::abort => { + fx.bcx.ins().trap(TrapCode::User(0)); } - return; + sym::transmute => { + crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info); + } + _ => unimplemented!("unsupported instrinsic {}", intrinsic), } + return; }; if intrinsic.as_str().starts_with("simd_") { - self::simd::codegen_simd_intrinsic_call(fx, intrinsic, substs, args, ret, source_info.span); - let ret_block = fx.get_block(destination.expect("SIMD intrinsics don't diverge").1); + self::simd::codegen_simd_intrinsic_call( + fx, + intrinsic, + substs, + args, + destination, + source_info.span, + ); + let ret_block = fx.get_block(target); fx.bcx.ins().jump(ret_block, &[]); - } else if codegen_float_intrinsic_call(fx, intrinsic, args, ret) { - let ret_block = fx.get_block(destination.expect("Float intrinsics don't diverge").1); + } else if codegen_float_intrinsic_call(fx, intrinsic, args, destination) { + let ret_block = fx.get_block(target); fx.bcx.ins().jump(ret_block, &[]); } else { codegen_regular_intrinsic_call( @@ -254,9 +261,9 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( intrinsic, substs, args, - ret, - source_info, destination, + Some(target), + source_info, ); } } @@ -339,8 +346,8 @@ fn codegen_regular_intrinsic_call<'tcx>( substs: SubstsRef<'tcx>, args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, + destination: Option<BasicBlock>, source_info: mir::SourceInfo, - destination: Option<(CPlace<'tcx>, BasicBlock)>, ) { let usize_layout = fx.layout_of(fx.tcx.types.usize); @@ -761,7 +768,7 @@ fn codegen_regular_intrinsic_call<'tcx>( if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { // special case for compiler-builtins to avoid having to patch it crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); - let ret_block = fx.get_block(destination.unwrap().1); + let ret_block = fx.get_block(destination.unwrap()); fx.bcx.ins().jump(ret_block, &[]); return; } else { @@ -789,7 +796,7 @@ fn codegen_regular_intrinsic_call<'tcx>( if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { // special case for compiler-builtins to avoid having to patch it crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); - let ret_block = fx.get_block(destination.unwrap().1); + let ret_block = fx.get_block(destination.unwrap()); fx.bcx.ins().jump(ret_block, &[]); return; } else { @@ -1130,6 +1137,6 @@ fn codegen_regular_intrinsic_call<'tcx>( }; } - let ret_block = fx.get_block(destination.unwrap().1); + let ret_block = fx.get_block(destination.unwrap()); fx.bcx.ins().jump(ret_block, &[]); } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a185eb298e0..f1007ba1578 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -519,7 +519,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { intrinsic: Option<Symbol>, instance: Option<Instance<'tcx>>, source_info: mir::SourceInfo, - destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, + target: Option<mir::BasicBlock>, cleanup: Option<mir::BasicBlock>, ) -> bool { // Emit a panic or a no-op for `assert_*` intrinsics. @@ -576,12 +576,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_abi, llfn, &[msg.0, msg.1, location], - destination.as_ref().map(|(_, bb)| (ReturnDest::Nothing, *bb)), + target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)), cleanup, ); } else { // a NOP - let target = destination.as_ref().unwrap().1; + let target = target.unwrap(); helper.funclet_br(self, bx, target) } true @@ -597,7 +597,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { terminator: &mir::Terminator<'tcx>, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], - destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, + destination: mir::Place<'tcx>, + target: Option<mir::BasicBlock>, cleanup: Option<mir::BasicBlock>, fn_span: Span, ) { @@ -624,7 +625,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let Some(ty::InstanceDef::DropGlue(_, None)) = def { // Empty drop glue; a no-op. - let &(_, target) = destination.as_ref().unwrap(); + let target = target.unwrap(); helper.funclet_br(self, &mut bx, target); return; } @@ -653,9 +654,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; if intrinsic == Some(sym::transmute) { - if let Some(destination_ref) = destination.as_ref() { - let &(dest, target) = destination_ref; - self.codegen_transmute(&mut bx, &args[0], dest); + if let Some(target) = target { + self.codegen_transmute(&mut bx, &args[0], destination); helper.funclet_br(self, &mut bx, target); } else { // If we are trying to transmute to an uninhabited type, @@ -676,7 +676,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { intrinsic, instance, source_info, - destination, + target, cleanup, ) { return; @@ -687,15 +687,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut llargs = Vec::with_capacity(arg_count); // Prepare the return value destination - let ret_dest = if let Some((dest, _)) = *destination { + let ret_dest = if target.is_some() { let is_intrinsic = intrinsic.is_some(); - self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, is_intrinsic) + self.make_return_dest(&mut bx, destination, &fn_abi.ret, &mut llargs, is_intrinsic) } else { ReturnDest::Nothing }; if intrinsic == Some(sym::caller_location) { - if let Some((_, target)) = destination.as_ref() { + if let Some(target) = target { let location = self .get_caller_location(&mut bx, mir::SourceInfo { span: fn_span, ..source_info }); @@ -703,7 +703,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { location.val.store(&mut bx, tmp); } self.store_return(&mut bx, ret_dest, &fn_abi.ret, location.immediate()); - helper.funclet_br(self, &mut bx, *target); + helper.funclet_br(self, &mut bx, target); } return; } @@ -766,7 +766,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval); } - if let Some((_, target)) = *destination { + if let Some(target) = target { helper.funclet_br(self, &mut bx, target); } else { bx.unreachable(); @@ -913,7 +913,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_abi, fn_ptr, &llargs, - destination.as_ref().map(|&(_, target)| (ret_dest, target)), + target.as_ref().map(|&target| (ret_dest, target)), cleanup, ); @@ -930,7 +930,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_abi, fn_ptr, &llargs, - destination.as_ref().map(|&(_, target)| (ret_dest, target)), + target.as_ref().map(|&target| (ret_dest, target)), cleanup, ); } @@ -1083,7 +1083,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::TerminatorKind::Call { ref func, ref args, - ref destination, + destination, + target, cleanup, from_hir_call: _, fn_span, @@ -1095,6 +1096,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { func, args, destination, + target, cleanup, fn_span, ); 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()); diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index fb3856b4952..c859d93043e 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -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, .. } => { diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 901f3bf4f7d..14d4cb2c330 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -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) } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index ef4f1f5e84e..d0d7f121a25 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -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 { diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 0fd67f15b75..fb0537c543d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -141,7 +141,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TerminatorKind::Call { func: exchange_malloc, args: vec![Operand::Move(size), Operand::Move(align)], - destination: Some((storage, success)), + destination: storage, + target: Some(success), cleanup: None, from_hir_call: false, fn_span: expr_span, diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index e912501d55f..569012e152b 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -255,18 +255,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { func: fun, args, cleanup: None, + destination, // The presence or absence of a return edge affects control-flow sensitive // MIR checks and ultimately whether code is accepted or not. We can only // omit the return edge if a return type is visibly uninhabited to a module // that makes the call. - destination: if this.tcx.is_ty_uninhabited_from( + target: if this.tcx.is_ty_uninhabited_from( this.parent_module, expr.ty, this.param_env, ) { None } else { - Some((destination, success)) + Some(success) }, from_hir_call, fn_span, diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 565345595d5..c15b3db1caa 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -444,7 +444,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { literal: method, })), args: vec![val, expect], - destination: Some((eq_result, eq_block)), + destination: eq_result, + target: Some(eq_block), cleanup: None, from_hir_call: false, fn_span: source_info.span, diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index f568121b219..027af5b9c1f 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -625,7 +625,8 @@ where kind: TerminatorKind::Call { func: Operand::function_handle(tcx, drop_fn, substs, self.source_info.span), args: vec![Operand::Move(Place::from(ref_place))], - destination: Some((unit_temp, succ)), + destination: unit_temp, + target: Some(succ), cleanup: unwind.into_option(), from_hir_call: true, fn_span: self.source_info.span, @@ -963,7 +964,8 @@ where let call = TerminatorKind::Call { func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), args, - destination: Some((unit_temp, target)), + destination: unit_temp, + target: Some(target), cleanup: None, from_hir_call: false, fn_span: self.source_info.span, diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index d6bfde8f34c..3a492b45849 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -237,14 +237,12 @@ impl Direction for Backward { // Apply terminator-specific edge effects. // // FIXME(ecstaticmorse): Avoid cloning the exit state unconditionally. - mir::TerminatorKind::Call { destination: Some((return_place, dest)), .. } - if dest == bb => - { + mir::TerminatorKind::Call { destination, target: Some(dest), .. } if dest == bb => { let mut tmp = exit_state.clone(); analysis.apply_call_return_effect( &mut tmp, pred, - CallReturnPlaces::Call(return_place), + CallReturnPlaces::Call(destination), ); propagate(pred, &tmp); } @@ -532,20 +530,28 @@ impl Direction for Forward { propagate(target, exit_state); } - Call { cleanup, destination, func: _, args: _, from_hir_call: _, fn_span: _ } => { + Call { + cleanup, + destination, + target, + func: _, + args: _, + from_hir_call: _, + fn_span: _, + } => { if let Some(unwind) = cleanup { if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) { propagate(unwind, exit_state); } } - if let Some((dest_place, target)) = destination { + if let Some(target) = target { // N.B.: This must be done *last*, otherwise the unwind path will see the call // return effect. analysis.apply_call_return_effect( exit_state, bb, - CallReturnPlaces::Call(dest_place), + CallReturnPlaces::Call(destination), ); propagate(target, exit_state); } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index c6a85bc43f4..3834c232ab6 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -218,7 +218,7 @@ where self.results.seek_to_block_end(block); if self.results.get() != &block_start_state || A::Direction::is_backward() { let after_terminator_name = match terminator.kind { - mir::TerminatorKind::Call { destination: Some(_), .. } => "(on unwind)", + mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)", _ => "(on end)", }; @@ -231,14 +231,14 @@ where // for the basic block itself. That way, we could display terminator-specific effects for // backward dataflow analyses as well as effects for `SwitchInt` terminators. match terminator.kind { - mir::TerminatorKind::Call { destination: Some((return_place, _)), .. } => { + mir::TerminatorKind::Call { destination, .. } => { self.write_row(w, "", "(on successful return)", |this, w, fmt| { let state_on_unwind = this.results.get().clone(); this.results.apply_custom_effect(|analysis, state| { analysis.apply_call_return_effect( state, block, - CallReturnPlaces::Call(return_place), + CallReturnPlaces::Call(destination), ); }); diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 708a142581a..74c3b44f425 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -37,7 +37,8 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { mir::TerminatorKind::Call { func: mir::Operand::Copy(dummy_place.clone()), args: vec![], - destination: Some((dummy_place.clone(), mir::START_BLOCK)), + destination: dummy_place.clone(), + target: Some(mir::START_BLOCK), cleanup: None, from_hir_call: false, fn_span: DUMMY_SP, @@ -50,7 +51,8 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { mir::TerminatorKind::Call { func: mir::Operand::Copy(dummy_place.clone()), args: vec![], - destination: Some((dummy_place.clone(), mir::START_BLOCK)), + destination: dummy_place.clone(), + target: Some(mir::START_BLOCK), cleanup: None, from_hir_call: false, fn_span: DUMMY_SP, diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 2730e8bd49b..356a6b7765e 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -169,8 +169,8 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc self.borrowed_locals.borrow().analysis().terminator_effect(trans, terminator, loc); match &terminator.kind { - TerminatorKind::Call { destination: Some((place, _)), .. } => { - trans.gen(place.local); + TerminatorKind::Call { destination, .. } => { + trans.gen(destination.local); } // Note that we do *not* gen the `resume_arg` of `Yield` terminators. The reason for @@ -198,8 +198,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc // Nothing to do for these. Match exhaustively so this fails to compile when new // variants are added. - TerminatorKind::Call { destination: None, .. } - | TerminatorKind::Abort + TerminatorKind::Abort | TerminatorKind::Assert { .. } | TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } @@ -225,8 +224,8 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc // and after the call returns successfully, but not after a panic. // Since `propagate_call_unwind` doesn't exist, we have to kill the // destination here, and then gen it again in `call_return_effect`. - TerminatorKind::Call { destination: Some((place, _)), .. } => { - trans.kill(place.local); + TerminatorKind::Call { destination, .. } => { + trans.kill(destination.local); } // The same applies to InlineAsm outputs. @@ -236,8 +235,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc // Nothing to do for these. Match exhaustively so this fails to compile when new // variants are added. - TerminatorKind::Call { destination: None, .. } - | TerminatorKind::Yield { .. } + TerminatorKind::Yield { .. } | TerminatorKind::Abort | TerminatorKind::Assert { .. } | TerminatorKind::Drop { .. } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 73072464872..b08cb50f77a 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -376,7 +376,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { TerminatorKind::Call { ref func, ref args, - ref destination, + destination, + target, cleanup: _, from_hir_call: _, fn_span: _, @@ -385,7 +386,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { for arg in args { self.gather_operand(arg); } - if let Some((destination, _bb)) = *destination { + if let Some(_bb) = target { self.create_move_path(destination); self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly); } diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index cd6b671a0db..10d52271734 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -50,12 +50,7 @@ impl AddCallGuards { for block in body.basic_blocks_mut() { match block.terminator { Some(Terminator { - kind: - TerminatorKind::Call { - destination: Some((_, ref mut destination)), - cleanup, - .. - }, + kind: TerminatorKind::Call { target: Some(ref mut destination), cleanup, .. }, source_info, }) if pred_count[*destination] > 1 && (cleanup.is_some() || self == &AllCallEdges) => diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index a245da658b9..0495439385b 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -130,11 +130,11 @@ impl<'tcx> MirPass<'tcx> for AddRetag { .iter_mut() .filter_map(|block_data| { match block_data.terminator().kind { - TerminatorKind::Call { destination: Some(ref destination), .. } - if needs_retag(&destination.0) => + TerminatorKind::Call { target: Some(target), destination, .. } + if needs_retag(&destination) => { // Remember the return destination for later - Some((block_data.terminator().source_info, destination.0, destination.1)) + Some((block_data.terminator().source_info, destination, target)) } // `Drop` is also a call, but it doesn't return anything so we are good. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 54c3cc46b26..b17485fd542 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -200,7 +200,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> _instance: ty::Instance<'tcx>, _abi: Abi, _args: &[OpTy<'tcx>], - _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, + _destination: &PlaceTy<'tcx>, + _target: Option<BasicBlock>, _unwind: StackPopUnwind, ) -> InterpResult<'tcx, Option<(&'mir Body<'tcx>, ty::Instance<'tcx>)>> { Ok(None) @@ -210,7 +211,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> _ecx: &mut InterpCx<'mir, 'tcx, Self>, _instance: ty::Instance<'tcx>, _args: &[OpTy<'tcx>], - _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, + _destination: &PlaceTy<'tcx>, + _target: Option<BasicBlock>, _unwind: StackPopUnwind, ) -> InterpResult<'tcx> { throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp") @@ -384,24 +386,22 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ConstPropMachine::new(only_propagate_inside_block_locals, can_const_prop), ); - let ret = ecx + let ret_layout = ecx .layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs)) .ok() - // Don't bother allocating memory for ZST types which have no values - // or for large values. - .filter(|ret_layout| { - !ret_layout.is_zst() && ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) - }) - .map(|ret_layout| { - ecx.allocate(ret_layout, MemoryKind::Stack) - .expect("couldn't perform small allocation") - .into() - }); + // Don't bother allocating memory for large values. + .filter(|ret_layout| ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT)) + .unwrap_or_else(|| ecx.layout_of(tcx.types.unit).unwrap()); + + let ret = ecx + .allocate(ret_layout, MemoryKind::Stack) + .expect("couldn't perform small allocation") + .into(); ecx.push_stack_frame( Instance::new(def_id, substs), dummy_body, - ret.as_ref(), + &ret, StackPopCleanup::Root { cleanup: false }, ) .expect("failed to push initial stack frame"); diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 6c0df98bc27..5fd9db3989d 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -192,7 +192,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> _instance: ty::Instance<'tcx>, _abi: Abi, _args: &[OpTy<'tcx>], - _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, + _destination: &PlaceTy<'tcx>, + _target: Option<BasicBlock>, _unwind: StackPopUnwind, ) -> InterpResult<'tcx, Option<(&'mir Body<'tcx>, ty::Instance<'tcx>)>> { Ok(None) @@ -202,7 +203,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> _ecx: &mut InterpCx<'mir, 'tcx, Self>, _instance: ty::Instance<'tcx>, _args: &[OpTy<'tcx>], - _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, + _destination: &PlaceTy<'tcx>, + _target: Option<BasicBlock>, _unwind: StackPopUnwind, ) -> InterpResult<'tcx> { throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp") @@ -377,24 +379,22 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ConstPropMachine::new(only_propagate_inside_block_locals, can_const_prop), ); - let ret = ecx + let ret_layout = ecx .layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs)) .ok() - // Don't bother allocating memory for ZST types which have no values - // or for large values. - .filter(|ret_layout| { - !ret_layout.is_zst() && ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) - }) - .map(|ret_layout| { - ecx.allocate(ret_layout, MemoryKind::Stack) - .expect("couldn't perform small allocation") - .into() - }); + // Don't bother allocating memory for large values. + .filter(|ret_layout| ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT)) + .unwrap_or_else(|| ecx.layout_of(tcx.types.unit).unwrap()); + + let ret = ecx + .allocate(ret_layout, MemoryKind::Stack) + .expect("couldn't perform small allocation") + .into(); ecx.push_stack_frame( Instance::new(def_id, substs), dummy_body, - ret.as_ref(), + &ret, StackPopCleanup::Root { cleanup: false }, ) .expect("failed to push initial stack frame"); diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index d787443f6aa..4615f9be33f 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -84,7 +84,7 @@ impl<'tcx> MockBlocks<'tcx> { fn link(&mut self, from_block: BasicBlock, to_block: BasicBlock) { match self.blocks[from_block].terminator_mut().kind { TerminatorKind::Assert { ref mut target, .. } - | TerminatorKind::Call { destination: Some((_, ref mut target)), .. } + | TerminatorKind::Call { target: Some(ref mut target), .. } | TerminatorKind::Drop { ref mut target, .. } | TerminatorKind::DropAndReplace { ref mut target, .. } | TerminatorKind::FalseEdge { real_target: ref mut target, .. } @@ -139,7 +139,8 @@ impl<'tcx> MockBlocks<'tcx> { TerminatorKind::Call { func: Operand::Copy(self.dummy_place.clone()), args: vec![], - destination: Some((self.dummy_place.clone(), TEMP_BLOCK)), + destination: self.dummy_place.clone(), + target: Some(TEMP_BLOCK), cleanup: None, from_hir_call: false, fn_span: DUMMY_SP, @@ -182,7 +183,7 @@ fn debug_basic_blocks<'tcx>(mir_body: &Body<'tcx>) -> String { let sp = format!("(span:{},{})", span.lo().to_u32(), span.hi().to_u32()); match kind { TerminatorKind::Assert { target, .. } - | TerminatorKind::Call { destination: Some((_, target)), .. } + | TerminatorKind::Call { target: Some(target), .. } | TerminatorKind::Drop { target, .. } | TerminatorKind::DropAndReplace { target, .. } | TerminatorKind::FalseEdge { real_target: target, .. } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 3732a308e3a..182dd6f379c 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -575,7 +575,8 @@ impl<'a> Conflicts<'a> { TerminatorKind::Call { func, args, - destination: Some((dest_place, _)), + destination, + target: _, cleanup: _, from_hir_call: _, fn_span: _, @@ -583,9 +584,9 @@ impl<'a> Conflicts<'a> { // No arguments may overlap with the destination. for arg in args.iter().chain(Some(func)) { if let Some(place) = arg.place() { - if !place.is_indirect() && !dest_place.is_indirect() { + if !place.is_indirect() && !destination.is_indirect() { self.record_local_conflict( - dest_place.local, + destination.local, place.local, "call dest/arg overlap", ); @@ -691,7 +692,6 @@ impl<'a> Conflicts<'a> { } TerminatorKind::Goto { .. } - | TerminatorKind::Call { destination: None, .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::Resume | TerminatorKind::Abort diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index f78c7a084d8..8a9f2107316 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -494,15 +494,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn drop_flags_for_fn_rets(&mut self) { for (bb, data) in self.body.basic_blocks().iter_enumerated() { if let TerminatorKind::Call { - destination: Some((ref place, tgt)), - cleanup: Some(_), - .. + destination, target: Some(tgt), cleanup: Some(_), .. } = data.terminator().kind { assert!(!self.patch.is_patched(bb)); let loc = Location { block: tgt, statement_index: 0 }; - let path = self.move_data().rev_lookup.find(place.as_ref()); + let path = self.move_data().rev_lookup.find(destination.as_ref()); on_lookup_result_bits(self.tcx, self.body, self.move_data(), path, |child| { self.set_drop_flag(loc, child, DropFlagState::Present) }); @@ -576,14 +574,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { // There may be a critical edge after this call, // so mark the return as initialized *before* the // call. - if let TerminatorKind::Call { - destination: Some((ref place, _)), cleanup: None, .. - } = data.terminator().kind + if let TerminatorKind::Call { destination, target: Some(_), cleanup: None, .. } = + data.terminator().kind { assert!(!self.patch.is_patched(bb)); let loc = Location { block: bb, statement_index: data.statements.len() }; - let path = self.move_data().rev_lookup.find(place.as_ref()); + let path = self.move_data().rev_lookup.find(destination.as_ref()); on_lookup_result_bits(self.tcx, self.body, self.move_data(), path, |child| { self.set_drop_flag(loc, child, DropFlagState::Present) }); diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 1f9bd90d11f..2e4fe1e3e5d 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -37,6 +37,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { func, args, destination: _, + target: _, cleanup: _, from_hir_call: _, fn_span: _, diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 9e7bf5c7929..4a3505ca3ff 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1459,12 +1459,13 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { TerminatorKind::Call { func, args, - destination: Some((dest, _)), + destination, + target: Some(_), cleanup: _, from_hir_call: _, fn_span: _, } => { - self.check_assigned_place(*dest, |this| { + self.check_assigned_place(*destination, |this| { this.visit_operand(func, location); for arg in args { this.visit_operand(arg, location); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 017d9e74dc4..66fb01bd464 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -248,7 +248,7 @@ impl<'tcx> Inliner<'tcx> { ) -> Option<CallSite<'tcx>> { // Only consider direct calls to functions let terminator = bb_data.terminator(); - if let TerminatorKind::Call { ref func, ref destination, .. } = terminator.kind { + if let TerminatorKind::Call { ref func, target, .. } = terminator.kind { let func_ty = func.ty(caller_body, self.tcx); if let ty::FnDef(def_id, substs) = *func_ty.kind() { // To resolve an instance its substs have to be fully normalized. @@ -266,7 +266,7 @@ impl<'tcx> Inliner<'tcx> { callee, fn_sig, block: bb, - target: destination.map(|(_, target)| target), + target, source_info: terminator.source_info, }); } @@ -395,7 +395,7 @@ impl<'tcx> Inliner<'tcx> { } } - TerminatorKind::Unreachable | TerminatorKind::Call { destination: None, .. } + TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. } if first_block => { // If the function always diverges, don't inline @@ -512,27 +512,22 @@ impl<'tcx> Inliner<'tcx> { false } - let dest = if let Some((destination_place, _)) = destination { - if dest_needs_borrow(destination_place) { - trace!("creating temp for return destination"); - let dest = Rvalue::Ref( - self.tcx.lifetimes.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, - destination_place, - ); - let dest_ty = dest.ty(caller_body, self.tcx); - let temp = Place::from(self.new_call_temp(caller_body, &callsite, dest_ty)); - caller_body[callsite.block].statements.push(Statement { - source_info: callsite.source_info, - kind: StatementKind::Assign(Box::new((temp, dest))), - }); - self.tcx.mk_place_deref(temp) - } else { - destination_place - } + let dest = if dest_needs_borrow(destination) { + trace!("creating temp for return destination"); + let dest = Rvalue::Ref( + self.tcx.lifetimes.re_erased, + BorrowKind::Mut { allow_two_phase_borrow: false }, + destination, + ); + let dest_ty = dest.ty(caller_body, self.tcx); + let temp = Place::from(self.new_call_temp(caller_body, &callsite, dest_ty)); + caller_body[callsite.block].statements.push(Statement { + source_info: callsite.source_info, + kind: StatementKind::Assign(Box::new((temp, dest))), + }); + self.tcx.mk_place_deref(temp) } else { - trace!("creating temp for return place"); - Place::from(self.new_call_temp(caller_body, &callsite, callee_body.return_ty())) + destination }; // Copy the arguments if needed. @@ -914,8 +909,8 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { *unwind = self.cleanup_block; } } - TerminatorKind::Call { ref mut destination, ref mut cleanup, .. } => { - if let Some((_, ref mut tgt)) = *destination { + TerminatorKind::Call { ref mut target, ref mut cleanup, .. } => { + if let Some(ref mut tgt) = *target { *tgt = self.map_block(*tgt); } if let Some(tgt) = *cleanup { diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 268ce1b2e8c..4fbb7643378 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -141,7 +141,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { terminator: &mut Terminator<'tcx>, statements: &mut Vec<Statement<'tcx>>, ) { - let TerminatorKind::Call { func, args, destination, .. } = &mut terminator.kind + let TerminatorKind::Call { func, args, destination, target, .. } = &mut terminator.kind else { return }; // It's definitely not a clone if there are multiple arguments @@ -149,7 +149,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { return; } - let Some((destination_place, destination_block)) = *destination + let Some(destination_block) = *target else { return }; // Only bother looking more if it's easy to know what we're calling @@ -193,7 +193,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Assign(Box::new(( - destination_place, + *destination, Rvalue::Use(Operand::Copy( arg_place.project_deeper(&[ProjectionElem::Deref], self.tcx), )), diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index d0d0e09d525..65801069560 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -14,7 +14,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); for block in basic_blocks { let terminator = block.terminator.as_mut().unwrap(); - if let TerminatorKind::Call { func, args, destination, .. } = &mut terminator.kind { + if let TerminatorKind::Call { func, args, destination, target, .. } = + &mut terminator.kind + { let func_ty = func.ty(local_decls, tcx); let Some((intrinsic_name, substs)) = resolve_rust_intrinsic(tcx, func_ty) else { continue; @@ -24,11 +26,11 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Unreachable; } sym::forget => { - if let Some((destination, target)) = *destination { + if let Some(target) = *target { block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Assign(Box::new(( - destination, + *destination, Rvalue::Use(Operand::Constant(Box::new(Constant { span: terminator.source_info.span, user_ty: None, @@ -40,7 +42,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } sym::copy_nonoverlapping => { - let target = destination.unwrap().1; + let target = target.unwrap(); let mut args = args.drain(..); block.statements.push(Statement { source_info: terminator.source_info, @@ -61,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => { - if let Some((destination, target)) = *destination { + if let Some(target) = *target { let lhs; let rhs; { @@ -78,7 +80,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Assign(Box::new(( - destination, + *destination, Rvalue::BinaryOp(bin_op, Box::new((lhs, rhs))), ))), }); @@ -91,7 +93,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { // during codegen. Issue #35310. } sym::size_of | sym::min_align_of => { - if let Some((destination, target)) = *destination { + if let Some(target) = *target { let tp_ty = substs.type_at(0); let null_op = match intrinsic_name { sym::size_of => NullOp::SizeOf, @@ -101,7 +103,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Assign(Box::new(( - destination, + *destination, Rvalue::NullaryOp(null_op, tp_ty), ))), }); @@ -109,14 +111,12 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { } } sym::discriminant_value => { - if let (Some((destination, target)), Some(arg)) = - (*destination, args[0].place()) - { + if let (Some(target), Some(arg)) = (*target, args[0].place()) { let arg = tcx.mk_place_deref(arg); block.statements.push(Statement { source_info: terminator.source_info, kind: StatementKind::Assign(Box::new(( - destination, + *destination, Rvalue::Discriminant(arg), ))), }); diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index 43d1d62a21e..07163cfe575 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -52,7 +52,8 @@ fn lower_slice_len_call<'tcx>( TerminatorKind::Call { func, args, - destination: Some((dest, bb)), + destination, + target: Some(bb), cleanup: None, from_hir_call: true, .. @@ -73,7 +74,8 @@ fn lower_slice_len_call<'tcx>( // make new RValue for Len let deref_arg = tcx.mk_place_deref(arg); let r_value = Rvalue::Len(deref_arg); - let len_statement_kind = StatementKind::Assign(Box::new((*dest, r_value))); + let len_statement_kind = + StatementKind::Assign(Box::new((*destination, r_value))); let add_statement = Statement { kind: len_statement_kind, source_info: terminator.source_info }; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 016b3bc0980..78a4ece2ecb 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -450,7 +450,8 @@ impl<'tcx> CloneShimBuilder<'tcx> { TerminatorKind::Call { func, args: vec![Operand::Move(ref_loc)], - destination: Some((dest, next)), + destination: dest, + target: Some(next), cleanup: Some(cleanup), from_hir_call: true, fn_span: self.span, @@ -676,7 +677,8 @@ fn build_call_shim<'tcx>( TerminatorKind::Call { func: callee, args, - destination: Some((Place::return_place(), BasicBlock::new(1))), + destination: Place::return_place(), + target: Some(BasicBlock::new(1)), cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment { Some(BasicBlock::new(3)) } else { |
